From 31852cb13e991ab5e9537fd5b6dad29647f16d4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 22 Mar 2009 11:27:01 +0000 Subject: [PATCH] Various fixes to BMenuField behavior: * In layout mode, using a BMenuField directly will make it behave like using a fixed size BMenuField in non-layout mode. This is open for debate, but not a change to the previous behavior. When using the Label and MenuBar- LayoutItems though, the behavior is now changed to be more what one would expect, ie the BMenuBar part is layouted across the full available width just like it happens with BTextControls. * Fixed invalidation of the BMenuBar when it auto-resizes according to picking another item, and when it is resized due to layout changes. * Fixed the problem with growing BMenuFields in file panels after changing folders the first time. The fix is not so nice, but the purpose of setting the menu item margins is to make sure it renders at the same vertical offset as the BMenuField label. The better fix would be to change the calculation of the content location or required margins in the BMenuItem code... however the BMCPrivate code needs to account for the popup indicator in the margins so I just kept the fix for the offset there as well. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29650 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/interface/BMCPrivate.cpp | 22 ++++++++++++++-------- src/kits/interface/MenuField.cpp | 29 ++++++++++++++++++++++------- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/kits/interface/BMCPrivate.cpp b/src/kits/interface/BMCPrivate.cpp index cd35198805..dec065c623 100644 --- a/src/kits/interface/BMCPrivate.cpp +++ b/src/kits/interface/BMCPrivate.cpp @@ -128,6 +128,7 @@ _BMCMenuBar_::AttachedToWindow() float left, top, right, bottom; GetItemMargins(&left, &top, &right, &bottom); +#if 0 // TODO: Better fix would be to make BMenuItem draw text properly // centered font_height fontHeight; @@ -135,6 +136,13 @@ _BMCMenuBar_::AttachedToWindow() top = ceilf((Bounds().Height() - ceilf(fontHeight.ascent) - ceilf(fontHeight.descent)) / 2) + 1; bottom = top - 1; +#else + // TODO: Fix content location properly. This is just a quick fix to + // make the BMenuField label and the super-item of the BMenuBar + // align vertically. + top++; + bottom--; +#endif if (be_control_look) left = right = be_control_look->DefaultLabelSpacing(); @@ -267,12 +275,7 @@ _BMCMenuBar_::FrameResized(float width, float height) { // we need to take care of resizing and cleaning up // the parent menu field - float diff; - if (fFixedSize) - diff = width - fPreviousWidth; - else - diff = Frame().right - (fMenuField->Bounds().right - 2); - + float diff = width - fPreviousWidth; fPreviousWidth = width; if (Window()) { @@ -280,7 +283,8 @@ _BMCMenuBar_::FrameResized(float width, float height) // clean up the dirty right border of // the menu field when enlarging BRect dirty(fMenuField->Bounds()); - dirty.left = dirty.right - diff - 2; + dirty.right = Frame().right + 2; + dirty.left = dirty.left - diff - 4; fMenuField->Invalidate(dirty); // clean up the arrow part @@ -292,7 +296,8 @@ _BMCMenuBar_::FrameResized(float width, float height) // clean up the dirty right line of // the menu field when shrinking BRect dirty(fMenuField->Bounds()); - dirty.left = dirty.right - 2; + dirty.left = Frame().right - 2; + dirty.right = dirty.left - diff + 4; fMenuField->Invalidate(dirty); // clean up the arrow part @@ -307,6 +312,7 @@ _BMCMenuBar_::FrameResized(float width, float height) // of the size of the parent menu field as well // NOTE: no worries about follow mode, we follow left and top // in autosize mode + diff = Frame().right + 2 - fMenuField->Bounds().right; fMenuField->ResizeBy(diff, 0.0); } BMenuBar::FrameResized(width, height); diff --git a/src/kits/interface/MenuField.cpp b/src/kits/interface/MenuField.cpp index 3af0826fd7..bd13d05d64 100644 --- a/src/kits/interface/MenuField.cpp +++ b/src/kits/interface/MenuField.cpp @@ -730,8 +730,12 @@ BMenuField::CreateLabelLayoutItem() BLayoutItem* BMenuField::CreateMenuBarLayoutItem() { - if (!fLayoutData->menu_bar_layout_item) + if (!fLayoutData->menu_bar_layout_item) { + // align the menu bar in the full available space + fMenuBar->SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH, + B_ALIGN_VERTICAL_UNSET)); fLayoutData->menu_bar_layout_item = new MenuBarLayoutItem(this); + } return fLayoutData->menu_bar_layout_item; } @@ -767,7 +771,7 @@ BMenuField::Perform(perform_code code, void* _data) BMenuField::GetHeightForWidth(data->width, &data->min, &data->max, &data->preferred); return B_OK; -} + } case PERFORM_CODE_SET_LAYOUT: { perform_data_set_layout* data = (perform_data_set_layout*)_data; @@ -1041,9 +1045,15 @@ BMenuField::_InitMenuBar(BMenu* menu, BRect frame, bool fixedSize) fMenuBar = new _BMCMenuBar_(frame, fixedSize, this); - // by default align the menu bar left in the available space - fMenuBar->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, - B_ALIGN_VERTICAL_UNSET)); + if (fixedSize) { + // align the menu bar left in the available space + fMenuBar->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, + B_ALIGN_VERTICAL_UNSET)); + } else { + // align the menu bar in the full available space + fMenuBar->SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH, + B_ALIGN_VERTICAL_UNSET)); + } AddChild(fMenuBar); fMenuBar->AddItem(menu); @@ -1268,14 +1278,19 @@ BMenuField::MenuBarLayoutItem::BaseMinSize() BSize BMenuField::MenuBarLayoutItem::BaseMaxSize() { - return BaseMinSize(); + BSize size(BaseMinSize()); + size.width = B_SIZE_UNLIMITED; + return size; } BSize BMenuField::MenuBarLayoutItem::BasePreferredSize() { - return BaseMinSize(); + BSize size(BaseMinSize()); + // puh, no idea... + size.width = 100; + return size; }