Ticket #6407: changes.txt

File changes.txt, 6.2 KB (added by yourpalal, 9 years ago)

description of patch

1Added BAbstractLayout class, which is simillar to BAbstractLayoutItem.
2It has only one member, fExplicitData, of the type BAbstractLayout::Proxy. This
3is a pointer to an object which implements most of the necessary code for
4each method BAbstractLayout provides. This way, when a BAbstractLayout has a
5view, its fExplicitData object forwards methods to its view. When
6BAbstractLayout does not have a view, its fExplicitData object actually holds
7real data. I implemented archiving for this class while I was at it.
9Added BLayout::OwnerChanged(BView* was) hook, which is called in
10BLayout::SetOwner(). I used this hook in BAbstractLayout, to change the proxy
11type of its fExplicitData member.
13Added BLayoutItem::AttachedToLayout()
14BLayoutItem::DetachedFromLayout(BLayout* was) hooks, which are called in
15BLayoutItem::SetLayout(). I used these hooks in BLayout to implement view
16targeting for viewless layouts, but there are other uses I can think of.
18Added BLayoutItem::AncestorVisibilityChanged(bool shown) hook, to allow for
19hiding of views which are in a nested layout that has been SetVisible(false)'d.
20Since BLayout has to remember this anyway, I added a
21BLayout::AncestorsVisible() method which returns false if any ancestors are
22hidden. Also to propagate this, I've added a BLayout::VisibilityChanged(bool)
23method, which derived classes (or BLayout) can call.
25Added a state tracking int32 to the BLayout class (BLayout::fState), which
26tracks the following states:
27*LAYOUT_INVALID this layout has been invalidated, but has not been laid out
28*LAYOUT_CACHE_INVALID this layout has been invalidate and not re-validated
29    via ResetLayoutInvalidation()
30*LAYOUT_REQUIRED this layout may be valid, but has had its RequireLayout()
31    perhaps the layout has been moved, but not resized, or something similar.
32*LAYOUT_IN_PROGRESS : self explanatory
33*LAYOUT_ALL_CLEAR just a convenient flag == 0.
35there are also some masks that | some of those fields together for convenience.
37All in all, layouts work more or less like views in regards to layout
38invalidation. Because a layout may be viewless, it must be able to function
39independently as well. BLayout::Invalidate() also takes a bool param for
40children, like BView::Invalidate().
42This leads to the next big change which is layout invalidation. My goal here was
43that no matter how you trigger an invalidation, it should invalidate all the
44right stuff. This presented a few challenges
45* invalidating a view must invalidate its layout, and vice-versa.
46* invalidating a view that is in a nested layout must invalidate not only
47    the view's Parent()'s layout, but also those layouts in between.
48    this can be accomplished two ways:
49        *through the BLayout::InvalidateLayoutsForView(), which would be called
50            with the view's Parent()'s layout as a param.
51        *by the view's layout, which will hopefully have been added as a
52            BLayoutItem (instead of using a BViewLayoutItem), and will know
53            the layout that view resides in, so invalidation can proceed as
54            normal. This is the prefferred method.
55When possible, the layouts propagates the invalidation upwards, and those that
56have views invalidate their views along the way. For views w/o layouts, the
57view propagates the invalidation upwards until it either gets to the top, or
58gets to a view with a layout, at which time it again becomes the layout's
59responsibility. Also, with all this invalidating, we try to avoid Invalidating
60layouts/views that have already been, since their derived implementation may
61proceed blindly and do who knows what!
63I also added a private method to BView, _InvalidateParentLayout(), which is
64called, for instance when a view is Hidden or Shown, it is also used in
67Also new is that BLayouts hold a BLayoutContext, and can create one as well.
68BLayout's LayoutItems() method does this, much like BView's Layout() method.
70BLayout has four layouting related methods:
71    LayoutItems() : new, creates a layout context and performs a
72        layout if required.
73    Relayout(bool immediate) : new, triggers a layout if there is not
74        one coming up, or if immediate == true.
75    _LayoutWithinContext(bool force, BLayoutContext*) : new
76        Handles the calling of fOwner->_Layout() and DerivedLayoutItems(), as
77        well as calling _LayoutWithinContext() on any nested layouts that need
78        it.
79    DerivedLayoutItems() : formerly LayoutView()
81If LayoutItems() is called on a BLayout w/ a view, it will ask its view to do a
82layout, and be triggered that way, if not, it will do its own layout. We also
83layout all nested layouts (that need it) in our layout.
85BLayout::Relayout(), is actually an implementation of the new
86BLayoutItem::Relayout() virtual method, which is called in BSplitLayout,
87for instance, when you wish to have an item layout now, assuming conditions are
88right. This replaces the spot where BSplitLayout did this:
89if (becameVisible) {
90    if (BView* itemView = item->View())
91        itemView->Layout(false);
94if (becameVisible)
95    item->Relayout(true);
96which allows compatibility with nested (viewless) layouts.
98One of my goals was that adding a BLayout w/ a view to another layout will
99result in pretty much equivalent beahaviour to what we currently expect from
100BViewLayoutItem. To this end, when adding a BView to a layout, we check if the
101view has a layout, and if so add that as an item, if not, we create a
102BViewLayoutItem for the view. This helps us avoid calling
103InvalidateLayoutsForView(), and save us a memory allocation too.
105Another method I've added to the BLayout class is LayoutArea(), which returns
106a rect which represents the area this layout has been given for its items.
107Without a view, LayoutArea() == Frame(), with a view,
108LayoutArea() == Frame().OffsetToSelf(B_ORIGIN).
110BLayouts now have fOwner and fTarget BView* fields, if the layout has a view,
111then fOwner == fTarget. For any nested layouts,
112fTarget == Layout()->TargetView(). For now these are in two separate fields,
113but they could be combined into one by adding a field to fState, I suppose.
115I have also added a BView::Private class for access to BView::fShowLevel in
116BViewLayoutItem and BAbstractLayout.
118I also added a BView::_LayoutLeft method, since a layout may be deleted either
119by its parent layout, or its 'owner' view, we need to avoid double frees.
121These are all the big changes, and I've also updated the existing layout
122classes to reflect them.