Re: GtkContainer Gtk 3.0 vs Gtk 3.2 geometry management



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.

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.


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]