diff options
-rw-r--r-- | client/menu.cpp | 50 | ||||
-rw-r--r-- | client/menu.h | 20 | ||||
-rw-r--r-- | client/windows/red_window.cpp | 16 |
3 files changed, 68 insertions, 18 deletions
diff --git a/client/menu.cpp b/client/menu.cpp index 343818c2..d260f3ab 100644 --- a/client/menu.cpp +++ b/client/menu.cpp @@ -20,7 +20,6 @@ #include "utils.h" #include "debug.h" - Menu::Menu(CommandTarget& target, const std::string& name) : _refs (1) , _target (target) @@ -30,13 +29,7 @@ Menu::Menu(CommandTarget& target, const std::string& name) Menu::~Menu() { - for (unsigned int i = 0; i < _items.size(); i++) { - if (_items[i].type == MENU_ITEM_TYPE_COMMAND) { - delete (MenuCommand*)_items[i].obj; - } else if (_items[i].type == MENU_ITEM_TYPE_MENU) { - ((Menu*)_items[i].obj)->unref(); - } - } + clear(); } void Menu::add_item(MenuItem& item) @@ -46,9 +39,9 @@ void Menu::add_item(MenuItem& item) _items[pos] = item; } -void Menu::add_command(const std::string& name, int cmd_id) +void Menu::add_command(const std::string& name, int cmd_id, int state) { - MenuCommand* cmd = new MenuCommand(name, cmd_id); + MenuCommand* cmd = new MenuCommand(name, cmd_id, state); MenuItem item; item.type = MENU_ITEM_TYPE_COMMAND; item.obj = cmd; @@ -72,6 +65,29 @@ void Menu::add_sub(Menu* menu) add_item(item); } +void Menu::remove_command(int cmd_id) +{ + for (unsigned int i = 0; i < _items.size(); i++) { + if (_items[i].type == MENU_ITEM_TYPE_COMMAND && + ((MenuCommand*)_items[i].obj)->get_cmd_id() == cmd_id) { + delete (MenuCommand*)_items[i].obj; + _items.erase(_items.begin() + i); + return; + } + } +} + +void Menu::remove_sub(Menu* menu) +{ + for (unsigned int i = 0; i < _items.size(); i++) { + if (_items[i].type == MENU_ITEM_TYPE_MENU && (Menu*)_items[i].obj == menu) { + ((Menu*)_items[i].obj)->unref(); + _items.erase(_items.begin() + i); + return; + } + } +} + Menu::ItemType Menu::item_type_at(int pos) { if (pos >= (int)_items.size()) { @@ -80,7 +96,7 @@ Menu::ItemType Menu::item_type_at(int pos) return _items[pos].type; } -void Menu::command_at(int pos, std::string& name, int& cmd_id) +void Menu::command_at(int pos, std::string& name, int& cmd_id, int& state) { if (_items[pos].type != MENU_ITEM_TYPE_COMMAND) { THROW("incorrect item type"); @@ -88,6 +104,7 @@ void Menu::command_at(int pos, std::string& name, int& cmd_id) MenuCommand* cmd = (MenuCommand*)_items[pos].obj; name = cmd->get_name(); cmd_id = cmd->get_cmd_id(); + state = cmd->get_state(); } Menu* Menu::sub_at(int pos) @@ -98,3 +115,14 @@ Menu* Menu::sub_at(int pos) return ((Menu*)_items[pos].obj)->ref(); } +void Menu::clear() +{ + for (unsigned int i = 0; i < _items.size(); i++) { + if (_items[i].type == MENU_ITEM_TYPE_COMMAND) { + delete (MenuCommand*)_items[i].obj; + } else if (_items[i].type == MENU_ITEM_TYPE_MENU) { + ((Menu*)_items[i].obj)->unref(); + } + } + _items.clear(); +} diff --git a/client/menu.h b/client/menu.h index b908e549..ee3c9ec9 100644 --- a/client/menu.h +++ b/client/menu.h @@ -35,37 +35,51 @@ public: MENU_ITEM_TYPE_SEPARATOR, }; + enum ItemState { + MENU_ITEM_STATE_CHECKED = 1 << 0, + MENU_ITEM_STATE_DIM = 1 << 1, + }; + Menu* ref() { _refs++; return this;} void unref() { if (!--_refs) delete this;} + void set_name(const std::string& name) { _name = name;} const std::string& get_name() { return _name;} CommandTarget& get_target() { return _target;} - void add_command(const std::string& name, int cmd_id); + void add_command(const std::string& name, int cmd_id, int state = 0); void add_separator(); void add_sub(Menu* sub); + void remove_command(int cmd_id); + void remove_sub(Menu* menu); + ItemType item_type_at(int pos); - void command_at(int pos, std::string& name, int& cmd_id); + void command_at(int pos, std::string& name, int& cmd_id, int& state); Menu* sub_at(int pos); + void clear(); + private: virtual ~Menu(); class MenuCommand { public: - MenuCommand(const std::string& name, int cmd_id) + MenuCommand(const std::string& name, int cmd_id, int state) : _name (name) , _cmd_id (cmd_id) + , _state (state) { } const std::string& get_name() { return _name;} int get_cmd_id() { return _cmd_id;} + int get_state() { return _state;} private: std::string _name; int _cmd_id; + int _state; }; struct MenuItem { diff --git a/client/windows/red_window.cpp b/client/windows/red_window.cpp index 47467194..2d415d1e 100644 --- a/client/windows/red_window.cpp +++ b/client/windows/red_window.cpp @@ -906,17 +906,24 @@ static void utf8_to_wchar(const std::string& src, std::wstring& dest) MultiByteToWideChar(CP_UTF8, 0, src.c_str(), -1, (wchar_t *)dest.c_str(), len); } -static void insert_command(HMENU menu, const std::string& name, int id) +static void insert_command(HMENU menu, const std::string& name, int id, int state) { MENUITEMINFO item_info; item_info.cbSize = sizeof(item_info); - item_info.fMask = MIIM_TYPE | MIIM_ID; + item_info.fMask = MIIM_ID | MIIM_STRING | MIIM_STATE; item_info.fType = MFT_STRING; std::wstring wname; utf8_to_wchar(name, wname); item_info.cch = wname.size(); item_info.dwTypeData = (wchar_t *)wname.c_str(); item_info.wID = id; + item_info.fState = MFS_ENABLED; + if (state & Menu::MENU_ITEM_STATE_CHECKED) { + item_info.fState |= MFS_CHECKED; + } + if (state & Menu::MENU_ITEM_STATE_DIM) { + item_info.fState |= MFS_DISABLED; + } InsertMenuItem(menu, GetMenuItemCount(menu), TRUE, &item_info); } @@ -969,10 +976,11 @@ static void insert_menu(Menu* menu, HMENU native, CommandMap& _commands_map) case Menu::MENU_ITEM_TYPE_COMMAND: { std::string name; int command_id; - menu->command_at(pos, name, command_id); + int state; + menu->command_at(pos, name, command_id, state); int sys_command = alloc_sys_cmd_id(); _commands_map[sys_command] = CommandInfo(menu, command_id); - insert_command(native, name, sys_command); + insert_command(native, name, sys_command, state); break; } case Menu::MENU_ITEM_TYPE_MENU: { |