diff --git a/headers/os/interface/View.h b/headers/os/interface/View.h index c6d0cc8a13..fd4e4e5294 100644 --- a/headers/os/interface/View.h +++ b/headers/os/interface/View.h @@ -143,6 +143,8 @@ public: static BArchivable* Instantiate(BMessage* archive); virtual status_t Archive(BMessage* archive, bool deep = true) const; + virtual status_t AllUnarchived(const BMessage* archive); + virtual status_t AllArchived(BMessage* archive) const; virtual void AttachedToWindow(); virtual void AllAttached(); diff --git a/src/kits/interface/View.cpp b/src/kits/interface/View.cpp index 7900625b4c..fccb7728b5 100644 --- a/src/kits/interface/View.cpp +++ b/src/kits/interface/View.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -315,6 +316,15 @@ ViewState::UpdateFrom(BPrivate::PortLink &link) // #pragma mark - +// archiving constants +namespace { + const char* kMinSizeField = "ViewLayoutData:minsize"; + const char* kMaxSizeField = "ViewLayoutData:maxsize"; + const char* kPreferredSizeField = "ViewLayoutData:prefsize"; + const char* kAlignmentField = "ViewLayoutData:alignment"; +} + + struct BView::LayoutData { LayoutData() : @@ -332,6 +342,32 @@ struct BView::LayoutData { { } + status_t + AddDataToArchive(BMessage* archive) + { + status_t err = archive->AddSize(kMinSizeField, fMinSize); + + if (err == B_OK) + err = archive->AddSize(kMaxSizeField, fMaxSize); + + if (err == B_OK) + err = archive->AddSize(kPreferredSizeField, fPreferredSize); + + if (err == B_OK) + err = archive->AddAlignment(kAlignmentField, fAlignment); + + return err; + } + + void + PopulateFromArchive(BMessage* archive) + { + archive->FindSize(kMinSizeField, &fMinSize); + archive->FindSize(kMaxSizeField, &fMaxSize); + archive->FindSize(kPreferredSizeField, &fPreferredSize); + archive->FindAlignment(kAlignmentField, &fAlignment); + } + BSize fMinSize; BSize fMaxSize; BSize fPreferredSize; @@ -366,8 +402,10 @@ BView::BView(BRect frame, const char* name, uint32 resizingMode, uint32 flags) BView::BView(BMessage* archive) : - BHandler(archive) + BHandler(BUnarchiver::PrepareArchive(archive)) { + BUnarchiver unarchiver(archive); + BRect frame; archive->FindRect("_frame", &frame); @@ -450,11 +488,25 @@ BView::BView(BMessage* archive) if (archive->FindInt32("_dmod", (int32*)&drawingMode) == B_OK) SetDrawingMode((drawing_mode)drawingMode); - BMessage msg; - for (int32 i = 0; archive->FindMessage("_views", i, &msg) == B_OK; i++) { - BArchivable* object = instantiate_object(&msg); - if (BView* child = dynamic_cast(object)) - AddChild(child); + fLayoutData->PopulateFromArchive(archive); + + if (archive->FindInt16("_show", &fShowLevel) != B_OK) + fShowLevel = 0; + + if (BUnarchiver::IsArchiveManaged(archive)) { + int32 i = 0; + while (unarchiver.EnsureUnarchived("_views", i++) == B_OK) + ; + unarchiver.EnsureUnarchived("_layout"); + + } else { + BMessage msg; + for (int32 i = 0; archive->FindMessage("_views", i, &msg) == B_OK; + i++) { + BArchivable* object = instantiate_object(&msg); + if (BView* child = dynamic_cast(object)) + AddChild(child); + } } } @@ -472,7 +524,9 @@ BView::Instantiate(BMessage* data) status_t BView::Archive(BMessage* data, bool deep) const { + BArchiver archiver(data); status_t ret = BHandler::Archive(data, deep); + if (ret != B_OK) return ret; @@ -552,20 +606,59 @@ BView::Archive(BMessage* data, bool deep) const if (ret == B_OK && (fState->archiving_flags & B_VIEW_DRAWING_MODE_BIT) != 0) ret = data->AddInt32("_dmod", DrawingMode()); - if (deep) { - int32 i = 0; - BView* child; + if (ret == B_OK) + ret = fLayoutData->AddDataToArchive(data); - while (ret == B_OK && (child = ChildAt(i++)) != NULL) { - BMessage childArchive; + if (ret == B_OK) + ret = data->AddInt16("_show", fShowLevel); - ret = child->Archive(&childArchive, deep); - if (ret == B_OK) - ret = data->AddMessage("_views", &childArchive); - } + if (deep && ret == B_OK) { + for (BView* child = fFirstChild; child != NULL && ret == B_OK; + child = child->fNextSibling) + ret = archiver.AddArchivable("_views", child, deep); + + if (ret == B_OK) + ret = archiver.AddArchivable("_layout", GetLayout(), deep); } - return ret; + return archiver.Finish(ret); +} + + +status_t +BView::AllUnarchived(const BMessage* from) +{ + BUnarchiver unarchiver(from); + status_t err = B_OK; + + int32 count; + from->GetInfo("_views", NULL, &count); + + for (int32 i = 0; err == B_OK && i < count; i++) { + BView* child; + err = unarchiver.FindObject("_views", i, child); + if (err == B_OK) + err = _AddChild(child, NULL) ? B_OK : B_ERROR; + } + + if (err == B_OK) { + BLayout*& layout = fLayoutData->fLayout; + err = unarchiver.FindObject("_layout", layout); + if (err == B_OK && layout) { + fFlags |= B_SUPPORTS_LAYOUT; + fLayoutData->fLayout->BLayout::SetView(this); + } + + } + + return err; +} + + +status_t +BView::AllArchived(BMessage* into) const +{ + return BHandler::AllArchived(into); } @@ -4398,6 +4491,22 @@ BView::Perform(perform_code code, void* _data) = BView::GetToolTipAt(data->point, data->tool_tip); return B_OK; } + case PERFORM_CODE_ALL_UNARCHIVED: + { + perform_data_all_unarchived* data = + (perform_data_all_unarchived*)_data; + + data->return_value = BView::AllUnarchived(data->archive); + return B_OK; + } + case PERFORM_CODE_ALL_ARCHIVED: + { + perform_data_all_archived* data = + (perform_data_all_archived*)_data; + + data->return_value = BView::AllArchived(data->archive); + return B_OK; + } } return BHandler::Perform(code, _data);