Skip to content

Commit

Permalink
Fix unarchiving of BScrollView with layout
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
pulkomandy committed Oct 12, 2014
1 parent 3b61a4b commit bdb4ae3
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 2 deletions.
1 change: 1 addition & 0 deletions headers/os/interface/ScrollView.h
Expand Up @@ -34,6 +34,7 @@ class BScrollView : public BView {

static BArchivable* Instantiate(BMessage* archive);
virtual status_t Archive(BMessage* archive, bool deep = true) const;
virtual status_t AllUnarchived(const BMessage* archive);

// Hook methods
virtual void AllAttached();
Expand Down
55 changes: 53 additions & 2 deletions src/kits/interface/ScrollView.cpp
Expand Up @@ -70,6 +70,9 @@ BScrollView::BScrollView(BMessage* archive)
fTarget = NULL;

// 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;
fVerticalScrollBar = NULL;
Expand All @@ -88,6 +91,7 @@ BScrollView::BScrollView(BMessage* archive)

fPreviousWidth = uint16(Bounds().Width());
fPreviousHeight = uint16(Bounds().Height());

}


Expand Down Expand Up @@ -127,11 +131,58 @@ BScrollView::Archive(BMessage* archive, bool deep) const
// The highlighted state is not archived, but since it is
// usually (or should be) used to indicate focus, this
// is probably the right thing to do.

return status;
}


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


Expand Down Expand Up @@ -682,7 +733,7 @@ BScrollView::_Init(bool horizontal, bool vertical)
fTarget, 0, 1000, B_VERTICAL);
AddChild(fVerticalScrollBar);
}

BRect targetFrame;
if (fTarget) {
// layout target and add it
Expand Down

0 comments on commit bdb4ae3

Please sign in to comment.