mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
Scroll Using Click-and-Drag with Middle Mouse Button (#1559)
* ChannelView: Rename mouse event related members This is more in line with the naming of the other members as well as future members. * ChannelView: Add ability to scroll with middle mouse button * Add scrolling resources * Use custom icons for scroll cursor * Slightly refactor scrolling logic * Respect screen scaling when calculating scroll offset * Nicer scrolling UX This change allows scrolling to be feel smoother when close to the starting point. * Add scrolling with keeping middle mouse pressed This mimics the behavior of browsers as well. * Refactor ChannelView::enableScrolling * Disable drag-scrolling on left or right click
This commit is contained in:
parent
2076715e23
commit
b4a2ced180
|
@ -28,8 +28,9 @@
|
||||||
<file>buttons/unmod.png</file>
|
<file>buttons/unmod.png</file>
|
||||||
<file>buttons/update.png</file>
|
<file>buttons/update.png</file>
|
||||||
<file>buttons/updateError.png</file>
|
<file>buttons/updateError.png</file>
|
||||||
<file>com.chatterino.chatterino.desktop</file>
|
|
||||||
<file>chatterino.icns</file>
|
<file>chatterino.icns</file>
|
||||||
|
<file>com.chatterino.chatterino.appdata.xml</file>
|
||||||
|
<file>com.chatterino.chatterino.desktop</file>
|
||||||
<file>contributors.txt</file>
|
<file>contributors.txt</file>
|
||||||
<file>emoji.json</file>
|
<file>emoji.json</file>
|
||||||
<file>emojidata.txt</file>
|
<file>emojidata.txt</file>
|
||||||
|
@ -50,6 +51,12 @@
|
||||||
<file>licenses/websocketpp.txt</file>
|
<file>licenses/websocketpp.txt</file>
|
||||||
<file>pajaDank.png</file>
|
<file>pajaDank.png</file>
|
||||||
<file>qss/settings.qss</file>
|
<file>qss/settings.qss</file>
|
||||||
|
<file>scrolling/downScroll.png</file>
|
||||||
|
<file>scrolling/downScroll.svg</file>
|
||||||
|
<file>scrolling/neutralScroll.png</file>
|
||||||
|
<file>scrolling/neutralScroll.svg</file>
|
||||||
|
<file>scrolling/upScroll.png</file>
|
||||||
|
<file>scrolling/upScroll.svg</file>
|
||||||
<file>settings/about.svg</file>
|
<file>settings/about.svg</file>
|
||||||
<file>settings/aboutlogo.png</file>
|
<file>settings/aboutlogo.png</file>
|
||||||
<file>settings/accounts.svg</file>
|
<file>settings/accounts.svg</file>
|
||||||
|
|
BIN
resources/scrolling/downScroll.png
Normal file
BIN
resources/scrolling/downScroll.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
96
resources/scrolling/downScroll.svg
Normal file
96
resources/scrolling/downScroll.svg
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
viewBox="0 0 8.4666665 8.4666669"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||||
|
sodipodi:docname="downScroll.svg"
|
||||||
|
inkscape:export-filename="/home/leon/Projects/Chatterino/chatterino2/resources/scrolling/neutralScroll.png"
|
||||||
|
inkscape:export-xdpi="7.6051788"
|
||||||
|
inkscape:export-ydpi="7.6051788">
|
||||||
|
<defs
|
||||||
|
id="defs2" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="15.839192"
|
||||||
|
inkscape:cx="14.417768"
|
||||||
|
inkscape:cy="15.865661"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:window-width="1918"
|
||||||
|
inkscape:window-height="1053"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="25"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
units="px"
|
||||||
|
inkscape:pagecheckerboard="true">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid4532" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(0,-288.53332)">
|
||||||
|
<circle
|
||||||
|
style="fill:#f6f6f6;fill-opacity:1;stroke:#000000;stroke-width:0.03761128;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path3719"
|
||||||
|
cx="4.2333331"
|
||||||
|
cy="292.76666"
|
||||||
|
r="4.2145276" />
|
||||||
|
<circle
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.05049507;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path4526"
|
||||||
|
cx="4.2333317"
|
||||||
|
cy="292.76425"
|
||||||
|
r="0.72627902" />
|
||||||
|
<path
|
||||||
|
sodipodi:type="star"
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.56499994;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path4538"
|
||||||
|
sodipodi:sides="3"
|
||||||
|
sodipodi:cx="99.21875"
|
||||||
|
sodipodi:cy="155.44792"
|
||||||
|
sodipodi:r1="13.229166"
|
||||||
|
sodipodi:r2="6.614583"
|
||||||
|
sodipodi:arg1="0"
|
||||||
|
sodipodi:arg2="1.0471976"
|
||||||
|
inkscape:flatsided="true"
|
||||||
|
inkscape:rounded="0"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="m 112.44792,155.44792 -19.843753,11.4568 v -22.91359 z"
|
||||||
|
inkscape:transform-center-x="5.0649804e-06"
|
||||||
|
inkscape:transform-center-y="2.2264812"
|
||||||
|
transform="matrix(0,0.09239709,-0.09239709,0,18.596269,286.19867)" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
BIN
resources/scrolling/neutralScroll.png
Normal file
BIN
resources/scrolling/neutralScroll.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
122
resources/scrolling/neutralScroll.svg
Normal file
122
resources/scrolling/neutralScroll.svg
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
viewBox="0 0 8.4666665 8.4666669"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||||
|
sodipodi:docname="neutralScroll.svg"
|
||||||
|
inkscape:export-filename="/home/leon/Projects/Chatterino/chatterino2/resources/scrolling/neutralScroll.png"
|
||||||
|
inkscape:export-xdpi="7.6051788"
|
||||||
|
inkscape:export-ydpi="7.6051788">
|
||||||
|
<defs
|
||||||
|
id="defs2" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="15.839192"
|
||||||
|
inkscape:cx="25.340042"
|
||||||
|
inkscape:cy="15.865661"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:window-width="1918"
|
||||||
|
inkscape:window-height="1053"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="25"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
units="px"
|
||||||
|
inkscape:pagecheckerboard="true">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid4532" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(0,-288.53332)">
|
||||||
|
<g
|
||||||
|
id="g5271"
|
||||||
|
transform="matrix(0.07922061,0,0,0.07922061,-4.1782222,281.17363)">
|
||||||
|
<circle
|
||||||
|
r="53.199886"
|
||||||
|
cy="146.33852"
|
||||||
|
cx="106.17888"
|
||||||
|
id="path3719"
|
||||||
|
style="fill:#f6f6f6;fill-opacity:1;stroke:#000000;stroke-width:0.47476631;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||||
|
<g
|
||||||
|
transform="matrix(1.7324984,0,0,1.7324984,-77.775866,-107.19273)"
|
||||||
|
id="g4665">
|
||||||
|
<circle
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.36790693;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path4526"
|
||||||
|
cx="106.17887"
|
||||||
|
cy="146.32092"
|
||||||
|
r="5.2916665" />
|
||||||
|
<path
|
||||||
|
sodipodi:type="star"
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.56499994;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path4538"
|
||||||
|
sodipodi:sides="3"
|
||||||
|
sodipodi:cx="99.21875"
|
||||||
|
sodipodi:cy="155.44792"
|
||||||
|
sodipodi:r1="13.229166"
|
||||||
|
sodipodi:r2="6.614583"
|
||||||
|
sodipodi:arg1="0"
|
||||||
|
sodipodi:arg2="1.0471976"
|
||||||
|
inkscape:flatsided="true"
|
||||||
|
inkscape:rounded="0"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="m 112.44792,155.44792 -19.843753,11.4568 v -22.91359 z"
|
||||||
|
inkscape:transform-center-x="5.0649804e-06"
|
||||||
|
inkscape:transform-center-y="2.2264812"
|
||||||
|
transform="matrix(0,0.67320493,-0.67320493,0,210.82719,98.484167)" />
|
||||||
|
<path
|
||||||
|
transform="matrix(0,-0.67320493,-0.67320493,0,210.82719,194.19287)"
|
||||||
|
inkscape:transform-center-y="-2.2264854"
|
||||||
|
inkscape:transform-center-x="5.0649804e-06"
|
||||||
|
d="m 112.44792,155.44792 -19.843753,11.4568 v -22.91359 z"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
inkscape:rounded="0"
|
||||||
|
inkscape:flatsided="true"
|
||||||
|
sodipodi:arg2="1.0471976"
|
||||||
|
sodipodi:arg1="0"
|
||||||
|
sodipodi:r2="6.614583"
|
||||||
|
sodipodi:r1="13.229166"
|
||||||
|
sodipodi:cy="155.44792"
|
||||||
|
sodipodi:cx="99.21875"
|
||||||
|
sodipodi:sides="3"
|
||||||
|
id="path4540"
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.56499994;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
sodipodi:type="star" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.2 KiB |
BIN
resources/scrolling/upScroll.png
Normal file
BIN
resources/scrolling/upScroll.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
96
resources/scrolling/upScroll.svg
Normal file
96
resources/scrolling/upScroll.svg
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
viewBox="0 0 8.4666665 8.4666669"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||||
|
sodipodi:docname="upScroll.svg"
|
||||||
|
inkscape:export-filename="/home/leon/Projects/Chatterino/chatterino2/resources/scrolling/neutralScroll.png"
|
||||||
|
inkscape:export-xdpi="7.6051788"
|
||||||
|
inkscape:export-ydpi="7.6051788">
|
||||||
|
<defs
|
||||||
|
id="defs2" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="15.839192"
|
||||||
|
inkscape:cx="14.417768"
|
||||||
|
inkscape:cy="15.865661"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:window-width="1918"
|
||||||
|
inkscape:window-height="1053"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="25"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
units="px"
|
||||||
|
inkscape:pagecheckerboard="true">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid4532" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(0,-288.53332)">
|
||||||
|
<circle
|
||||||
|
style="fill:#f6f6f6;fill-opacity:1;stroke:#000000;stroke-width:0.03761128;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path3719"
|
||||||
|
cx="4.2333331"
|
||||||
|
cy="292.76666"
|
||||||
|
r="4.2145276" />
|
||||||
|
<circle
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.05049507;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path4526"
|
||||||
|
cx="4.2333317"
|
||||||
|
cy="292.76425"
|
||||||
|
r="0.72627902" />
|
||||||
|
<path
|
||||||
|
transform="matrix(0,-0.09239709,-0.09239709,0,18.596269,299.33465)"
|
||||||
|
inkscape:transform-center-y="-2.2264854"
|
||||||
|
inkscape:transform-center-x="5.0649804e-06"
|
||||||
|
d="m 112.44792,155.44792 -19.843753,11.4568 v -22.91359 z"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
inkscape:rounded="0"
|
||||||
|
inkscape:flatsided="true"
|
||||||
|
sodipodi:arg2="1.0471976"
|
||||||
|
sodipodi:arg1="0"
|
||||||
|
sodipodi:r2="6.614583"
|
||||||
|
sodipodi:r1="13.229166"
|
||||||
|
sodipodi:cy="155.44792"
|
||||||
|
sodipodi:cx="99.21875"
|
||||||
|
sodipodi:sides="3"
|
||||||
|
id="path4540"
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.56499994;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
sodipodi:type="star" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
|
@ -30,6 +30,9 @@ Resources2::Resources2()
|
||||||
this->error = QPixmap(":/error.png");
|
this->error = QPixmap(":/error.png");
|
||||||
this->icon = QPixmap(":/icon.png");
|
this->icon = QPixmap(":/icon.png");
|
||||||
this->pajaDank = QPixmap(":/pajaDank.png");
|
this->pajaDank = QPixmap(":/pajaDank.png");
|
||||||
|
this->scrolling.downScroll = QPixmap(":/scrolling/downScroll.png");
|
||||||
|
this->scrolling.neutralScroll = QPixmap(":/scrolling/neutralScroll.png");
|
||||||
|
this->scrolling.upScroll = QPixmap(":/scrolling/upScroll.png");
|
||||||
this->settings.aboutlogo = QPixmap(":/settings/aboutlogo.png");
|
this->settings.aboutlogo = QPixmap(":/settings/aboutlogo.png");
|
||||||
this->split.down = QPixmap(":/split/down.png");
|
this->split.down = QPixmap(":/split/down.png");
|
||||||
this->split.left = QPixmap(":/split/left.png");
|
this->split.left = QPixmap(":/split/left.png");
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
|
|
||||||
#include "common/Singleton.hpp"
|
#include "common/Singleton.hpp"
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
@ -39,6 +38,11 @@ public:
|
||||||
QPixmap error;
|
QPixmap error;
|
||||||
QPixmap icon;
|
QPixmap icon;
|
||||||
QPixmap pajaDank;
|
QPixmap pajaDank;
|
||||||
|
struct {
|
||||||
|
QPixmap downScroll;
|
||||||
|
QPixmap neutralScroll;
|
||||||
|
QPixmap upScroll;
|
||||||
|
} scrolling;
|
||||||
struct {
|
struct {
|
||||||
QPixmap aboutlogo;
|
QPixmap aboutlogo;
|
||||||
} settings;
|
} settings;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <QGraphicsBlurEffect>
|
#include <QGraphicsBlurEffect>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
#include <QScreen>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
@ -25,6 +26,7 @@
|
||||||
#include "messages/layouts/MessageLayoutElement.hpp"
|
#include "messages/layouts/MessageLayoutElement.hpp"
|
||||||
#include "providers/twitch/TwitchChannel.hpp"
|
#include "providers/twitch/TwitchChannel.hpp"
|
||||||
#include "providers/twitch/TwitchIrcServer.hpp"
|
#include "providers/twitch/TwitchIrcServer.hpp"
|
||||||
|
#include "singletons/Resources.hpp"
|
||||||
#include "singletons/Settings.hpp"
|
#include "singletons/Settings.hpp"
|
||||||
#include "singletons/Theme.hpp"
|
#include "singletons/Theme.hpp"
|
||||||
#include "singletons/TooltipPreviewImage.hpp"
|
#include "singletons/TooltipPreviewImage.hpp"
|
||||||
|
@ -114,6 +116,10 @@ ChannelView::ChannelView(BaseWidget *parent)
|
||||||
this->initializeScrollbar();
|
this->initializeScrollbar();
|
||||||
this->initializeSignals();
|
this->initializeSignals();
|
||||||
|
|
||||||
|
this->cursors_.neutral = QCursor(getResources().scrolling.neutralScroll);
|
||||||
|
this->cursors_.up = QCursor(getResources().scrolling.upScroll);
|
||||||
|
this->cursors_.down = QCursor(getResources().scrolling.downScroll);
|
||||||
|
|
||||||
this->pauseTimer_.setSingleShot(true);
|
this->pauseTimer_.setSingleShot(true);
|
||||||
QObject::connect(&this->pauseTimer_, &QTimer::timeout, this, [this] {
|
QObject::connect(&this->pauseTimer_, &QTimer::timeout, this, [this] {
|
||||||
/// remove elements that are finite
|
/// remove elements that are finite
|
||||||
|
@ -131,6 +137,10 @@ ChannelView::ChannelView(BaseWidget *parent)
|
||||||
this->clickTimer_->setSingleShot(true);
|
this->clickTimer_->setSingleShot(true);
|
||||||
this->clickTimer_->setInterval(500);
|
this->clickTimer_->setInterval(500);
|
||||||
|
|
||||||
|
this->scrollTimer_.setInterval(20);
|
||||||
|
QObject::connect(&this->scrollTimer_, &QTimer::timeout, this,
|
||||||
|
&ChannelView::scrollUpdateRequested);
|
||||||
|
|
||||||
this->setFocusPolicy(Qt::FocusPolicy::StrongFocus);
|
this->setFocusPolicy(Qt::FocusPolicy::StrongFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1060,8 +1070,13 @@ void ChannelView::mouseMoveEvent(QMouseEvent *event)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->isScrolling_)
|
||||||
|
{
|
||||||
|
this->currentMousePosition_ = event->screenPos();
|
||||||
|
}
|
||||||
|
|
||||||
// is selecting
|
// is selecting
|
||||||
if (this->isMouseDown_)
|
if (this->isLeftMouseDown_)
|
||||||
{
|
{
|
||||||
// this->pause(PauseReason::Selecting, 300);
|
// this->pause(PauseReason::Selecting, 300);
|
||||||
int index = layout->getSelectionIndex(relativePos);
|
int index = layout->getSelectionIndex(relativePos);
|
||||||
|
@ -1326,8 +1341,11 @@ void ChannelView::mousePressEvent(QMouseEvent *event)
|
||||||
switch (event->button())
|
switch (event->button())
|
||||||
{
|
{
|
||||||
case Qt::LeftButton: {
|
case Qt::LeftButton: {
|
||||||
this->lastPressPosition_ = event->screenPos();
|
if (this->isScrolling_)
|
||||||
this->isMouseDown_ = true;
|
this->disableScrolling();
|
||||||
|
|
||||||
|
this->lastLeftPressPosition_ = event->screenPos();
|
||||||
|
this->isLeftMouseDown_ = true;
|
||||||
|
|
||||||
if (layout->flags.has(MessageLayoutFlag::Collapsed))
|
if (layout->flags.has(MessageLayoutFlag::Collapsed))
|
||||||
return;
|
return;
|
||||||
|
@ -1344,11 +1362,22 @@ void ChannelView::mousePressEvent(QMouseEvent *event)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::RightButton: {
|
case Qt::RightButton: {
|
||||||
|
if (this->isScrolling_)
|
||||||
|
this->disableScrolling();
|
||||||
|
|
||||||
this->lastRightPressPosition_ = event->screenPos();
|
this->lastRightPressPosition_ = event->screenPos();
|
||||||
this->isRightMouseDown_ = true;
|
this->isRightMouseDown_ = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Qt::MiddleButton: {
|
||||||
|
if (this->isScrolling_)
|
||||||
|
this->disableScrolling();
|
||||||
|
else
|
||||||
|
this->enableScrolling(event->screenPos());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1373,11 +1402,11 @@ void ChannelView::mouseReleaseEvent(QMouseEvent *event)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (this->isMouseDown_)
|
else if (this->isLeftMouseDown_)
|
||||||
{
|
{
|
||||||
this->isMouseDown_ = false;
|
this->isLeftMouseDown_ = false;
|
||||||
|
|
||||||
if (fabsf(distanceBetweenPoints(this->lastPressPosition_,
|
if (fabsf(distanceBetweenPoints(this->lastLeftPressPosition_,
|
||||||
event->screenPos())) > 15.f)
|
event->screenPos())) > 15.f)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -1405,6 +1434,13 @@ void ChannelView::mouseReleaseEvent(QMouseEvent *event)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (event->button() == Qt::MiddleButton)
|
||||||
|
{
|
||||||
|
if (event->screenPos() == this->lastMiddlePressPosition_)
|
||||||
|
this->enableScrolling(event->screenPos());
|
||||||
|
else
|
||||||
|
this->disableScrolling();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// not left or right button
|
// not left or right button
|
||||||
|
@ -1638,7 +1674,7 @@ void ChannelView::mouseDoubleClickEvent(QMouseEvent *event)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this->isMouseDown_)
|
if (!this->isLeftMouseDown_)
|
||||||
{
|
{
|
||||||
this->isDoubleClick_ = true;
|
this->isDoubleClick_ = true;
|
||||||
|
|
||||||
|
@ -1803,4 +1839,59 @@ void ChannelView::getWordBounds(MessageLayout *layout,
|
||||||
wordEnd = wordStart + length;
|
wordEnd = wordStart + length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChannelView::enableScrolling(const QPointF &scrollStart)
|
||||||
|
{
|
||||||
|
this->isScrolling_ = true;
|
||||||
|
this->lastMiddlePressPosition_ = scrollStart;
|
||||||
|
// The line below prevents a sudden jerk at the beginning
|
||||||
|
this->currentMousePosition_ = scrollStart;
|
||||||
|
|
||||||
|
this->scrollTimer_.start();
|
||||||
|
|
||||||
|
if (!QGuiApplication::overrideCursor())
|
||||||
|
QGuiApplication::setOverrideCursor(this->cursors_.neutral);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChannelView::disableScrolling()
|
||||||
|
{
|
||||||
|
this->isScrolling_ = false;
|
||||||
|
this->scrollTimer_.stop();
|
||||||
|
QGuiApplication::restoreOverrideCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChannelView::scrollUpdateRequested()
|
||||||
|
{
|
||||||
|
const qreal dpi =
|
||||||
|
QGuiApplication::screenAt(this->pos())->devicePixelRatio();
|
||||||
|
const qreal delta = dpi * (this->currentMousePosition_.y() -
|
||||||
|
this->lastMiddlePressPosition_.y());
|
||||||
|
const int cursorHeight = this->cursors_.neutral.pixmap().height();
|
||||||
|
|
||||||
|
if (fabs(delta) <= cursorHeight * dpi)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If within an area close to the initial position, don't do any
|
||||||
|
* scrolling at all.
|
||||||
|
*/
|
||||||
|
QGuiApplication::changeOverrideCursor(this->cursors_.neutral);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal offset;
|
||||||
|
if (delta > 0)
|
||||||
|
{
|
||||||
|
QGuiApplication::changeOverrideCursor(this->cursors_.down);
|
||||||
|
offset = delta - cursorHeight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QGuiApplication::changeOverrideCursor(this->cursors_.up);
|
||||||
|
offset = delta + cursorHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "Good" feeling multiplier found by trial-and-error
|
||||||
|
const qreal multiplier = qreal(0.02);
|
||||||
|
this->scrollBar_->offset(multiplier * offset);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -148,6 +148,9 @@ private:
|
||||||
void updatePauses();
|
void updatePauses();
|
||||||
void unpaused();
|
void unpaused();
|
||||||
|
|
||||||
|
void enableScrolling(const QPointF &scrollStart);
|
||||||
|
void disableScrolling();
|
||||||
|
|
||||||
QTimer *layoutCooldown_;
|
QTimer *layoutCooldown_;
|
||||||
bool layoutQueued_;
|
bool layoutQueued_;
|
||||||
|
|
||||||
|
@ -183,15 +186,26 @@ private:
|
||||||
bool onlyUpdateEmotes_ = false;
|
bool onlyUpdateEmotes_ = false;
|
||||||
|
|
||||||
// Mouse event variables
|
// Mouse event variables
|
||||||
bool isMouseDown_ = false;
|
bool isLeftMouseDown_ = false;
|
||||||
bool isRightMouseDown_ = false;
|
bool isRightMouseDown_ = false;
|
||||||
bool isDoubleClick_ = false;
|
bool isDoubleClick_ = false;
|
||||||
DoubleClickSelection doubleClickSelection_;
|
DoubleClickSelection doubleClickSelection_;
|
||||||
QPointF lastPressPosition_;
|
QPointF lastLeftPressPosition_;
|
||||||
QPointF lastRightPressPosition_;
|
QPointF lastRightPressPosition_;
|
||||||
QPointF lastDClickPosition_;
|
QPointF lastDClickPosition_;
|
||||||
QTimer *clickTimer_;
|
QTimer *clickTimer_;
|
||||||
|
|
||||||
|
bool isScrolling_ = false;
|
||||||
|
QPointF lastMiddlePressPosition_;
|
||||||
|
QPointF currentMousePosition_;
|
||||||
|
QTimer scrollTimer_;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
QCursor neutral;
|
||||||
|
QCursor up;
|
||||||
|
QCursor down;
|
||||||
|
} cursors_;
|
||||||
|
|
||||||
Selection selection_;
|
Selection selection_;
|
||||||
bool selecting_ = false;
|
bool selecting_ = false;
|
||||||
|
|
||||||
|
@ -211,6 +225,8 @@ private slots:
|
||||||
queueLayout();
|
queueLayout();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void scrollUpdateRequested();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
Loading…
Reference in a new issue