BColorMenuItem: add custom color menufield
http://insightfactory.tumblr.com/image/142366356207 * Make the color box a rectangle with proportions of golden ratio. * Override GetContentSize() to make menu item area larger. * Label should never truncate since I make sure there is enough room. * Draw the label using BMenuItem parent class * Carefully adjust the spacing so that there is an attractive amount of padding between the checkmark and color box and the color box and label. Add _AddMenu method to BMenuField that adds BColorMenuItem as its base menu item. This shows the BColorMenuItem in the closed state. Create BPrivate::MenuItemPrivate Add a SetSubmenu() method to MenuItemPrivate that gives you the ability to add a submenu after creating the object. This method should be public Skip disabled items Color gets updated even if you select an item in a submenu
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006-2015, Haiku, Inc. All rights reserved.
|
* Copyright 2006-2016 Haiku, Inc. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef _MENU_FIELD_H
|
#ifndef _MENU_FIELD_H
|
||||||
@@ -135,6 +135,7 @@ private:
|
|||||||
void _InitMenuBar(BMenu* menu,
|
void _InitMenuBar(BMenu* menu,
|
||||||
BRect frame, bool fixedSize);
|
BRect frame, bool fixedSize);
|
||||||
void _InitMenuBar(const BMessage* archive);
|
void _InitMenuBar(const BMessage* archive);
|
||||||
|
void _AddMenu(BMenu* menu);
|
||||||
|
|
||||||
void _ValidateLayoutData();
|
void _ValidateLayoutData();
|
||||||
float _MenuBarOffset() const;
|
float _MenuBarOffset() const;
|
||||||
@@ -159,4 +160,5 @@ private:
|
|||||||
uint32 _reserved[2];
|
uint32 _reserved[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // _MENU_FIELD_H
|
#endif // _MENU_FIELD_H
|
||||||
|
|||||||
@@ -15,6 +15,10 @@
|
|||||||
class BMessage;
|
class BMessage;
|
||||||
class BWindow;
|
class BWindow;
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
class MenuItemPrivate;
|
||||||
|
}
|
||||||
|
|
||||||
class BMenuItem : public BArchivable, public BInvoker {
|
class BMenuItem : public BArchivable, public BInvoker {
|
||||||
public:
|
public:
|
||||||
BMenuItem(const char* label, BMessage* message,
|
BMenuItem(const char* label, BMessage* message,
|
||||||
@@ -57,6 +61,7 @@ private:
|
|||||||
friend class BMenu;
|
friend class BMenu;
|
||||||
friend class BPopUpMenu;
|
friend class BPopUpMenu;
|
||||||
friend class BMenuBar;
|
friend class BMenuBar;
|
||||||
|
friend class BPrivate::MenuItemPrivate;
|
||||||
|
|
||||||
virtual void _ReservedMenuItem1();
|
virtual void _ReservedMenuItem1();
|
||||||
virtual void _ReservedMenuItem2();
|
virtual void _ReservedMenuItem2();
|
||||||
@@ -77,6 +82,7 @@ private:
|
|||||||
BMenuItem(const BMenuItem& other);
|
BMenuItem(const BMenuItem& other);
|
||||||
BMenuItem& operator=(const BMenuItem& other);
|
BMenuItem& operator=(const BMenuItem& other);
|
||||||
|
|
||||||
|
private:
|
||||||
void _InitData();
|
void _InitData();
|
||||||
void _InitMenuData(BMenu* menu);
|
void _InitMenuData(BMenu* menu);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 Haiku, Inc. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* John Scipione, [email protected]
|
||||||
|
*/
|
||||||
|
#ifndef COLOR_MENU_ITEM_H
|
||||||
|
#define COLOR_MENU_ITEM_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <InterfaceDefs.h>
|
||||||
|
#include <MenuItem.h>
|
||||||
|
|
||||||
|
|
||||||
|
class BColorMenuItem : public BMenuItem {
|
||||||
|
public:
|
||||||
|
BColorMenuItem(const char* label,
|
||||||
|
BMessage* message, rgb_color color,
|
||||||
|
char shortcut = 0,
|
||||||
|
uint32 modifiers = 0);
|
||||||
|
BColorMenuItem(BMenu* menu, rgb_color color,
|
||||||
|
BMessage* message = NULL);
|
||||||
|
BColorMenuItem(BMessage* data);
|
||||||
|
|
||||||
|
static BArchivable* Instantiate(BMessage* archive);
|
||||||
|
virtual status_t Archive(BMessage* archive,
|
||||||
|
bool deep = true) const;
|
||||||
|
|
||||||
|
virtual void DrawContent();
|
||||||
|
virtual void GetContentSize(float* _width, float* _height);
|
||||||
|
|
||||||
|
virtual void SetMarked(bool mark);
|
||||||
|
|
||||||
|
rgb_color Color() const { return fColor; };
|
||||||
|
virtual void SetColor(rgb_color color) { fColor = color; };
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void _ReservedColorMenuItem1();
|
||||||
|
virtual void _ReservedColorMenuItem2();
|
||||||
|
virtual void _ReservedColorMenuItem3();
|
||||||
|
virtual void _ReservedColorMenuItem4();
|
||||||
|
virtual void _ReservedColorMenuItem5();
|
||||||
|
virtual void _ReservedColorMenuItem6();
|
||||||
|
virtual void _ReservedColorMenuItem7();
|
||||||
|
virtual void _ReservedColorMenuItem8();
|
||||||
|
virtual void _ReservedColorMenuItem9();
|
||||||
|
virtual void _ReservedColorMenuItem10();
|
||||||
|
virtual void _ReservedColorMenuItem11();
|
||||||
|
virtual void _ReservedColorMenuItem12();
|
||||||
|
virtual void _ReservedColorMenuItem13();
|
||||||
|
virtual void _ReservedColorMenuItem14();
|
||||||
|
virtual void _ReservedColorMenuItem15();
|
||||||
|
virtual void _ReservedColorMenuItem16();
|
||||||
|
virtual void _ReservedColorMenuItem17();
|
||||||
|
virtual void _ReservedColorMenuItem18();
|
||||||
|
virtual void _ReservedColorMenuItem19();
|
||||||
|
virtual void _ReservedColorMenuItem20();
|
||||||
|
|
||||||
|
float _LeftMargin();
|
||||||
|
float _Padding();
|
||||||
|
float _ColorRectWidth();
|
||||||
|
|
||||||
|
private:
|
||||||
|
rgb_color fColor;
|
||||||
|
|
||||||
|
uint32 _reserved[30];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // COLOR_MENU_ITEM_H
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 Haiku, Inc. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* John Scipione, [email protected]
|
||||||
|
*/
|
||||||
|
#ifndef __MENU_ITEM_PRIVATE_H
|
||||||
|
#define __MENU_ITEM_PRIVATE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <MenuItem.h>
|
||||||
|
|
||||||
|
|
||||||
|
class BMenu;
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class MenuItemPrivate {
|
||||||
|
public:
|
||||||
|
MenuItemPrivate(BMenuItem* menuItem);
|
||||||
|
|
||||||
|
void SetSubmenu(BMenu* submenu);
|
||||||
|
|
||||||
|
void Install(BWindow* window);
|
||||||
|
void Uninstall();
|
||||||
|
|
||||||
|
private:
|
||||||
|
BMenuItem* fMenuItem;
|
||||||
|
};
|
||||||
|
|
||||||
|
}; // namespace BPrivate
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __MENU_ITEM_PRIVATE_H
|
||||||
@@ -0,0 +1,233 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 Haiku, Inc. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* John Scipione, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "ColorMenuItem.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <MenuField.h>
|
||||||
|
#include <MenuPrivate.h>
|
||||||
|
|
||||||
|
|
||||||
|
// golden ratio
|
||||||
|
#ifdef M_PHI
|
||||||
|
# undef M_PHI
|
||||||
|
#endif
|
||||||
|
#define M_PHI 1.61803398874989484820
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma - ColorMenuItem
|
||||||
|
|
||||||
|
|
||||||
|
BColorMenuItem::BColorMenuItem(const char* label, BMessage* message,
|
||||||
|
rgb_color color, char shortcut, uint32 modifiers)
|
||||||
|
:
|
||||||
|
BMenuItem(label, message, shortcut, modifiers),
|
||||||
|
fColor(color)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BColorMenuItem::BColorMenuItem(BMenu* menu, rgb_color color,
|
||||||
|
BMessage* message)
|
||||||
|
:
|
||||||
|
BMenuItem(menu, message),
|
||||||
|
fColor(color)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BColorMenuItem::BColorMenuItem(BMessage* data)
|
||||||
|
:
|
||||||
|
BMenuItem(data)
|
||||||
|
{
|
||||||
|
if (data->HasColor("_color")) {
|
||||||
|
rgb_color color;
|
||||||
|
|
||||||
|
color = data->GetColor("_color", (rgb_color){ 0, 0, 0 });
|
||||||
|
fColor = color;
|
||||||
|
} else
|
||||||
|
fColor = (rgb_color){ 0, 0, 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BArchivable*
|
||||||
|
BColorMenuItem::Instantiate(BMessage* data)
|
||||||
|
{
|
||||||
|
if (validate_instantiation(data, "BColorMenuItem"))
|
||||||
|
return new BColorMenuItem(data);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BColorMenuItem::Archive(BMessage* data, bool deep) const
|
||||||
|
{
|
||||||
|
status_t result = BMenuItem::Archive(data, deep);
|
||||||
|
|
||||||
|
if (result == B_OK)
|
||||||
|
result = data->AddColor("_color", fColor);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BColorMenuItem::DrawContent()
|
||||||
|
{
|
||||||
|
float leftMargin = _LeftMargin();
|
||||||
|
float padding = _Padding();
|
||||||
|
float colorRectWidth = _ColorRectWidth();
|
||||||
|
|
||||||
|
BRect colorRect(Frame().InsetByCopy(2.0f, 2.0f));
|
||||||
|
colorRect.left = colorRect.right = leftMargin;
|
||||||
|
colorRect.right += colorRectWidth;
|
||||||
|
|
||||||
|
rgb_color highColor = Menu()->HighColor();
|
||||||
|
|
||||||
|
Menu()->SetDrawingMode(B_OP_OVER);
|
||||||
|
|
||||||
|
Menu()->SetHighColor(fColor);
|
||||||
|
Menu()->FillRect(colorRect);
|
||||||
|
|
||||||
|
Menu()->SetHighColor(ui_color(B_CONTROL_BORDER_COLOR));
|
||||||
|
Menu()->StrokeRect(colorRect);
|
||||||
|
|
||||||
|
float width = colorRectWidth + padding;
|
||||||
|
|
||||||
|
Menu()->MovePenBy(width, 0.0f);
|
||||||
|
Menu()->SetHighColor(highColor);
|
||||||
|
|
||||||
|
BMenuItem::DrawContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BColorMenuItem::GetContentSize(float* _width, float* _height)
|
||||||
|
{
|
||||||
|
float labelWidth;
|
||||||
|
float height;
|
||||||
|
BMenuItem::GetContentSize(&labelWidth, &height);
|
||||||
|
|
||||||
|
if (_width != NULL)
|
||||||
|
*_width = _LeftMargin() + _ColorRectWidth() + _Padding() + labelWidth;
|
||||||
|
|
||||||
|
if (_height != NULL)
|
||||||
|
*_height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BColorMenuItem::SetMarked(bool mark)
|
||||||
|
{
|
||||||
|
BMenuItem::SetMarked(mark);
|
||||||
|
|
||||||
|
if (!mark)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// we are marking the item
|
||||||
|
|
||||||
|
BMenu* menu = Menu();
|
||||||
|
if (menu == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// we have a parent menu
|
||||||
|
|
||||||
|
BMenu* _menu = menu;
|
||||||
|
while ((_menu = _menu->Supermenu()) != NULL)
|
||||||
|
menu = _menu;
|
||||||
|
|
||||||
|
// went up the hierarchy to found the topmost menu
|
||||||
|
|
||||||
|
if (menu == NULL || menu->Parent() == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// our topmost menu has a parent
|
||||||
|
|
||||||
|
if (dynamic_cast<BMenuField*>(menu->Parent()) == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// our topmost menu's parent is a BMenuField
|
||||||
|
|
||||||
|
BMenuItem* topLevelItem = menu->ItemAt((int32)0);
|
||||||
|
|
||||||
|
if (topLevelItem == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// our topmost menu has a menu item
|
||||||
|
|
||||||
|
BColorMenuItem* topLevelColorMenuItem
|
||||||
|
= dynamic_cast<BColorMenuItem*>(topLevelItem);
|
||||||
|
if (topLevelColorMenuItem == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// our topmost menu's item is a BColorMenuItem
|
||||||
|
|
||||||
|
// update the color
|
||||||
|
topLevelColorMenuItem->SetColor(fColor);
|
||||||
|
menu->Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - BColorMenuItem private methods
|
||||||
|
|
||||||
|
|
||||||
|
float
|
||||||
|
BColorMenuItem::_LeftMargin()
|
||||||
|
{
|
||||||
|
BPrivate::MenuPrivate menuPrivate(Menu());
|
||||||
|
float leftMargin;
|
||||||
|
menuPrivate.GetItemMargins(&leftMargin, NULL, NULL, NULL);
|
||||||
|
return leftMargin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float
|
||||||
|
BColorMenuItem::_Padding()
|
||||||
|
{
|
||||||
|
return floorf(std::max(14.0f, be_plain_font->Size() + 2) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float
|
||||||
|
BColorMenuItem::_ColorRectWidth()
|
||||||
|
{
|
||||||
|
return floorf(std::max(14.0f, be_plain_font->Size() + 2) * M_PHI);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - BColorMenuItem reserved virtual methods
|
||||||
|
|
||||||
|
|
||||||
|
void BColorMenuItem::_ReservedColorMenuItem1() {}
|
||||||
|
void BColorMenuItem::_ReservedColorMenuItem2() {}
|
||||||
|
void BColorMenuItem::_ReservedColorMenuItem3() {}
|
||||||
|
void BColorMenuItem::_ReservedColorMenuItem4() {}
|
||||||
|
void BColorMenuItem::_ReservedColorMenuItem5() {}
|
||||||
|
void BColorMenuItem::_ReservedColorMenuItem6() {}
|
||||||
|
void BColorMenuItem::_ReservedColorMenuItem7() {}
|
||||||
|
void BColorMenuItem::_ReservedColorMenuItem8() {}
|
||||||
|
void BColorMenuItem::_ReservedColorMenuItem9() {}
|
||||||
|
void BColorMenuItem::_ReservedColorMenuItem10() {}
|
||||||
|
void BColorMenuItem::_ReservedColorMenuItem11() {}
|
||||||
|
void BColorMenuItem::_ReservedColorMenuItem12() {}
|
||||||
|
void BColorMenuItem::_ReservedColorMenuItem13() {}
|
||||||
|
void BColorMenuItem::_ReservedColorMenuItem14() {}
|
||||||
|
void BColorMenuItem::_ReservedColorMenuItem15() {}
|
||||||
|
void BColorMenuItem::_ReservedColorMenuItem16() {}
|
||||||
|
void BColorMenuItem::_ReservedColorMenuItem17() {}
|
||||||
|
void BColorMenuItem::_ReservedColorMenuItem18() {}
|
||||||
|
void BColorMenuItem::_ReservedColorMenuItem19() {}
|
||||||
|
void BColorMenuItem::_ReservedColorMenuItem20() {}
|
||||||
@@ -57,6 +57,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
|||||||
CheckBox.cpp
|
CheckBox.cpp
|
||||||
ColorConversion.cpp
|
ColorConversion.cpp
|
||||||
ColorControl.cpp
|
ColorControl.cpp
|
||||||
|
ColorMenuItem.cpp
|
||||||
Control.cpp
|
Control.cpp
|
||||||
ControlLook.cpp
|
ControlLook.cpp
|
||||||
DecorInfo.cpp
|
DecorInfo.cpp
|
||||||
@@ -90,6 +91,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
|||||||
MenuBar.cpp
|
MenuBar.cpp
|
||||||
MenuField.cpp
|
MenuField.cpp
|
||||||
MenuItem.cpp
|
MenuItem.cpp
|
||||||
|
MenuItemPrivate.cpp
|
||||||
MenuPrivate.cpp
|
MenuPrivate.cpp
|
||||||
MenuWindow.cpp
|
MenuWindow.cpp
|
||||||
OptionControl.cpp
|
OptionControl.cpp
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2001-2013, Haiku, Inc.
|
* Copyright 2006-2016 Haiku, Inc. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -13,17 +13,20 @@
|
|||||||
#include <MenuField.h>
|
#include <MenuField.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
// for printf in TRACE
|
// for printf in TRACE
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <AbstractLayoutItem.h>
|
#include <AbstractLayoutItem.h>
|
||||||
|
#include <Archivable.h>
|
||||||
#include <BMCPrivate.h>
|
#include <BMCPrivate.h>
|
||||||
#include <ControlLook.h>
|
#include <ControlLook.h>
|
||||||
#include <LayoutUtils.h>
|
#include <LayoutUtils.h>
|
||||||
#include <MenuBar.h>
|
#include <MenuBar.h>
|
||||||
#include <MenuItem.h>
|
#include <MenuItem.h>
|
||||||
|
#include <MenuItemPrivate.h>
|
||||||
#include <MenuPrivate.h>
|
#include <MenuPrivate.h>
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
#include <MessageFilter.h>
|
#include <MessageFilter.h>
|
||||||
@@ -194,8 +197,6 @@ MouseDownFilter::Filter(BMessage* message, BHandler** target)
|
|||||||
// #pragma mark - BMenuField
|
// #pragma mark - BMenuField
|
||||||
|
|
||||||
|
|
||||||
using BPrivate::MenuPrivate;
|
|
||||||
|
|
||||||
BMenuField::BMenuField(BRect frame, const char* name, const char* label,
|
BMenuField::BMenuField(BRect frame, const char* name, const char* label,
|
||||||
BMenu* menu, uint32 resizingMode, uint32 flags)
|
BMenu* menu, uint32 resizingMode, uint32 flags)
|
||||||
:
|
:
|
||||||
@@ -300,6 +301,7 @@ BMenuField::BMenuField(BMessage* data)
|
|||||||
|
|
||||||
if (!BUnarchiver::IsArchiveManaged(data))
|
if (!BUnarchiver::IsArchiveManaged(data))
|
||||||
_InitMenuBar(data);
|
_InitMenuBar(data);
|
||||||
|
|
||||||
unarchiver.Finish();
|
unarchiver.Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1081,7 +1083,7 @@ BMenuField::_DrawLabel(BRect updateRect)
|
|||||||
PushState();
|
PushState();
|
||||||
rgb_color textColor;
|
rgb_color textColor;
|
||||||
|
|
||||||
MenuPrivate menuPrivate(fMenuBar);
|
BPrivate::MenuPrivate menuPrivate(fMenuBar);
|
||||||
if (menuPrivate.State() != MENU_STATE_CLOSED) {
|
if (menuPrivate.State() != MENU_STATE_CLOSED) {
|
||||||
// highlight the background of the label grey (like BeOS R5)
|
// highlight the background of the label grey (like BeOS R5)
|
||||||
SetLowColor(ui_color(B_MENU_SELECTED_BACKGROUND_COLOR));
|
SetLowColor(ui_color(B_MENU_SELECTED_BACKGROUND_COLOR));
|
||||||
@@ -1207,9 +1209,6 @@ BMenuField::_InitMenuBar(BMenu* menu, BRect frame, bool fixedSize)
|
|||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
fMenu = menu;
|
|
||||||
InitMenu(menu);
|
|
||||||
|
|
||||||
if ((Flags() & B_SUPPORTS_LAYOUT) != 0) {
|
if ((Flags() & B_SUPPORTS_LAYOUT) != 0) {
|
||||||
fMenuBar = new _BMCMenuBar_(this);
|
fMenuBar = new _BMCMenuBar_(this);
|
||||||
} else {
|
} else {
|
||||||
@@ -1236,7 +1235,9 @@ BMenuField::_InitMenuBar(BMenu* menu, BRect frame, bool fixedSize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
AddChild(fMenuBar);
|
AddChild(fMenuBar);
|
||||||
fMenuBar->AddItem(menu);
|
|
||||||
|
_AddMenu(menu);
|
||||||
|
|
||||||
fMenuBar->SetFont(be_plain_font);
|
fMenuBar->SetFont(be_plain_font);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1257,7 +1258,7 @@ BMenuField::_InitMenuBar(const BMessage* archive)
|
|||||||
// this is normally done in InitObject2()
|
// this is normally done in InitObject2()
|
||||||
}
|
}
|
||||||
|
|
||||||
fMenu = fMenuBar->SubmenuAt(0);
|
_AddMenu(fMenuBar->SubmenuAt(0));
|
||||||
|
|
||||||
bool disable;
|
bool disable;
|
||||||
if (archive->FindBool("_disable", &disable) == B_OK)
|
if (archive->FindBool("_disable", &disable) == B_OK)
|
||||||
@@ -1271,6 +1272,62 @@ BMenuField::_InitMenuBar(const BMessage* archive)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BMenuField::_AddMenu(BMenu* menu)
|
||||||
|
{
|
||||||
|
if (menu == NULL || fMenuBar == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fMenu = menu;
|
||||||
|
InitMenu(menu);
|
||||||
|
|
||||||
|
BMenuItem* item = NULL;
|
||||||
|
if (!menu->IsRadioMode() || (item = menu->FindMarked()) == NULL) {
|
||||||
|
// find the first enabled non-seperator item
|
||||||
|
int32 itemCount = menu->CountItems();
|
||||||
|
for (int32 i = 0; i < itemCount; i++) {
|
||||||
|
item = menu->ItemAt((int32)i);
|
||||||
|
if (item == NULL || !item->IsEnabled()
|
||||||
|
|| dynamic_cast<BSeparatorItem*>(item) != NULL) {
|
||||||
|
item = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item == NULL) {
|
||||||
|
fMenuBar->AddItem(menu);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// build an empty copy of item
|
||||||
|
|
||||||
|
BMessage data;
|
||||||
|
status_t result = item->Archive(&data, false);
|
||||||
|
if (result != B_OK) {
|
||||||
|
fMenuBar->AddItem(menu);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BArchivable* object = instantiate_object(&data);
|
||||||
|
if (object == NULL) {
|
||||||
|
fMenuBar->AddItem(menu);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BMenuItem* newItem = static_cast<BMenuItem*>(object);
|
||||||
|
|
||||||
|
// unset parameters
|
||||||
|
BPrivate::MenuItemPrivate newMenuItemPrivate(newItem);
|
||||||
|
newMenuItemPrivate.Uninstall();
|
||||||
|
|
||||||
|
// set the menu
|
||||||
|
newMenuItemPrivate.SetSubmenu(menu);
|
||||||
|
fMenuBar->AddItem(newItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BMenuField::_ValidateLayoutData()
|
BMenuField::_ValidateLayoutData()
|
||||||
{
|
{
|
||||||
@@ -1630,4 +1687,3 @@ B_IF_GCC_2(InvalidateLayout__10BMenuFieldb, _ZN10BMenuField16InvalidateLayoutEb)
|
|||||||
|
|
||||||
field->Perform(PERFORM_CODE_LAYOUT_INVALIDATED, &data);
|
field->Perform(PERFORM_CODE_LAYOUT_INVALIDATED, &data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 Haiku, Inc. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* John Scipione, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <MenuItemPrivate.h>
|
||||||
|
|
||||||
|
#include <Menu.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
MenuItemPrivate::MenuItemPrivate(BMenuItem* menuItem)
|
||||||
|
:
|
||||||
|
fMenuItem(menuItem)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MenuItemPrivate::SetSubmenu(BMenu* submenu)
|
||||||
|
{
|
||||||
|
delete fMenuItem->fSubmenu;
|
||||||
|
|
||||||
|
fMenuItem->_InitMenuData(submenu);
|
||||||
|
|
||||||
|
if (fMenuItem->fSuper != NULL) {
|
||||||
|
fMenuItem->fSuper->InvalidateLayout();
|
||||||
|
|
||||||
|
if (fMenuItem->fSuper->LockLooper()) {
|
||||||
|
fMenuItem->fSuper->Invalidate();
|
||||||
|
fMenuItem->fSuper->UnlockLooper();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MenuItemPrivate::Install(BWindow* window)
|
||||||
|
{
|
||||||
|
fMenuItem->Install(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MenuItemPrivate::Uninstall()
|
||||||
|
{
|
||||||
|
fMenuItem->Uninstall();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
Reference in New Issue
Block a user