Add the standard OS X "Window" menu
This commit is contained in:
parent
cac4ba910d
commit
9bbfdddde0
7 changed files with 133 additions and 5 deletions
|
@ -265,6 +265,41 @@ struct app_updates final : public Command {
|
|||
}
|
||||
};
|
||||
|
||||
#ifdef __WXMAC__
|
||||
struct app_minimize final : public Command {
|
||||
CMD_NAME("app/minimize")
|
||||
STR_MENU("Minimize")
|
||||
STR_DISP("Minimize")
|
||||
STR_HELP("Minimize the active window")
|
||||
|
||||
void operator()(agi::Context *c) override {
|
||||
c->frame->Iconize();
|
||||
}
|
||||
};
|
||||
|
||||
struct app_maximize final : public Command {
|
||||
CMD_NAME("app/maximize")
|
||||
STR_MENU("Zoom")
|
||||
STR_DISP("Zoom")
|
||||
STR_HELP("Maximize the active window")
|
||||
|
||||
void operator()(agi::Context *c) override {
|
||||
c->frame->Maximize(!c->frame->IsMaximized());
|
||||
}
|
||||
};
|
||||
|
||||
struct app_bring_to_front final : public Command {
|
||||
CMD_NAME("app/bring_to_front")
|
||||
STR_MENU("Bring All to Front")
|
||||
STR_DISP("Bring All to Front")
|
||||
STR_HELP("Bring forward all open documents to the front")
|
||||
|
||||
void operator()(agi::Context *) override {
|
||||
osx::bring_to_front();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
namespace cmd {
|
||||
|
@ -281,6 +316,11 @@ namespace cmd {
|
|||
reg(agi::make_unique<app_options>());
|
||||
reg(agi::make_unique<app_toggle_global_hotkeys>());
|
||||
reg(agi::make_unique<app_toggle_toolbar>());
|
||||
#ifdef __WXMAC__
|
||||
reg(agi::make_unique<app_minimize>());
|
||||
reg(agi::make_unique<app_maximize>());
|
||||
reg(agi::make_unique<app_bring_to_front>());
|
||||
#endif
|
||||
#ifdef WITH_UPDATE_CHECKER
|
||||
reg(agi::make_unique<app_updates>());
|
||||
#endif
|
||||
|
|
|
@ -47,6 +47,11 @@ namespace {
|
|||
{nullptr}
|
||||
};
|
||||
|
||||
const char *added_hotkeys_minimize[][3] = {
|
||||
{"app/minimize", "Default", "Ctrl-M"},
|
||||
{nullptr}
|
||||
};
|
||||
|
||||
void migrate_hotkeys(const char *added[][3]) {
|
||||
auto hk_map = hotkey::inst->GetHotkeyMap();
|
||||
bool changed = false;
|
||||
|
@ -109,6 +114,13 @@ void init() {
|
|||
migrations.emplace_back("duplicate -> split");
|
||||
}
|
||||
|
||||
#ifdef __WXMAC__
|
||||
if (boost::find(migrations, "app/minimize") == end(migrations)) {
|
||||
migrate_hotkeys(added_hotkeys_minimize);
|
||||
migrations.emplace_back("app/minimize");
|
||||
}
|
||||
#endif
|
||||
|
||||
OPT_SET("App/Hotkey Migrations")->SetListString(std::move(migrations));
|
||||
}
|
||||
|
||||
|
|
|
@ -107,6 +107,9 @@
|
|||
]
|
||||
},
|
||||
"Default" : {
|
||||
"app/minimize" : [
|
||||
"Ctrl-M"
|
||||
],
|
||||
"app/exit" : [
|
||||
"Ctrl-Q"
|
||||
],
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
{ "submenu" : "main/video", "text" : "&Video" },
|
||||
{ "submenu" : "main/audio", "text" : "&Audio" },
|
||||
{ "special" : "automation", "text" : "A&utomation" },
|
||||
{ "submenu" : "main/window", "text" : "Window" },
|
||||
{ "submenu" : "main/help", "text" : "&Help", "special" : "help" }
|
||||
],
|
||||
"main/file" : [
|
||||
|
@ -200,6 +201,14 @@
|
|||
{},
|
||||
{ "command" : "app/toggle/toolbar" }
|
||||
],
|
||||
"main/window" : [
|
||||
{ "command" : "app/minimize" },
|
||||
{ "command" : "app/maximize" },
|
||||
{},
|
||||
{ "command" : "app/bring_to_front" },
|
||||
{},
|
||||
{ "special" : "window" }
|
||||
],
|
||||
"main/help" : [
|
||||
{ "command" : "help/contents" },
|
||||
{},
|
||||
|
|
39
src/menu.cpp
39
src/menu.cpp
|
@ -27,6 +27,7 @@
|
|||
#include "format.h"
|
||||
#include "libresrc/libresrc.h"
|
||||
#include "options.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <libaegisub/cajun/reader.h>
|
||||
#include <libaegisub/hotkey.h>
|
||||
|
@ -170,6 +171,10 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
void SetContext(agi::Context *c) {
|
||||
context = c;
|
||||
}
|
||||
|
||||
int AddCommand(cmd::Command *co, wxMenu *parent, std::string const& text = "") {
|
||||
return AddCommand(co, parent, text.empty() ? co->StrMenu(context) : _(to_wx(text)));
|
||||
}
|
||||
|
@ -229,6 +234,8 @@ public:
|
|||
}
|
||||
|
||||
void OnMenuOpen(wxMenuEvent &) {
|
||||
if (!context)
|
||||
return;
|
||||
for (auto const& item : dynamic_items) UpdateItem(item);
|
||||
for (auto item : mru) item->Update();
|
||||
}
|
||||
|
@ -237,7 +244,7 @@ public:
|
|||
// This also gets clicks on unrelated things such as the toolbar, so
|
||||
// the window ID ranges really need to be unique
|
||||
size_t id = static_cast<size_t>(evt.GetId() - MENU_ID_BASE);
|
||||
if (id < items.size())
|
||||
if (id < items.size() && context)
|
||||
cmd::call(items[id], context);
|
||||
|
||||
#ifdef __WXMAC__
|
||||
|
@ -336,6 +343,11 @@ void process_menu_item(wxMenu *parent, agi::Context *c, json::Object const& ele,
|
|||
std::string submenu, recent, command, text, special;
|
||||
read_entry(ele, "special", &special);
|
||||
|
||||
#ifdef __WXMAC__
|
||||
if (special == "window")
|
||||
osx::make_windows_menu(parent);
|
||||
#endif
|
||||
|
||||
if (read_entry(ele, "submenu", &submenu) && read_entry(ele, "text", &text)) {
|
||||
wxString tl_text = _(to_wx(text));
|
||||
parent->AppendSubMenu(build_menu(submenu, c, cm), tl_text);
|
||||
|
@ -487,6 +499,21 @@ public:
|
|||
|
||||
namespace menu {
|
||||
void GetMenuBar(std::string const& name, wxFrame *window, agi::Context *c) {
|
||||
#ifdef __WXMAC__
|
||||
auto bind_events = [&](CommandMenuBar *menu) {
|
||||
window->Bind(wxEVT_ACTIVATE, [=](wxActivateEvent&) { menu->cm.SetContext(c); });
|
||||
window->Bind(wxEVT_DESTROY, [=](wxWindowDestroyEvent&) {
|
||||
if (!osx::activate_top_window_other_than(window))
|
||||
menu->cm.SetContext(nullptr);
|
||||
});
|
||||
};
|
||||
|
||||
if (wxMenuBar *menu = wxMenuBar::MacGetCommonMenuBar()) {
|
||||
bind_events(static_cast<CommandMenuBar *>(menu));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto menu = agi::make_unique<CommandMenuBar>(c);
|
||||
for (auto const& item : get_menu(name)) {
|
||||
std::string submenu, disp;
|
||||
|
@ -502,9 +529,15 @@ namespace menu {
|
|||
}
|
||||
}
|
||||
|
||||
window->Bind(wxEVT_MENU_OPEN, &CommandManager::OnMenuOpen, &menu->cm);
|
||||
window->Bind(wxEVT_MENU, &CommandManager::OnMenuClick, &menu->cm);
|
||||
menu->Bind(wxEVT_MENU_OPEN, &CommandManager::OnMenuOpen, &menu->cm);
|
||||
menu->Bind(wxEVT_MENU, &CommandManager::OnMenuClick, &menu->cm);
|
||||
|
||||
#ifdef __WXMAC__
|
||||
bind_events(menu.get());
|
||||
wxMenuBar::MacSetCommonMenuBar(menu.get());
|
||||
#else
|
||||
window->SetMenuBar(menu.get());
|
||||
#endif
|
||||
|
||||
menu.release();
|
||||
}
|
||||
|
|
|
@ -66,3 +66,25 @@ void RestartAegisub() {
|
|||
[NSTask launchedTaskWithLaunchPath:helperPath
|
||||
arguments:@[NSBundle.mainBundle.executablePath]];
|
||||
}
|
||||
|
||||
namespace osx {
|
||||
void make_windows_menu(wxMenu* wxmenu) {
|
||||
NSApp.windowsMenu = wxmenu->GetHMenu();
|
||||
}
|
||||
|
||||
bool activate_top_window_other_than(wxFrame *wx) {
|
||||
NSWindow *w = wx->GetWXWindow();
|
||||
for (NSNumber *windowNumber in [NSWindow windowNumbersWithOptions:0]) {
|
||||
NSWindow *window = [NSApp windowWithWindowNumber:windowNumber.integerValue];
|
||||
if (window && window.canBecomeMainWindow && window != w) {
|
||||
[window makeMainWindow];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void bring_to_front() {
|
||||
[NSApp arrangeInFront:nil];
|
||||
}
|
||||
}
|
||||
|
|
13
src/utils.h
13
src/utils.h
|
@ -99,11 +99,20 @@ agi::fs::path SaveFileSelector(wxString const& message, std::string const& optio
|
|||
|
||||
wxString LocalizedLanguageName(wxString const& lang);
|
||||
|
||||
namespace osx { namespace ime {
|
||||
namespace osx {
|
||||
/// Make the given menu the OS X Window menu
|
||||
void make_windows_menu(wxMenu *wxmenu);
|
||||
/// Activate a top-level document window other than the given one
|
||||
bool activate_top_window_other_than(wxFrame *wx);
|
||||
// Bring all windows to the front, maintaining relative z-order
|
||||
void bring_to_front();
|
||||
|
||||
namespace ime {
|
||||
/// Inject the IME helper into the given wxSTC
|
||||
void inject(wxStyledTextCtrl *ctrl);
|
||||
/// Invalidate any pending text from the IME
|
||||
void invalidate(wxStyledTextCtrl *ctrl);
|
||||
/// Give the IME a chance to process a key event and return whether it did
|
||||
bool process_key_event(wxStyledTextCtrl *ctrl, wxKeyEvent &);
|
||||
} }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue