Re: New menu ideas

Hi James,

	So - firstly, this is a really bad time for me to put any review into
this sort of thing at all. I'm working really hard on making Gnome 2.0
workable, and I must confess that I am dismaid that instead of working
up the heap, helping fix problems in real applications and getting Gnome
out - people are wanting to create more changes and new APIs at the
bottom levels, although there can be no sensible scrutiny.

	It would also be nice if you could cross post any new Gtk menu /
toolbar API discussion to gcl, since I will at least notice it there.

On Mon, 2002-03-25 at 07:05, James Henstridge wrote:
> I was going to post this to the list earlier, but got a bit sidetracked. 
>  Attached is the design document for my new action based menu API.  The 
> merge support is not fully implemented (and will probably require 
> changes to other bits of the code to get right).  I am interested in 
> feedback though.

	Merging is tricky, not least because I did a lot of work in bonobo and
I'm not convinced it was worth it or that I designed it right, now there
are more use cases a re-thing is merited I think. Again, I will be
extremely unhappy to see the same or different mistakes without input,
but I can't spend the hours of thinking time that this problem deserves
yet - in a month perhaps. Please don't set anything in stone.

>   - a name (not translated)
>   - text label
>   - whether label indicates a stock id
>   - tooltip (optional)
>   - icon (optional, ignored with stock_id)
>   - toolbar label (optional, shorter than label)

	Ok - there are problems we hit with this - you say lower that only an
action & a name is allowed for a dockitem, menuitem etc. - which is
great, and the design I was aiming for on bonobo. The problem is
accelerators / mnemonics. With a menuitem you want '_Open' with the
toolbar item with the same Action you want 'Open'. Moderately easy to
solve in several ways - which is the best ? what is a good
representation for that ?

> We can have different types of actions:
>   - check actions (can be toggled between two states)
>   - radio actions (only one in a group can be in the "active" state)

	Ok - the problem with radio actions is how to group them; it's not
trivial - if I was to implement this again I would bin GtkRadioButton
for this - since it's idea of a RadioGroup is hard to sync with anyone
else's idea - and it's just not clear how to sync different sets of
different radio buttons to ensure that they get their state right.

> Each action can have one or more proxy menu item, toolbar button or
> other proxy widgets.  Proxies mirror the state of the action (text
> label, tooltip, icon, visible, sensitive, etc), and should change when
> the action's state changes.  When the proxy is activated, it should
> activate its action.
> => Actions are GObjects.
> => proxies all share the same accel path, so accels are consistent.
> => Action state is exported through properties, and should probably be
>    propagated to proxies through the "notify::xxx" signal.

	Again in libbonoboui we binned the Gtk+ accelerator stuff where
possible, mostly because we need to be able to add remote accelerated
actions, and we didn't have a GObject per action that we could have a
signal on that we could add accelerators with.

> Action Groups

	If this is essentially just an ActionFactory - it sounds fine; do you
anticipate it doing much more than manufacturing Actions by name /
listing actions ?

>    It might be easier to get rid of the interface if bonobo could just
>    subclass the local action group implementation -- if no action is
>    found in the hash table, check for the remote action, and create a
>    proxy action object to return (cache in the hash table).

	? it's not clear to me quite what you're suggesting here.

> User Interface Definitions
> --------------------------
> See the documentation in libbonoboui for details on the structure.

	One thing that would have been fairly useful in bonobo I think is the
concept of a symbolic link - which sounds pretty crack smoking, but
could help substantially with merging - eliminating some of the
complexity arising from placeholders.

> Interface definitions are parsed with a GMarkup based parser.  A tree
> is built up from the elements in the UI tree.  The nodes in the tree
> hold the name of the node, an (action, UI file) pair, a pointer to the
> widget representing this node and a tag identifying which UI file it
> came from.
> When parsing subsequent UI files, the following rules are used for
> merging:
>  1. if a particular node already exists, add another (action, UI file)
>     pair to the node.
>  2. if it doesn't exist, create a new node, and append it to the list
>     of children for the parent node.
> More complex ordering of merged UI elements should be handled through
> the use of <placeholder> elements (placeholders are essentially like
> <submenu>, except that their children get pasted into the parent menu
> directly).

	Sigh; I want to re-visit this decision and consider whether
placeholders are really that good, whether some sort of virtual link
concept might be better, and review how they are used around the place.

	Also for compound documents, we should go for a really different /
simpler approach IMHO, which is mostly a subset of the above.

> The actual widgets are not constructed immediately.  Instead the new
> nodes are marked "dirty", and an idle function is queued to update the
> UI.  This should speed things up a bit.
> To remove a UI file, we simply walk the tree and remove the (action,
> UI file) pairs from all nodes that match.  If a node is not referenced
> anywhere else, it is marked dirty (will get removed in the idle).  The
> same if the node's controlling action would change due to the removal.

	There is a fair bit of logic to do this in bonobo - but also to reveal
things hidden by being merged over etc. again it's not clear to me what
is best to do with those concepts.

> Registering and Unregistering Action Groups
> -------------------------------------------
> A list of action groups are used as the source for actions referenced
> in the UI definitions.  When adding or removing action groups, diffent
> actions may be exposed (adding a group may shadow existing actions of
> the same name.  removing a group may expose different actions).
> Therefore, all nodes in the tree are marked dirty when this sort of
> change occurs, and the idle is scheduled.

	Curious. A relatively common thing to do is changing labels on toolbar
items. It'd be interesting to see how this worked with this scheme.

> The idle handler should be fairly high priority (it is merely to speed
> up multiple changes performed in a row).  It walks the tree doing the
> following:
>  1. is this node dirty, and do any UI defs reference it?  If so:
>       a. if there is no widget constructed ask the action to create a
>          proxy, and store it on the node.  This widget should also be
>          added to the parent node's widget (for placeholders,
>          recursively ascend the tree finding a non placeholder
>          parent).
>       b. if there is a widget, but it is associated with a different
>          action than the correct one, destroy the widget and create a
>          new one (or if possible, disconnect the proxy from the old
>          action and reconnect it to the new action).
>  2. if there are any child nodes, recurse down to them.
>  3. if this node is not referenced by any UI defs, destroy its widget
>     (if any exists), and remove the node.

	NB. the process of synchronizing an arbitrary container with the widget
list is really extremely and un-necessarily complicated. My feeling is
that it would be considerably better to have a custom container
associated with the nodes a 'node view' container; and that this would
simply be queue_resized' [ or whatever ] when a change happens - thus
avoiding the 'dirty concept' - and hopefully also avoiding constructing
lots of unneccessary / invisible widgets at any given time. Yes this
would probably involve re-writing GtkMenu / GtkMenuItem - and yes it's
worth doing.

	Anyway - just some thoughts; I'd like to sit down and discuss it at
GUADEC with any interested parties - or subsequently. Preferably not



 mmeeks gnu org  <><, Pseudo Engineer, itinerant idiot

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