EDIT: this was splitted from the original topic, labeled "Code::Blocks Menus and Shortcuts revamping"[/url].
These last couple of days, I 've been coding an initial implementation of an ActionsManager. I will now describe where I 'm at and listen to comments.
------------------
We have Actions. They can be constructed in one of two ways:
Action(int id, const Shortcut& shortcut);
// or
Action(const wxString& script, const Shortcut& shortcut);
All constructor arguments have default values, except the
script one.
This means that we can have two types of actions:
- Code actions. These are implemented as wx events, hence the required ID, so ActionsManager can call the correct event handler using the action's ID.
- Script actions. When launched, these actions load and run a script file.
The application can add Actions to ActionsManager in two ways:
Action action(idActionFileOpen);
action.description = _("Opens a file");
action.shortcut = Shortcut(AK_O, false, true, false); // args are: key, alt, ctrl, shift
ActionsManager::Get()->Add(_T("File.Open"), action); // add the action named as "File.Open"
// etc
- Many actions at once. For this, a special struct is provided:
ActionRegistrar actions[] =
{
{ _T("File.Open"), Action(idActionOpen, Shortcut(AK_O, false, true, false)) },
{ _T("App.Quit"), Action(idActionQuit, Shortcut(AK_Q, false, true, false)) },
{ _T("App.About"), Action(idActionAbout, Shortcut(AK_F1, false, false, false)) },
{ _T("App.Test"), Action(idActionTest) },
{ _T("App.Test2"), Action(idActionTest2) },
EndOfActionRegistrar // this just helps ActionsManager to see the end of this array
};
// register all actions at once
ActionsManager::Get()->Add(&actions[0]);
[/list]
Now that actions are registered, you can "launch" an action at any time using
ActionsManager::Get()->Launch(action_name).
Actions can be enabled/disabled using
ActionsManager::Get()->Enable(action_name, true|false). Automatically, all menu entries or toolbars bound to the specified action become enabled/disabled accordingly.
ActionsManager will offer all that is needed to create menubars, popup menus and toolbars. Only toolbars are not implemented yet.
ActionsManager* am = ActionsManager::Get();
// create main menubar layout
// add a "File" menu in "MainMenu"
int id = am->AddMenu(_T("MainMenu"), _("&File"));
// add "Open" entry (under "File") and bind to action "File.Open"
am->AddMenuEntry(id, _("&Open"), _T("File.Open"));
// just add a separator
am->AddMenuSeparator(id);
// add "Quit" entry and bind to action "App.Quit"
am->AddMenuEntry(id, _("&Quit"), _T("App.Quit"));
// ask ActionsManager for the "MainMenu" menubar
// it will be created on-the-fly
SetMenuBar(am->GetMenuBar(_T("MainMenu"));
// create a menu for the editor popup "EditorCtxMenu"
id = am->AddMenu(_T("EditorCtxMenu"), _("Editor menu"));
am->AddMenuEntry(id, _("&Enable quit"), _T("App.Test2"));
// when you want to launch the editor popup menu, use:
// wxMenu* menu = new wxMenu;
// ActionsManager::Get()->CreateContextMenu(&menu, _T("EditorCtxMenu"));
// PopupMenu(menu);
// delete menu;
Here's the current to-do:
// TODO (mandrav#1#): Serialize actions
// TODO (mandrav#1#): Create toolbar(s) from actions
// TODO (mandrav#1#): Create UI to edit menus/toolbars
// TODO (mandrav#1#): Add support for check/radio actions
Serialization should be trivial to do. The actions configuration file will be loaded after all modules have finished registering their actions and menu/toolbar layouts. This way, the actions configuration will override any in-program settings.
Actions not registered by the application will not be serialized. The exception to this are script-actions. The user will be able to add script actions freely.
So, comments?