Re: Bug in get_preferred_height_for_width() [was Re: Minimum height for minimum width]

2010-10-21 Thread Tristan Van Berkom
On Thu, 2010-10-21 at 14:51 +0900, Tristan Van Berkom wrote:
 On Thu, 2010-10-21 at 14:10 +0900, Tristan Van Berkom wrote:
  On Thu, 2010-10-21 at 13:57 +0900, Tristan Van Berkom wrote:
   On Mon, 2010-10-18 at 01:28 -0400, Havoc Pennington wrote:
Hi,

On Sun, Oct 17, 2010 at 11:58 PM, Tristan Van Berkom
trista...@openismus.com wrote:

 What happens when another subclass wants to use
 -adjust_size_allocation() to realign itself further ? how
 can it cooperate with GtkWidgetClass and not cause bad side
 effects ?

In the patch I posted (assuming the FIXME is fixed), what would still 
be broken?
I'm sort of lost what problems are unsolved. Granted, I might find out
if I tested the patch ;-)

   
   This part will be re-broken, in this patch you are not adjusting the
   allocated width for margins and alignments *before* getting the height
   for the real allocated width:
   
   ---
 adjusted_allocation = real_allocation;
 if (gtk_widget_get_request_mode (widget) ==
 GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
   {
 int min_width;
   
 gtk_widget_get_preferred_width (widget, min_width,
 natural_width);
 /* natural_width is a white lie; it's reduced to the
  * actual allocation but kept above min.
  */
 if (natural_width  real_allocation.width)
   natural_width = MAX(real_allocation.width, min_width);
 gtk_widget_get_preferred_height_for_width (widget, natural_width,
NULL, natural_height);
   }
 else ...
   ---
   
   And then it goes on too adjust the allocations after checking
   the height for width:
   ---
   
 GTK_WIDGET_GET_CLASS (widget)-adjust_size_allocation (widget,
GTK_ORIENTATION_HORIZONTAL,
natural_width,
adjusted_allocation.x,
adjusted_allocation.width);
 GTK_WIDGET_GET_CLASS (widget)-adjust_size_allocation (widget,
GTK_ORIENTATION_VERTICAL,
natural_height,
adjusted_allocation.y,
adjusted_allocation.height);
   ---
   
   Let's see what we can do with this api... it would have to be
   something more like:
   
  
  Actually even that is wrong, since we're passing a size that
  has it's margins stripped to get_height_for_width(), which
  will do the operation again on the for_size.
  
  So it needs to add another line:
  
   ---
   
   if (widget_is_height_for_width) {
   
 gtk_widget_get_preferred_width (widget, min_width,
 natural_width);
 GTK_WIDGET_GET_CLASS (widget)-adjust_size_allocation (widget,
GTK_ORIENTATION_HORIZONTAL,
natural_width,
adjusted_allocation.x,
adjusted_allocation.width);
  
  After adjusting adjusting the allocated width with the aid of the real
  natural width... we get a new adjusted_allocation.width, before passing
  that width to get_preferred_height_for_width we need to:
  
  gint adjusted_allocated_width = adjusted_allocation.width;
  
  GTK_WIDGET_GET_CLASS (widget)-adjust_size_request(widget, 
 GTK_ORIENTATION_HORIZONTAL,
 /* for_size is never needed
for this api afaics */
 adjusted_allocated_width,
 NULL);
  
  And then we need to call get_height_for_width () to obtain the natural
  height for the allocated width... /after/ adding some margins to the
  inner allocated width, since those margins will be removed from the
  for_size deep inside get_height_for_width() and then others re-added 
  to the output natural height.
  
  Thanks for trying a patch out with this new API (it helps alot), 
  I'll try updating the patch to do what I think it needs to do and 
  send that one back.
  
  I'll remove the for_size argument from -adjust_size_request() as
  well since it's not used anywhere and I cant imagine what it can
  be used for.
  
 
 I've attached my patch here, with your API approach seems everything
 falls into place.
 
 Besides the changes I outlined above I also had to change GtkContainer
 

Re: Bug in get_preferred_height_for_width() [was Re: Minimum height for minimum width]

2010-10-20 Thread Tristan Van Berkom
On Mon, 2010-10-18 at 01:28 -0400, Havoc Pennington wrote:
 Hi,
 
 On Sun, Oct 17, 2010 at 11:58 PM, Tristan Van Berkom
 trista...@openismus.com wrote:
 
  What happens when another subclass wants to use
  -adjust_size_allocation() to realign itself further ? how
  can it cooperate with GtkWidgetClass and not cause bad side
  effects ?
 
 In the patch I posted (assuming the FIXME is fixed), what would still be 
 broken?
 I'm sort of lost what problems are unsolved. Granted, I might find out
 if I tested the patch ;-)
 

This part will be re-broken, in this patch you are not adjusting the
allocated width for margins and alignments *before* getting the height
for the real allocated width:

---
  adjusted_allocation = real_allocation;
  if (gtk_widget_get_request_mode (widget) ==
  GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
{
  int min_width;

  gtk_widget_get_preferred_width (widget, min_width,
  natural_width);
  /* natural_width is a white lie; it's reduced to the
   * actual allocation but kept above min.
   */
  if (natural_width  real_allocation.width)
natural_width = MAX(real_allocation.width, min_width);
  gtk_widget_get_preferred_height_for_width (widget, natural_width,
 NULL, natural_height);
}
  else ...
---

And then it goes on too adjust the allocations after checking
the height for width:
---

  GTK_WIDGET_GET_CLASS (widget)-adjust_size_allocation (widget,
 GTK_ORIENTATION_HORIZONTAL,
 natural_width,
 adjusted_allocation.x,
 adjusted_allocation.width);
  GTK_WIDGET_GET_CLASS (widget)-adjust_size_allocation (widget,
 GTK_ORIENTATION_VERTICAL,
 natural_height,
 adjusted_allocation.y,
 adjusted_allocation.height);
---

Let's see what we can do with this api... it would have to be
something more like:

---

if (widget_is_height_for_width) {

  gtk_widget_get_preferred_width (widget, min_width,
  natural_width);
  GTK_WIDGET_GET_CLASS (widget)-adjust_size_allocation (widget,
 GTK_ORIENTATION_HORIZONTAL,
 natural_width,
 adjusted_allocation.x,
 adjusted_allocation.width);

  gtk_widget_get_preferred_height_for_width (widget, 
 adjusted_allocation.width,
 NULL, natural_height);
  GTK_WIDGET_GET_CLASS (widget)-adjust_size_allocation (widget,
 GTK_ORIENTATION_VERTICAL,
 natural_height,
 adjusted_allocation.y,
 adjusted_allocation.height);
}

---

From first glance at the portion that touches 
gtksizerequest.c, the answer to the FIXME comment is
pretty much: yes it's going to be in the cache, we need
to call gtk_widget_get_preferred_width() there directly
to get a probably cached natural_width that has already been
treated by -adjust_size_request().


  ... and more importantly, why is this useful
  to anybody except GtkWidget and GtkContainer ?
 
 It is useful in any abstract base class that wants to provide stuff
 around whatever its subclasses draw.
 
 I think GtkContainer is actually a good enough reason to have this.
 border-width is deprecated sure, but it's not going away soon, it'd be
 nice to clean up all the code that has to deal with it.
 
 Another example in GTK is GtkMisc, though we want to deprecate that
 too, you could use this vfunc to delete the align and pad handling
 from its subclasses and delete some code, which would be nice.
 
 Hypothetically you could do things like:
  * a base class that aligned in a more precise way than
 left/right/center (like GtkAlignment)
  * a base class providing more complex CSS-like border/margin/pad
 capability with colors for each
  * a base class that provided a frame
  * a base class that adds any kind of display or status next to subclass 
 content
 
 All of these could also be implemented as a container, granted. (That
 is, GtkMisc and GtkAlignment solve the same problem.)
 However, I think there can be good reasons to do this stuff in a base
 class so your widgets can have the stuff built in

Hmm 

Re: Bug in get_preferred_height_for_width() [was Re: Minimum height for minimum width]

2010-10-20 Thread Tristan Van Berkom
On Thu, 2010-10-21 at 13:57 +0900, Tristan Van Berkom wrote:
 On Mon, 2010-10-18 at 01:28 -0400, Havoc Pennington wrote:
  Hi,
  
  On Sun, Oct 17, 2010 at 11:58 PM, Tristan Van Berkom
  trista...@openismus.com wrote:
  
   What happens when another subclass wants to use
   -adjust_size_allocation() to realign itself further ? how
   can it cooperate with GtkWidgetClass and not cause bad side
   effects ?
  
  In the patch I posted (assuming the FIXME is fixed), what would still be 
  broken?
  I'm sort of lost what problems are unsolved. Granted, I might find out
  if I tested the patch ;-)
  
 
 This part will be re-broken, in this patch you are not adjusting the
 allocated width for margins and alignments *before* getting the height
 for the real allocated width:
 
 ---
   adjusted_allocation = real_allocation;
   if (gtk_widget_get_request_mode (widget) ==
   GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
 {
   int min_width;
 
   gtk_widget_get_preferred_width (widget, min_width,
   natural_width);
   /* natural_width is a white lie; it's reduced to the
* actual allocation but kept above min.
*/
   if (natural_width  real_allocation.width)
 natural_width = MAX(real_allocation.width, min_width);
   gtk_widget_get_preferred_height_for_width (widget, natural_width,
  NULL, natural_height);
 }
   else ...
 ---
 
 And then it goes on too adjust the allocations after checking
 the height for width:
 ---
 
   GTK_WIDGET_GET_CLASS (widget)-adjust_size_allocation (widget,
  GTK_ORIENTATION_HORIZONTAL,
  natural_width,
  adjusted_allocation.x,
  adjusted_allocation.width);
   GTK_WIDGET_GET_CLASS (widget)-adjust_size_allocation (widget,
  GTK_ORIENTATION_VERTICAL,
  natural_height,
  adjusted_allocation.y,
  adjusted_allocation.height);
 ---
 
 Let's see what we can do with this api... it would have to be
 something more like:
 

Actually even that is wrong, since we're passing a size that
has it's margins stripped to get_height_for_width(), which
will do the operation again on the for_size.

So it needs to add another line:

 ---
 
 if (widget_is_height_for_width) {
 
   gtk_widget_get_preferred_width (widget, min_width,
   natural_width);
   GTK_WIDGET_GET_CLASS (widget)-adjust_size_allocation (widget,
  GTK_ORIENTATION_HORIZONTAL,
  natural_width,
  adjusted_allocation.x,
  adjusted_allocation.width);

After adjusting adjusting the allocated width with the aid of the real
natural width... we get a new adjusted_allocation.width, before passing
that width to get_preferred_height_for_width we need to:

gint adjusted_allocated_width = adjusted_allocation.width;

GTK_WIDGET_GET_CLASS (widget)-adjust_size_request(widget, 
   GTK_ORIENTATION_HORIZONTAL,
   /* for_size is never needed
  for this api afaics */
   adjusted_allocated_width,
   NULL);

And then we need to call get_height_for_width () to obtain the natural
height for the allocated width... /after/ adding some margins to the
inner allocated width, since those margins will be removed from the
for_size deep inside get_height_for_width() and then others re-added 
to the output natural height.

Thanks for trying a patch out with this new API (it helps alot), 
I'll try updating the patch to do what I think it needs to do and 
send that one back.

I'll remove the for_size argument from -adjust_size_request() as
well since it's not used anywhere and I cant imagine what it can
be used for.

Cheers,
  -Tristan

 
   gtk_widget_get_preferred_height_for_width (widget, 
  adjusted_allocation.width,
  NULL, natural_height);
   GTK_WIDGET_GET_CLASS (widget)-adjust_size_allocation (widget,
  GTK_ORIENTATION_VERTICAL,
  natural_height,
  adjusted_allocation.y,

Re: Bug in get_preferred_height_for_width() [was Re: Minimum height for minimum width]

2010-10-20 Thread Tristan Van Berkom
On Thu, 2010-10-21 at 14:10 +0900, Tristan Van Berkom wrote:
 On Thu, 2010-10-21 at 13:57 +0900, Tristan Van Berkom wrote:
  On Mon, 2010-10-18 at 01:28 -0400, Havoc Pennington wrote:
   Hi,
   
   On Sun, Oct 17, 2010 at 11:58 PM, Tristan Van Berkom
   trista...@openismus.com wrote:
   
What happens when another subclass wants to use
-adjust_size_allocation() to realign itself further ? how
can it cooperate with GtkWidgetClass and not cause bad side
effects ?
   
   In the patch I posted (assuming the FIXME is fixed), what would still be 
   broken?
   I'm sort of lost what problems are unsolved. Granted, I might find out
   if I tested the patch ;-)
   
  
  This part will be re-broken, in this patch you are not adjusting the
  allocated width for margins and alignments *before* getting the height
  for the real allocated width:
  
  ---
adjusted_allocation = real_allocation;
if (gtk_widget_get_request_mode (widget) ==
GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
  {
int min_width;
  
gtk_widget_get_preferred_width (widget, min_width,
natural_width);
/* natural_width is a white lie; it's reduced to the
 * actual allocation but kept above min.
 */
if (natural_width  real_allocation.width)
  natural_width = MAX(real_allocation.width, min_width);
gtk_widget_get_preferred_height_for_width (widget, natural_width,
   NULL, natural_height);
  }
else ...
  ---
  
  And then it goes on too adjust the allocations after checking
  the height for width:
  ---
  
GTK_WIDGET_GET_CLASS (widget)-adjust_size_allocation (widget,
   GTK_ORIENTATION_HORIZONTAL,
   natural_width,
   adjusted_allocation.x,
   adjusted_allocation.width);
GTK_WIDGET_GET_CLASS (widget)-adjust_size_allocation (widget,
   GTK_ORIENTATION_VERTICAL,
   natural_height,
   adjusted_allocation.y,
   adjusted_allocation.height);
  ---
  
  Let's see what we can do with this api... it would have to be
  something more like:
  
 
 Actually even that is wrong, since we're passing a size that
 has it's margins stripped to get_height_for_width(), which
 will do the operation again on the for_size.
 
 So it needs to add another line:
 
  ---
  
  if (widget_is_height_for_width) {
  
gtk_widget_get_preferred_width (widget, min_width,
natural_width);
GTK_WIDGET_GET_CLASS (widget)-adjust_size_allocation (widget,
   GTK_ORIENTATION_HORIZONTAL,
   natural_width,
   adjusted_allocation.x,
   adjusted_allocation.width);
 
 After adjusting adjusting the allocated width with the aid of the real
 natural width... we get a new adjusted_allocation.width, before passing
 that width to get_preferred_height_for_width we need to:
 
 gint adjusted_allocated_width = adjusted_allocation.width;
 
 GTK_WIDGET_GET_CLASS (widget)-adjust_size_request(widget, 
GTK_ORIENTATION_HORIZONTAL,
  /* for_size is never needed
   for this api afaics */
adjusted_allocated_width,
NULL);
 
 And then we need to call get_height_for_width () to obtain the natural
 height for the allocated width... /after/ adding some margins to the
 inner allocated width, since those margins will be removed from the
 for_size deep inside get_height_for_width() and then others re-added 
 to the output natural height.
 
 Thanks for trying a patch out with this new API (it helps alot), 
 I'll try updating the patch to do what I think it needs to do and 
 send that one back.
 
 I'll remove the for_size argument from -adjust_size_request() as
 well since it's not used anywhere and I cant imagine what it can
 be used for.
 

I've attached my patch here, with your API approach seems everything
falls into place.

Besides the changes I outlined above I also had to change GtkContainer
adjust_size_allocation() implementation to do it's own magic *first*
and then chain up to GtkWidgetClass after.

Otherwise with extra-large allocations, a container border width
would be 

Re: Bug in get_preferred_height_for_width() [was Re: Minimum height for minimum width]

2010-10-17 Thread Tristan Van Berkom
On Fri, 2010-10-15 at 11:32 -0400, Havoc Pennington wrote:
 Hi,
 
 I think I get what you're saying. If not I'll probably understand it
 reading your code.
 
 btw things are looking kind of messed up to me in the current code in
 gtkwidget.c ... this:
 
   gtk_widget_get_preferred_width (widget, NULL, natural_width);
   get_span_inside_border_horizontal (widget,
aux_info,
allocation-width,
natural_width,
x, w);
 
 so natural_width has the margins in it, right? But it's centered
 without removing those margins first. The code up in
 get_span_inside_border() removes margins from allocation-width but
 not natural_width.
 
 It seems like we need to remove the margins to get
 adjusted_natural_width. And then say in GtkContainer, we need that
 adjusted_natural_width and we remove border_width from it, and then we
 pass the twice-adjusted natural width with both margins and border
 width and alignment-added-padding stripped down to the actual subclass
 like GtkButton.
 
 Without trying to code it and see if it works, it could look like:
 
 (* adjust_size_allocation) (GtkWidget *widget,
GtkOrientation orientation,
gint   *for_size_opposite,
gint   *natural_size,
gint   *offset,
gint   *adjusted_size);
 
 where all four numbers are changing as we're chaining 
 Widget-Container-Button
 
 Might be nicer to do struct GtkAllocatedSize { int for_size_opposite;
 int natural_size; int offset; int adjusted_size }  ?


Ok my brain is about to explode trying to figure out the right
implementation for this, lets look in detail to the requirements.

From what I understand, come time to adjust the size for allocation
GtkWidget needs to do the following steps (for simplicity, lets assume
GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH mode):

  - Strip any padding added by itself and any subclasses from the 
allocation-width (this produces a 'stripped_allocated_width')

  - If halign != FILL, it needs to limit the width to the real natural
size, this in itself involves:

  a.) calling gtk_widget_get_preferred_width()

  b.) stripping any padding from the returned natural width
  (producing a 'stripped_natural_width')

  c.) interior width available for alignments becomes
  MIN (stripped_allocation_width, stripped_natural_width)

  - Now that we have the proper width for interior allocation; go ahead
and strip any padding added to the allocation-height, i.e. get
a 'stripped_allocated_height'.

  - If valign != FILL, we need to further limit the height to the
proper natural height for width, the fun continues:

  a.) We need to *re-add* any required padding to the concluded
  interior allocation width, presumably by calling
  -adjust_size_request() on our _final_ width which was
  concluded by the previous steps.

  b.) We need to use this new adjusted width to obtain the natural
  height and do that by calling
  gtk_widget_get_preferred_height_for_width()

  c.) Now we need to strip the added padding from the returned
  natural height (getting us a usable
 'stripped_natural_height').

  d.) The interior height available for alignment/allocation
  now becomes:
  MIN (stripped_allocated_height, stripped_natural_height)

  - Now we have a proper width and height we can go on to align
the interior allocation inside the padded space in both
orientations.

Of course furthermore, gtk_widget_get_height_for_width needs to be
amended to adjust the for_width by:

  - Stripping any extra padding added by -adjust_size_request from
the for_width.

  - If halign != FILL then it needs to:

a.) gtk_widget_get_preferred_width() to obtain the natural width
b.) strip any padding previously added to the natural width
c.) 'for_width' then becomes
MIN (stripped_for_width, stripped_natural_width);

  - Call the class vfunc -height_for_width() using the adjusted
'for_width'

That's the big picture of what needs to happen, however it's still
not mapped to any proper API... I've been tentatively writing some
pseudo code that should do it but I keep getting stuck somewhere.

Maybe splitting the adjust_size_allocation() and align_size_allocation()
makes sense, but I get the feeling that adding apis here is creating
a mess factor we dont want to deal with in the long run (and admittedly
I still dont have a clear picture of how it can all work).

There's also another alternative, all of this alignment/padding code
so far belongs to GtkWidget (and marginally GtkContainer), so does all
of the size-requesting 

Re: Bug in get_preferred_height_for_width() [was Re: Minimum height for minimum width]

2010-10-17 Thread Havoc Pennington
Hi,

I would think of it like this maybe

real_adjust_request(orientation, request_data)
{
   adjust_request_by_adding_margin(orientation, request_data)
  /* alignment does not affect request */
}

real_adjust_allocation(orientation, allocation_data)
{
  adjust_allocation_by_removing_margin(orientation, allocation_data)
  adjust_allocation_by_aligning(orientation, allocation_data)
}

I think allocation_data *includes* the natural size, which is itself
adjusted. So when you by_removing_margin you are dropping down the
natural size you started with so that the align stuff has the
marginless size. Same for for_size.

Conceptually GtkWidget contains two adjustments. But those two
adjustments should not have anything to do with each other. It's as if
you had a hierarchy like:

GtkWidget - GtkWidgetWithMargin - GtkWidgetWithAlignment

Those would chain up to each other. But since it's all in one class
the two adjusts are invoked inline. However if our adjust vfunc has
the right signature, it should be possible to do margin and alignment
orthogonally.

On Sun, Oct 17, 2010 at 5:36 AM, Tristan Van Berkom
trista...@openismus.com wrote:
  - Strip any padding added by itself and any subclasses from the
    allocation-width (this produces a 'stripped_allocated_width')

Widget base class need not strip what subclasses added - each subclass
strips its own. When overriding, subclass has to chain up so widget
can do its stuff just as container does.

I'd also say margin here for clarity rather than padding

  - If halign != FILL, it needs to limit the width to the real natural
    size, this in itself involves:

      a.) calling gtk_widget_get_preferred_width()


I think get_preferred_width should be called outside of the adjust
vfunc, and then initial natural size passed in. As the adjustment
proceeds, the natural size is chopped down by each adjustment.

      b.) stripping any padding from the returned natural width
          (producing a 'stripped_natural_width')

This should be done by the adjust_allocation_by_removing_margin() and
the natural width that then gets passed for aligning would be reduced.

      c.) interior width available for alignments becomes
          MIN (stripped_allocation_width, stripped_natural_width)

Hmm this doesn't sound right. Conceptually we have to decide if the
margin is inside or outside the alignment-required padding. This
basically means whether we do the margin adjust first or the align
adjust first. (Note that on request you go from inner adjust to outer,
i.e. chain up last, and on allocation the other direction, i.e. chain
up first. So if margin is on the outside, it would be added second in
request, and removed first in allocate.)

Anyway. What should come in to
adjust_allocation_by_aligning(allocation_data) should be a natural
size de-margined and an allocation also de-margined. We just align the
de-margined natural size in the de-margined allocation.

  - Now that we have the proper width for interior allocation; go ahead
    and strip any padding added to the allocation-height, i.e. get
    a 'stripped_allocated_height'.

I think you go back and have your unadjusted width allocation, and you
pass that as the for_width to the
adjust_allocation(orientation=height). Now as the allocation
adjustment proceeds, each adjust step has to also adjust for_width (in
addition to the allocation itself and the natural size).

 Of course furthermore, gtk_widget_get_height_for_width needs to be
 amended to adjust the for_width by:

  - Stripping any extra padding added by -adjust_size_request from
    the for_width.

Rather, each adjust_size_allocation step (align, margin,
border_width are 3 steps) should compensate for itself in the
for_width as the chaining up proceeds.

 That's the big picture of what needs to happen, however it's still
 not mapped to any proper API... I've been tentatively writing some
 pseudo code that should do it but I keep getting stuck somewhere.

I think just adding the natural size, for_size, and orientation to the
existing two vfuncs should work. Probably need a struct to hold {
size, natural_size, for_size } which are the three things to adjust.

 There's also another alternative, all of this alignment/padding code
 so far belongs to GtkWidget (and marginally GtkContainer), so does all
 of the size-requesting logic... so we could go the direction of:

  - remove vfuncs -adjust_size_allocation/-adjust_size_request

I think the adjust approach should be workable as described above and
keep the nice encapsulation / flexibility of the vfuncs.

Havoc
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Bug in get_preferred_height_for_width() [was Re: Minimum height for minimum width]

2010-10-17 Thread Havoc Pennington
Hi,

On Sun, Oct 17, 2010 at 11:58 PM, Tristan Van Berkom
trista...@openismus.com wrote:

 What happens when another subclass wants to use
 -adjust_size_allocation() to realign itself further ? how
 can it cooperate with GtkWidgetClass and not cause bad side
 effects ?

In the patch I posted (assuming the FIXME is fixed), what would still be broken?
I'm sort of lost what problems are unsolved. Granted, I might find out
if I tested the patch ;-)

 ... and more importantly, why is this useful
 to anybody except GtkWidget and GtkContainer ?

It is useful in any abstract base class that wants to provide stuff
around whatever its subclasses draw.

I think GtkContainer is actually a good enough reason to have this.
border-width is deprecated sure, but it's not going away soon, it'd be
nice to clean up all the code that has to deal with it.

Another example in GTK is GtkMisc, though we want to deprecate that
too, you could use this vfunc to delete the align and pad handling
from its subclasses and delete some code, which would be nice.

Hypothetically you could do things like:
 * a base class that aligned in a more precise way than
left/right/center (like GtkAlignment)
 * a base class providing more complex CSS-like border/margin/pad
capability with colors for each
 * a base class that provided a frame
 * a base class that adds any kind of display or status next to subclass content

All of these could also be implemented as a container, granted. (That
is, GtkMisc and GtkAlignment solve the same problem.)
However, I think there can be good reasons to do this stuff in a base
class so your widgets can have the stuff built in

Havoc
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Bug in get_preferred_height_for_width() [was Re: Minimum height for minimum width]

2010-10-15 Thread Tristan Van Berkom
On Thu, 2010-10-14 at 10:45 -0400, Havoc Pennington wrote:
 In sounds like in short the for_size somehow needs to be adjusted
 (strip out the pixels that adjust_size_request added). (If I'm
 understanding properly.) Of course that's what adjust_size_allocation
 does, except it's both dimensions. for_size is after all the proposed
 allocation size in one dimension.

Ouch, indeed.

The for_size fed to widget implementations additionally needs to
strip the added padding that can happen in -adjust_size_request()

However the bug I'm referring to is another one; the for_size also
needs to be limited to the natural size in the case that the widget
does not fill (i.e. not to compensate for pixels stripped in
-adjust_size_request(), but for pixels that will further be stripped
in -adjust_size_allocation(), in the case that the widget expanded).

 Maybe just change adjust_size_allocation to take a GtkOrientation and
 return a single integer (could have a convenience function to do the
 current full GtkAllocation adjust). Then use that to clean up for_size
 when it comes in to compute_size_for_orientation() in
 gtksizerequest.c. Or I think for now it'd also work to make a
 GtkAllocation allocation = { MAXINT, for_height } and adjust that,
 seems less hacky to change adjust_size_allocation to be able to do
 just one dimension.

Right, this will be a bit more difficult as the current
adjust_size_allocation() needs to use the context of both
APIs (i.e. it needs to call get_request_mode() and then
either get_preferred_width and get_preferred_height_for_width()
or the other way around).

However changing that API seems like the right thing to do,
I suppose it will need to take the natural_width as an argument,
which seems strange.. the api would look similar to the current
gtkwidget.c static functions:
 get_span_inside_border_horizontal/vertical().

In the end the adjust_size_allocation() api/vfunc 
will look like this:

void gtk_widget_adjust_allocated_size (GtkWidget *widget,
   GtkOrientation orientation,
   gint   proposed_size,
   gint   natural_size,
   gint  *offset,
   gint  *adjusted_size);

And then gtk_widget_adjust_allocation() would be a convenience API
that would call the above api, this convenience API would function
in the same way as the current implementation does internally:
   'gtk_widget_real_adjust_size_allocation()'

The part that feels weird here is that we are feeding in the
natural_size, however it's important because come allocation time
specifically; the 'natural_size' may be in context to a for_size
in the other orientation (i.e. the widget cannot be expected to
just know its natural size in this stage).

I'll give this approach a shot with the above API change and
file a bug for it shortly...

-Tristan

PS: After looking at this, it feels also a bit strange that we need
to have -adjust_size_request/allocation() (i.e. it seems that the
added border-width that GtkContainer computes here should just be 
pulled in by chaining up vfuncs through parent classes during
the request/allocate cycles), however I suppose there's nothing
to be done for that... or is there...

 I don't think a solution that looks at xalign specifically is needed,
 so we can keep the abstraction barrier. The generic mechanism just
 needs to be smart enough to know that the for_size is a proposed
 (adjusted up) allocation and thus has to be unadjusted before
 computing the unadjusted request.
 
 Havoc


___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Bug in get_preferred_height_for_width() [was Re: Minimum height for minimum width]

2010-10-15 Thread Havoc Pennington
Hi,

On Fri, Oct 15, 2010 at 8:55 AM, Tristan Van Berkom
trista...@openismus.com wrote:
 The for_size fed to widget implementations additionally needs to
 strip the added padding that can happen in -adjust_size_request()

Right, adjust_size_allocation should basically invert anything
adjust_size_request does so the widget is seeing things as if only the
widget itself had set the request.

By padding I don't just mean the margin properties, I mean anything
adjust_size_request adds (also the padding for fill alignment, the
container border width, etc.)

 However the bug I'm referring to is another one; the for_size also
 needs to be limited to the natural size in the case that the widget
 does not fill (i.e. not to compensate for pixels stripped in
 -adjust_size_request(), but for pixels that will further be stripped
 in -adjust_size_allocation(), in the case that the widget expanded).

Wouldn't it fix this to do adjust_size_allocation on the for_size?

 In the end the adjust_size_allocation() api/vfunc
 will look like this:

 void gtk_widget_adjust_allocated_size (GtkWidget *widget,
                                       GtkOrientation orientation,
                                       gint           proposed_size,
                                       gint           natural_size,
                                       gint          *offset,
                                       gint          *adjusted_size);

If you have a for_size (which can be -1 for unset) then you could skip
the natural size and just call the size request API again, using the
for_size if = 0. I think that would be better, because as you say:

 The part that feels weird here is that we are feeding in the
 natural_size, however it's important because come allocation time
 specifically; the 'natural_size' may be in context to a for_size
 in the other orientation (i.e. the widget cannot be expected to
 just know its natural size in this stage).

I think you should just call the request methods again. (Not the
wrappers of course, the vfuncs directly.) Instead of passing in a
natural size.

Havoc
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Bug in get_preferred_height_for_width() [was Re: Minimum height for minimum width]

2010-10-15 Thread Havoc Pennington
Hi,

On Fri, Oct 15, 2010 at 9:55 AM, Havoc Pennington h...@pobox.com wrote:
 I think you should just call the request methods again. (Not the
 wrappers of course, the vfuncs directly.) Instead of passing in a
 natural size.


I guess this doesn't work when chaining up and down

Havoc
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Bug in get_preferred_height_for_width() [was Re: Minimum height for minimum width]

2010-10-15 Thread Tristan Van Berkom
On Fri, 2010-10-15 at 09:55 -0400, Havoc Pennington wrote:
 Hi,
 
 On Fri, Oct 15, 2010 at 8:55 AM, Tristan Van Berkom
 trista...@openismus.com wrote:
  The for_size fed to widget implementations additionally needs to
  strip the added padding that can happen in -adjust_size_request()
 
 Right, adjust_size_allocation should basically invert anything
 adjust_size_request does so the widget is seeing things as if only the
 widget itself had set the request.
 
 By padding I don't just mean the margin properties, I mean anything
 adjust_size_request adds (also the padding for fill alignment, the
 container border width, etc.)
 
  However the bug I'm referring to is another one; the for_size also
  needs to be limited to the natural size in the case that the widget
  does not fill (i.e. not to compensate for pixels stripped in
  -adjust_size_request(), but for pixels that will further be stripped
  in -adjust_size_allocation(), in the case that the widget expanded).
 
 Wouldn't it fix this to do adjust_size_allocation on the for_size?
 
  In the end the adjust_size_allocation() api/vfunc
  will look like this:
 
  void gtk_widget_adjust_allocated_size (GtkWidget *widget,
GtkOrientation orientation,
gint   proposed_size,
gint   natural_size,
gint  *offset,
gint  *adjusted_size);
 
 If you have a for_size (which can be -1 for unset) then you could skip
 the natural size and just call the size request API again, using the
 for_size if = 0. I think that would be better, because as you say:
 
  The part that feels weird here is that we are feeding in the
  natural_size, however it's important because come allocation time
  specifically; the 'natural_size' may be in context to a for_size
  in the other orientation (i.e. the widget cannot be expected to
  just know its natural size in this stage).
 
 I think you should just call the request methods again. (Not the
 wrappers of course, the vfuncs directly.) Instead of passing in a
 natural size.

It needs to:

  a.) call the wrappers to get a natural_width before entering
  adjust_size_allocation(for_size, natural_width) so as to pick 
  up a good cached value that was treated by sizegroups and by
  adjust_size_request()

  b.) feed a natural size vs a proposed size to the
  adjust_size_allocation() because as I mentioned above: at
  allocation time, a widget cannot know its natural size, since
  it's natural size can be contextual to its dimension in the
  other orientation.

  Otherwise when doing valign at allocate time, the implementation
  calls get_preferred_height () ? no it cant because it's height
  already depends on its already allocated width (I recently fixed
  gtk_widget_real_adjust_natural_allocation() since it was calling 
  gtk_widget_get_preferred_size(), which results in vertically
  clipped labels when valigned CENTER).

So the convenience function that calls the new
gtk_widget_adjust_size_allocation(), clearly has to do the right
contextual request that gtk_widget_real_adjust_size_allocation()
does now (i.e. not the one it was doing 2 weeks ago)... the 
orientation contextual adjust_size_allocation()... needs to be
told what is the natural size... it has no context to make a guess.

Sorry, but this really is as complex as it seems... 

-Tristan

 
 Havoc


___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Bug in get_preferred_height_for_width() [was Re: Minimum height for minimum width]

2010-10-15 Thread Havoc Pennington
Hi,

I think I get what you're saying. If not I'll probably understand it
reading your code.

btw things are looking kind of messed up to me in the current code in
gtkwidget.c ... this:

  gtk_widget_get_preferred_width (widget, NULL, natural_width);
  get_span_inside_border_horizontal (widget,
 aux_info,
 allocation-width,
 natural_width,
 x, w);

so natural_width has the margins in it, right? But it's centered
without removing those margins first. The code up in
get_span_inside_border() removes margins from allocation-width but
not natural_width.

It seems like we need to remove the margins to get
adjusted_natural_width. And then say in GtkContainer, we need that
adjusted_natural_width and we remove border_width from it, and then we
pass the twice-adjusted natural width with both margins and border
width and alignment-added-padding stripped down to the actual subclass
like GtkButton.

Without trying to code it and see if it works, it could look like:

(* adjust_size_allocation) (GtkWidget *widget,
   GtkOrientation orientation,
   gint   *for_size_opposite,
   gint   *natural_size,
   gint   *offset,
   gint   *adjusted_size);

where all four numbers are changing as we're chaining Widget-Container-Button

Might be nicer to do struct GtkAllocatedSize { int for_size_opposite;
int natural_size; int offset; int adjusted_size }  ?

Sorry I got this wrong in my original patch :-/

Havoc
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Bug in get_preferred_height_for_width() [was Re: Minimum height for minimum width]

2010-10-14 Thread Havoc Pennington
In sounds like in short the for_size somehow needs to be adjusted
(strip out the pixels that adjust_size_request added). (If I'm
understanding properly.) Of course that's what adjust_size_allocation
does, except it's both dimensions. for_size is after all the proposed
allocation size in one dimension.

Maybe just change adjust_size_allocation to take a GtkOrientation and
return a single integer (could have a convenience function to do the
current full GtkAllocation adjust). Then use that to clean up for_size
when it comes in to compute_size_for_orientation() in
gtksizerequest.c. Or I think for now it'd also work to make a
GtkAllocation allocation = { MAXINT, for_height } and adjust that,
seems less hacky to change adjust_size_allocation to be able to do
just one dimension.

I don't think a solution that looks at xalign specifically is needed,
so we can keep the abstraction barrier. The generic mechanism just
needs to be smart enough to know that the for_size is a proposed
(adjusted up) allocation and thus has to be unadjusted before
computing the unadjusted request.

Havoc
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list