Go to the documentation of this file.00001
00002 #include "vgui_wx_menu.h"
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <vgui/vgui_command.h>
00012
00013 #include <wx/menu.h>
00014
00015 #ifndef wxCommandEventHandler // wxWidgets-2.5.3 doesn't define this
00016 #define wxCommandEventHandler(func) \
00017 (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxCommandEventFunction, &func)
00018 #endif
00019
00020 #include <vcl_cctype.h>
00021 #include <vcl_cassert.h>
00022
00023
00024
00025
00026 namespace
00027 {
00028 wxMenuBar* strip_extra_separators(wxMenuBar* menubar);
00029 wxMenu* strip_extra_separators(wxMenu* menu);
00030 }
00031
00032
00033
00034
00035 const int vgui_wx_menu::MENU_ID_OFFSET = 1000;
00036
00037 vgui_wx_menu::vgui_wx_menu(void)
00038 : item_count_(-1)
00039 {
00040 }
00041
00042 vgui_wx_menu::~vgui_wx_menu(void)
00043 {
00044 disconnect_handlers();
00045
00046
00047
00048 }
00049
00050
00051
00052
00053 BEGIN_EVENT_TABLE(vgui_wx_menu, wxEvtHandler)
00054 END_EVENT_TABLE()
00055
00056
00057 wxMenuBar* vgui_wx_menu::create_wx_menubar(const vgui_menu& menu)
00058 {
00059 disconnect_handlers();
00060
00061 wxMenuBar* menubar = new wxMenuBar;
00062
00063
00064 for (unsigned int i = 0; i < menu.size(); i++)
00065 {
00066 if (menu[i].is_separator())
00067 {
00068 assert(false);
00069 }
00070 else if (menu[i].is_command())
00071 {
00072 #ifdef DEBUG
00073 vcl_cerr << __FILE__ ":command as top level menu item!\n";
00074 #endif
00075
00076 vgui_menu submenu;
00077 submenu.add(menu[i].name,
00078 menu[i].cmnd,
00079 menu[i].short_cut.key,
00080 menu[i].short_cut.mod);
00081
00082 menubar->Append(create_wx_submenu(submenu), wxString(menu[i].name.c_str(),wxConvUTF8));
00083 }
00084 else if (menu[i].is_submenu())
00085 {
00086 menubar->Append(
00087 create_wx_submenu(*menu[i].menu), wxString(menu[i].name.c_str(),wxConvUTF8));
00088 }
00089 }
00090
00091 return strip_extra_separators(menubar);
00092 }
00093
00094
00095 wxMenu* vgui_wx_menu::create_wx_menu(const vgui_menu& menu)
00096 {
00097 disconnect_handlers();
00098 return strip_extra_separators(create_wx_submenu(menu));
00099 }
00100
00101
00102 wxMenu* vgui_wx_menu::create_wx_submenu(const vgui_menu& menu)
00103 {
00104 wxMenu* popup = new wxMenu;
00105
00106 for (unsigned int i = 0; i < menu.size(); i++)
00107 {
00108 const int menu_id = MENU_ID_OFFSET + ++item_count_;
00109
00110 if (menu[i].is_separator())
00111 {
00112 popup->AppendSeparator();
00113 }
00114 else if (menu[i].is_command())
00115 {
00116
00117 vcl_string menu_item = menu[i].name
00118 + create_accelerator_string(menu[i]);
00119
00120 popup->Append(menu_id, wxString(menu_item.c_str(),wxConvUTF8));
00121
00122
00123 handlers_[menu_id] = static_cast<vgui_command_sptr>(menu[i].cmnd);
00124
00125
00126 Connect(menu_id, wxEVT_COMMAND_MENU_SELECTED,
00127 wxCommandEventHandler(vgui_wx_menu::on_command));
00128 }
00129 else if (menu[i].is_submenu())
00130 {
00131 popup->Append(
00132 menu_id,
00133 wxString(menu[i].name.c_str(),wxConvUTF8),
00134 strip_extra_separators(create_wx_submenu(*menu[i].menu)));
00135 }
00136 }
00137
00138 return popup;
00139 }
00140
00141
00142 vcl_string
00143 vgui_wx_menu::create_accelerator_string(const vgui_menu_item& item) const
00144 {
00145 if ( item.short_cut.key == vgui_KEY_NULL )
00146 {
00147 return vcl_string("");
00148 }
00149
00150 vcl_string accelerator("\t");
00151
00152
00153 if (item.short_cut.mod == vgui_CTRL)
00154 {
00155 accelerator += vcl_string("Ctrl+");
00156 }
00157 else if (item.short_cut.mod == vgui_SHIFT)
00158 {
00159 accelerator += vcl_string("Shift+");
00160 }
00161 else if (item.short_cut.mod == vgui_ALT)
00162 {
00163 accelerator += vcl_string("Alt+");
00164 }
00165
00166 accelerator += vcl_toupper(item.short_cut.key);
00167
00168 return accelerator;
00169 }
00170
00171
00172 void vgui_wx_menu::disconnect_handlers()
00173 {
00174 vcl_map<int,vgui_command_sptr>::const_iterator iter = handlers_.begin();
00175 for (; iter != handlers_.end(); iter++)
00176 {
00177 Disconnect(iter->first, wxEVT_COMMAND_MENU_SELECTED);
00178 }
00179 handlers_.clear();
00180 }
00181
00182
00183 void vgui_wx_menu::on_command(wxCommandEvent& event)
00184 {
00185 handlers_[event.GetId()]->execute();
00186 }
00187
00188
00189
00190
00191 namespace
00192 {
00193 wxMenuBar* strip_extra_separators(wxMenuBar* menubar)
00194 {
00195 assert(menubar);
00196
00197 for (unsigned int i = 0; i < menubar->GetMenuCount(); i++)
00198 {
00199 strip_extra_separators(menubar->GetMenu(i));
00200 }
00201
00202 return menubar;
00203 }
00204
00205 wxMenu* strip_extra_separators(wxMenu* menu)
00206 {
00207 assert(menu);
00208
00209 wxMenuItemList::Node* node = menu->GetMenuItems().GetLast();
00210 while (node)
00211 {
00212 if (node->GetData()->IsSeparator())
00213 {
00214 if ( !node->GetNext() ||
00215 !node->GetPrevious() ||
00216 node->GetPrevious()->GetData()->IsSeparator())
00217 {
00218 menu->Delete(node->GetData());
00219 node = menu->GetMenuItems().GetLast();
00220 }
00221 }
00222 node = node->GetPrevious();
00223 }
00224
00225 return menu;
00226 }
00227 }