spice: menu additons

-functions: set_name, remove_command, remove_sub, clear
-item state & enum
-add state support in RedWindow insert_command & insert_menu
This commit is contained in:
Arnon Gilboa 2010-01-07 11:02:50 +02:00 committed by Yaniv Kamay
parent 81945d8971
commit dcf326cfd5
3 changed files with 68 additions and 18 deletions

View File

@ -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();
}

View File

@ -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 {

View File

@ -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: {