diff --git a/headers/private/interface/MenuWindow.h b/headers/private/interface/MenuWindow.h index 2a586f9856..dc8bb24112 100644 --- a/headers/private/interface/MenuWindow.h +++ b/headers/private/interface/MenuWindow.h @@ -34,9 +34,10 @@ class BMenuScroller; class BMenuWindow : public BWindow { public: - BMenuWindow(const char *name); + BMenuWindow(const char *name, BMenu *menu); virtual ~BMenuWindow(); + void SetMenu(BMenu *menu); void UpdateScrollers(); private: diff --git a/src/kits/interface/Menu.cpp b/src/kits/interface/Menu.cpp index 312f483e33..a8e6e2d5a3 100644 --- a/src/kits/interface/Menu.cpp +++ b/src/kits/interface/Menu.cpp @@ -1044,15 +1044,17 @@ BMenu::_show(bool selectFirstItem) // See if the supermenu has a cached menuwindow, // and use that one if possible. BMenuWindow *window = NULL; - if (fSuper != NULL) + if (fSuper != NULL) { window = fSuper->MenuWindow(); - + if (window != NULL) + window->SetMenu(this); + } // Otherwise, create a new one // Actually, I think this can only happen for // "stand alone" BPopUpMenus (i.e. not within a BMenuField) if (window == NULL) { // Menu windows get the BMenu's handler name - window = new BMenuWindow(Name()); + window = new BMenuWindow(Name(), this); } if (window == NULL) @@ -1572,7 +1574,7 @@ BMenu::MenuWindow() if (fCachedMenuWindow == NULL) { char windowName[64]; snprintf(windowName, 64, "%s cached menuwindow\n", Name()); - fCachedMenuWindow = new BMenuWindow(windowName); + fCachedMenuWindow = new BMenuWindow(windowName, this); } return fCachedMenuWindow; @@ -1807,7 +1809,12 @@ BMenu::UpdateWindowViewSize(bool upWind) BRect frame = CalcFrame(ScreenLocation(), &scroll); ResizeTo(frame.Width(), frame.Height()); - window->ResizeTo(Bounds().Width() + 2, Bounds().Height() + 2); + if (fItems.CountItems() > 0) + window->ResizeTo(Bounds().Width() + 2, Bounds().Height() + 2); + else { + CacheFontInfo(); + window->ResizeTo(StringWidth("") + 4, fFontHeight + 6); + } window->MoveTo(frame.LeftTop()); } diff --git a/src/kits/interface/MenuWindow.cpp b/src/kits/interface/MenuWindow.cpp index dcb9aabc3d..6011d63439 100644 --- a/src/kits/interface/MenuWindow.cpp +++ b/src/kits/interface/MenuWindow.cpp @@ -36,14 +36,17 @@ const window_feel kMenuWindowFeel = (window_feel)1025; // This draws the frame around the BMenu class BMenuFrame : public BView { public: - BMenuFrame() ; + BMenuFrame(BMenu *menu) ; virtual void AttachedToWindow(); virtual void Draw(BRect updateRect); + +private: + BMenu *fMenu; }; -BMenuWindow::BMenuWindow(const char *name) +BMenuWindow::BMenuWindow(const char *name, BMenu *menu) : // The window will be resized by BMenu, so just pass a dummy rect //BWindow(BRect(0, 0, 0, 0), name, B_BORDERED_WINDOW_LOOK, kMenuWindowFeel, @@ -53,8 +56,7 @@ BMenuWindow::BMenuWindow(const char *name) fUpperScroller(NULL), fLowerScroller(NULL) { - BMenuFrame *menuFrame = new BMenuFrame(); - AddChild(menuFrame); + SetMenu(menu); } @@ -63,10 +65,21 @@ BMenuWindow::~BMenuWindow() } +void +BMenuWindow::SetMenu(BMenu *menu) +{ + if (CountChildren() > 0) + RemoveChild(ChildAt(0)); + BMenuFrame *menuFrame = new BMenuFrame(menu); + AddChild(menuFrame); +} + + // BMenuFrame -BMenuFrame::BMenuFrame() +BMenuFrame::BMenuFrame(BMenu *menu) : - BView(BRect(0, 0, 1, 1), "menu frame", B_FOLLOW_ALL_SIDES, B_WILL_DRAW) + BView(BRect(0, 0, 1, 1), "menu frame", B_FOLLOW_ALL_SIDES, B_WILL_DRAW), + fMenu(menu) { } @@ -82,9 +95,18 @@ BMenuFrame::AttachedToWindow() void BMenuFrame::Draw(BRect updateRect) { + if (fMenu->CountItems() == 0) { + SetHighColor(ui_color(B_MENU_BACKGROUND_COLOR)); + FillRect(updateRect); + font_height height; + fMenu->GetFontHeight(&height); + fMenu->SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DISABLED_LABEL_TINT)); + // TODO: This doesn't get drawn for some reason + fMenu->DrawString("", BPoint(2, ceilf(height.ascent + 2))); + } + + SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_2_TINT)); BRect bounds(Bounds()); - - SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_2_TINT)); StrokeLine(BPoint(bounds.right, bounds.top), BPoint(bounds.right, bounds.bottom - 1)); StrokeLine(BPoint(bounds.left + 1, bounds.bottom),