Table of Contents
Layout Resources
External Links
This is a list of external information sources for implementing layout managers:
- Java
- Qt
- XUL
- wxWidgets (formerly wxWindows)
- Web
- HTML/CSS
- WebCore Rendering III - Layout Basics (Not directly related to widget layouting but interesting because of its concept of dirty bits)
Implementation Details
Quote from the Java Layout Howto:
When you invoke revalidate on a component, a request is passed up the containment hierarchy until it encounters a container, such as a scroll pane or top-level container, that should not be affected by the component’s resizing. (This is determined by calling the container’s isValidateRoot method.) The container is then laid out, which has the effect of adjusting the revalidated component’s size and the size of all affected components.
Widget classes of other frameworks:
Interesting Concepts
XUL
Flex
Type: string (representing an integer)
Indicates the flexibility of the element, which indicates how an element’s container distributes remaining empty space among its children. Flexible elements grow and shrink to fit their given space. Elements with larger flex values will be made larger than elements with lower flex values, at the ratio determined by the two elements. The actual value is not relevant unless there are other flexible elements within the same container. Once the default sizes of elements in a box are calculated, the remaining space in the box is divided among the flexible elements, according to their flex ratios. Specifying a flex value of 0 has the same effect as leaving the flex attribute out entirely.
The flex attribute isn’t used to specify an actual size. Instead, it specifies how empty space it divided among the children of a container box.
It seems to me that flex is an additional attribute to the height/width attribute.
Width
Type: string (representing an integer)
The preferred width of the element. The value should not include a unit as all values are in pixels. The actual displayed width may be different if the element or its contents have a minimum or maximum width, or the size is adjusted by the flexibility or alignment of its parent. The CSS width property may also be used.
Question: Does XUL support percent dimensions?
Qt
- setGeometry() applies the layout to the widget. It contains left, top, width and height as styles. This is the Qt variant and I would love to have the same in qooxdoo.
- Calling QLayoutItem::sizeHint(), etc. may be expensive, so you should store the value in a local variable if you need it again later in the same function.
- You should not call QLayoutItem::setGeometry() twice on the same item in the same function. That can be very expensive if the item has several child widgets, because it must do a complete layout every time. Instead, calculate the geometry and then set it. (This doesn’t only apply to layouts, you should do the same if you implement your own resizeEvent().)
- Qt comes with a spacing property in the generic layout class, but return
-1for it in grid layouts because these layouts offer different vertical and horizontal spacings. Really a bad concept in my opinion. Another reason to move all layout stuff for children and parents to a generic layout data field instead of separate properties.
- Qt use the wording content margins for paddings. The CSS like wording “padding” is much more user friendly in my opinion.
- HeightForWidth comes with an additional flag on each item to allow pre layout information if the widget is capable of calculating this. (Some widgets have no need for this at all, too).
- Qt have different addWidget methods which differ from layout to layout. This is interesting because it allows to handle children managment differently from layout to layout. For example in some layouts like GridLayouts, FormLayouts, etc. the order of the children (in an internal array - if so) is completely unimportant. Instead children are positioned using cell/row positions (GridLayout) or absolute/relative coordinates (FormLayout). This is also true for the simplest of all layouts: the CanvasLayout. In such layouts methods like removeAt, insertAt etc. are also useless. PUUUHHH: A lot to discuss here like it seems as this differs from the current idea of children managment. See also: http://doc.trolltech.com/4.3/qwidgetitem.html
Size Hint
“By default, composite widgets which do not provide a size hint will be sized according to the space requirements of their child widgets. The size policy lets you supply good default behavior for the layout management system, so that other widgets can contain and manage yours easily. The default size policy indicates that the size hint represents the preferred size of the widget, and this is often good enough for many widgets.”
Size Policy
“The default policy is Preferred/Preferred, which means that the widget can be freely resized, but prefers to be the size sizeHint() returns. Button-like widgets set the size policy to specify that they may stretch horizontally, but are fixed vertically. The same applies to lineedit controls (such as QLineEdit, QSpinBox or an editable QComboBox) and other horizontally orientated widgets (such as QProgressBar). QToolButton’s are normally square, so they allow growth in both directions. Widgets that support different directions (such as QSlider, QScrollBar or QHeader) specify stretching in the respective direction only. Widgets that can provide scroll bars (usually subclasses of QScrollArea) tend to specify that they can use additional space, and that they can make do with less than sizeHint().”
Focus Policy
(Not really layout relevant, but interesting concept for 0.8 anyway)
“This property holds the way the widget accepts keyboard focus. The policy is Qt::TabFocus if the widget accepts keyboard focus by tabbing, Qt::ClickFocus if the widget accepts focus by clicking, Qt::StrongFocus if it accepts both, and Qt::NoFocus (the default) if it does not accept focus at all.”
Min/Max Support
- maximumHeight
- maximumWidth
- minimumHeight
- minimumWidth
- minimumSizeHint
“This property holds the recommended minimum size for the widget.
If the value of this property is an invalid size, no minimum size is recommended.
The default implementation of minimumSizeHint() returns an invalid size if there is no layout for this widget, and returns the layout’s minimum size otherwise. Most built-in widgets reimplement minimumSizeHint().
QLayout will never resize a widget to a size smaller than the minimum size hint unless minimumSize() is set or the size policy is set to QSizePolicy::Ignore. If minimumSize() is set, the minimum size hint will be ignored.”
Layouts
- QHBoxLayout ⇒ HorizontalBoxLayout
- QVBoxLayout ⇒ VerticalBoxLayout
- QGridLayout ⇒ GridLayout
- QBorderLayout ⇒ DockLayout (as custom layout mgr example)
- QFlowLayout ⇒ FlowLayout (as custom layout mgr example)
http://doc.trolltech.com/4.3/layouts-borderlayout.html http://doc.trolltech.com/4.3/layouts-flowlayout.html
In Qt widgets are added to the layout instance. The layout is later applied to any widget using setLayout. I don’t like this much. I prefer the way qooxdoo does it currently: Widgets contains children directly. The layout to use is a property of each Widget (at least for the ones which have children). The good thing however is that they configure the children at the insertion to the layout. Each layout comes with a special addWidget method which has additional parameters. However the relevant information should be stored in the widget, not in the layout... or do they really store this in the layout?
Custom widgets
You can change the behavior of the widget using any or all of the following mechanisms:
- Reimplement QWidget::sizeHint() to return the preferred size of the widget.
- Reimplement QWidget::minimumSizeHint() to return the smallest size the widget can have.
- Call QWidget::setSizePolicy() to specify the space requirements of the widget.
X-Y Dependencies
If the preferred height of your widget depends on its actual width (e.g., a label with automatic word-breaking), set the height-for-width flag in the widget’s size policy and reimplement QWidget::heightForWidth().
Even if you implement QWidget::heightForWidth(), it is still a good idea to provide a reasonable sizeHint().
Interesting read: http://doc.trolltech.com/qq/qq04-height-for-width.html
“The base QWidget implementation of heightForWidth() returns 0 to signify that a widget’s height and width are independent. This is appropriate for most QWidget subclasses. Classes like QLabel, QMenuBar, and QTextEdit reimplement heightForWidth().
Implementing a heightForWidth() function is not difficult. In the case of the Aquarium class, we reimplemented heightForWidth() as a monotonically decreasing function. But Qt’s layout system makes no such assumption, so we can reimplement heightForWidth() as we like – for example, to ensure that a widget maintains a constant aspect ratio.”
