Live updating menu classes listen for B_MODIFIERS_CHANGED messages and update the item label and shortcut on Shift or Control. -- File -- Create link => Create relative link Move to Trash => Delete Cut => Cut more Copy => Copy more Paste => Paste links Identify => Force identify -- Window -- Close => Close all Open parent enable/disable on Control to open root window -- Window => Arrange by/Desktop -- Clean up => Clean up all Create TLiveMenu and TLivePopUpMenu classes that inherit from BMenu and BPopUpMenu respectively. Create TLiveFileMenu, TLivePosePopUpMenu, TLiveWindowMenu and TLiveWindowPopUpMenu subclasses for the File and Window menu and context menus respectively. Create TLiveMixin to share methods between menus. Pass in parent window and use window shortcuts to enable/disable "Open parent". Change-Id: I5dfbd4d468fad02894f1f31aa08d1abf630a4b5d Reviewed-on: https://review.haiku-os.org/c/haiku/+/2293 Reviewed-by: John Scipione <[email protected]>
310 lines
5.0 KiB
C++
310 lines
5.0 KiB
C++
/*
|
|
* Copyright 2020-2024 Haiku, Inc. All rights reserved.
|
|
* Distributed under the terms of the MIT License.
|
|
*
|
|
* Authors:
|
|
* John Scipione, [email protected]
|
|
*/
|
|
|
|
|
|
#include "LiveMenu.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include <Application.h>
|
|
#include <Locale.h>
|
|
#include <MenuItem.h>
|
|
#include <Window.h>
|
|
|
|
#include "Commands.h"
|
|
#include "TrackerSettings.h"
|
|
|
|
|
|
// #pragma mark - TLiveMixin
|
|
|
|
|
|
TLiveMixin::TLiveMixin(const BContainerWindow* window)
|
|
{
|
|
fWindow = window;
|
|
}
|
|
|
|
|
|
void
|
|
TLiveMixin::UpdateFileMenu(BMenu* menu)
|
|
{
|
|
if (menu == NULL)
|
|
return;
|
|
|
|
if (menu->Window()->LockLooper()) {
|
|
int32 itemCount = menu->CountItems();
|
|
for (int32 index = 0; index < itemCount; index++) {
|
|
BMenuItem* item = menu->ItemAt(index);
|
|
if (item == NULL || item->Message() == NULL)
|
|
continue;
|
|
|
|
switch (item->Message()->what) {
|
|
// Move to Trash/Delete
|
|
case kMoveSelectionToTrash:
|
|
case kDeleteSelection:
|
|
if (!fWindow->Shortcuts()->IsTrash())
|
|
fWindow->Shortcuts()->UpdateMoveToTrashItem(item);
|
|
break;
|
|
|
|
// Create link/Create relative link
|
|
case kCreateLink:
|
|
case kCreateRelativeLink:
|
|
fWindow->Shortcuts()->UpdateCreateLinkItem(item);
|
|
break;
|
|
|
|
// Cut/Cut more
|
|
case B_CUT:
|
|
case kCutMoreSelectionToClipboard:
|
|
fWindow->Shortcuts()->UpdateCutItem(item);
|
|
break;
|
|
|
|
// Copy/Copy more
|
|
case B_COPY:
|
|
case kCopyMoreSelectionToClipboard:
|
|
fWindow->Shortcuts()->UpdateCopyItem(item);
|
|
break;
|
|
|
|
// Paste/Paste links
|
|
case B_PASTE:
|
|
case kPasteLinksFromClipboard:
|
|
fWindow->Shortcuts()->UpdatePasteItem(item);
|
|
break;
|
|
|
|
// Identify/Force identify
|
|
case kIdentifyEntry:
|
|
fWindow->Shortcuts()->UpdateIdentifyItem(item);
|
|
break;
|
|
}
|
|
}
|
|
|
|
menu->Window()->UnlockLooper();
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
TLiveMixin::UpdateWindowMenu(BMenu* menu)
|
|
{
|
|
if (menu == NULL)
|
|
return;
|
|
|
|
// update using the window version of TShortcuts class
|
|
|
|
if (menu->Window()->LockLooper()) {
|
|
int32 itemCount = menu->CountItems();
|
|
for (int32 index = 0; index < itemCount; index++) {
|
|
BMenuItem* item = menu->ItemAt(index);
|
|
if (item == NULL || item->Message() == NULL)
|
|
continue;
|
|
|
|
switch (item->Message()->what) {
|
|
// Clean up/Clean up all
|
|
case kCleanup:
|
|
case kCleanupAll:
|
|
fWindow->Shortcuts()->UpdateCleanupItem(item);
|
|
break;
|
|
|
|
// Open parent
|
|
case kOpenParentDir:
|
|
fWindow->Shortcuts()->UpdateOpenParentItem(item);
|
|
break;
|
|
|
|
// Close/Close all
|
|
case B_QUIT_REQUESTED:
|
|
case kCloseAllWindows:
|
|
fWindow->Shortcuts()->UpdateCloseItem(item);
|
|
break;
|
|
}
|
|
}
|
|
|
|
menu->Window()->UnlockLooper();
|
|
}
|
|
}
|
|
|
|
|
|
// #pragma mark - TLiveMenu
|
|
|
|
|
|
TLiveMenu::TLiveMenu(const char* label)
|
|
:
|
|
BMenu(label)
|
|
{
|
|
}
|
|
|
|
|
|
TLiveMenu::~TLiveMenu()
|
|
{
|
|
}
|
|
|
|
|
|
void
|
|
TLiveMenu::MessageReceived(BMessage* message)
|
|
{
|
|
if (message != NULL && message->what == B_MODIFIERS_CHANGED)
|
|
Update();
|
|
else
|
|
BMenu::MessageReceived(message);
|
|
}
|
|
|
|
|
|
void
|
|
TLiveMenu::Update()
|
|
{
|
|
// hook method
|
|
}
|
|
|
|
|
|
// #pragma mark - TLivePopUpMenu
|
|
|
|
|
|
TLivePopUpMenu::TLivePopUpMenu(const char* label, bool radioMode, bool labelFromMarked,
|
|
menu_layout layout)
|
|
:
|
|
BPopUpMenu(label, radioMode, labelFromMarked, layout)
|
|
{
|
|
}
|
|
|
|
|
|
TLivePopUpMenu::~TLivePopUpMenu()
|
|
{
|
|
}
|
|
|
|
|
|
void
|
|
TLivePopUpMenu::MessageReceived(BMessage* message)
|
|
{
|
|
if (message != NULL && message->what == B_MODIFIERS_CHANGED)
|
|
Update();
|
|
else
|
|
BMenu::MessageReceived(message);
|
|
}
|
|
|
|
|
|
void
|
|
TLivePopUpMenu::Update()
|
|
{
|
|
// hook method
|
|
}
|
|
|
|
|
|
// #pragma mark - TLiveArrangeByMenu
|
|
|
|
|
|
TLiveArrangeByMenu::TLiveArrangeByMenu(const char* label, const BContainerWindow* window)
|
|
:
|
|
TLiveMenu(label),
|
|
TLiveMixin(window)
|
|
{
|
|
}
|
|
|
|
|
|
TLiveArrangeByMenu::~TLiveArrangeByMenu()
|
|
{
|
|
}
|
|
|
|
|
|
void
|
|
TLiveArrangeByMenu::Update()
|
|
{
|
|
// Clean up/Clean up all
|
|
TShortcuts().UpdateCleanupItem(TShortcuts().FindItem(this, kCleanup, kCleanupAll));
|
|
}
|
|
|
|
|
|
// #pragma mark - TLiveFileMenu
|
|
|
|
|
|
TLiveFileMenu::TLiveFileMenu(const char* label, const BContainerWindow* window)
|
|
:
|
|
TLiveMenu(label),
|
|
TLiveMixin(window)
|
|
{
|
|
}
|
|
|
|
|
|
TLiveFileMenu::~TLiveFileMenu()
|
|
{
|
|
}
|
|
|
|
|
|
void
|
|
TLiveFileMenu::Update()
|
|
{
|
|
UpdateFileMenu(this);
|
|
}
|
|
|
|
|
|
// #pragma mark - TLivePosePopUpMenu
|
|
|
|
|
|
TLivePosePopUpMenu::TLivePosePopUpMenu(const char* label, const BContainerWindow* window,
|
|
bool radioMode, bool labelFromMarked, menu_layout layout)
|
|
:
|
|
TLivePopUpMenu(label, radioMode, labelFromMarked, layout),
|
|
TLiveMixin(window)
|
|
{
|
|
}
|
|
|
|
|
|
TLivePosePopUpMenu::~TLivePosePopUpMenu()
|
|
{
|
|
}
|
|
|
|
|
|
void
|
|
TLivePosePopUpMenu::Update()
|
|
{
|
|
UpdateFileMenu(this);
|
|
}
|
|
|
|
|
|
// #pragma mark - TLiveWindowMenu
|
|
|
|
|
|
TLiveWindowMenu::TLiveWindowMenu(const char* label, const BContainerWindow* window)
|
|
:
|
|
TLiveMenu(label),
|
|
TLiveMixin(window)
|
|
{
|
|
}
|
|
|
|
|
|
TLiveWindowMenu::~TLiveWindowMenu()
|
|
{
|
|
}
|
|
|
|
|
|
void
|
|
TLiveWindowMenu::Update()
|
|
{
|
|
UpdateWindowMenu(this);
|
|
}
|
|
|
|
|
|
// #pragma mark - TLiveWindowPopUpMenu
|
|
|
|
|
|
TLiveWindowPopUpMenu::TLiveWindowPopUpMenu(const char* label, const BContainerWindow* window,
|
|
bool radioMode, bool labelFromMarked, menu_layout layout)
|
|
:
|
|
TLivePopUpMenu(label, radioMode, labelFromMarked, layout),
|
|
TLiveMixin(window)
|
|
{
|
|
}
|
|
|
|
|
|
TLiveWindowPopUpMenu::~TLiveWindowPopUpMenu()
|
|
{
|
|
}
|
|
|
|
|
|
void
|
|
TLiveWindowPopUpMenu::Update()
|
|
{
|
|
UpdateWindowMenu(this);
|
|
}
|