There was one case where horizontally and vertically were mixed up in a
call to gimp_display_shell_scale_image_stops_to_fit.
The more usual order of parameters is first horizontal and then vertical.
So, let's fix the actual functions that have the illogical order
of vertically, horizontally instead of fixing the one call.
This brings it in line with the order in other functions and makes it less
likely we mistakenly mess up the parameters.
Besides that gimp_display_shell_scale_image_stops_to_fit also was not
declared as a local function, so we add that too.
Adds the new configuration option "drag-zoom-speed" to adjust the rate
at which mouse movement can zoom the canvas, ranging from 25% to 300%
of the base rate and applying to both drag-to-zoom modes.
This option can be found in the preferences dialog as:
Image Windows -> Zoom & Resize Behavior -> Drag-to-zoom speed
Adds a new configuration option "drag-zoom-mode" to choose whether to
zoom by distance of movement (newly added) or by duration of movement
(previous behavior) when zooming via dragging the mouse, defaulting to
distance.
This option can be found in the preferences dialog as:
Image Windows -> Zoom & Resize Behavior -> Drag-to-zoom behavior
Changes the behavior of gimp_display_shell_scale_drag() to factor in
the distance dragged, rather than just scaling a flat +/- 10% for each
detected movement event. The factor by which to change the scaling is
also altered from 10% at each movement event, to 1% compounded for
each pixel of distance dragged.
This makes zooming via Ctrl + Middle Click or Ctrl + Spacebar behave
more consistently and less jittery versus the previous method, while
offering more fine grained control.
This started as yet another report of leak by Massimo. But really the
leak of the GdkPoint created by the function
gimp_display_shell_push_zoom_focus_pointer_pos() is not only when
delta_y is 0. There are a few code paths in gimp_display_shell_scale()
when we would not pop this point. One of them is for instance when
window resizing in multi-window mode is allowed. There might be more
(but the code is convoluted enough not to be 100% sure if these are
possible with our specific case).
This specific function was initially created only to be used for unit
testing code (commit 7e3898da09), but it ended up being also used
internally (commit 792cd581a2). Since I see that the test for which
this code was initially created even seem broken right now (the assert
part for position check is commented out!), I even wonder if we should
keep it. We could indeed instead just add optional start_x|y arguments
to gimp_display_shell_scale(), which would be much cleaner. But I leave
it for now.
Instead I just make sure we clean the created GdkPoint after calling
gimp_display_shell_scale(). Also I get rid of the GQueue. It is clear in
the code that we are not expecting queuing interaction of several
positions. Worse right now, we could end up in weird cases where the
pushed points are not used when they should, then could end up being
used later in totally unrelated interactions (this would make the shell
position jump here and there). So let's just make it a single point.
Finally adding some appropriate comments in parts which are still a bit
wrong.
In "show all" mode, the image is thought to be "infinite"; this
commit improves the overall scrolling/zooming behavior in this mode
according to this assumption. In cases where a specific image size
is needed (e.g., for the scrollbar bounds, fit-image-in-window,
etc.), the image's full bounding box is used; however, in cases
where a center point is needed (e.g., for the zoomed-out scrollbar
bounds, center-image-in-window), the canvas center, rather than the
bounding-box center, is still used.
Add a "show all" mode to GimpDisplayShell, controlled through a
corresponding "View -> Show All" menu item. When enabled, the
entire image content is displayed, instead of cropping the image
to the canvas size. More generally, the display behaves as if the
canvas were infinite. The following commits improve the overall
behavior in this mode.
Add a prefernces option to control the default "show all" state.
Introduce a render cache that keeps the result of scaling, color
management, display filters and shell mask (for tools like fuzzy
select).
Change gimpdisplayshell-render.[ch] to only render to the cache and
manage a cairo region of the cache's valid area. Call cache
invalidation functions form various places. Change the API of all
render functions to be in display coordinates.
Also get rid of gimpdisplayxfer.[ch] because we now have a
canvas-sized cairo surface which is a surface similar to the
destination surface.
When Control-Button2-Zooming, remember the start point, pass it to
gimp_display_shell_scale_drag() and force gimp_display_shell_scale()
to zoom around that point by passing GIMP_ZOOM_FOCUS_POINTER and
faking the point using gimp_display_shell_push_zoom_focus_pointer_pos().
- Fix gimp_scroll_adjustment_values() for smooth scroll events
- Set GDK_SMOOTH_SCROLL_MASK on all widgets where we set GDK_SCROLL_MASK
- Add GIMP_ZOOM_SMOOTH to enum GimpZoomType
- Add "gdouble delta" to gimp_zoom_model_step()
- Change the meaning of the "scale" parameter to "scale or delta" in
all functions that take GimpZoomType and a scale factor.
... _even at low zoom levels_
Pass GIMP_ZOOM_FOCUS_POINTER to gimp_display_shell_scale() when
wheel-scrolling, and change the scaling code to really honor
GIMP_ZOOM_FOCUS_POINTER and not apply magic image centering.
This keep the same point centered under the mouse for wheel-scrolling
and the zoom tool (== when the zooming is really triggered at a
certain mouse position).
Place the rulers' origin at the top-left corner of the canvas
(screen space) bounding box, and set their scale to the image-
space scale along the screen-space horizontal/vertical directions
(in other words, measuring a distance using the rulers should
give the same results as the measure tool; note that rotation
comes into play here only when the horizontal and vertical
image or screen resolutions are different, since otherwise the
scale is direction invariant.)
Make scrollbar step match ruler step under the new behavior.
...several different zooms tiled together
In gimp_display_shell_scale() don't shortcut things in the case where
we resize the window, but call gimp_display_shell_scale_resize() like
all other scaling functions do in the end.
gimp_display_shell_scale_to(): calculate the point that should not
move with GimpDisplayShell's untransform/transform functions before
and after scaling, then scroll to the right point. Just using the
scale functions doesn't work any longer when a rotation is
active. Other functions are affected too, but this most important
issue can be fixed by fixing just this function.