Previously, we were repainting each widget as repainting was needed.
However, this created issues with clipping, since the widgets were not
aware of their parent's clips. It also created many other issues, including
performance problems and the lack of support for overlapping widgets.
This commit improves repainting behavior by adopting a painting model similar
to the one found in SerenityOS's LibGUI. It uses "damage rectangles", which
are translated to the widget coordinate space as needed, since the position of
widgets is relative to their parent's origin.
When a widget needs to be repainted, a repaint event with the damage
rectangle equal to the widget's current geometry translated to the window's coordinate
space is dispatched to the main widget. It will recursively follow the widget tree.
Widgets fully contain their children, thus widgets not contained by the damage
rectangle will reject the event, ensuring repainting is only done where needed.
Relayouting is done on a per-subtree basis only.
This commit should pave the way for things like scrolling
and overlapping widgets.
This commit prevents the dispatch of activation/focus events if the
status did not change. This eliminates useless repaints when mousing
around inside a button.
widgets
This commit introduces "batches", which makes Raven hold off on doing
full reflows until the batch is ended. When a window is created, a batch
is automatically started to ensure that no useless reflows are done
during initialization. The batch is automatically ended in window.run().
Users of the library can create and end batches as well. This commit
also factors out automatic scaling based on text size into set_text for
buttons (should be done for labels as well).