1// Aseprite
2// Copyright (C) 2019-2020 Igara Studio S.A.
3// Copyright (C) 2001-2018 David Capello
4//
5// This program is distributed under the terms of
6// the End-User License Agreement for Aseprite.
7
8#ifndef APP_APP_MENUS_H_INCLUDED
9#define APP_APP_MENUS_H_INCLUDED
10#pragma once
11
12#include "app/i18n/xml_translator.h"
13#include "app/ui/key.h"
14#include "app/widget_type_mismatch.h"
15#include "base/disable_copying.h"
16#include "obs/connection.h"
17#include "os/menus.h"
18#include "ui/base.h"
19#include "ui/menu.h"
20
21#include <memory>
22
23class TiXmlElement;
24class TiXmlHandle;
25
26namespace app {
27 class Command;
28 class Params;
29
30 using namespace ui;
31
32 // Class to handle/get/reload available menus in gui.xml file.
33 class AppMenus {
34 AppMenus();
35 DISABLE_COPYING(AppMenus);
36
37 public:
38 static AppMenus* instance();
39
40 void reload();
41 void initTheme();
42
43 // Updates the menu of recent files.
44 bool rebuildRecentList();
45
46 Menu* getRootMenu() { return m_rootMenu.get(); }
47 Menu* getTabPopupMenu() { return m_tabPopupMenu.get(); }
48 Menu* getDocumentTabPopupMenu() { return m_documentTabPopupMenu.get(); }
49 Menu* getLayerPopupMenu() { return m_layerPopupMenu.get(); }
50 Menu* getFramePopupMenu() { return m_framePopupMenu.get(); }
51 Menu* getCelPopupMenu() { return m_celPopupMenu.get(); }
52 Menu* getCelMovementPopupMenu() { return m_celMovementPopupMenu.get(); }
53 Menu* getTagPopupMenu() { return m_tagPopupMenu.get(); }
54 Menu* getSlicePopupMenu() { return m_slicePopupMenu.get(); }
55 Menu* getPalettePopupMenu() { return m_palettePopupMenu.get(); }
56 Menu* getInkPopupMenu() { return m_inkPopupMenu.get(); }
57
58 void applyShortcutToMenuitemsWithCommand(Command* command, const Params& params,
59 const KeyPtr& key);
60 void syncNativeMenuItemKeyShortcuts();
61
62 // Menu item handling in groups
63 void addMenuItemIntoGroup(const std::string& groupId,
64 std::unique_ptr<MenuItem>&& menuItem);
65 void removeMenuItemFromGroup(Command* cmd);
66 void removeMenuItemFromGroup(Widget* menuItem);
67
68 private:
69 template<typename Pred>
70 void removeMenuItemFromGroup(Pred pred);
71
72 Menu* loadMenuById(TiXmlHandle& handle, const char *id);
73 Menu* convertXmlelemToMenu(TiXmlElement* elem);
74 Widget* convertXmlelemToMenuitem(TiXmlElement* elem);
75 void applyShortcutToMenuitemsWithCommand(Menu* menu, Command* command, const Params& params,
76 const KeyPtr& key);
77 void syncNativeMenuItemKeyShortcuts(Menu* menu);
78 void updateMenusList();
79 void createNativeMenus();
80 void createNativeSubmenus(os::Menu* osMenu,
81 const ui::Menu* uiMenu);
82
83#ifdef ENABLE_SCRIPTING
84 void loadScriptsSubmenu(ui::Menu* menu,
85 const std::string& dir,
86 const bool rootLevel);
87#endif
88
89 struct GroupInfo {
90 Widget* end = nullptr;
91 WidgetsList items;
92 };
93
94 std::unique_ptr<Menu> m_rootMenu;
95 Widget* m_recentFilesPlaceholder;
96 MenuItem* m_helpMenuitem;
97 std::unique_ptr<Menu> m_tabPopupMenu;
98 std::unique_ptr<Menu> m_documentTabPopupMenu;
99 std::unique_ptr<Menu> m_layerPopupMenu;
100 std::unique_ptr<Menu> m_framePopupMenu;
101 std::unique_ptr<Menu> m_celPopupMenu;
102 std::unique_ptr<Menu> m_celMovementPopupMenu;
103 std::unique_ptr<Menu> m_tagPopupMenu;
104 std::unique_ptr<Menu> m_slicePopupMenu;
105 std::unique_ptr<Menu> m_palettePopupMenu;
106 std::unique_ptr<Menu> m_inkPopupMenu;
107 obs::scoped_connection m_recentFilesConn;
108 std::vector<Menu*> m_menus;
109 // List of recent menu items pointing to recent files.
110 WidgetsList m_recentMenuItems;
111 // Extension points for plugins (each group is a place where new
112 // menu items can be added).
113 std::map<std::string, GroupInfo> m_groups;
114 // Native main menu bar (== nullptr if the platform doesn't
115 // support native menus)
116 os::MenuRef m_osMenu;
117 XmlTranslator m_xmlTranslator;
118 };
119
120 os::Shortcut get_os_shortcut_from_key(const Key* key);
121
122} // namespace app
123
124#endif
125