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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user