Re: Invisible GtkImage



On Sun, Jun 23, 2013 at 10:04 PM, Kip Warner <kip 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 tamen cum de rebus grandioribus
dicas, ipsae res verba rapiunt; Dolor ergo, id est summum malum,
metuetur semper, etiamsi non aderit; Etenim nec iustitia nec amicitia
esse omnino poterunt, nisi ipsae per se expetuntur. Summum ením bonum
exposuit vacuitatem doloris")
tv.set_wrap_mode(Gtk.WrapMode.WORD)

sw = Gtk.ScrolledWindow()
sw.add(tv)
sw.set_vexpand(True)
bin.add(sw)

win.add(bin)
win.show_all()
win.resize(600,800)
Gtk.main()


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]