Hi,

On Wed, Feb 13, 2008 at 8:13 PM, Matthew Allum <[EMAIL PROTECTED]> wrote:
>
>  Yeah, we were thinking about some kind of 'memory' or lose binding for
>  actors where they could essentially 'ghost' or free themselves from a
>  container but no how to get back. I think this is similar to what you
>  are suggesting ?
>

I think so, yes.

>  Ok, can you send a rough patch (bugzilla maybe better) showing what you
>  mean for something like the rectangle ?

Most of the patch work is GObject boilerplate I believe... well,
probably also making necessary alterations to repair the effects of
any API breakage.

Let me try to kind of map it out first, below. I may be able to do the
patch, but I need to wait until I genuinely can justify spending a
couple days on it because I know I need it - I'm not quite to that
point.
If I do end up needing it, however, I'd like a little roadmap in my
head for how to do the patch... thus this thread ;-) And of course I
can also hope someone else solves the problem before it becomes the
problem I'm blocking on... ;-)

If you guys prefer bugzilla for discussion by all means - is that your
preference? we can relocate there.

I have no idea what the previous Clutter layout stuff looked like
btw... so this may be kind of a wacky proposal below.

>  I think the kind of route we took before was this layout interface which
>  provided a number of extra methods for doing the allocations that actors
>  could implement. But it seemed pretty complex, too much ?
>
>  Also for fixed sized 'displays/windows' it could be argued clutter is
>  more targeted for, too heavier/obtrusive layouting can be more of a
>  hindrance than an advantage. Not that Im saying layouts arn't useful
>  there just not as critical as in desktop app - at least they should not
>  get in the way if you want to do mostly fixed. A clutter app will
>  usually know its eventual window size from start whilst a GTK+ will not
>  (which makes sense to me - different use cases). Its worth keeping all
>  this in mind.

For sure I think there should be a nice, simple fixed-size API. I
think that can be accomplished.

>  > This seems to imply that the Clutter core would contain a "get size
>  > request" interface, the Fixed layout manager, and transient
>  > transform/allocation support, and a higher level such as Tidy would
>  > pile on with the more complex layout managers.
>
>  Yes I think so.
>

OK, here's a theory on how we could do things.

Algorithm Flow
===

* Each actor has a needs-relayout flag. This is true if the actor, or
any of its children, queued a relayout.
* Prior to any painting or window-mapping operation, if an actor's
needs-relayout flag is TRUE, we will do a layout pass.
* needs-relayout basically means the allocation of an actor is no good
and can't be used.

A layout pass is implemented in ClutterGroup as follows:

* For each child with a fixed position set on it, get the child's size
request, then allocate the fixed position and the child's requested
natural size
* For children without a fixed position set, if a layout manager is
set on the group, pass the children to the layout manager; if no
layout manager is set, position the children as if their fixed
position were 0,0
* When a child is allocated, the needs-relayout flag is set to FALSE
* The size request of a Group is the union of the boxes it would
allocate to fixed-position children, and the size request provided by
the layout manager for non-fixed-position children.

After relayout, we can paint; invariant when painting is that
needs-relayout=FALSE.

* Before painting, the child's allocation is transformed; there is a
translate transform and a scale transform. The transforms do not
modify the allocation, only transform it for rendering purposes.
* Then we paint.

ClutterGroup properties and methods
===

* "layout-manager" - an object implementing some kind of
ClutterLayoutManager interface.
Normally the layout manager is NULL, which means all layout is
fixed-positioning. If the layout-manager is non-NULL, then the layout
manager is passed all children without a fixed position set on them.

ClutterActor properties and methods
===

* "x", "y", and "position-set."

set_position() sets x and y, and sets position-set=TRUE. position-set
is a property in its own right that can also be toggled off, however.
The effect of position-set is to control whether fixed positioning is
used, if there is a layout manager. If there is no layout manager,
actors without position-set are positioned at 0,0.

Equivalent to gtk_fixed_move(). NOT equivalent to GtkWidget::allocation.x,y

* "width", "height", "width-set", "height-set"

set_size() sets width and height, and implicitly toggles on width-set
and height-set. If these are set, they are size request overrides.
They force both minimum and natural size request to the given width or
height. If these properties are not set, then the normal size request
of an actor is used; for example a texture might default to the size
of its pixbuf. A Rectangle actor would probably default to 1x1, you
would always need to set width and height on a Rectangle when using
fixed positioning. (When using a layout manager, you might allow the
Rectangle to have a 1x1 min size but expand to fill an area.)

"width" and "height" are equivalent to gtk_widget_set_size_request(),
which overrides any size request provided by the
GtkWidget::size_request virtual method implementation.

* virtual get_width_request(int *min_width_p, int *natural_width_p);
* virtual get_height_request(int for_width, int *min_height_p, int
*natural_height_p);

These methods are implemented by an actor to provide the preferred
size of the actor. Two notable simplifications: there is
height-for-width but not width-for-height; there is no max size.

If "width" or "height" are set, remember they override the results of
these methods.

If "width" or "height" are not set, these methods would return
something sensible depending on the actor. A label's width for example
is the width of the text in it, a texture's width is probably the
width of the pixbuf, etc.

For a Group containing only fixed-positioned children, the group
assumes each child will get its fixed position and be given its
natural size, and returns the union of those child boxes as the
request.

If a Group has a layout manager and non-fixed children, then the
layout manager determines the union of the requests of children with
layout.

These methods are the equivalent of the GtkWidget::size_request method.

* "allocation" struct ClutterAllocation { x, y, width, height }

The allocation is determined by the layout algorithm, based on the
size requests. For fixed-position children it will always just be "x"
and "y" plus the child's requested natural width and height.

If a layout manager controls a child, however, the allocation may and
often will differ from the provided fixed position.

If needs-relayout=TRUE, the allocation is meaningless junk and should
never be used. In practice, this means the allocation should rarely be
looked at except in paint().

This is equivalent to GtkWidget::allocation.

* "xscale", "yscale" and a translate transform of some kind (is that
already the anchor_x stuff?)

The transform is used for rendering, but is not visible to the layout
system. No GTK equivalent.
What I was calling "transient allocation"

* queue_relayout()

Sets the needs-relayout flag, and notifies parent group; parent group
also sets needs-relayout; when it gets up to the Stage, the stage
ensures a paint idle is queued. When the paint idle runs, it will
encounter the invariant that it can't paint without layout, so will do
the layout first, then paint.

* request cache
  struct ClutterSizeRequestCache { min_width, min_height,
natural_width, natural_height }

In ClutterGroup, it's probably a worthwhile optimization to cache the
size request. Then, if needs-relayout is not set on the group (and
thus is not set on any children), if the size request is asked for,
the group just returns the cache rather than recursing children and
running the layout manager.

Equivalent to GtkWidget::requisition (which is just a cache in
general, a couple exceptions).

Could also cache the request in non-group actors, but I doubt it's worth it.

ClutterBehaviour
===

It may be useful at different times for behaviors to affect
"x"/"y"/"width"/"height" or the transform. Behaviors should never
affect "allocation"

For the move behavior, suggest it has a flag for whether to change
"x"/"y" or the transform.

ClutterStage
===

When the stage is a toplevel window, the X size hints min size should
be the min size request of the stage. The default size
(gtk_window_set_default_size()) should be the natural size request of
the stage.
If the stage is set user_resizable(), there is no max size. If not,
the X size hints max size should be set equal to the min size request,
preventing any resize.

The effect of all this is that if "width" or "height" gets set, those
are the min size (and also the max size, if the window is not user
resizable). If "width" and "height" are not explicitly set on the
stage, the stage is sized according to what's on the stage.

ClutterRectangle
===

* In paint(), the rectangle simply fills the allocation
* The virtual size request methods return 1x1 as min and natural size
* If "width" or "height" is set, that overrides the virtual size
request methods with another size

If rectangle is used with fixed positioning, apps really must set
"width" and "height" (as they do already)

ClutterTexture
===

* In paint(), the allocation is used and texture is scaled or tiled to fit in it
* The virtual size request methods return something based on
gdk_pixbuf_get_width()/get_height()
* If "width" or "height" is set, that overrides the virtual size request methods
* sync-size is not needed; sync-size=TRUE is accomplished by not
setting "width" or "height"

Overview of how this looks
===

For an app developer using fixed positioning, I think the above setup
looks virtually the same as current Clutter. If you set size or
position, the actor instantly becomes fixed-positioned. If you don't
set a layout manager, all actors remain fixed-positioned.

This is very "do what I mean" - if you don't set sizes or positions
things Just Work, if you do they also Just Work.

The internals of Clutter could change quite a bit, though. All uses of
query_coords(), get_size(), get_position(), etc. will have to be gone
through, to determine what was intended - request, allocation, or
transformed allocation. There are in effect at least three sizes,
internally.

When apps are calling get_size() or get_position() today, they
probably usually intend to get "what the fixed layout manager would
use" - the natural size request, "x" or "y" if set, "0,0" if those are
not set.
However, calls to get_size() or get_position() in paint() methods
probably need to change, apps should instead get the allocation inside
paint(). Fortunately getting the request will still work inside
paint() as long as only fixed positioning is used, so apps would not
immediately break.

In Tidy, there would be a TidyBox which is pretty much just a
ClutterGroup with layout-manager set to TidyBoxLayout.

Havoc
-- 
To unsubscribe send a mail to [EMAIL PROTECTED]

Reply via email to