summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/menu.cpp50
-rw-r--r--client/menu.h20
-rw-r--r--client/windows/red_window.cpp16
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: {