I'm trying to implement an image viewer using GTK+3, and it's supposed to have two modes:
- Fit-to-something mode (fit-to-width/height)
- Original size mode
Now, in both modes, I need the image are to be scrollable, and in fit-to-X, I need to know the actual size of the "displayed image area" which is actually the directly visible window region. Also, since the window could be resized, I need to scale the image dynamically.
In Qt, it is just a breeze. No 3rd party libraries (gdkpixbuf), no need to create a custom widget, no worries.
I can set the image for a QLabel, and on resize, I can smoothly scale the image (without relying on any 3rd party libraries such as gdkpixbuf) to the new size (it seems it's not possible to get the current size with GTK+ due to some convoluted reasons which clearly don't apply to Qt; in order to get the size of the "image arena", Comix gets the total window dimensions, subtracts dimensions of menubar, scrollbar, toolbar and scrollbars in get_visible_area_size if they are visible!) . With correct parameters, this plays well both with expanding and shrinking, and the parent scroll area can do the scrolling depending on the size of QLabel.
But to my surprise, such an elementary thing, if I'm not missing something, is not possible using out-of-the box widgets with GTK+.
Here's what I have tried so far:
Using a Layout directly, moving Image object around manually, and adding & handling horizontal and vertical scrollbars manually (and of course, handle signals and move()ing of the image inside Layout manually). This is what Comix does! This is terrible, so I stopped doing this in the mid-way.
Placed an image object inside ScrolledWindow + Viewport: scrolls nice and neat, but the problem is, I don't know the visible size of the "directly visible" part of the ScrolledWindow (nor the encapsulating window or Viewport); get_allocation returns the size of the total image area, that is, the visible part plus the non-visible part (that user can see by scrolling). The allocation for Viewport reports the correct size after "ordinary" resize events, but it reports the previous size after maximize/minimize (I'm listening at both window-state-event and configure-event). A behavior which I think is a long standing GTK+ bug.
Other things I have exhausted:
- Checking page_size field of adjustment: returns the previous old value after maximization/minimization
- Checking width and height fields in the configure-event: works ok even after maximization/minimization, but, configure-event is not dispatched for a GtkViewport or GtkScrolledWindow, so I can only use the parent window for that. And unfortunately, the parent window size is larger than viewport due to some other widgets (statusbar, toolbar etc).
The problem would be basically solved if GTK+ provided:
- A way of obtaining the actual size of the visible area in the ScrolledWindow.
- And optionally, a way of disabling the scrolling in ScrolledWindow.
My question is, am I missing something obvious here? It's hard to believe such an elementary thing cannot be done directly using out-of-the-box widgets with such an established library. What is the most straightforward way of implementing an image viewer that can do scrolling as well as responsive scaling of the image?