GtkImageView
ToDo
The Google Summer of Code is over and the widget is not 100% done. Current TODO items:
- Implement the rotate-around-point behavior. This is what I'm currently working on and it's driving me crazy.
- See whether to keep the prepare-image signal or not.
- Add more documentation (see the placeholders for properties) and add proper transfer annotations
- Before merging, I'd like to port eog to it in order to find missing functionality or inconsistencies.
GtkImageView is supposed to be a widget to present an image to the user. Features include gestures to rotate/scale the image, different zoom modes (see below), etc.
Relevant bug report in Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=726490
API
GtkImageView is a GtkWidget subclass and implements GtkScrollable.
There are currently 3 zoom modes:
- GTK_IMAGE_VIEW_ZOOM_MODE_FIT: The minimum size of the widget is 1×1, the natural size the image's size. if the widget's allocation is smaller than the image's size, the image gets scalled to the allocation (i.e. we never scale it up).
- GTK_IMAGE_VIEW_ZOOM_MODE_ORIGINAL: Minimum size of the widget is the image's size. The image doesn't get scaled.
- GTK_IMAGE_VIEW_ZOOM_MODE_NONE: See question at the end
So, these seem to be weird to me. When using FIT, setting the scale property manually doesn'y make sense*, because the "output" size, i.e. the size we draw the image in is determined by the widget allocation. So NONE would be "use the scale property to determine the output size (and nothing else), but make sure the final image can be seen, so set the minimum size to the output size". However, that's exactly what ORIGINAL is, except for the part that ORIGINAL never cares about the scale property. So on closer inspection, it seems like it makes sense to reduce that to 2 zoom modes and use ORIGINAL for "I want to zoom in or out but keep the widget at the output size".
OTOH none of these make sense for e.g. eog, which tries to keep the image at the window size (i.e. FIT) until the user zooms in/out, in which case the image can take any size (i.e. ORIGINAL).
Also, when rotating using gestures, the corners of the rotated image should probably be cut off, which none of the zoom modes do currently (maybe do that using a property?)
Of course now ORIGINAL should maybe be renamed to something else.
* How to handle? Just print a warning and don't set the scale?
Constructors:
- gtk_image_view_new ()
Loading:
gtk_image_view_load_from_file_async (GtkImageView, GFile)
gtk_image_view_load_from_stream_async (GtkImageView, GInputStream)
Properties:
- zoom-mode
- scale
- angle
- zoom-gesture-enabled
- rotate-gesture-enabled
(GtkScrollable properties)
Signals:
prepare-image: Gets emitted everytime we update the internal cairo surface so things like cropping can be implemented Doesn't work, you can't resize a cairo_surface.
Additional Use Cases
gnome-photos uses gegl to apply filters, etc. to the image, then lets gegl draw its buffer on a cairo_surface. So it'd need to pass just that cairo_surface to GtkImageView. Theoretically this is possible right now using the prepare-image signal, but you'd still need to load an image in the correct size so GtkImageView creates the appropriate cairo_surface.
- In addition to 1), gegl can use mipmap based rendering when scaling the image down, but in that case we need information about in which size we will draw the surface (in the prepare-image signal).
Cropping isn't doable using cairo surfaces. One way to implement it is to take the GdkPixbuf and gdk_pixbuf_copy_area a part from it, then set it on the GtkImageView again (needs setter for the pixbuf, unless we want the user to create a GMemoryInputStream for the pixbuf, etc.). gnome-photos however uses (read: will use) gegl to crop, then draws its buffer on the cairo_surface again, etc.
- Additionally, rishi wants to draw the cropping UI (a simple rectangle probably) directly on the surface.
Open Questions
- Even if you enable the rotation gesture, most image viewers constrain the image rotation to 90 degree steps, so we probably want to do that (optionally) as well.
- Are other zoom modes needed?
Controlling the scale/angle properties "manually" like e.g. eog does with its scale slider would reset the zoom-mode to NONE so the zoom modes only ever seem important for the initial view of the image and/or if the GtkImageView is not in a GtkScrolledWindow and just presents the image (with both gestures disabled).