Re: Invisible GtkImage
On Thu, 2013-06-27 at 16:01 -0700, Andrew Potter wrote: Please show the code that deals with the TextView and ScrolledWindow. The clipping is almost certainly due to setting the minimum size on either the TextView, or the GtkBox the two are contained in. I have example GtkAssistant code at the bottom of this email that does not exhibit this issue until extraordinarily small window sizes. Hey Andrew. The code I posted on pastebin was the only GUI related code for that stuff. The TextView and ScrolledWindow were all created via GtkBuilder / Glade, so there isn't really anything to show, save the XML unless you want that too. That's the bad news. The good news is by changing the minimum height returned in the following override for your Gtk.Drawing subclass to 1, the clipping issue seems solved - well, almost. def do_get_preferred_height_for_width(self, width): preferredHeight = width / self.get_aspect_ratio() return (1, preferredHeight) When scaling an image, both its height and width are changing. In order to fit the allocated rectangle without clipping, one must figure out which dimension is smallest (normalized to the aspect ratio). For example, if a 200x100 image is allocated 200x50, the allocation is height-limited and the image must be scaled to 100x50. OTOH if allocated 100x100, the image is width-limited and must be scaled to 100x50. Right. Makes sense. Thank you for that clarification. I'm getting motivated to work on a patch to GtkImage to add scaling support... I think that given how much work it took for us to figure out how to get it working, probably a lot of other people might benefit from your patch, so I applaud your efforts. - Below is an example program with ScalableImage in a GtkAssistant. Example 1, start up: http://i.imgur.com/ZdqwUZG.jpg Example 2, Resized to less height. Notice the TextView/ScrolledWindow had plenty of space to give up because it has no minimum height http://i.imgur.com/wTN5rY9.jpg Example 3, Clipping occurs at this very small size due to minimum size on the ScalableImage as well as the ScrolledWindow/TextView http://i.imgur.com/EAzFYOG.jpg Yup. That's what I had observed. Example 4, ScalableImage is modified to return a 0 minimum size in get_preferred_height_for_width(). This means that at very small heights the image will not have enough space to fill the allocated width, allowing the other widgets get some space in this corner case. http://i.imgur.com/ZrOPt75.jpg It is your choice whether or not to allow your header image to become smaller when the window is pressured for height. Ok, for the sake of my application, setting it to zero / one vs leaving it at the preferred height seems to solve the clipping issue, but creates a new problem. On subsequent assistant pages, the image starts off too small and is not using the full width available. However on the first page, it fits the full width. Resizing the assistant makes it fill the full width, but only after a certain amount is met. -- Kip Warner -- Software Engineer OpenPGP encrypted/signed mail preferred http://www.thevertigo.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Wed, Jun 26, 2013 at 2:51 PM, Kip Warner k...@thevertigo.com wrote: On Mon, 2013-06-24 at 13:56 -0700, Andrew Potter wrote: So two questions now I have for you, if you don't mind. The first is a problem with clipping, the same one I experienced a few days ago. Note the assistant button widgets at the bottom of the assistant. Implementation: http://pastebin.com/ynsQFTzU Please show the code that deals with the TextView and ScrolledWindow. The clipping is almost certainly due to setting the minimum size on either the TextView, or the GtkBox the two are contained in. I have example GtkAssistant code at the bottom of this email that does not exhibit this issue until extraordinarily small window sizes. The second is just a request for clarification on the min() calculation in your do_draw() override. I'd just like to better understand what that calculation is attempting to do. When scaling an image, both its height and width are changing. In order to fit the allocated rectangle without clipping, one must figure out which dimension is smallest (normalized to the aspect ratio). For example, if a 200x100 image is allocated 200x50, the allocation is height-limited and the image must be scaled to 100x50. OTOH if allocated 100x100, the image is width-limited and must be scaled to 100x50. ... Hopefully now if anyone else in the future wants to do something similar with an image in Gtk+, they'll manage to find this thread. Actually, it might even be worth adding on the FAQ. I'm getting motivated to work on a patch to GtkImage to add scaling support... - Below is an example program with ScalableImage in a GtkAssistant. Example 1, start up: http://i.imgur.com/ZdqwUZG.jpg Example 2, Resized to less height. Notice the TextView/ScrolledWindow had plenty of space to give up because it has no minimum height http://i.imgur.com/wTN5rY9.jpg Example 3, Clipping occurs at this very small size due to minimum size on the ScalableImage as well as the ScrolledWindow/TextView http://i.imgur.com/EAzFYOG.jpg Example 4, ScalableImage is modified to return a 0 minimum size in get_preferred_height_for_width(). This means that at very small heights the image will not have enough space to fill the allocated width, allowing the other widgets get some space in this corner case. http://i.imgur.com/ZrOPt75.jpg It is your choice whether or not to allow your header image to become smaller when the window is pressured for height. #!/usr/bin/python # coding=UTF-8 from gi.repository import Gtk, Gdk, GdkPixbuf class ScalableImage(Gtk.DrawingArea): def __init__(self, filename): super(ScalableImage, self).__init__() self.pb = GdkPixbuf.Pixbuf.new_from_file(filename) def do_get_preferred_width(self): pw = self.pb.get_width() return (0, pw) def do_get_preferred_height(self): ph = self.pb.get_height() return (0, ph) def do_get_preferred_height_for_width(self, width): ph = width / self.get_aspect_ratio() return (0, ph) def do_get_request_mode(self): return Gtk.SizeRequestMode.HEIGHT_FOR_WIDTH def get_aspect_ratio(self): return self.pb.get_width() / self.pb.get_height() def do_draw(self, cr): alloc = self.get_allocation() pw, ph = self.pb.get_width(), self.pb.get_height() aw, ah = float(alloc.width), float(alloc.height) r = min(aw/pw, ah/ph) cr.scale(r, r) Gdk.cairo_set_source_pixbuf(cr, self.pb, 0.0, 0.0) cr.paint() return False bin = Gtk.Box(False) bin.set_orientation(Gtk.Orientation.VERTICAL) img = ScalableImage(gnome-logo.png) bin.add(img) tv = Gtk.TextView() buf = tv.get_buffer() buf.set_text(Lorem ipsum dolor sit amet, consectetur adipiscing elit.\ Quas enim kakaw Graeci appellant, vitia malo quam malitias nominare.\ Quod autem satis est, eo quicquid accessit, nimium est; Solum\ praeterea formosum, solum liberum, solum civem, stultost; Erat enim\ Polemonis. Conferam tecum, quam cuique verso rem subicias; Duo Reges:\ constructio interrete. Aufert enim sensus actionemque tollit\ omnem.\n\nQuae cum magnifice primo dici viderentur, considerata minus\ probabantur. In quibus doctissimi illi veteres inesse quiddam caeleste\ et divinum putaverunt. Dolere malum est: in crucem qui agitur, beatus\ esse non potest. Tu vero, inquam, ducas licet, si sequetur; Eademne,\ quae restincta siti? Sint modo partes vitae beatae. Sextilio Rufo, cum\ is rem ad amicos ita deferret, se esse heredem Q. Negat enim summo\ bono afferre incrementum diem. Sin te auctoritas commovebat, nobisne\ omnibus et Platoni ipsi nescio quem illum anteponebas?\n\nIstam\ voluptatem, inquit, Epicurus ignorat? Inde sermone vario sex illa a\ Dipylo stadia confecimus. Quam ob rem tandem, inquit, non satisfacit?\ Duae sunt enim res quoque, ne tu verba solum putes.\n\nComprehensum,\ quod cognitum non habet? Nunc ita separantur, ut disiuncta sint, quo\ nihil potest esse
Re: Invisible GtkImage
On Mon, 2013-06-24 at 13:56 -0700, Andrew Potter wrote: Actually, it occurs to me that Kip is almost certainly going to want to change the size request methods to: def do_get_preferred_width(self): pw = self.pb.get_width() return (0, pw) def do_get_preferred_height(self): ph = self.pb.get_height() return (0, ph) def do_get_preferred_height_for_width(self, width): ph = width / self.get_aspect_ratio() return (ph, ph) Otherwise it won't scale down properly. Hey Andrew, So two questions now I have for you, if you don't mind. The first is a problem with clipping, the same one I experienced a few days ago. Note the assistant button widgets at the bottom of the assistant. Before resizing horizontally: http://en.zimagez.com/zimage/screenshot-13-06-14-051249pm.php After resizing horizontally, buttons clipped: http://en.zimagez.com/zimage/screenshot-13-06-14-051057pm.php Implementation: http://pastebin.com/ynsQFTzU The second is just a request for clarification on the min() calculation in your do_draw() override. I'd just like to better understand what that calculation is attempting to do. I also wanted to say thank you for having bared with me on this one. It's amazing how sometimes what looks like a really simple problem turns out to require a dozen minds and weeks of posts to really get to the bottom of it and realize that sometimes these things are trickier than they seem. Hopefully now if anyone else in the future wants to do something similar with an image in Gtk+, they'll manage to find this thread. Actually, it might even be worth adding on the FAQ. Another thing I'd like to thank you for is how much cleaner this implementation is than the mess I had before. It's much simpler and doesn't require the client of ScalableImage to have to know or do as much. Take care, -- Kip Warner -- Software Engineer OpenPGP encrypted/signed mail preferred http://www.thevertigo.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Sun, Jun 23, 2013 at 10:04 PM, Kip Warner k...@thevertigo.com wrote: Hey Andrew. Thanks for the help. I've almost got it working after I took your advise, but the image is still taking up too much room in the vertical GtkBox above and below it. See all the extra space above and below it I'd like collapsed: It turns out that GtkAspectFrame doesn't do what most of us in the thread expect. All it does is ensures the child receives an allocation of the correct aspect ratio; it does this by just giving the child a subset of its own allocation: From the Gtk+ source: static void gtk_aspect_frame_compute_child_allocation (GtkFrame *frame, GtkAllocation *child_allocation) { ... if (ratio * full_allocation.height full_allocation.width) { child_allocation-width = full_allocation.width; child_allocation-height = full_allocation.width / ratio + 0.5; } else { child_allocation-width = ratio * full_allocation.height + 0.5; child_allocation-height = full_allocation.height; } ... This means that the GtkAspectFrame does not attempt to do any sort of height-for-width requests (in fact, it does not override any size request method).This makes it unsuitable for the purpose of scaling _up_ an image. In an effort to definitively answer Kip's question, here is a complete working program. You can see that I had to override get_preferred_height_for_width and get_request_mode. For any future readers, keep in mind this code assumes one wants to scale a wide, short image up or down to fill the width of the containing GtkBox. Kip: In this implementation on my machine, printing out the width in get_preferred_height_for_width() and the allocation in do_draw() never showed any bizarre or out of bounds values. The sample banner image is simply https://www.gnome.org/wp-content/themes/gnome-grass/images/gnome-logo.png Result: http://en.zimagez.com/zimage/2013-06-24-130547620x850scrot.php Code: #!/usr/bin/python # coding=UTF-8 from gi.repository import Gtk, Gdk, GdkPixbuf class ScalableImage(Gtk.DrawingArea): def __init__(self, filename): super(ScalableImage, self).__init__() self.pb = GdkPixbuf.Pixbuf.new_from_file(filename) def do_get_preferred_width(self): pw = self.pb.get_width() return (pw, pw) def do_get_preferred_height(self): ph = self.pb.get_height() return (ph, ph) # Note here that the minimum request is set to the natural height of the input pixbuf # This may not be the desired behavior in all circumstances def do_get_preferred_height_for_width(self, width): return (self.pb.get_height(), width / self.get_aspect_ratio()) def do_get_request_mode(self): return Gtk.SizeRequestMode.HEIGHT_FOR_WIDTH def get_aspect_ratio(self): return self.pb.get_width() / self.pb.get_height() def do_draw(self, cr): alloc = self.get_allocation() pw, ph = self.pb.get_width(), self.pb.get_height() aw, ah = float(alloc.width), float(alloc.height) r = min(aw/pw, ah/ph) cr.scale(r, r) Gdk.cairo_set_source_pixbuf(cr, self.pb, 0.0, 0.0) cr.paint() return False win = Gtk.Window() win.connect(delete-event, Gtk.main_quit) bin = Gtk.Box(False) bin.set_orientation(Gtk.Orientation.VERTICAL) img = ScalableImage(gnome-logo.png) bin.add(img) tv = Gtk.TextView() buf = tv.get_buffer() buf.set_text(Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quas enim kakaw Graeci appellant, vitia malo quam malitias nominare. Quod autem satis est, eo quicquid accessit, nimium est; Solum praeterea formosum, solum liberum, solum civem, stultost; Erat enim Polemonis. Conferam tecum, quam cuique verso rem subicias; Duo Reges: constructio interrete. Aufert enim sensus actionemque tollit omnem.\n\nQuae cum magnifice primo dici viderentur, considerata minus probabantur. In quibus doctissimi illi veteres inesse quiddam caeleste et divinum putaverunt. Dolere malum est: in crucem qui agitur, beatus esse non potest. Tu vero, inquam, ducas licet, si sequetur; Eademne, quae restincta siti? Sint modo partes vitae beatae. Sextilio Rufo, cum is rem ad amicos ita deferret, se esse heredem Q. Negat enim summo bono afferre incrementum diem. Sin te auctoritas commovebat, nobisne omnibus et Platoni ipsi nescio quem illum anteponebas?\n\nIstam voluptatem, inquit, Epicurus ignorat? Inde sermone vario sex illa a Dipylo stadia confecimus. Quam ob rem tandem, inquit, non satisfacit? Duae sunt enim res quoque, ne tu verba solum putes.\n\nComprehensum, quod cognitum non habet? Nunc ita separantur, ut disiuncta sint, quo nihil potest esse perversius. Quod ea non occurrentia fingunt, vincunt Aristonem; Nos commodius agimus.\n\nCerte, nisi voluptatem tanti aestimaretis. Roges enim Aristonem, bonane ei videantur haec: vacuitas doloris, divitiae, valitudo; Quid ergo aliud intellegetur nisi uti ne quae pars naturae neglegatur? Ab hoc autem quaedam non melius quam veteres, quaedam omnino relicta. Verum
Re: Invisible GtkImage
2013/6/24 Andrew Potter agpot...@gmail.com: # Note here that the minimum request is set to the natural height of the input pixbuf # This may not be the desired behavior in all circumstances def do_get_preferred_height_for_width(self, width): return (self.pb.get_height(), width / self.get_aspect_ratio()) Actually, it occurs to me that Kip is almost certainly going to want to change the size request methods to: def do_get_preferred_width(self): pw = self.pb.get_width() return (0, pw) def do_get_preferred_height(self): ph = self.pb.get_height() return (0, ph) def do_get_preferred_height_for_width(self, width): ph = width / self.get_aspect_ratio() return (ph, ph) Otherwise it won't scale down properly. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Sun, 2013-06-23 at 21:17 +0200, z...@excite.it wrote: Hi, maybe adding a callback to a window signal and redraw the image could be an option? take a look at http://zetcode.com/tutorials/gtktutorial/gtkevents/ gtk_widget_add_events(GTK_WIDGET(window), GDK_CONFIGURE); The event mask of the widget determines, what kind of event will a particular widget receive. Some event are preconfigured, other events have to be added to the event mask. The gtk_widget_add_events() adds a GDK_CONFIGURE event type to the mask. The GDK_CONFIGURE event type accounts for all size, position and stack order events. g_signal_connect(G_OBJECT(window), configure-event, G_CALLBACK(your_callback), NULL); Just an idea. Ciao, ZZ Hey ZZ, It's a good idea, but it's tough to implement because if you are talking about resizing a GtkImage widget dynamically, I don't think it's really designed to do that. I think some of its internal data functions on the assumption that it won't resize. I think the GtkDrawingArea widget can be dynamically resized and, as long as the client takes responsibility for resizing whatever pixels that are to be painted on it, it should work. The trick at this point is to try and get the AspectFrame and DrawingArea to resize and expand in the right way which seems very difficult so far. -- Kip Warner -- Software Engineer OpenPGP encrypted/signed mail preferred http://www.thevertigo.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
Hey Kip, You can try to place your image into a 1x1 GtkGrid and see if it works. If not... hmmm... I'm trying to think of an existing Gnome app which has scaling images. Hmmm... probably none. Scaling images (unless in Gimp/Inkspace) to containing widget size is probably rarely done. Anyway, here's another idea: You can try to solve the recursive scaling problem by not using all the available space. Try to make the image fit, say 90% of the aspect frame. Then the image is not big enough to cause the aspect frame to rescale (which probably would cause the recursive scaling). You may get a little bit of screen space wasted, but if you don't mind the 10% (maybe you can reduce it to 5% or less) it's okay. Another idea: Image editing software usually uses a custom canvas and draws things on it, including scaled SVG images. Maybe you can put such a canvas in the aspect frame, possible also inside a 1x1 GtkGrid, and scale the image within the canvas. Then, the image scaling is just a canvas drawing operation and has no effect on the AspectFrame size, and shouldn't cause recursive scaling. On ו', 2013-06-21 at 11:33 +0300, Anatoly Krasner wrote: -- Forwarded message -- From: Kip Warner k...@thevertigo.com Date: Fri, Jun 21, 2013 at 4:10 AM Subject: Re: Invisible GtkImage To: אנטולי קרסנר tomback...@gmail.com Cc: gtk-app-devel-list gtk-app-devel-list@gnome.org On Thu, 2013-06-20 at 17:59 -0700, Kip Warner wrote: On Wed, 2013-06-19 at 14:03 +0300, אנטולי קרסנר wrote: I have another idea for you: In the Gnome Mines game (which you can probably find on git.gnome.org) written in Vala, the game board has a fixed ratio and resizes with the window, exactly like your requirement. Go there and see how the MinefieldView and Window classes word. Hey Tom. So I'm looking through his gnome-mines.vala and I see in his startup_custom_game_screen () function he is creating the GtkAspectFrame as I do. I think the key difference is the child he is using is a GtkGrid which already knows on how to resize inside of anything, whereas the GtkImage does not. I'll keep looking through his code and fiddling with my own, but any help appreciated. Ah hah. So I noticed something. When I set the shadow type to NONE in the AspectFrame, the recursive resizing stops. I can make the window larger, but not smaller. Hmm... -- Kip Warner -- Software Engineer OpenPGP encrypted/signed mail preferred http://www.thevertigo.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Sat, 22 Jun 2013 15:30:34 -0700, Kip Warner wrote: Yes, your code is similar to what I had tried before with GtkImage, only you're subclassing the DrawingArea instead which is probably a better idea, except it still doesn't work properly either. So how exactly does the behaviour of my simple example differ from what you want? The widget fills the allocated space and the image scales, keeping the aspect ratio. Yeti ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Sun, 2013-06-23 at 11:51 +0200, David Nečas wrote: So how exactly does the behaviour of my simple example differ from what you want? The widget fills the allocated space and the image scales, keeping the aspect ratio. When the parent window is resized, I'd like the image to scale to fill the allocated space as much as possible, maintaining the aspect ratio. My code draws the image correctly, but it doesn't resize as the parent window is resized: http://pastebin.com/6LEzFk8A -- Kip Warner -- Software Engineer OpenPGP encrypted/signed mail preferred http://www.thevertigo.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Sun, 2013-06-23 at 00:53 +0200, Colomban Wendling wrote: 2) you say it doesn't expand: check your packing flags. You have: page.pack_start(page._bannerAspectFrame, False, False, 0) the 2 False mean don't expand and don't fill the available space. Change this to True, True and you'll be happy. Hey Colomban. I actually already tried that. If I set the second parameter to True, it does expand to fill the available space, but the other widgets below it in the next row below in the vbox are pushed down to the bottom half of the box's available space so that there is a huge wasted space between the banner image and the bottom half. -- Kip Warner -- Software Engineer OpenPGP encrypted/signed mail preferred http://www.thevertigo.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Sun, Jun 23, 2013 at 11:05:00AM -0700, Kip Warner wrote: When the parent window is resized, I'd like the image to scale to fill the allocated space as much as possible, maintaining the aspect ratio. My code draws the image correctly, but it doesn't resize as the parent window is resized: http://pastebin.com/6LEzFk8A Well, as it has already been suggested, this is a matter of packing. If you request that the widget does not expand page.pack_start(page._bannerAspectFrame, False, False, 0) then the containing box will not expand the widget when it is enlarged itself. You have to pass expand=True, fill=True. Yeti ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Sun, 2013-06-23 at 20:11 +0200, David Nečas wrote: Well, as it has already been suggested, this is a matter of packing. If you request that the widget does not expand page.pack_start(page._bannerAspectFrame, False, False, 0) then the containing box will not expand the widget when it is enlarged itself. You have to pass expand=True, fill=True. Hey David. Like I said to Colomban already, I already tried that. https://mail.gnome.org/archives/gtk-app-devel-list/2013-June/msg00134.html -- Kip Warner -- Software Engineer OpenPGP encrypted/signed mail preferred http://www.thevertigo.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Sunday 23 June 2013 20:05:00 Kip Warner wrote: On Sun, 2013-06-23 at 11:51 +0200, David Nečas wrote: So how exactly does the behaviour of my simple example differ from what you want? The widget fills the allocated space and the image scales, keeping the aspect ratio. When the parent window is resized, I'd like the image to scale to fill the allocated space as much as possible, maintaining the aspect ratio. My code draws the image correctly, but it doesn't resize as the parent window is resized: http://pastebin.com/6LEzFk8A Hi, maybe adding a callback to a window signal and redraw the image could be an option? take a look at http://zetcode.com/tutorials/gtktutorial/gtkevents/ gtk_widget_add_events(GTK_WIDGET(window), GDK_CONFIGURE); The event mask of the widget determines, what kind of event will a particular widget receive. Some event are preconfigured, other events have to be added to the event mask. The gtk_widget_add_events() adds a GDK_CONFIGURE event type to the mask. The GDK_CONFIGURE event type accounts for all size, position and stack order events. g_signal_connect(G_OBJECT(window), configure-event, G_CALLBACK(your_callback), NULL); Just an idea. Ciao, ZZ ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Sun, Jun 23, 2013 at 11:17 AM, Kip Warner k...@thevertigo.com wrote: On Sun, 2013-06-23 at 20:11 +0200, David Nečas wrote: Well, as it has already been suggested, this is a matter of packing. If you request that the widget does not expand page.pack_start(page._bannerAspectFrame, False, False, 0) then the containing box will not expand the widget when it is enlarged itself. You have to pass expand=True, fill=True. Hey David. Like I said to Colomban already, I already tried that. For a vertically orientated GtkBox, the 'expand' field in pack_start is going to be vertical expansion, so you are not going to want that. Instead set the GtkBox.set_hexpand(true) (and GtkBox.set_halign(GTK_ALIGN_FILL)), but definitely do pack children with Fill=True. Make sure both the GtkAspectFrame and the GtkDrawingArea are set to both set_halign(GTK_ALIGN_FILL) and set_valign(GTK_ALIGN_FILL). That means the aspect frame will receive the extra width, and its internal ratio keeping will make its implementation of get_requested_height_for_width() request enough height for your image to expand properly. Its all a problem of packing with expand fill at this point. Just think about how you want the toolkit to work and make sure each component in the hierarchy is doing the right thing. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
For a vertically orientated GtkBox, the 'expand' field in pack_start is going to be vertical expansion, so you are not going to want that. Instead set the GtkBox.set_hexpand(true) (and GtkBox.set_halign(GTK_ALIGN_FILL)), but definitely do pack children with Fill=True. Make sure both the GtkAspectFrame and the GtkDrawingArea are set to both set_halign(GTK_ALIGN_FILL) and set_valign(GTK_ALIGN_FILL). That means the aspect frame will receive the extra width, and its internal ratio keeping will make its implementation of get_requested_height_for_width() request enough height for your image to expand properly. Its all a problem of packing with expand fill at this point. Just think about how you want the toolkit to work and make sure each component in the hierarchy is doing the right thing. Hey Andrew. Thanks for the help. I've almost got it working after I took your advise, but the image is still taking up too much room in the vertical GtkBox above and below it. See all the extra space above and below it I'd like collapsed: http://en.zimagez.com/zimage/box36.php Here is my code: http://pastebin.com/mtVNsPrb Thanks a lot, -- Kip Warner -- Software Engineer OpenPGP encrypted/signed mail preferred http://www.thevertigo.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
The code looks fine. I think the problem is that scaling images are rarely used in GUI. Usually, they scale to fixed sizes and not directly depend on a container scaling to arbitrary size. This is probably why getting the result you want is not easy. Try the canvas idea. You can probably use any simple drawing area widget (I never used one personally) from Gtk or Cairo. On ו', 2013-06-21 at 21:30 -0700, Kip Warner wrote: On Fri, 2013-06-21 at 11:46 +0300, אנטולי קרסנר wrote: Hey Kip, Hey Tom. You can try to place your image into a 1x1 GtkGrid and see if it works. If not... hmmm... I'm trying to think of an existing Gnome app which has scaling images. Hmmm... probably none. Scaling images (unless in Gimp/Inkspace) to containing widget size is probably rarely done. Ok, I tried it with GtkGrid containing the image widget with the parent of the former being the AspectFrame. No love. It behaves the same as without it. Anyway, here's another idea: You can try to solve the recursive scaling problem by not using all the available space. Try to make the image fit, say 90% of the aspect frame. Then the image is not big enough to cause the aspect frame to rescale (which probably would cause the recursive scaling). You may get a little bit of screen space wasted, but if you don't mind the 10% (maybe you can reduce it to 5% or less) it's okay. I think that's a good idea, but I'll try that as a last resort. So I've almost got it working. It resizes properly when I make the window larger, but the window's width can never be made smaller (including after maximization). http://pastebin.com/q76RJ4UH Can you see anything broken in that? Another idea: Image editing software usually uses a custom canvas and draws things on it, including scaled SVG images. Maybe you can put such a canvas in the aspect frame, possible also inside a 1x1 GtkGrid, and scale the image within the canvas. Then, the image scaling is just a canvas drawing operation and has no effect on the AspectFrame size, and shouldn't cause recursive scaling. I don't know much about the canvas. But I'll try it and get back to you. Thank you for your help, ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Sat, 2013-06-22 at 11:33 +0300, אנטולי קרסנר wrote: The code looks fine. I think the problem is that scaling images are rarely used in GUI. Usually, they scale to fixed sizes and not directly depend on a container scaling to arbitrary size. This is probably why getting the result you want is not easy. Hey Tom. Yes, definitely the resizing is the difficulty. It's amazing how much time I've spent on just trying to get the image to resize. Try the canvas idea. You can probably use any simple drawing area widget (I never used one personally) from Gtk or Cairo. This is what I've come up with so far. The image paints on the DrawingArea properly, but it doesn't resize at all when I resize the parent window. http://pastebin.com/Mj7bTJLh -- Kip Warner -- Software Engineer OpenPGP encrypted/signed mail preferred http://www.thevertigo.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
I never used drawing areas, but here are my suggestions. First, does the drawing area resize? If it does, all you need to do is to change the code which draws the image to use the drawing area's dimensions, and scale the image accordingly (I don't know how to do that, but I'm sure Cairo can help. In the worst case, from personal experience I know OpenGL can do that, if you have no choice...). If the drawing area doesn't resize, try to put it in a GtkGrid. If it doesn't help - maybe you can removing the aspect frame and calculating the image dimensions manually. If it still doesn't work, I suggest you try asking on gtk-l...@gnome.org and have some GTK experts give you ideas. On ש', 2013-06-22 at 08:49 -0700, Kip Warner wrote: On Sat, 2013-06-22 at 11:33 +0300, אנטולי קרסנר wrote: The code looks fine. I think the problem is that scaling images are rarely used in GUI. Usually, they scale to fixed sizes and not directly depend on a container scaling to arbitrary size. This is probably why getting the result you want is not easy. Hey Tom. Yes, definitely the resizing is the difficulty. It's amazing how much time I've spent on just trying to get the image to resize. Try the canvas idea. You can probably use any simple drawing area widget (I never used one personally) from Gtk or Cairo. This is what I've come up with so far. The image paints on the DrawingArea properly, but it doesn't resize at all when I resize the parent window. http://pastebin.com/Mj7bTJLh ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Sat, 2013-06-22 at 19:18 +0300, אנטולי קרסנר wrote: I never used drawing areas, but here are my suggestions. First, does the drawing area resize? If it does, all you need to do is to change the code which draws the image to use the drawing area's dimensions, and scale the image accordingly (I don't know how to do that, but I'm sure Cairo can help. In the worst case, from personal experience I know OpenGL can do that, if you have no choice...). That was my first line of inquiry, except it doesn't seem to resize. I can see this because if I leave a frame border on the parent AspectFrame, it doesn't resize. If the drawing area doesn't resize, try to put it in a GtkGrid. I tried putting the DrawingArea into a 1x1 Grid, in turn inside of an AspectFrame, but it still doesn't resize. If it doesn't help - maybe you can removing the aspect frame and calculating the image dimensions manually. Even if I remove the aspect frame and calculate the image dimensions myself, there still seems to be no way I can find to reliably resize it dynamically. I can't believe resizing a widget in Gtk+ is this difficult. I think I've tried everything by now. Viewports, AspectFrame, cairo, Gdk pixbuf, subclassing and overrides. You'd think something like this would be really straightforward. =( -- Kip Warner -- Software Engineer OpenPGP encrypted/signed mail preferred http://www.thevertigo.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Sat, Jun 22, 2013 at 01:09:17PM -0700, Kip Warner wrote: I can't believe resizing a widget in Gtk+ is this difficult. Frankly, I don't quite understand what you are trying to achieve since you have never posted anything runnable and your examples have never included any actual drawing code. Anyway, it is trivial to create a scaleable widget (whether it draws an image or anything else): --- from gi.repository import Gtk, GdkPixbuf, Gdk class ScalableImage(Gtk.DrawingArea): def __init__(self, filename): super(ScalableImage, self).__init__() self.pb = GdkPixbuf.Pixbuf.new_from_file(filename) def do_get_preferred_width(self): pw = self.pb.get_width() return (pw, pw) def do_get_preferred_height(self): ph = self.pb.get_height() return (ph, ph) def do_draw(self, cr): alloc = self.get_allocation() pw, ph = self.pb.get_width(), self.pb.get_height() aw, ah = float(alloc.width), float(alloc.height) r = min(aw/pw, ah/ph) cr.scale(r, r) Gdk.cairo_set_source_pixbuf(cr, self.pb, 0.0, 0.0) cr.paint() return False w = Gtk.Window(Gtk.WindowType.TOPLEVEL) w.connect('destroy', Gtk.main_quit) b = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) w.add(b) b.pack_start(Gtk.Label(label='Test'), False, False, 0) d = ScalableImage('/usr/share/icons/HighContrast/48x48/stock/gtk-ok.png') b.pack_start(d, True, True, 0) b.pack_start(Gtk.Label(label='Somewhat longer test'), False, False, 0) w.show_all() Gtk.main() --- This might not be exactly what you need but as I noted I don't get where the problem is... If you need your widget to be a GtkImage subclass things will likely turn hairy because GtkImage is not scaleable, all its methods think it is not scaleable so you will end up fighting the implementation of the widget. Yeti ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Sun, 2013-06-23 at 00:08 +0200, David Nečas wrote: Frankly, I don't quite understand what you are trying to achieve since you have never posted anything runnable and your examples have never included any actual drawing code. Hey David. I had posted my cairo drawing code a couple posts ago, but this thread is getting long and you may have missed it: http://pastebin.com/Mj7bTJLh Before that, I had posted several times code using GtkImage as well. In any case, they didn't work properly, it doesn't matter now, and I'm grateful for your help. Anyway, it is trivial to create a scaleable widget (whether it draws an image or anything else): --- from gi.repository import Gtk, GdkPixbuf, Gdk class ScalableImage(Gtk.DrawingArea): def __init__(self, filename): super(ScalableImage, self).__init__() self.pb = GdkPixbuf.Pixbuf.new_from_file(filename) def do_get_preferred_width(self): pw = self.pb.get_width() return (pw, pw) def do_get_preferred_height(self): ph = self.pb.get_height() return (ph, ph) def do_draw(self, cr): alloc = self.get_allocation() pw, ph = self.pb.get_width(), self.pb.get_height() aw, ah = float(alloc.width), float(alloc.height) r = min(aw/pw, ah/ph) cr.scale(r, r) Gdk.cairo_set_source_pixbuf(cr, self.pb, 0.0, 0.0) cr.paint() return False w = Gtk.Window(Gtk.WindowType.TOPLEVEL) w.connect('destroy', Gtk.main_quit) b = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) w.add(b) b.pack_start(Gtk.Label(label='Test'), False, False, 0) d = ScalableImage('/usr/share/icons/HighContrast/48x48/stock/gtk-ok.png') b.pack_start(d, True, True, 0) b.pack_start(Gtk.Label(label='Somewhat longer test'), False, False, 0) w.show_all() Gtk.main() --- This might not be exactly what you need but as I noted I don't get where the problem is... Yes, your code is similar to what I had tried before with GtkImage, only you're subclassing the DrawingArea instead which is probably a better idea, except it still doesn't work properly either. My code draws the image correctly, but it doesn't resize as the parent window is resized... http://pastebin.com/6LEzFk8A If you need your widget to be a GtkImage subclass things will likely turn hairy because GtkImage is not scaleable, all its methods think it is not scaleable so you will end up fighting the implementation of the widget. Yup. -- Kip Warner -- Software Engineer OpenPGP encrypted/signed mail preferred http://www.thevertigo.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
Le 23/06/2013 00:30, Kip Warner a écrit : On Sun, 2013-06-23 at 00:08 +0200, David Nečas wrote: [...] This might not be exactly what you need but as I noted I don't get where the problem is... Yes, your code is similar to what I had tried before with GtkImage, only you're subclassing the DrawingArea instead which is probably a better idea, except it still doesn't work properly either. My code draws the image correctly, but it doesn't resize as the parent window is resized... http://pastebin.com/6LEzFk8A 1) you don't need an AspectFrame if the drwaing takes care of not messing up the ratio. 2) you say it doesn't expand: check your packing flags. You have: page.pack_start(page._bannerAspectFrame, False, False, 0) the 2 False mean don't expand and don't fill the available space. Change this to True, True and you'll be happy. Regards, Colomban ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Fri, 2013-06-21 at 11:46 +0300, אנטולי קרסנר wrote: Hey Kip, Hey Tom. You can try to place your image into a 1x1 GtkGrid and see if it works. If not... hmmm... I'm trying to think of an existing Gnome app which has scaling images. Hmmm... probably none. Scaling images (unless in Gimp/Inkspace) to containing widget size is probably rarely done. Ok, I tried it with GtkGrid containing the image widget with the parent of the former being the AspectFrame. No love. It behaves the same as without it. Anyway, here's another idea: You can try to solve the recursive scaling problem by not using all the available space. Try to make the image fit, say 90% of the aspect frame. Then the image is not big enough to cause the aspect frame to rescale (which probably would cause the recursive scaling). You may get a little bit of screen space wasted, but if you don't mind the 10% (maybe you can reduce it to 5% or less) it's okay. I think that's a good idea, but I'll try that as a last resort. So I've almost got it working. It resizes properly when I make the window larger, but the window's width can never be made smaller (including after maximization). http://pastebin.com/q76RJ4UH Can you see anything broken in that? Another idea: Image editing software usually uses a custom canvas and draws things on it, including scaled SVG images. Maybe you can put such a canvas in the aspect frame, possible also inside a 1x1 GtkGrid, and scale the image within the canvas. Then, the image scaling is just a canvas drawing operation and has no effect on the AspectFrame size, and shouldn't cause recursive scaling. I don't know much about the canvas. But I'll try it and get back to you. Thank you for your help, -- Kip Warner -- Software Engineer OpenPGP encrypted/signed mail preferred http://www.thevertigo.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Wed, 2013-06-19 at 14:03 +0300, אנטולי קרסנר wrote: I have another idea for you: In the Gnome Mines game (which you can probably find on git.gnome.org) written in Vala, the game board has a fixed ratio and resizes with the window, exactly like your requirement. Go there and see how the MinefieldView and Window classes word. Hey Tom. So I'm looking through his gnome-mines.vala and I see in his startup_custom_game_screen () function he is creating the GtkAspectFrame as I do. I think the key difference is the child he is using is a GtkGrid which already knows on how to resize inside of anything, whereas the GtkImage does not. I'll keep looking through his code and fiddling with my own, but any help appreciated. -- Kip Warner -- Software Engineer OpenPGP encrypted/signed mail preferred http://www.thevertigo.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Thu, 2013-06-20 at 17:59 -0700, Kip Warner wrote: On Wed, 2013-06-19 at 14:03 +0300, אנטולי קרסנר wrote: I have another idea for you: In the Gnome Mines game (which you can probably find on git.gnome.org) written in Vala, the game board has a fixed ratio and resizes with the window, exactly like your requirement. Go there and see how the MinefieldView and Window classes word. Hey Tom. So I'm looking through his gnome-mines.vala and I see in his startup_custom_game_screen () function he is creating the GtkAspectFrame as I do. I think the key difference is the child he is using is a GtkGrid which already knows on how to resize inside of anything, whereas the GtkImage does not. I'll keep looking through his code and fiddling with my own, but any help appreciated. Ah hah. So I noticed something. When I set the shadow type to NONE in the AspectFrame, the recursive resizing stops. I can make the window larger, but not smaller. Hmm... -- Kip Warner -- Software Engineer OpenPGP encrypted/signed mail preferred http://www.thevertigo.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
I have another idea for you: In the Gnome Mines game (which you can probably find on git.gnome.org) written in Vala, the game board has a fixed ratio and resizes with the window, exactly like your requirement. Go there and see how the MinefieldView and Window classes word. On ג', 2013-06-18 at 15:44 -0700, Kip Warner wrote: On Tue, 2013-06-18 at 10:33 +0300, אנטולי קרסנר wrote: Hmmm... did you try not to resize the image at all, and see if it gets resized automatically by the aspect frame? If the ratio of the image isn't identical to the aspect frame ratio, I guess it may result in each one of them resizing the other recursively. Try without the resize code, and see if it works. If not, maybe use some layout/alignment properties to make the image adapt, rather than manually setting the new size. Maybe this will work. I Hope it helps :-) Hey Tom. Thanks for the help. If I comment out the draw signal connection on line 34, the aspect ratio doesn't resize at all, but just stays fixed, albeit at the correct aspect ratio. http://pastebin.com/jFCcWyig Ugh, *slams head on desk* ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
Hmmm... did you try not to resize the image at all, and see if it gets resized automatically by the aspect frame? If the ratio of the image isn't identical to the aspect frame ratio, I guess it may result in each one of them resizing the other recursively. Try without the resize code, and see if it works. If not, maybe use some layout/alignment properties to make the image adapt, rather than manually setting the new size. Maybe this will work. I Hope it helps :-) On ב', 2013-06-17 at 19:32 -0700, Kip Warner wrote: On Mon, 2013-06-17 at 22:05 +0300, אנטולי קרסנר wrote: Just to make sure you checked the small things... Did you try AspectFrame? IIRC that's exactly what it does: keeps the ratio of the contained widget. IIRC, the Gnome Mines game (aka minesweeper) uses this kind of container to keep the minefield view square-shaped even when the window is stretched to different directions. It fills the space, but without losing the ratio. Hey Tom. Great idea. I definitely overlooked the small and obvious thing this time. I totally forgot about the GtkAspectFrame. It makes a lot more sense to use that in this case than going to all this trouble subclassing GtkImage, overriding virtual methods, etc. So this is what I came up with... http://pastebin.com/jFCcWyig It works great, except for one thing. The GUI doesn't freeze thankfully, but the image or aspect frame just keeps _growing_ and doesn't stop. I'm guessing what's happening in the draw signal callback is I am resizing the image widget, which in turn is resizing the AspectFrame widget, which is in turn resizing the image widget, etc... ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Tue, 2013-06-18 at 10:33 +0300, אנטולי קרסנר wrote: Hmmm... did you try not to resize the image at all, and see if it gets resized automatically by the aspect frame? If the ratio of the image isn't identical to the aspect frame ratio, I guess it may result in each one of them resizing the other recursively. Try without the resize code, and see if it works. If not, maybe use some layout/alignment properties to make the image adapt, rather than manually setting the new size. Maybe this will work. I Hope it helps :-) Hey Tom. Thanks for the help. If I comment out the draw signal connection on line 34, the aspect ratio doesn't resize at all, but just stays fixed, albeit at the correct aspect ratio. http://pastebin.com/jFCcWyig Ugh, *slams head on desk* -- Kip Warner -- Software Engineer OpenPGP encrypted/signed mail preferred http://www.thevertigo.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
Just to make sure you checked the small things... Did you try AspectFrame? IIRC that's exactly what it does: keeps the ratio of the contained widget. IIRC, the Gnome Mines game (aka minesweeper) uses this kind of container to keep the minefield view square-shaped even when the window is stretched to different directions. It fills the space, but without losing the ratio. On ה', 2013-06-13 at 18:09 -0700, Kip Warner wrote: Hey list, I am attempting to create a GtkImage that resizes to fill its parent container while maintaining its aspect ratio. I do this by subclassing GtkImage and overriding do_size_allocate(). http://pastebin.com/SD4RBkes The code mostly works in that I can see that the area the widget is taking appears to be the correct size as I resize its parent. However, the actual image pixels do not appear to be painted. Any help appreciated, ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Mon, 2013-06-17 at 22:05 +0300, אנטולי קרסנר wrote: Just to make sure you checked the small things... Did you try AspectFrame? IIRC that's exactly what it does: keeps the ratio of the contained widget. IIRC, the Gnome Mines game (aka minesweeper) uses this kind of container to keep the minefield view square-shaped even when the window is stretched to different directions. It fills the space, but without losing the ratio. Hey Tom. Great idea. I definitely overlooked the small and obvious thing this time. I totally forgot about the GtkAspectFrame. It makes a lot more sense to use that in this case than going to all this trouble subclassing GtkImage, overriding virtual methods, etc. So this is what I came up with... http://pastebin.com/jFCcWyig It works great, except for one thing. The GUI doesn't freeze thankfully, but the image or aspect frame just keeps _growing_ and doesn't stop. I'm guessing what's happening in the draw signal callback is I am resizing the image widget, which in turn is resizing the AspectFrame widget, which is in turn resizing the image widget, etc... -- Kip Warner -- Software Engineer OpenPGP encrypted/signed mail preferred http://www.thevertigo.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Thu, Jun 13, 2013 at 9:54 PM, Kip Warner k...@thevertigo.com wrote: What you can do to (try to) prevent that situation is to set the widget to do height for width allocation, and override get_preferred_height_for_width() to honor your aspect ratio. In some situations of course the toolkit won't be able to perfectly honor the allocation request, so be sure not to scale out of bounds no matter what. Right. What I will do is resize to exactly what is passed into my do_size_allocate() override since that size should theoretically meet the aspect ratio I am maintaining via my do_get_preferred_height_for_width() override. def do_get_preferred_height_for_width(self, width): return (width / self._aspectRatio) def do_get_request_mode(self): return Gtk.SizeRequestMode.HEIGHT_FOR_WIDTH ...but something very interesting happens immediately after the return in do_get_preferred_height_for_width(). I get an assertion fail buried deep somewhere in python-gi... I suspect something weird is happening because you have the wrong function signature. I can't find any reference to the basic widget methods on the python gtk documentation website, but the C signature is: voidgtk_widget_get_preferred_height_for_width (GtkWidget *widget, gint width, gint *minimum_height, gint *natural_height); So try: def do_get_preferred_height_for_width(self, width, minimum_height, natural_height): minimum_height = width / self._aspectRatio natural_height = width / self._aspectRatio If that doesn't work, try and find out how the python gintrospection stuff deals with out parameters. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Fri, 2013-06-14 at 00:17 -0700, Andrew Potter wrote: I suspect something weird is happening because you have the wrong function signature. I can't find any reference to the basic widget methods on the python gtk documentation website, but the C signature is: voidgtk_widget_get_preferred_height_for_width (GtkWidget *widget, gint width, gint *minimum_height, gint *natural_height); So try: def do_get_preferred_height_for_width(self, width, minimum_height, natural_height): minimum_height = width / self._aspectRatio natural_height = width / self._aspectRatio Hey Andrew. You're quite right. My override was implemented wrong. However, I think the problem was not in the in parameters, but in the out parameters. The input parameters I think were correct, but the caller is expecting a two-tuple back out. get_preferred_height_for_width(self, width:int) - minimum_height:int, natural_height:int When I fixed that, it doesn't core dump anymore. I just return the same value for both fields. I have three concerns. The first is that sometimes the incoming allocation has some very strange width and height values in it, but are usually valid the rest of the time. Sometimes I see values like width of -408563232 and height of 32767. My second concern is that when the assistant window is resized to be made larger horizontally, the image grows, as it should, but the bottom of the assistant page with the usual assistant buttons (e.g. Cancel, Continue) get clipped some how. Clipping: http://www.zimagez.com/zimage/screenshot-13-06-14-051057pm.php No clipping: http://www.zimagez.com/zimage/screenshot-13-06-14-051249pm.php My final concern is I'm worried about the introspection system's error control on handling bad return signatures the way it did here. Since the introspection data knows that the method should have provided two out parameters, you'd think it would have caught this more gracefully with an exception than a core dump? But I guess that's probably nothing you or I can do about that right now. -- Kip Warner -- Software Engineer OpenPGP encrypted/signed mail preferred http://www.thevertigo.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Fri, Jun 14, 2013 at 5:20 PM, Kip Warner k...@thevertigo.com wrote: I have three concerns. The first is that sometimes the incoming allocation has some very strange width and height values in it, but are usually valid the rest of the time. Sometimes I see values like width of -408563232 and height of 32767. That's unusual. Quick testing of my own image resizing does not seem to have that occur. If you're sure that your requests are always absolutely sane, you might want to put together a small test case as it could indicate a pygtk bug, or maybe a gtk+ bug. My second concern is that when the assistant window is resized to be made larger horizontally, the image grows, as it should, but the bottom of the assistant page with the usual assistant buttons (e.g. Cancel, Continue) get clipped some how. Is your TextView set to have a minimum height? My final concern is I'm worried about the introspection system's error control on handling bad return signatures the way it did here. Since the introspection data knows that the method should have provided two out parameters, you'd think it would have caught this more gracefully with an exception than a core dump? But I guess that's probably nothing you or I can do about that right now. I suspect it has more to do with Python's dynamic typing. But you might raise the issue with the pygtk folks [1]. [1]: https://mail.gnome.org/mailman/listinfo/python-hackers-list ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Fri, 2013-06-14 at 18:17 -0700, Andrew Potter wrote: That's unusual. Quick testing of my own image resizing does not seem to have that occur. If you're sure that your requests are always absolutely sane, you might want to put together a small test case as it could indicate a pygtk bug, or maybe a gtk+ bug. It could be a bug, but in my experience, it's probably the developer's fault (me). But I'll try to look into it further if I get a chance. In the mean time, I'll have to be content with... if allocation.width = 0 or allocation.height = 0: return Is your TextView set to have a minimum height? So the bad news is I tried setting a minimum height for the TextView and no love. But the good news is I changed the do_get_preferred_height_for_width() override to return a value of 1 for the minimum_height... def do_get_preferred_height_for_width(self, width): height = width / self._aspectRatio # Return the minimum height and natural height... return 1, height I'm still not sure what exactly the minimum_height is for, or if leaving it at 1 is going to be a problem, but the clipping issue seems fine and the image rescales _almost_ fine now. If I advance the assistant page to the next one, however, the image is no longer scaled uniformly, but is squished at only half the height it was while maintaining the same width. I suspect it has more to do with Python's dynamic typing. But you might raise the issue with the pygtk folks [1]. Done. Thanks. -- Kip Warner -- Software Engineer OpenPGP encrypted/signed mail preferred http://www.thevertigo.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Thu, Jun 13, 2013 at 6:09 PM, Kip Warner k...@thevertigo.com wrote: The code mostly works in that I can see that the area the widget is taking appears to be the correct size as I resize its parent. However, the actual image pixels do not appear to be painted. Hi Kip, After setting the rescaled image, you should probably Chain Up to the default size_allocate method. I'm not a python expert, but I believe Gtk.Image.do_size_allocate(self, allocation) at the end of your override should work. Looking at the implementation, the allocation needs to be stored in GtkWidget's private structure. Without chaining up, the allocation is never stored, and thus when on_draw() is called it is likely making a 0x0 sized Cairo context. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
Hi Kip, After setting the rescaled image, you should probably Chain Up to the default size_allocate method. I'm not a python expert, but I believe Gtk.Image.do_size_allocate(self, allocation) Hey Andrew. You are right. I had no idea that that had to be done, but based on my knowledge of other windowing toolkits and the underlying native implementation, what you suggest makes sense. at the end of your override should work. Looking at the implementation, the allocation needs to be stored in GtkWidget's private structure. Without chaining up, the allocation is never stored, and thus when on_draw() is called it is likely making a 0x0 sized Cairo context. That makes sense, but should the allocation passed to the base class's do_size_allocate() be the original allocation parameter that was passed into the override, or the one that I modified to contain the new image dimensions adjusted to maintain the aspect ratio? If I use the allocation passed into the override, the pixels in the image appear to rescale appropriately, but the image as a whole does not. It grows horizontally, but the height of the widget remains fixed. Any suggestions? The image is being added to the GtkAssistant page as such... page._bannerImage = BannerImage() #Gtk.Image() page.pack_start(page._bannerImage, False, False, 0) page.reorder_child(page._bannerImage, 0) Thanks for your help. -- Kip Warner -- Software Engineer OpenPGP encrypted/signed mail preferred http://www.thevertigo.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Thu, Jun 13, 2013 at 8:42 PM, Kip Warner k...@thevertigo.com wrote: That makes sense, but should the allocation passed to the base class's do_size_allocate() be the original allocation parameter that was passed into the override, or the one that I modified to contain the new image dimensions adjusted to maintain the aspect ratio? If I use the allocation passed into the override, the pixels in the image appear to rescale appropriately, but the image as a whole does not. It grows horizontally, but the height of the widget remains fixed. Yes, you should pass in the same allocation you received. A really proper way to do this would be to scale the image to less than the full allocation depending on the margins/padding/border etc., and then the base class could do the right job with honoring that stuff after you set the pixbuf. But by default that stuff is 0 and you don't have to worry about it in this case. What you can't do is allocate additional height to yourself in do_size_allocate(). So if you have a short wide image and are allocated more width than the height at your aspect ratio allows, you _shouldn't_ scale up or else your image will be clipped; the toolkit knows what it allocated to you and will not let you draw outside of that region. What you can do to (try to) prevent that situation is to set the widget to do height for width allocation, and override get_preferred_height_for_width() to honor your aspect ratio. In some situations of course the toolkit won't be able to perfectly honor the allocation request, so be sure not to scale out of bounds no matter what. I'm not sure on how to set the widget to do height for width allocation, it seems you may have to override get_request_mode()? What I did was override all the size request methods instead. ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
Re: Invisible GtkImage
On Thu, 2013-06-13 at 21:32 -0700, Andrew Potter wrote: What you can't do is allocate additional height to yourself in do_size_allocate(). So if you have a short wide image and are allocated more width than the height at your aspect ratio allows, you _shouldn't_ scale up or else your image will be clipped; the toolkit knows what it allocated to you and will not let you draw outside of that region. Ok, fair enough. What you can do to (try to) prevent that situation is to set the widget to do height for width allocation, and override get_preferred_height_for_width() to honor your aspect ratio. In some situations of course the toolkit won't be able to perfectly honor the allocation request, so be sure not to scale out of bounds no matter what. Right. What I will do is resize to exactly what is passed into my do_size_allocate() override since that size should theoretically meet the aspect ratio I am maintaining via my do_get_preferred_height_for_width() override. I'm not sure on how to set the widget to do height for width allocation, it seems you may have to override get_request_mode()? What I did was override all the size request methods instead. Here's what I did... def do_get_preferred_height_for_width(self, width): return (width / self._aspectRatio) def do_get_request_mode(self): return Gtk.SizeRequestMode.HEIGHT_FOR_WIDTH ...but something very interesting happens immediately after the return in do_get_preferred_height_for_width(). I get an assertion fail buried deep somewhere in python-gi... ERROR:../../gi/pygi-closure.c:494:_pygi_closure_set_out_arguments: code should not be reached One thing is clear. The latter do_get_request_mode() is in fact being queried. -- Kip Warner -- Software Engineer OpenPGP encrypted/signed mail preferred http://www.thevertigo.com ___ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list