From 0a53cbb3b9a02fb374fcccca525cd99b5c78e7ed Mon Sep 17 00:00:00 2001 From: John Scipione Date: Sun, 1 Aug 2021 15:44:40 -0400 Subject: [PATCH] BMenu: Add SortItems(), SwapItems() and MoveItem() ... methods which call the respective methods in BList. These convinience methods allow you to sort a menu of menu items via a compare function, swap two menu items, or move a menu item to a new index. Update items layout if menu is open. Previously there was no easy way to rearrange menu items in a menu. Change-Id: Ice3d6e5404e895196d8bd32d696dce7c55bd72d4 Reviewed-on: https://review.haiku-os.org/c/haiku/+/4296 Reviewed-by: John Scipione Reviewed-by: waddlesplash Tested-by: Commit checker robot --- headers/os/interface/Menu.h | 6 +++++ src/kits/interface/Menu.cpp | 50 +++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/headers/os/interface/Menu.h b/headers/os/interface/Menu.h index 017cbe0242..1eae671881 100644 --- a/headers/os/interface/Menu.h +++ b/headers/os/interface/Menu.h @@ -170,6 +170,12 @@ public: void SetTrackingHook(menu_tracking_hook hook, void* state); + // Reorder items + void SortItems(int (*compare)(const BMenuItem*, + const BMenuItem*)); + bool SwapItems(int32 indexA, int32 indexB); + bool MoveItem(int32 indexFrom, int32 indexTo); + private: friend class BMenuBar; friend class BSeparatorItem; diff --git a/src/kits/interface/Menu.cpp b/src/kits/interface/Menu.cpp index 0268733492..bfc7b1936e 100644 --- a/src/kits/interface/Menu.cpp +++ b/src/kits/interface/Menu.cpp @@ -1439,6 +1439,56 @@ BMenu::SetTrackingHook(menu_tracking_hook func, void* state) } +// #pragma mark - Reorder item methods + + +void +BMenu::SortItems(int (*compare)(const BMenuItem*, const BMenuItem*)) +{ + fItems.SortItems((int (*)(const void*, const void*))compare); + InvalidateLayout(); + if (Window() != NULL && !Window()->IsHidden() && LockLooper()) { + _LayoutItems(0); + Invalidate(); + UnlockLooper(); + } +} + + +bool +BMenu::SwapItems(int32 indexA, int32 indexB) +{ + bool swapped = fItems.SwapItems(indexA, indexB); + if (swapped) { + InvalidateLayout(); + if (Window() != NULL && !Window()->IsHidden() && LockLooper()) { + _LayoutItems(std::min(indexA, indexB)); + Invalidate(); + UnlockLooper(); + } + } + + return swapped; +} + + +bool +BMenu::MoveItem(int32 indexFrom, int32 indexTo) +{ + bool moved = fItems.MoveItem(indexFrom, indexTo); + if (moved) { + InvalidateLayout(); + if (Window() != NULL && !Window()->IsHidden() && LockLooper()) { + _LayoutItems(std::min(indexFrom, indexTo)); + Invalidate(); + UnlockLooper(); + } + } + + return moved; +} + + void BMenu::_ReservedMenu3() {} void BMenu::_ReservedMenu4() {} void BMenu::_ReservedMenu5() {}