Updated BMenuField and its custom BLayoutItems for layout-safe archiving. Added an _InitMenu(const BMessage*) method that inits the menu during unarchival.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37778 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Alex Wilson
2010-07-27 20:59:47 +00:00
parent 4a254e4ddb
commit 7a37b89be9
2 changed files with 214 additions and 25 deletions
+3
View File
@@ -35,6 +35,8 @@ public:
static BArchivable* Instantiate(BMessage* archive);
virtual status_t Archive(BMessage* archive,
bool deep = true) const;
virtual status_t AllArchived(BMessage* into) const;
virtual status_t AllUnarchived(const BMessage* from);
virtual void Draw(BRect update);
virtual void AttachedToWindow();
@@ -122,6 +124,7 @@ private:
void _UpdateFrame();
void _InitMenuBar(BMenu* menu,
BRect frame, bool fixedSize);
void _InitMenuBar(const BMessage* archive);
void _ValidateLayoutData();
float _MenuBarOffset() const;
+211 -25
View File
@@ -23,6 +23,7 @@
#include <Window.h>
#include <binary_compatibility/Interface.h>
#include <binary_compatibility/Support.h>
//#define TRACE_MENU_FIELD
@@ -40,9 +41,17 @@
#endif
namespace {
const char* const kFrameField = "BMenuField:layoutItem:frame";
const char* const kMenuBarItemField = "BMenuField:barItem";
const char* const kLabelItemField = "BMenuField:labelItem";
}
class BMenuField::LabelLayoutItem : public BAbstractLayoutItem {
public:
LabelLayoutItem(BMenuField* parent);
LabelLayoutItem(BMessage* archive);
virtual bool IsVisible();
virtual void SetVisible(bool visible);
@@ -50,6 +59,7 @@ public:
virtual BRect Frame();
virtual void SetFrame(BRect frame);
void SetParent(BMenuField* parent);
virtual BView* View();
virtual BSize BaseMinSize();
@@ -57,6 +67,9 @@ public:
virtual BSize BasePreferredSize();
virtual BAlignment BaseAlignment();
virtual status_t Archive(BMessage* into, bool deep = true) const;
static BArchivable* Instantiate(BMessage* from);
private:
BMenuField* fParent;
BRect fFrame;
@@ -66,6 +79,7 @@ private:
class BMenuField::MenuBarLayoutItem : public BAbstractLayoutItem {
public:
MenuBarLayoutItem(BMenuField* parent);
MenuBarLayoutItem(BMessage* from);
virtual bool IsVisible();
virtual void SetVisible(bool visible);
@@ -73,6 +87,7 @@ public:
virtual BRect Frame();
virtual void SetFrame(BRect frame);
void SetParent(BMenuField* parent);
virtual BView* View();
virtual BSize BaseMinSize();
@@ -80,6 +95,9 @@ public:
virtual BSize BasePreferredSize();
virtual BAlignment BaseAlignment();
virtual status_t Archive(BMessage* into, bool deep = true) const;
static BArchivable* Instantiate(BMessage* from);
private:
BMenuField* fParent;
BRect fFrame;
@@ -176,38 +194,23 @@ BMenuField::BMenuField(const char* label, BMenu* menu, BMessage* message)
BMenuField::BMenuField(BMessage* data)
:
BView(data)
BView(BUnarchiver::PrepareArchive(data))
{
BUnarchiver unarchiver(data);
const char* label = NULL;
data->FindString("_label", &label);
InitObject(label);
fMenuBar = (BMenuBar*)FindView("_mc_mb_");
if (!fMenuBar)
_InitMenuBar(new BMenu(""), BRect(0, 0, 100, 15), false);
fMenu = fMenuBar->SubmenuAt(0);
InitObject2();
bool disable;
if (data->FindBool("_disable", &disable) == B_OK)
SetEnabled(!disable);
int32 align;
data->FindInt32("_align", &align);
SetAlignment((alignment)align);
data->FindFloat("_divide", &fDivider);
bool fixed;
if (data->FindBool("be:fixeds", &fixed) == B_OK)
fFixedSizeMB = fixed;
bool dmark = false;
data->FindBool("be:dmark", &dmark);
if (_BMCMenuBar_* menuBar = dynamic_cast<_BMCMenuBar_*>(fMenuBar))
menuBar->TogglePopUpMarker(dmark);
int32 align;
if (data->FindInt32("_align", &align) == B_OK)
SetAlignment((alignment)align);
if (!BUnarchiver::IsArchiveManaged(data))
_InitMenuBar(data);
unarchiver.Finish();
}
@@ -236,6 +239,7 @@ BMenuField::Instantiate(BMessage* data)
status_t
BMenuField::Archive(BMessage* data, bool deep) const
{
BArchiver archiver(data);
status_t ret = BView::Archive(data, deep);
if (ret == B_OK && Label())
@@ -258,7 +262,66 @@ BMenuField::Archive(BMessage* data, bool deep) const
data->AddBool("be:dmark", dmark);
return ret;
return archiver.Finish(ret);
}
status_t
BMenuField::AllArchived(BMessage* into) const
{
status_t err;
if ((err = BView::AllArchived(into)) != B_OK)
return err;
BArchiver archiver(into);
BArchivable* menuBarItem = fLayoutData->menu_bar_layout_item;
if (archiver.IsArchived(menuBarItem))
err = archiver.AddArchivable(kMenuBarItemField, menuBarItem);
if (err != B_OK)
return err;
BArchivable* labelBarItem = fLayoutData->label_layout_item;
if (archiver.IsArchived(labelBarItem))
err = archiver.AddArchivable(kLabelItemField, labelBarItem);
return err;
}
status_t
BMenuField::AllUnarchived(const BMessage* from)
{
BUnarchiver unarchiver(from);
status_t err = B_OK;
if ((err = BView::AllUnarchived(from)) != B_OK)
return err;
_InitMenuBar(from);
if (unarchiver.IsInstantiated(kMenuBarItemField)) {
MenuBarLayoutItem*& menuItem = fLayoutData->menu_bar_layout_item;
err = unarchiver.FindObject(kMenuBarItemField,
BUnarchiver::B_DONT_ASSUME_OWNERSHIP, menuItem);
if (err == B_OK)
menuItem->SetParent(this);
else
return err;
}
if (unarchiver.IsInstantiated(kLabelItemField)) {
LabelLayoutItem*& labelItem = fLayoutData->label_layout_item;
err = unarchiver.FindObject(kLabelItemField,
BUnarchiver::B_DONT_ASSUME_OWNERSHIP, labelItem);
if (err == B_OK)
labelItem->SetParent(this);
}
return err;
}
@@ -794,6 +857,22 @@ BMenuField::Perform(perform_code code, void* _data)
BMenuField::DoLayout();
return B_OK;
}
case PERFORM_CODE_ALL_UNARCHIVED:
{
perform_data_all_unarchived* data
= (perform_data_all_unarchived*)_data;
data->return_value = BMenuField::AllUnarchived(data->archive);
return B_OK;
}
case PERFORM_CODE_ALL_ARCHIVED:
{
perform_data_all_archived* data
= (perform_data_all_archived*)_data;
data->return_value = BMenuField::AllArchived(data->archive);
return B_OK;
}
}
return BView::Perform(code, _data);
@@ -1062,6 +1141,35 @@ BMenuField::_InitMenuBar(BMenu* menu, BRect frame, bool fixedSize)
}
void
BMenuField::_InitMenuBar(const BMessage* archive)
{
bool fixed;
if (archive->FindBool("be:fixeds", &fixed) == B_OK)
fFixedSizeMB = fixed;
fMenuBar = (BMenuBar*)FindView("_mc_mb_");
if (!fMenuBar) {
_InitMenuBar(new BMenu(""), BRect(0, 0, 100, 15), fFixedSizeMB);
InitObject2();
} else {
fMenuBar->AddFilter(new _BMCFilter_(this, B_MOUSE_DOWN));
// this is normally done in InitObject2()
}
fMenu = fMenuBar->SubmenuAt(0);
bool disable;
if (archive->FindBool("_disable", &disable) == B_OK)
SetEnabled(!disable);
bool dmark = false;
archive->FindBool("be:dmark", &dmark);
if (_BMCMenuBar_* menuBar = dynamic_cast<_BMCMenuBar_*>(fMenuBar))
menuBar->TogglePopUpMarker(dmark);
}
void
BMenuField::_ValidateLayoutData()
{
@@ -1144,6 +1252,16 @@ BMenuField::LabelLayoutItem::LabelLayoutItem(BMenuField* parent)
}
BMenuField::LabelLayoutItem::LabelLayoutItem(BMessage* from)
:
BAbstractLayoutItem(from),
fParent(NULL),
fFrame()
{
from->FindRect(kFrameField, &fFrame);
}
bool
BMenuField::LabelLayoutItem::IsVisible()
{
@@ -1173,6 +1291,13 @@ BMenuField::LabelLayoutItem::SetFrame(BRect frame)
}
void
BMenuField::LabelLayoutItem::SetParent(BMenuField* parent)
{
fParent = parent;
}
BView*
BMenuField::LabelLayoutItem::View()
{
@@ -1214,6 +1339,28 @@ BMenuField::LabelLayoutItem::BaseAlignment()
}
status_t
BMenuField::LabelLayoutItem::Archive(BMessage* into, bool deep) const
{
BArchiver archiver(into);
status_t err = BAbstractLayoutItem::Archive(into, deep);
if (err == B_OK)
err = into->AddRect(kFrameField, fFrame);
return archiver.Finish(err);
}
BArchivable*
BMenuField::LabelLayoutItem::Instantiate(BMessage* from)
{
if (validate_instantiation(from, "BMenuField::LabelLayoutItem"))
return new LabelLayoutItem(from);
return NULL;
}
// #pragma mark -
@@ -1228,6 +1375,16 @@ BMenuField::MenuBarLayoutItem::MenuBarLayoutItem(BMenuField* parent)
}
BMenuField::MenuBarLayoutItem::MenuBarLayoutItem(BMessage* from)
:
BAbstractLayoutItem(from),
fParent(NULL),
fFrame()
{
from->FindRect(kFrameField, &fFrame);
}
bool
BMenuField::MenuBarLayoutItem::IsVisible()
{
@@ -1257,6 +1414,13 @@ BMenuField::MenuBarLayoutItem::SetFrame(BRect frame)
}
void
BMenuField::MenuBarLayoutItem::SetParent(BMenuField* parent)
{
fParent = parent;
}
BView*
BMenuField::MenuBarLayoutItem::View()
{
@@ -1299,3 +1463,25 @@ BMenuField::MenuBarLayoutItem::BaseAlignment()
return BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT);
}
status_t
BMenuField::MenuBarLayoutItem::Archive(BMessage* into, bool deep) const
{
BArchiver archiver(into);
status_t err = BAbstractLayoutItem::Archive(into, deep);
if (err == B_OK)
err = into->AddRect(kFrameField, fFrame);
return archiver.Finish(err);
}
BArchivable*
BMenuField::MenuBarLayoutItem::Instantiate(BMessage* from)
{
if (validate_instantiation(from, "BMenuField::MenuBarLayoutItem"))
return new MenuBarLayoutItem(from);
return NULL;
}