* Added layout-related methods (Min/Max/PreferredSize(), InvalidateLayout(),

DoLayout()).
* Don't resize the view and the window anymore, when fResizeToFit is not
  set.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21426 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2007-06-17 01:15:05 +00:00
parent 05e3a10655
commit 4fa167e12d
2 changed files with 127 additions and 22 deletions
+9 -1
View File
@@ -113,11 +113,16 @@ virtual void SetMaxContentWidth(float max);
virtual void MessageReceived(BMessage *msg); virtual void MessageReceived(BMessage *msg);
virtual void KeyDown(const char *bytes, int32 numBytes); virtual void KeyDown(const char *bytes, int32 numBytes);
virtual void Draw(BRect updateRect); virtual void Draw(BRect updateRect);
virtual BSize MinSize();
virtual BSize MaxSize();
virtual BSize PreferredSize();
virtual void GetPreferredSize(float *width, float *height); virtual void GetPreferredSize(float *width, float *height);
virtual void ResizeToPreferred(); virtual void ResizeToPreferred();
virtual void DoLayout();
virtual void FrameMoved(BPoint new_position); virtual void FrameMoved(BPoint new_position);
virtual void FrameResized(float new_width, float new_height); virtual void FrameResized(float new_width, float new_height);
void InvalidateLayout(); void InvalidateLayout();
virtual void InvalidateLayout(bool descendants);
virtual BHandler *ResolveSpecifier(BMessage *msg, virtual BHandler *ResolveSpecifier(BMessage *msg,
int32 index, int32 index,
@@ -180,6 +185,8 @@ friend status_t _init_interface_kit_();
friend status_t set_menu_info(menu_info *); friend status_t set_menu_info(menu_info *);
friend status_t get_menu_info(menu_info *); friend status_t get_menu_info(menu_info *);
struct LayoutData;
virtual void _ReservedMenu3(); virtual void _ReservedMenu3();
virtual void _ReservedMenu4(); virtual void _ReservedMenu4();
virtual void _ReservedMenu5(); virtual void _ReservedMenu5();
@@ -202,6 +209,7 @@ virtual void _ReservedMenu6();
bool del = false); bool del = false);
bool RelayoutIfNeeded(); bool RelayoutIfNeeded();
void LayoutItems(int32 index); void LayoutItems(int32 index);
BSize _ValidatePreferredSize();
void ComputeLayout(int32 index, bool bestFit, bool moveItems, void ComputeLayout(int32 index, bool bestFit, bool moveItems,
float* width, float* height); float* width, float* height);
void _ComputeColumnLayout(int32 index, bool bestFit, bool moveItems, BRect &outRect); void _ComputeColumnLayout(int32 index, bool bestFit, bool moveItems, BRect &outRect);
@@ -292,7 +300,7 @@ static bool sAltAsCommandKey;
BPoint *fInitMatrixSize; BPoint *fInitMatrixSize;
_ExtraMenuData_ *fExtraMenuData; _ExtraMenuData_ *fExtraMenuData;
uint32 _reserved[1]; LayoutData* fLayoutData;
int32 fSubmenus; int32 fSubmenus;
+118 -21
View File
@@ -14,6 +14,8 @@
#include <Debug.h> #include <Debug.h>
#include <File.h> #include <File.h>
#include <FindDirectory.h> #include <FindDirectory.h>
#include <Layout.h>
#include <LayoutUtils.h>
#include <Menu.h> #include <Menu.h>
#include <MenuBar.h> #include <MenuBar.h>
#include <MenuItem.h> #include <MenuItem.h>
@@ -143,6 +145,11 @@ sPropList[] = {
const char *kEmptyMenuLabel = "<empty>"; const char *kEmptyMenuLabel = "<empty>";
struct BMenu::LayoutData {
BSize preferred;
};
BMenu::BMenu(const char *name, menu_layout layout) BMenu::BMenu(const char *name, menu_layout layout)
: BView(BRect(0, 0, 0, 0), name, 0, B_WILL_DRAW), : BView(BRect(0, 0, 0, 0), name, 0, B_WILL_DRAW),
fChosenItem(NULL), fChosenItem(NULL),
@@ -220,6 +227,7 @@ BMenu::~BMenu()
delete fInitMatrixSize; delete fInitMatrixSize;
delete fExtraMenuData; delete fExtraMenuData;
delete fLayoutData;
} }
@@ -840,10 +848,48 @@ BMenu::Draw(BRect updateRect)
} }
BSize
BMenu::MinSize()
{
_ValidatePreferredSize();
BSize size = (GetLayout() ? GetLayout()->MinSize()
: fLayoutData->preferred);
return BLayoutUtils::ComposeSize(ExplicitMinSize(), size);
}
BSize
BMenu::MaxSize()
{
_ValidatePreferredSize();
BSize size = (GetLayout() ? GetLayout()->MaxSize()
: fLayoutData->preferred);
return BLayoutUtils::ComposeSize(ExplicitMaxSize(), size);
}
BSize
BMenu::PreferredSize()
{
_ValidatePreferredSize();
BSize size = (GetLayout() ? GetLayout()->PreferredSize()
: fLayoutData->preferred);
return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), size);
}
void void
BMenu::GetPreferredSize(float *_width, float *_height) BMenu::GetPreferredSize(float *_width, float *_height)
{ {
ComputeLayout(0, true, false, _width, _height); _ValidatePreferredSize();
if (_width)
*_width = fLayoutData->preferred.width;
if (_height)
*_height = fLayoutData->preferred.height;
} }
@@ -854,6 +900,21 @@ BMenu::ResizeToPreferred()
} }
void
BMenu::DoLayout()
{
// If the user set a layout, we let the base class version call its
// hook.
if (GetLayout()) {
BView::DoLayout();
return;
}
if (RelayoutIfNeeded())
Invalidate();
}
void void
BMenu::FrameMoved(BPoint new_position) BMenu::FrameMoved(BPoint new_position)
{ {
@@ -870,8 +931,18 @@ BMenu::FrameResized(float new_width, float new_height)
void void
BMenu::InvalidateLayout() BMenu::InvalidateLayout()
{
InvalidateLayout(false);
}
void
BMenu::InvalidateLayout(bool descendants)
{ {
fUseCachedMenuLayout = false; fUseCachedMenuLayout = false;
fLayoutData->preferred.Set(B_SIZE_UNSET, B_SIZE_UNSET);
BView::InvalidateLayout(descendants);
} }
@@ -1127,10 +1198,12 @@ BMenu::InitData(BMessage *data)
font.SetFamilyAndStyle(sMenuInfo.f_family, sMenuInfo.f_style); font.SetFamilyAndStyle(sMenuInfo.f_family, sMenuInfo.f_style);
font.SetSize(sMenuInfo.font_size); font.SetSize(sMenuInfo.font_size);
SetFont(&font, B_FONT_FAMILY_AND_STYLE | B_FONT_SIZE); SetFont(&font, B_FONT_FAMILY_AND_STYLE | B_FONT_SIZE);
fLayoutData = new LayoutData;
SetLowColor(sMenuInfo.background_color); SetLowColor(sMenuInfo.background_color);
SetViewColor(sMenuInfo.background_color); SetViewColor(sMenuInfo.background_color);
if (data != NULL) { if (data != NULL) {
data->FindInt32("_layout", (int32 *)&fLayout); data->FindInt32("_layout", (int32 *)&fLayout);
data->FindBool("_rsize_to_fit", &fResizeToFit); data->FindBool("_rsize_to_fit", &fResizeToFit);
@@ -1488,10 +1561,13 @@ BMenu::RemoveItems(int32 index, int32 count, BMenuItem *item, bool deleteItems)
} }
} }
if (invalidateLayout && locked && window != NULL) { if (invalidateLayout) {
LayoutItems(0); InvalidateLayout();
UpdateWindowViewSize(false); if (locked && window != NULL) {
Invalidate(); LayoutItems(0);
UpdateWindowViewSize(false);
Invalidate();
}
} }
if (locked) if (locked)
@@ -1522,7 +1598,18 @@ BMenu::LayoutItems(int32 index)
float width, height; float width, height;
ComputeLayout(index, fResizeToFit, true, &width, &height); ComputeLayout(index, fResizeToFit, true, &width, &height);
ResizeTo(width, height); if (fResizeToFit)
ResizeTo(width, height);
}
BSize
BMenu::_ValidatePreferredSize()
{
if (!fLayoutData->preferred.IsWidthSet())
ComputeLayout(0, true, false, NULL, NULL);
return fLayoutData->preferred;
} }
@@ -1552,21 +1639,28 @@ BMenu::ComputeLayout(int32 index, bool bestFit, bool moveItems,
break; break;
} }
if (_width) { // change width depending on resize mode
// change width depending on resize mode BSize size;
if ((ResizingMode() & B_FOLLOW_LEFT_RIGHT) == B_FOLLOW_LEFT_RIGHT) { if ((ResizingMode() & B_FOLLOW_LEFT_RIGHT) == B_FOLLOW_LEFT_RIGHT) {
if (Parent()) if (Parent())
*_width = Parent()->Frame().Width() + 1; size.width = Parent()->Frame().Width() + 1;
else if (Window()) else if (Window())
*_width = Window()->Frame().Width() + 1; size.width = Window()->Frame().Width() + 1;
else else
*_width = Bounds().Width(); size.width = Bounds().Width();
} else } else
*_width = frame.Width(); size.width = frame.Width();
}
size.height = frame.Height();
if (_width)
*_width = size.width;
if (_height) if (_height)
*_height = frame.Height(); *_height = size.height;
if (bestFit)
fLayoutData->preferred = size;
if (moveItems) if (moveItems)
fUseCachedMenuLayout = true; fUseCachedMenuLayout = true;
@@ -2152,6 +2246,9 @@ BMenu::UpdateWindowViewSize(bool upWind)
if (dynamic_cast<BMenuBar *>(this) != NULL) if (dynamic_cast<BMenuBar *>(this) != NULL)
return; return;
if (fResizeToFit)
return;
bool scroll; bool scroll;
const BPoint screenLocation = upWind ? ScreenLocation() : window->Frame().LeftTop(); const BPoint screenLocation = upWind ? ScreenLocation() : window->Frame().LeftTop();
BRect frame = CalcFrame(screenLocation, &scroll); BRect frame = CalcFrame(screenLocation, &scroll);