Re: GtkContainer Gtk 3.0 vs Gtk 3.2 geometry management





2011/10/24 Denis Linvinus <linvinus gmail com>


2011/10/24 Tristan Van Berkom <tvb gnome org>
On Sun, Oct 23, 2011 at 4:38 PM, Denis Linvinus <linvinus gmail com> wrote:
>
>
> 2011/10/19 Tristan Van Berkom <tvb gnome org>
>>
>> Note I spent a lot of time writing something like this last year.
>>
>> I would like to eventually port it into GTK+ as the internal
>> implementation
>> of the GtkToolPalette.
>>
>> See:
>>   http://git.gnome.org/browse/libegg/tree/libegg/wrapbox
>
> Thanks for answer!
> But in your example same problem!
> If you pack wrapbox directly in to frame (without scrolled_window)
> then, you can not change the height of the window to smaller than it was at
> the start.

Ah, I get what you are saying.

This is a limitation that cannot be avoided because GTK+ already
mandates that every widget in an interface receives a size allocation
of at least it's minimum size request.

yes, it is the main problem, but take a look on my videos

This is my HVBox on gtk3.0
http://www.youtube.com/watch?v=sMB0qhuPMXc

And this is same program but on Gtk3.2
http://www.youtube.com/watch?v=artJWLhlpms


added yet another video http://www.youtube.com/watch?v=t7DioFe7FBk
 

Main different in logs, is that, while resizing on Gtk3.0, it always recalculate size
get_preferred_width minimum=86 natural=2150
get_preferred_height minimum=28 natural=28
get_preferred_height_for_width=86 != 597 minimum=140 natural=140
get_preferred_height_for_width=597 != 597 minimum=140 natural=140
get_preferred_height_for_width=597 != 597 minimum=140 natural=140
orig size_allocate x=5 y=59 w=597 h=140
orig2 size_allocate x=5 y=59 w=597 h=140
get_preferred_height minimum=28 natural=28
get_preferred_height_for_width=86 != 597 minimum=140 natural=140
get_preferred_height minimum=28 natural=28
get_preferred_height_for_width=86 != 597 minimum=140 natural=140
get_preferred_height_for_width=597 != 597 minimum=140 natural=140
get_preferred_height_for_width=597 != 597 minimum=140 natural=140
get_preferred_height minimum=28 natural=28
get_preferred_height_for_width=86 != 597 minimum=140 natural=140

on gtk3.2 it recalculate size only if size increases, if i reduce size then i see only
orig size_allocate x=5 y=111 w=1247 h=28
orig2 size_allocate x=5 y=111 w=1247 h=28
orig size_allocate x=5 y=55 w=1247 h=28
orig2 size_allocate x=5 y=55 w=1247 h=28
orig size_allocate x=5 y=55 w=623 h=28
orig2 size_allocate x=5 y=55 w=623 h=84
orig size_allocate x=5 y=55 w=623 h=28
orig2 size_allocate x=5 y=55 w=623 h=84
orig size_allocate x=5 y=55 w=456 h=28
orig2 size_allocate x=5 y=55 w=456 h=84
orig size_allocate x=5 y=55 w=456 h=28
orig2 size_allocate x=5 y=55 w=456 h=84
(called only size_allocate)

until i move mouse inside my box (at the end of video), only after that widget recalculate size.

But i can't understand how to force size calculation manually (like i move mouse inside).
gtk_widget_set_size_request() - don't helps.
 

When you add height-for-width to this equation, then:

 o For a "height-for-width" interface, the screen will always
    be tall enough to hold all the content at the smallest width.

 o For a "width-for-height" interface the opposite is true, the
    window must always stay wide enough to fit all of the content
    at the smallest possible height.

This deserves an explanation, so lets consider wrapping text instead
of the wrapbox (in practice it is the same thing though)...

If you have a window with a wrapping text label, and the label is
allowed to wrap down to the smallest word... then the window
will need to be tall enough to fit the text in the case that it is
wrapped down to the smallest word, even if at display time the
default width is larger.


So you have 2 main ways of dealing with this:

 o Once, by setting a reasonable width on the toplevel

    Define a very small minimum width for the screen widgets
    which are height-for-width (possibly that is default for
    some widgets, like yours I think).  Then, before showing
    your interface set a hard limit on the toplevel GtkWindow's
    minimum width. (using gtk_widget_set_size_request()).

    This will cause your overall window to be "shorter"
    in height proportionally to the hard limit of width which
    you set on the interface (If you assign a larger minimum width
    to a window, it will receive a smaller dynamically resolved
    minimum height).

 o Per component, by setting reasonable minimum widths
    for any height-for-width content providing widgets in your interface.

    For instance in the above label example, if you set the
    label's "width-chars" property then the label will always
    request at least "width-chars" for the width of it's label.



Thanks for explanation, i think the same way.
 
Cheers,
          -Tristan

>
> look at screenshots
> this is window after start
> http://imageshack.us/photo/my-images/847/testwrapbox1.png/
> and this is
> http://imageshack.us/photo/my-images/696/testwrapbox.png/
> after changing the width of the window, it should allow to reduce its
> height, because there are many free space, but it does not.
>
> With GTK3.0 i use little trick for that,
> i store maximum allowed width in private variable, and in function
> get_preferred_height_for_width
> i always calculate height not for minimum width but for stored width.
>
> There is how it looks like
>     public override void get_preferred_height_for_width (int width,out int
> minimum_height, out int natural_height) {
>
>         /*workaround for min_height, if actual available width more than
> self minimum width*/
>         if( this.minimum_width!=width ||
>         !(this.minimum_width==width && this.natural_width >= width) ){
>             this.natural_width=width;
>         }
>
>         this._get_preferred_height_for_width(this.natural_width,out
> minimum_height, out natural_height);
>         this.natural_height = natural_height;
>     }
>
> where this.natural_width is stored maximum width.
> Because get_preferred_height_for_width called several times , first time for
> minimum width, others for allocated width,
> and because while i resizing window, gtk always recalculate size , in gtk3.0
> my window always have actual size.
>
>
> As i'm understand, problem appears because of the following changes in
> gtkcontainer.c in GTK3.2
>
> +typedef struct {
> +  gint hfw;
> +  gint wfh;
> +} RequestModeCount;
> +
> +static void
> +count_request_modes (GtkWidget        *widget,
> +             RequestModeCount *count)
> +{
> +  GtkSizeRequestMode mode = gtk_widget_get_request_mode (widget);
> +
> +  switch (mode)
> +    {
> +    case GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH:
> +      count->hfw++;
> +      break;
> +    case GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT:
> +      count->wfh++;
> +      break;
> +    case GTK_SIZE_REQUEST_CONSTANT_SIZE:
> +    default:
> +      break;
> +    }
> +}
> +
> +static GtkSizeRequestMode
> +gtk_container_get_request_mode (GtkWidget *widget)
> +{
> +  GtkContainer        *container = GTK_CONTAINER (widget);
> +  GtkContainerPrivate *priv      = container->priv;
> +
> +  /* Recalculate the request mode of the children by majority
> +   * vote whenever the internal content changes */
> +  if (_gtk_widget_get_width_request_needed (widget) ||
> +      _gtk_widget_get_height_request_needed (widget))
> +    {
> +      RequestModeCount count = { 0, 0 };
> +
> +      gtk_container_forall (container, (GtkCallback)count_request_modes,
> &count);
> +
> +      if (!count.hfw && !count.wfh)
> +    priv->request_mode = GTK_SIZE_REQUEST_CONSTANT_SIZE;
> +      else
> +    priv->request_mode = count.wfh > count.hfw ?
> +      GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT :
> +      GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
> +    }
> +
> +  return priv->request_mode;
> +}
> +
>
> so, container will recalculate it size only if
>   if (_gtk_widget_get_width_request_needed (widget) ||
>       _gtk_widget_get_height_request_needed (widget))
>
> because of that, my trick don't working with GTK 3.2,
> so, my question is, how to force the container/window  to recalculate its
> size in gtk 3.2 ?
>
> i try to use set_size_request and queue_resize (for container and for
> window),
> but this functions don't help.
>
> I hope I have clearly described their thoughts.
>
>
>>
>> Cheers,
>>        -Tristan
>>
>> On Wed, Oct 19, 2011 at 3:09 PM, Denis Linvinus <linvinus gmail com>
>> wrote:
>> > Hi all,
>> > i'm writing new GtkContainer which allocate children, firstly
>> > horizontally,
>> > then vertically. - HVBox.
>> >
>> > On gtk 3.0 it works without problems (with little trick), but with gtk
>> > 3.2.
>> > window don't change height when container change, until i move mouse
>> > above
>> > my container.
>> >
>> > My idea is that my container should use minimum space as possible, but
>> > enough to show all children.
>> > If available width not enough for children then container should
>> > increase
>> > height  for second line, and so on.
>> > Something like multiline tabs in firefox. (children is a buttons)
>> >
>> > There is my sources http://pastebin.com/8qugyfqk (i use valac --pkg
>> > gtk+-3.0
>> > -C ./main.vala to compile)
>> >
>> > image with  explanation of the problem
>> > http://imageshack.us/photo/my-images/508/resulte.png/
>> > there is two control buttons (add, remove) in one VBox, all other
>> > buttons
>> > in my HVBox container.
>> > As you can see at last screenshot, i lost two buttons after resize
>> > window on
>> > Gtk3.2, if i move mouse on buttons again then window will change it
>> > height ,
>> > so that the lost buttons will be visible.
>> >
>> > I'm check, problem is not in vala, i use generated *.c from ubuntu 11.10
>> > to
>> > compile on Ubuntu 11.04 without modifications, and it also works
>> > correctly.
>> >
>> > May be someone know how to force window to recalculate size?
>> > Or some other method to resolve my problem?
>> >
>> > My system ubuntu 11.10
>> > libgtk-3-0  3.2.0-0ubuntu3
>> >
>> > Ubuntu 11.04 for Gtk 3.0
>> > libgtk-3-0  3.0.8-0ubuntu1
>> >
>> > I will appreciate for any help.
>> > p.s. sorry for my English.
>> >
>> >
>> > _______________________________________________
>> > gtk-list mailing list
>> > gtk-list gnome org
>> > http://mail.gnome.org/mailman/listinfo/gtk-list
>> >
>> >
>
>




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