rtgui/cropwindow: Improve behavior with smooth scrolling devices

Accumulate/coalesce GDK_SCROLL_SMOOTH events until we equal or exceed +/-1.0

This avoids having one zoom adjustment for every single event which makes touchpad zooming unusable due to frequent
small deltas

This makes trackpad zooming usable while having no effect on mice that emit GDK_SMOOTH_SCROLL with values of +/-1.0 instead
of GDK_SCROLL_UP and GDK_SCROLL_DOWN

If any mice exist that have scroll wheel detents but emit smaller values per detent, this may have the negative effect of
requiring multiple detents per zoom level.  It remains to be seen whether any mice behave like this.  The discrete step
implementation of zoomSteps requires us to coalesce events instead of smoothly zooming in and out.
This commit is contained in:
Andy Dodd 2019-08-28 18:40:00 -04:00
parent dadf01fe95
commit 1a6d1b038f
2 changed files with 11 additions and 5 deletions

View File

@ -51,7 +51,7 @@ CropWindow::CropWindow (ImageArea* parent, bool isLowUpdatePriority_, bool isDet
backColor(options.bgcolor), decorated(true), isFlawnOver(false), titleHeight(30), sideBorderWidth(3), lowerBorderWidth(3),
upperBorderWidth(1), sepWidth(2), xpos(30), ypos(30), width(0), height(0), imgAreaX(0), imgAreaY(0), imgAreaW(0), imgAreaH(0),
imgX(-1), imgY(-1), imgW(1), imgH(1), iarea(parent), cropZoom(0), zoomVersion(0), exposeVersion(0), cropgl(nullptr),
pmlistener(nullptr), pmhlistener(nullptr), observedCropWin(nullptr),
pmlistener(nullptr), pmhlistener(nullptr), scrollAccum(0.0), observedCropWin(nullptr),
crop_custom_ratio(0.f)
{
initZoomSteps();
@ -295,11 +295,16 @@ void CropWindow::scroll (int state, GdkScrollDirection direction, int x, int y,
} else {
delta = deltaY;
}
if (delta == 0.0 && direction == GDK_SCROLL_SMOOTH) {
// sometimes this case happens. To avoid zooming into the wrong direction in this case, we just do nothing
return;
if (direction == GDK_SCROLL_SMOOTH) {
scrollAccum += delta;
//Only change zoom level if we've accumulated +/- 1.0 of deltas. This conditional handles the previous delta=0.0 case
if (abs(scrollAccum) < 1.0) {
return;
}
}
bool isUp = direction == GDK_SCROLL_UP || (direction == GDK_SCROLL_SMOOTH && delta < 0.0);
bool isUp = direction == GDK_SCROLL_UP || (direction == GDK_SCROLL_SMOOTH && scrollAccum < 0.0);
scrollAccum = 0.0;
if ((state & GDK_CONTROL_MASK) && onArea(ColorPicker, x, y)) {
// resizing a color picker
if (isUp) {

View File

@ -102,6 +102,7 @@ class CropWindow : public LWButtonListener, public CropDisplayHandler, public Ed
PointerMotionListener* pmlistener;
PointerMotionListener* pmhlistener;
std::list<CropWindowListener*> listeners;
double scrollAccum;
CropWindow* observedCropWin; // Pointer to the currently active detail CropWindow