I have a Notebook in my application and instead of using tabs I would like to show the user a ListBox with a set of thumbnails one for each page. Drawing the currently visible page is no problem, however the pages that are not visible are proving challenging.
My current code is shown below and uses an OffscreenWindow to manage it but I dislike this solution for several reasons as follows: a. I'd prefer to keep the re-parenting to a minimum, b. having to run the event loop so the window actually draws is worrisome to me c. I'm getting GTK critical errors under 3.18 (Gdk-CRITICAL **: gdk_window_move_resize_internal: assertion 'GDK_IS_WINDOW (window)' failed) d. The solution is flakey. Showing the listbox is bound to a GAction which is in turn bound to a ToggleButton. If I press the toggle button it works fine and I get a thumbnail, if I execute the action through a shortcut it fails and I get a complaint from the pixbuf: GdkPixbuf-CRITICAL **: gdk_pixbuf_scale_simple: assertion 'dest_width > 0' failed In short I can't help but feel this is all a bit of kludge and there's got to be a better way. As shown in the code below, getting the thumbnail of widget which is drawable is clean and simple in comparison. Is there no way to call the draw method and override the check for isDrawable to force a non-visible widget to be drawn? My only other solution is to simply take and store a thumbnail of each page as the user switches to a new page. This is less then ideal though since activity can be happening in that page while it is non-visible and I'd really prefer to show a current view if possible. The code below is done in D and GtkD but should be easy enough to follow for people more familiar with C or python. Pixbuf getWidgetImage(Widget widget, double factor) { int w = widget.getAllocatedWidth(); int h = widget.getAllocatedHeight(); int pw = to!int(w * factor); int ph = to!int(h * factor); // If widget is drawable get thumbnail directly if (widget.isDrawable()) { Surface surface = widget.getWindow().createSimilarSurface(gtkc.cairotypes.cairo_content_t.COLOR, pw, ph); Context cr = Context.create(surface); cr.scale(factor, factor); widget.draw(cr); return gdk.Pixbuf.getFromSurface(surface, 0, 0, pw, ph); } else { RenderWindow window = new RenderWindow(); window.setDefaultSize(w,h); Container parent = cast(Container) widget.getParent(); if (parent is null) { error("Parent is not a Container, cannot draw offscreen image"); return null; } widget.reparent(window); window.show(); StopWatch sw = StopWatch(AutoStart.yes); Pixbuf pb = window.pixbuf; while (pb is null && sw.peek().msecs<500) { gtk.Main.Main.iteration(); pb = window.pixbuf; } sw.stop(); if (pb is null) { error("Pixbuf from renderwindow is null"); pb = window.getPixbuf(); } pb = pb.scaleSimple(pw, ph , GdkInterpType.BILINEAR); widget.reparent(parent); window.destroy(); return pb; } } private: class RenderWindow: OffscreenWindow { Pixbuf pb; bool onDamage(gdk.Event.Event, Widget) { trace("Damage event received"); pb = getPixbuf(); return false; } public: this() { super(); addOnDamage(&onDamage); } @property Pixbuf pixbuf() { return pb; } } _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list