From 82a54995b5e7938312a398632feae2852cd7eb9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 7 Nov 2007 14:24:09 +0000 Subject: [PATCH] * Fixed _ComputeColumnLayout() optimization introduced in r22658: it actually never worked correctly for any case which was very visible in Tracker (and especially so if you had "sorting apps" turned on). * Removed superfluous white space at the end of lines. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22850 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/interface/Menu.cpp | 213 ++++++++++++++++++------------------ 1 file changed, 109 insertions(+), 104 deletions(-) diff --git a/src/kits/interface/Menu.cpp b/src/kits/interface/Menu.cpp index 9550d5496c..dc1e7ef3d1 100644 --- a/src/kits/interface/Menu.cpp +++ b/src/kits/interface/Menu.cpp @@ -77,12 +77,12 @@ bool BMenu::sAltAsCommandKey; static property_info sPropList[] = { { "Enabled", { B_GET_PROPERTY, 0 }, { B_DIRECT_SPECIFIER, 0 }, "Returns true if menu or menu item is enabled; false " - "otherwise.", + "otherwise.", 0, { B_BOOL_TYPE } }, { "Enabled", { B_SET_PROPERTY, 0 }, - { B_DIRECT_SPECIFIER, 0 }, "Enables or disables menu or menu item.", + { B_DIRECT_SPECIFIER, 0 }, "Enables or disables menu or menu item.", 0, { B_BOOL_TYPE } }, @@ -98,7 +98,7 @@ static property_info sPropList[] = { { "Mark", { B_GET_PROPERTY, 0 }, { B_DIRECT_SPECIFIER, 0 }, "Returns true if the menu item or the menu's superitem " - "is marked; false otherwise.", + "is marked; false otherwise.", 0, { B_BOOL_TYPE } }, @@ -111,9 +111,9 @@ static property_info sPropList[] = { { B_NAME_SPECIFIER, B_INDEX_SPECIFIER, B_REVERSE_INDEX_SPECIFIER, 0 }, "Adds a new menu item at the specified index with the text label found in \"data\" " "and the int32 command found in \"what\" (used as the what field in the CMessage " - "sent by the item)." , 0, {}, + "sent by the item)." , 0, {}, { {{{"data", B_STRING_TYPE}}} - } + } }, { "Menu", { B_DELETE_PROPERTY, 0 }, @@ -136,7 +136,7 @@ static property_info sPropList[] = { { B_NAME_SPECIFIER, B_INDEX_SPECIFIER, B_REVERSE_INDEX_SPECIFIER, 0 }, "Adds a new menu item at the specified index with the text label found in \"data\" " "and the int32 command found in \"what\" (used as the what field in the CMessage " - "sent by the item).", 0, {}, + "sent by the item).", 0, {}, { { {{"data", B_STRING_TYPE }, {"be:invoke_message", B_MESSAGE_TYPE}, {"what", B_INT32_TYPE}, @@ -146,18 +146,18 @@ static property_info sPropList[] = { { "MenuItem", { B_DELETE_PROPERTY, 0 }, { B_NAME_SPECIFIER, B_INDEX_SPECIFIER, B_REVERSE_INDEX_SPECIFIER, 0 }, - "Removes the specified menu item from its parent menu." + "Removes the specified menu item from its parent menu." }, { "MenuItem", { B_EXECUTE_PROPERTY, 0 }, { B_NAME_SPECIFIER, B_INDEX_SPECIFIER, B_REVERSE_INDEX_SPECIFIER, 0 }, - "Invokes the specified menu item." + "Invokes the specified menu item." }, { "MenuItem", { }, { B_NAME_SPECIFIER, B_INDEX_SPECIFIER, B_REVERSE_INDEX_SPECIFIER, 0 }, "Directs scripting message to the specified menu, first popping the current " - "specifier off the stack." + "specifier off the stack." }, {} @@ -244,7 +244,7 @@ BMenu::~BMenu() _DeleteMenuWindow(); RemoveItems(0, CountItems(), true); - + delete fInitMatrixSize; delete fExtraMenuData; delete fLayoutData; @@ -339,8 +339,8 @@ BMenu::AttachedToWindow() BView::AttachedToWindow(); sAltAsCommandKey = true; - key_map *keys = NULL; - char *chars = NULL; + key_map *keys = NULL; + char *chars = NULL; get_key_map(&keys, &chars); if (keys == NULL || keys->left_command_key != 0x5d || keys->right_command_key != 0x5f) @@ -398,7 +398,7 @@ BMenu::AddItem(BMenuItem *item, int32 index) _LayoutItems(index); _UpdateWindowViewSize(false); Invalidate(); - } + } UnlockLooper(); } return true; @@ -411,10 +411,10 @@ BMenu::AddItem(BMenuItem *item, BRect frame) if (fLayout != B_ITEMS_IN_MATRIX) debugger("BMenu::AddItem(BMenuItem *, BRect) this method can only " "be called if the menu layout is B_ITEMS_IN_MATRIX"); - + if (!item) return false; - + item->fBounds = frame; int32 index = CountItems(); @@ -426,7 +426,7 @@ BMenu::AddItem(BMenuItem *item, BRect frame) if (!Window()->IsHidden()) { _LayoutItems(index); Invalidate(); - } + } UnlockLooper(); } @@ -434,13 +434,13 @@ BMenu::AddItem(BMenuItem *item, BRect frame) } -bool +bool BMenu::AddItem(BMenu *submenu) { BMenuItem *item = new (nothrow) BMenuItem(submenu); if (!item) return false; - + if (!AddItem(item, CountItems())) { item->fSubmenu = NULL; delete item; @@ -461,7 +461,7 @@ BMenu::AddItem(BMenu *submenu, int32 index) BMenuItem *item = new (nothrow) BMenuItem(submenu); if (!item) return false; - + if (!AddItem(item, index)) { item->fSubmenu = NULL; delete item; @@ -478,7 +478,7 @@ BMenu::AddItem(BMenu *submenu, BRect frame) if (fLayout != B_ITEMS_IN_MATRIX) debugger("BMenu::AddItem(BMenu *, BRect) this method can only " "be called if the menu layout is B_ITEMS_IN_MATRIX"); - + BMenuItem *item = new (nothrow) BMenuItem(submenu); if (!item) return false; @@ -499,7 +499,7 @@ BMenu::AddList(BList *list, int32 index) // TODO: test this function, it's not documented in the bebook. if (list == NULL) return false; - + bool locked = LockLooper(); int32 numItems = list->CountItems(); @@ -510,13 +510,13 @@ BMenu::AddList(BList *list, int32 index) break; } } - + InvalidateLayout(); - if (locked && Window() != NULL && !Window()->IsHidden()) { + if (locked && Window() != NULL && !Window()->IsHidden()) { // Make sure we update the layout if needed. _LayoutItems(index); _UpdateWindowViewSize(false); - Invalidate(); + Invalidate(); } if (locked) @@ -660,7 +660,7 @@ BMenu::FindItem(uint32 command) const } -status_t +status_t BMenu::SetTargetForItems(BHandler *handler) { status_t status = B_OK; @@ -669,7 +669,7 @@ BMenu::SetTargetForItems(BHandler *handler) if (status < B_OK) break; } - + return status; } @@ -695,7 +695,7 @@ BMenu::SetEnabled(bool enabled) return; fEnabled = enabled; - + if (fSuperitem) fSuperitem->SetEnabled(enabled); } @@ -1030,18 +1030,18 @@ BMenu::GetSupportedSuites(BMessage *data) if (err < B_OK) return err; - + BPropertyInfo propertyInfo(sPropList); err = data->AddFlat("messages", &propertyInfo); if (err < B_OK) return err; - + return BView::GetSupportedSuites(data); } -status_t +status_t BMenu::Perform(perform_code d, void *arg) { return BView::Perform(d, arg); @@ -1157,13 +1157,13 @@ BMenu::Hide() BMenuItem * BMenu::Track(bool sticky, BRect *clickToOpenRect) -{ +{ if (sticky && LockLooper()) { //RedrawAfterSticky(Bounds()); // the call above didn't do anything, so I've removed it for now UnlockLooper(); } - + if (clickToOpenRect != NULL && LockLooper()) { fExtraRect = clickToOpenRect; ConvertFromScreen(fExtraRect); @@ -1172,10 +1172,10 @@ BMenu::Track(bool sticky, BRect *clickToOpenRect) int action; BMenuItem *menuItem = _Track(&action); - + _SetStickyMode(false); fExtraRect = NULL; - + return menuItem; } @@ -1277,7 +1277,7 @@ BMenu::_Show(bool selectFirstItem) fSuperbounds = fSuper->ConvertToScreen(fSuper->Bounds()); window = fSuper->_MenuWindow(); } - + // Otherwise, create a new one // This happens for "stand alone" BPopUpMenus // (i.e. not within a BMenuField) @@ -1330,11 +1330,11 @@ BMenu::_Hide() BMenuWindow *window = static_cast(Window()); if (window == NULL || !window->Lock()) return; - + if (fSelected != NULL) _SelectItem(NULL); - window->Hide(); + window->Hide(); window->DetachMenu(); // we don't want to be deleted when the window is removed @@ -1351,7 +1351,7 @@ BMenu::_Hide() const bigtime_t kHysteresis = 200000; // TODO: Test and reduce if needed. - + BMenuItem * BMenu::_Track(int *action, long start) @@ -1359,8 +1359,8 @@ BMenu::_Track(int *action, long start) // TODO: cleanup BMenuItem *item = NULL; bigtime_t openTime = system_time(); - bigtime_t closeTime = 0; - + bigtime_t closeTime = 0; + fState = MENU_STATE_TRACKING; if (fSuper != NULL) fSuper->fState = MENU_STATE_TRACKING_SUBMENU; @@ -1368,7 +1368,7 @@ BMenu::_Track(int *action, long start) while (true) { if (_CustomTrackingWantsToQuit()) break; - + bool locked = LockLooper(); if (!locked) break; @@ -1506,12 +1506,12 @@ BMenu::_UpdateStateClose(BMenuItem* item, const BPoint& where, for(; supermenu; supermenu = supermenu->Supermenu()) supermenu->_SetStickyMode(false); _SetStickyMode(false); - } + } } else if (buttons == 0 && !_IsStickyMode()) { if (fExtraRect != NULL && fExtraRect->Contains(where)) { _SetStickyMode(true); fExtraRect = NULL; - // This code should be executed only once + // This code should be executed only once } else fState = MENU_STATE_CLOSED; } @@ -1528,7 +1528,7 @@ BMenu::_AddItem(BMenuItem *item, int32 index) if (!fItems.AddItem(item, index)) return false; - // install the item on the supermenu's window + // install the item on the supermenu's window // or onto our window, if we are a root menu BWindow* window = NULL; if (Superitem() != NULL) @@ -1558,7 +1558,7 @@ BMenu::_RemoveItems(int32 index, int32 count, BMenuItem *item, bool deleteItems) if (fItems.RemoveItem(item)) { if (item == fSelected && window != NULL) _SelectItem(NULL); - item->Uninstall(); + item->Uninstall(); item->SetSuper(NULL); if (deleteItems) delete item; @@ -1652,9 +1652,8 @@ BMenu::_ComputeLayout(int32 index, bool bestFit, bool moveItems, // Recalculate only the needed items, // not the whole layout every time - BRect frame(0, 0, 0, 0); - if (index > 0) - frame = Bounds(); + BRect frame; + switch (fLayout) { case B_ITEMS_IN_COLUMN: _ComputeColumnLayout(index, bestFit, moveItems, frame); @@ -1665,7 +1664,7 @@ BMenu::_ComputeLayout(int32 index, bool bestFit, bool moveItems, break; case B_ITEMS_IN_MATRIX: - _ComputeMatrixLayout(frame); + _ComputeMatrixLayout(frame); break; default: @@ -1694,7 +1693,7 @@ BMenu::_ComputeLayout(int32 index, bool bestFit, bool moveItems, if (bestFit) fLayoutData->preferred = size; - + if (moveItems) fUseCachedMenuLayout = true; } @@ -1709,41 +1708,46 @@ BMenu::_ComputeColumnLayout(int32 index, bool bestFit, bool moveItems, bool command = false; bool control = false; bool shift = false; - for (int32 i = index; i < fItems.CountItems(); i++) { - BMenuItem *item = ItemAt(i); - if (item != NULL) { - float iWidth, iHeight; - item->GetContentSize(&iWidth, &iHeight); - if (item->fModifiers && item->fShortcutChar) { - iWidth += font.Size(); - if (item->fModifiers & B_COMMAND_KEY) - command = true; - if (item->fModifiers & B_CONTROL_KEY) - control = true; - if (item->fModifiers & B_SHIFT_KEY) - shift = true; - } + if (index > 0) + frame = ItemAt(index - 1)->Frame(); + else + frame.Set(0, 0, 0, 0); - item->fBounds.left = 0.0f; - item->fBounds.top = frame.bottom; - item->fBounds.bottom = item->fBounds.top + iHeight + fPad.top - + fPad.bottom; + for (; index < fItems.CountItems(); index++) { + BMenuItem *item = ItemAt(index); - iWidth += item->Frame().Height(); - - frame.right = max_c(frame.right, iWidth + fPad.left + fPad.right); - frame.bottom = item->fBounds.bottom + 1.0f; + float width, height; + item->GetContentSize(&width, &height); + + if (item->fModifiers && item->fShortcutChar) { + width += font.Size(); + if (item->fModifiers & B_COMMAND_KEY) + command = true; + if (item->fModifiers & B_CONTROL_KEY) + control = true; + if (item->fModifiers & B_SHIFT_KEY) + shift = true; } + + item->fBounds.left = 0.0f; + item->fBounds.top = frame.bottom + (index > 0 ? 1.0f : 0.0f); + item->fBounds.bottom = item->fBounds.top + height + fPad.top + + fPad.bottom; + + width += item->Frame().Height(); + + frame.right = max_c(frame.right, width + fPad.left + fPad.right); + frame.bottom = item->fBounds.bottom; } - + if (command) frame.right += 17; if (control) frame.right += 17; if (shift) - frame.right += 22; - + frame.right += 22; + if (fMaxContentWidth > 0) frame.right = min_c(frame.right, fMaxContentWidth); @@ -1751,8 +1755,9 @@ BMenu::_ComputeColumnLayout(int32 index, bool bestFit, bool moveItems, for (int32 i = 0; i < fItems.CountItems(); i++) ItemAt(i)->fBounds.right = frame.right; } + + frame.top = 0; frame.right = ceilf(frame.right); - frame.bottom--; } @@ -1762,28 +1767,28 @@ BMenu::_ComputeRowLayout(int32 index, bool bestFit, bool moveItems, { font_height fh; GetFontHeight(&fh); - frame = BRect(0.0f, 0.0f, 0.0f, ceilf(fh.ascent + fh.descent + fPad.top - + fPad.bottom)); + frame.Set(0.0f, 0.0f, 0.0f, ceilf(fh.ascent + fh.descent + fPad.top + + fPad.bottom)); for (int32 i = 0; i < fItems.CountItems(); i++) { BMenuItem *item = ItemAt(i); - float iWidth, iHeight; + float width, height; if (item != NULL) { - item->GetContentSize(&iWidth, &iHeight); + item->GetContentSize(&width, &height); item->fBounds.left = frame.right; item->fBounds.top = 0.0f; - item->fBounds.right = item->fBounds.left + iWidth + fPad.left + item->fBounds.right = item->fBounds.left + width + fPad.left + fPad.right; frame.right = item->Frame().right + 1.0f; - frame.bottom = max_c(frame.bottom, iHeight + fPad.top + fPad.bottom); + frame.bottom = max_c(frame.bottom, height + fPad.top + fPad.bottom); } } if (moveItems) { for (int32 i = 0; i < fItems.CountItems(); i++) - ItemAt(i)->fBounds.bottom = frame.bottom; + ItemAt(i)->fBounds.bottom = frame.bottom; } if (bestFit) @@ -1804,8 +1809,8 @@ BMenu::_ComputeMatrixLayout(BRect &frame) frame.right = max_c(frame.right, item->Frame().right); frame.top = min_c(frame.top, item->Frame().top); frame.bottom = max_c(frame.bottom, item->Frame().bottom); - } - } + } + } } @@ -1883,9 +1888,9 @@ BMenu::_CalcFrame(BPoint where, bool *scrollOn) frame.OffsetBy(0, screenFrame.bottom - frame.bottom); } else { if (frame.bottom > screenFrame.bottom) { - if (scrollOn != NULL && superMenu != NULL && - dynamic_cast(superMenu) != NULL && - frame.top < (screenFrame.bottom - 80)) { + if (scrollOn != NULL && superMenu != NULL + && dynamic_cast(superMenu) != NULL + && frame.top < (screenFrame.bottom - 80)) { *scrollOn = true; } else { frame.OffsetBy(0, -superItem->Frame().Height() - frame.Height() - 3); @@ -1907,7 +1912,7 @@ BMenu::_DrawItems(BRect updateRect) for (int32 i = 0; i < itemCount; i++) { BMenuItem *item = ItemAt(i); if (item->Frame().Intersects(updateRect)) - item->Draw(); + item->Draw(); } } @@ -1920,7 +1925,7 @@ BMenu::State(BMenuItem **item) const if (fSelected != NULL && fSelected->Submenu() != NULL) return fSelected->Submenu()->State(item); - + return fState; } @@ -1939,10 +1944,10 @@ BMenu::InvokeItem(BMenuItem *item, bool now) snooze(50000); item->Select(false); Sync(); - snooze(50000); + snooze(50000); item->Select(true); Sync(); - snooze(50000); + snooze(50000); item->Select(false); Sync(); UnlockLooper(); @@ -2077,15 +2082,15 @@ BMenu::_Uninstall() void BMenu::_SelectItem(BMenuItem* menuItem, bool showSubmenu, bool selectFirstItem) -{ +{ // Avoid deselecting and then reselecting the same item // which would cause flickering - if (menuItem != fSelected) { + if (menuItem != fSelected) { if (fSelected != NULL) { fSelected->Select(false); BMenu *subMenu = fSelected->Submenu(); if (subMenu != NULL && subMenu->Window() != NULL) - subMenu->_Hide(); + subMenu->_Hide(); } fSelected = menuItem; @@ -2106,7 +2111,7 @@ BMenu::_SelectItem(BMenuItem* menuItem, bool showSubmenu, bool selectFirstItem) } -bool +bool BMenu::_SelectNextItem(BMenuItem *item, bool forward) { BMenuItem *nextItem = _NextItem(item, forward); @@ -2141,7 +2146,7 @@ BMenu::_NextItem(BMenuItem *item, bool forward) const } -void +void BMenu::_SetIgnoreHidden(bool on) { fIgnoreHidden = on; @@ -2160,7 +2165,7 @@ BMenu::_SetStickyMode(bool on) menuBar->_StealFocus(); menuBar->UnlockLooper(); } - + fStickyMode = on; } @@ -2242,7 +2247,7 @@ BMenu::_ChooseTrigger(const char *title, int32& index, uint32& trigger, void BMenu::_UpdateWindowViewSize(bool updatePosition) { - BMenuWindow *window = static_cast(Window()); + BMenuWindow *window = static_cast(Window()); if (window == NULL) return; @@ -2270,7 +2275,7 @@ BMenu::_UpdateWindowViewSize(bool updatePosition) window->ResizeTo(Bounds().Width() + 2, screen.Frame().bottom); frame.top = 0; } else { - // Or, in case our parent was a BMenuBar enable scrolling with + // Or, in case our parent was a BMenuBar enable scrolling with // normal size. window->ResizeTo(Bounds().Width() + 2, screen.Frame().bottom - frame.top); @@ -2348,7 +2353,7 @@ set_menu_info(menu_info *info) BPrivate::AppServerLink link; link.StartMessage(AS_SET_MENU_INFO); link.Attach(*info); - + status_t status = B_ERROR; if (link.FlushWithReply(status) == B_OK && status == B_OK) BMenu::sMenuInfo = *info; @@ -2363,13 +2368,13 @@ get_menu_info(menu_info *info) { if (!info) return B_BAD_VALUE; - + BPrivate::AppServerLink link; link.StartMessage(AS_GET_MENU_INFO); - + status_t status = B_ERROR; if (link.FlushWithReply(status) == B_OK && status == B_OK) link.Read(info); - + return status; }