Fix unarchiving of BScrollView with layout
* We archive views using "managed" archives, and the children are not attached in the BView(BMessage*) constructor, but later. So it's not possible to find the target and scrollbars in the constructor of BScrollView. * Make BScrollView override AllUnarchived and find the target and scrollbars again there. The code is slightly different as there is no guarantee that the first child will be the target in that case. The existing code in the constructor is preserved for non-managed archives.
This commit is contained in:
@@ -34,6 +34,7 @@ public:
|
|||||||
|
|
||||||
static BArchivable* Instantiate(BMessage* archive);
|
static BArchivable* Instantiate(BMessage* archive);
|
||||||
virtual status_t Archive(BMessage* archive, bool deep = true) const;
|
virtual status_t Archive(BMessage* archive, bool deep = true) const;
|
||||||
|
virtual status_t AllUnarchived(const BMessage* archive);
|
||||||
|
|
||||||
// Hook methods
|
// Hook methods
|
||||||
virtual void AllAttached();
|
virtual void AllAttached();
|
||||||
|
|||||||
@@ -70,6 +70,9 @@ BScrollView::BScrollView(BMessage* archive)
|
|||||||
fTarget = NULL;
|
fTarget = NULL;
|
||||||
|
|
||||||
// search for our scroll bars
|
// search for our scroll bars
|
||||||
|
// This will not work for managed archives (when the layout kit is used).
|
||||||
|
// In that case the children are attached later, and we perform the search
|
||||||
|
// again in the AllUnarchived method.
|
||||||
|
|
||||||
fHorizontalScrollBar = NULL;
|
fHorizontalScrollBar = NULL;
|
||||||
fVerticalScrollBar = NULL;
|
fVerticalScrollBar = NULL;
|
||||||
@@ -88,6 +91,7 @@ BScrollView::BScrollView(BMessage* archive)
|
|||||||
|
|
||||||
fPreviousWidth = uint16(Bounds().Width());
|
fPreviousWidth = uint16(Bounds().Width());
|
||||||
fPreviousHeight = uint16(Bounds().Height());
|
fPreviousHeight = uint16(Bounds().Height());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -132,6 +136,53 @@ BScrollView::Archive(BMessage* archive, bool deep) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BScrollView::AllUnarchived(const BMessage* archive)
|
||||||
|
{
|
||||||
|
status_t result = BView::AllUnarchived(archive);
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
// search for our scroll bars and target
|
||||||
|
int32 firstBar = 0;
|
||||||
|
BView* view;
|
||||||
|
while ((view = ChildAt(firstBar++)) != NULL) {
|
||||||
|
printf("scaning %s\n", view->Name());
|
||||||
|
BScrollBar *bar = dynamic_cast<BScrollBar *>(view);
|
||||||
|
// We assume that the first non-scrollbar child view is the target.
|
||||||
|
// So the target view can't be a BScrollBar, but who would do that?
|
||||||
|
if (bar == NULL) {
|
||||||
|
// in a shallow archive, we may not have a target anymore. We must
|
||||||
|
// be prepared for this case
|
||||||
|
if (fTarget == NULL && !archive->FindBool("_no_target_"))
|
||||||
|
fTarget = view;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bar->Orientation() == B_HORIZONTAL)
|
||||||
|
fHorizontalScrollBar = bar;
|
||||||
|
else if (bar->Orientation() == B_VERTICAL)
|
||||||
|
fVerticalScrollBar = bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("UA %p %p %p\n", fTarget, fHorizontalScrollBar, fVerticalScrollBar);
|
||||||
|
|
||||||
|
// Now connect the bars to the target, and make the target aware of them
|
||||||
|
if (fHorizontalScrollBar)
|
||||||
|
fHorizontalScrollBar->SetTarget(fTarget);
|
||||||
|
if (fVerticalScrollBar)
|
||||||
|
fVerticalScrollBar->SetTarget(fTarget);
|
||||||
|
|
||||||
|
if (fTarget)
|
||||||
|
fTarget->TargetedByScrollView(this);
|
||||||
|
|
||||||
|
fPreviousWidth = uint16(Bounds().Width());
|
||||||
|
fPreviousHeight = uint16(Bounds().Height());
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - Hook methods
|
// #pragma mark - Hook methods
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user