Thoughts on applet layouts

Alex Merry huntedhacker at tiscali.co.uk
Thu Mar 13 13:58:10 CET 2008


I was bored on the bus home last night, and got thinking about applet layouts.

I think the current system is overly complicated for applet developers.  Most 
of the time, I have no idea what I should be implementing or how.  I think the 
issue here is that applets are treated like widgets, when the layout requireme
nts are much simpler.

Laying out applets comes down to three cases at the moment (ignoring media
center form factors) - in a row, in a column or free.

Here's an idea I came up with for an applet layout system.  This comes down
to a few convenience methods in Applet, a virtual method layout() in
Containment (that can be overridden by custom containments) and
applets just have to respond to changed heights or widths in
updateConstraints().


===========================

when an applet is added to a constrained containment
(FormFactor == Horizontal || FormFactor == Vertical),
it calls updateConstraints on the new applet, informing
it of the fixed dimension (either width or height) and
the form factor, and then calls layout(applets).  In any
case (even if the containment isn't constrained),
updateConstraints is called to notify the applet of the
form factor.

when the containment is resized, it calls updateContraints
on all the applets informing them of the new fixed width/height
and then calls layout(applets).

Applets should, when informed of a new fixed dimension (in
updateConstraints), set their ideal and minimum sizes in the
free dimension and whether they can expand indefinitely in
that direction.

eg:

DigitalClock::updateContraints(constraint)
{
    constraint == fixed dimension:
        FormFactor == Horizontal:
            // fixed dimension is height
            setIdealWidth(text->widthForHeight(height))
            setMinimumWidth(text->widthForHeight(height))
        FormFactor == Vertical:
            // fixed dimension is width
            setIdealHeight(text->heightForWidth(width))
            setMinimumHeight(text->heightForWidth(width))
}

TaskBar::updateConstraints(constraint)
{
    constraint == fixed dimension:
        FormFactor == Horizontal:
            // fixed dimension is height
            // this is simplified: doesn't account for two rows of tasks
            setIdealWidth(no. apps * height * 4) // 4:1 ratio, say
            setMinimumWidth(no. apps * height) // no smaller than square
            setExpands(true)
        FormFactor == Vertical:
            // fixed dimension is width
            // this is simplified: doesn't account for two rows of tasks
            setIdealHeight(no. apps * (width / 4)) // 4:1 ratio, say
            setMinimumHeight(no. apps * width) // no smaller than square
            setExpands(true)
}

virtual Containment::layout(QList<Applet*>);

Containment::layout(QList<Applet*> applets)
{
    if (FormFactor == Planar) do nothing (applet handles take care of everythi
ng)
    if (FormFactor == Horizontal) {
        1. get the ideal width for each applet
        2. if space left over, and the containment has fixed width, distribute
d
           the extra width between applets that can expand
           amount allocated should possibly be proportional to the ideal width
        3. (a) if not enough space, get the minimum width for each applet
           (b) if there would not enough space for all applets at their
               minimum width, discard applets from the end until there is,
               or move to two rows (?)
               this might happen if screen resolution changes, for example
           (c) starting at their ideal width, take space enough space from
               each applet so that the total is the width of the containment,
               making sure no applet ends up smaller than its minimum width.
               space taken should possibly be proportional to
                   (ideal width) / (minimum width)
        4. set sizes and place on containment in list order
    }
    if (FormFactor == Vertical) {
        similar to above, but heights instead of widths
}

applets can notify that their minimum/ideal sizes or expanding property has
changed (with a signal, say), and cause the containment to layout again.

custom containments can override layout(), for example desktops can scan the
list for icons, lay those out, then pass the remaining applets to the default
implementation (which in this case does nothing, since it's a Planar layout).

=====================

Given applets have to set 2-3 values in one method, this seems to be a much
simpler implementation to me.

Comments?  Feel free to tear to shreds and tell me it's nonsense (as long as
you can tell me why...)

Alex



-- 
KDE: http://www.kde.org
Ubuntu/Kubuntu: http://www.ubuntu.org http://www.kubuntu.org

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: This is a digitally signed message part.
Url : http://mail.kde.org/pipermail/panel-devel/attachments/20080313/57ec3302/attachment.pgp 


More information about the Panel-devel mailing list