Each widget has an allocation at a given time, this includes
The canvas is the whole area available for the widgets, in most cases, only a part is seen in a viewport. The allocation of the toplevel widget is exactly the allocation of the canvas, i.e.
The size of a widget is not simply defined by the width and the height, instead, widgets may have a base line, and so are vertically divided into an ascender (which height is called ascent), and a descender (which height is called descent). The total height is so the sum of ascent and descent.
Sizes of zero are allowed. The upper limit for the size of a widget is defined by the limits of the C++ type int.
Allocation of a Widget
In the example in the image, the widget has the following allocation:
The current allocation of a widget is hold in dw::core::Widget::allocation. It can be set from outside by calling dw::core::Widget::sizeAllocate. This is a concrete method, which will call dw::core::Widget::sizeAllocateImpl (see code of dw::core::Widget::sizeAllocate for details).
For trivial widgets (like dw::Bullet), dw::core::Widget::sizeAllocateImpl does not need to be implemented. For more complex widgets, the implementation should call dw::core::Widget::sizeAllocate (not dw::core::Widget::sizeAllocateImpl) on all child widgets, with appropriate child allocations. dw::core::Widget::allocation should not be changed here, this is already done in dw::core::Widget::sizeAllocate.
A widget may prefer a given size for the allocation. This size, the requisition, should be returned by the method dw::core::Widget::sizeRequestImpl. In the simplest case, this is independent of the context, e.g. for an image. dw::Image::sizeRequestImpl returns the following size:
This is a bit simplified, dw::Image::sizeRequestImpl should also deal with margins, borders and paddings, see dw::core::style.
From the outside, dw::Image::sizeRequest should be called, which does a bit of optimization. Notice that in dw::Image::sizeRequestImpl, no optimization like lazy evaluation is necessary, this is already done in dw::Image::sizeRequest.
A widget, which has children, will likely call dw::Image::sizeRequest on its children, to calculate the total requisition.
The caller (this is either the dw::core::Layout, or the parent widget), may, but also may not consider the requisition. Instead, a widget must deal with any allocation. (For example, dw::Image scales the image buffer when allocated at another size.)
Some widgets do not have an inherent size, but depend on the context, e.g. the viewport size. These widgets should adhere to size hints, i.e. implement the methods dw::core::Widget::setWidth, dw::core::Widget::setAscent and dw::core::Widget::setDescent. The values passed to the callees are
Generally, the values should define the available space for the widget.
A widget, which depends on size hints, should call dw::core::Widget::queueResize, when apropriate.
dw::Table uses width extremes for fast calculation of column widths. The structure dw::core::Extremes represents the minimal and maximal width of a widget, as defined by:
Especially the latter is vaguely defined, here are some examples:
Handling width extremes is similar to handling requisitions, a widget must implement dw::core::Widget::getExtremesImpl, but a caller will use dw::core::Widget::getExtremes.
When the widget changes its size (requisition), it should call dw::core::Widget::queueResize. The next call of dw::core::Widget::sizeRequestImpl should then return the new size. See dw::Image::setBuffer as an example.
Interna are described in the code of dw::core::Widget::queueResize.
A widget may calculate its size based on size calculations already done before. In this case, a widget must exactly know the reasons, why a call of dw::core::Widget::sizeRequestImpl is necessary. To make use of this, a widget must implement the following:
This way, a widget can exactly keep track on size changes, and so implement resizing in a faster way. A good example on how to use this is dw::Textblock.
1.5.9