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



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
<tristanvb 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


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