One of the coolest features that has been added to Quartex Pascal’s RTL in the past few months, is most likely support for Align: TAlign for TQTXWidget. This greatly simplifies form layout, and also doing layout when writing your own custom controls.
Rules and differences
HTML5 is not the same as WinAPI or GTK, and as such there are sometimes subtle and small differences in how things are done. Aligning widgets is fairly straight forward (from a user’s perspective), but behind the scenes it’s actually a bit more complex than how the VCL or LCL frameworks operates.
The challenge is not technique or anything special we do in our code, but rather how the browser calculates things – and when it does it. For example, a change in content of a widget can trigger what is known as a reflow. This is when the browser decides to completely re-calculate the layout for a branch in the DOM (document object model). The browser can even force a full reflow, meaning that it recalculates the entire layout for the whole DOM. A reflow is not a problem for QTX, but if you are doing a lot of animations, resizing and content changes – non aligned content might jitter while the browser performs its calculations.
To avoid this, TQTXWidget cache’s the bounds-rect it had before the Align property was set. This cache is used to calculate the order in which widgets occupy horizontal and vertical space – and how much space they are allowed to use in the overall layout.
For example: If you have two labels that are both aligned left, which one of them should be placed first? Obviously the one that is closest to the left-edge at the time the widget was aligned. To avoid reflows jittering widgets during a complex layout operation (e.g the user resizing the browser window excessively), even for a millisecond, the RTL cache the original bounds.
This way, regardless of what the browser might do – widget layout remains consistent.
Adjusting pre align bounds
If you try to change the width of a widget that is aligned left or right at runtime, you will notice that nothing happens. This is because altering the width property does not alter the cache’d boundsrect values. It’s the cache that has to be adjusted, because that’s what TQTXWidget uses as the basis for it’s calculations.
In other words, you have to alter the properties inside the TQTXWidget.PreAlignBounds property if you want to change size proportions or order of aligned widgets.
In the present build this can only be done from within a TQTXWidget (it can only adjust itself). However that is about to change. In the next build, TQTXBounds exposes SetLeft(), SetTop(), SetWidth, SetHeight and SetBounds() methods. This greatly simplifies altering proportions at runtime.
So the correct approach would be something like this:
Procedure TMyControl.Resize(Orientation: TQTXOrientation);
begin
if fChild.Align <> alNone then
fChild.PreAlignBounds.SetWidth( round(Height * 1.5) )
else
fChild.Width := fDefaultSize;
// Allow the RTL to do it's resize calculations
inherited Resize(Orientation);
end;