core/vgui/vgui_menu.cxx

Go to the documentation of this file.
00001 // This is core/vgui/vgui_menu.cxx
00002 #include "vgui_menu.h"
00003 //:
00004 // \file
00005 // \author fsm
00006 // \brief  See vgui_menu.h for a description of this file.
00007 
00008 #include <vcl_iostream.h>
00009 #include <vgui/vgui_command.h>
00010 
00011 //--------------------------------------------------------------------------------
00012 
00013 vgui_menu_item::vgui_menu_item()
00014   : name("[]")
00015   , menu(0)
00016 {
00017   short_cut.mod = vgui_MODIFIER_NULL;
00018   short_cut.key = vgui_KEY_NULL;
00019 }
00020 
00021 vgui_menu_item::vgui_menu_item(vgui_menu_item const &that)
00022   : name(that.name)
00023   , cmnd(that.cmnd)
00024   , menu(that.menu)
00025   , short_cut(that.short_cut)
00026 {
00027   if (menu)
00028     menu = new vgui_menu( *menu ); // make a copy.
00029 }
00030 
00031 vgui_menu_item::~vgui_menu_item()
00032 {
00033   if (menu)
00034     delete menu;
00035   menu = 0;
00036 }
00037 
00038 bool vgui_menu_item::is_toggle_button() const
00039 {
00040   // The use of dynamic_cast is forbidden by the VXL
00041   // guidelines. However, the alternative here is to implement our own
00042   // RTTI in vgui_command using a virtual function like
00043   // is_a_toggle_command. However, this is GUI code. It's not
00044   // performance critical, and mostly requires RTTI and threads and
00045   // all kinds of things. Let's just use the compiler generated
00046   // version until we run into a real problem.
00047   //
00048   return name!="" &&  (bool)cmnd && (menu == 0) &&  dynamic_cast<vgui_command_toggle*>(cmnd.ptr()) != 0;
00049 }
00050 
00051 //--------------------------------------------------------------------------------
00052 
00053 vgui_menu::vgui_menu(vgui_menu const &that)
00054 {
00055   operator=(that);
00056 }
00057 
00058 void vgui_menu::operator=(vgui_menu const &that)
00059 {
00060   if (this != &that) {
00061     clear();
00062     this->include(that);
00063   }
00064 }
00065 
00066 //--------------------------------------------------------------------------------
00067 
00068 #define im_here do { /* vcl_cerr << __FILE__ " : " << __LINE__ << vcl_endl; */ } while (false)
00069 
00070 void vgui_menu::add(vcl_string const &n,
00071                     vgui_command_sptr c,
00072                     vgui_key key,
00073                     vgui_modifier modifiers)
00074 {
00075   im_here;
00076   vgui_menu_item i;
00077   i.name = n;
00078   i.cmnd = c;
00079   i.short_cut.key = key;
00080   i.short_cut.mod = modifiers;
00081   items.push_back(i);
00082 }
00083 
00084 void vgui_menu::add(vcl_string const &n,
00085                     vgui_menu_callback f,
00086                     void const* client_data,
00087                     vgui_key key,
00088                     vgui_modifier modifiers)
00089 {
00090   im_here;
00091   vgui_command* cfunc = new vgui_command_cfunc(f, client_data); //KYM fix for SunPro
00092   add(n, /* (vgui_command*) */cfunc, key, modifiers);
00093 }
00094 
00095 void vgui_menu::add(vcl_string const &n,
00096                     vgui_menu_callback_no_client_data f,
00097                     vgui_key key,
00098                     vgui_modifier modifiers)
00099 {
00100   im_here;
00101   vgui_command* cfunc = new vgui_command_cfunc(f);  //KYM fix for SunPro
00102   add(n, /* (vgui_command*) */cfunc, key, modifiers);
00103 }
00104 
00105 void vgui_menu::add(vcl_string const &n,
00106                     vgui_menu const &m,
00107                     vgui_key key,
00108                     vgui_modifier modifiers)
00109 {
00110   im_here;
00111   vgui_menu_item i;
00112   i.name = n;
00113   i.menu = new vgui_menu(m);
00114   i.short_cut.key = key;
00115   i.short_cut.mod = modifiers;
00116   items.push_back(i);
00117 }
00118 
00119 void vgui_menu::separator()
00120 {
00121   vgui_menu_item i;
00122   i.name = "";
00123   items.push_back(i);
00124 }
00125 
00126 void vgui_menu::include(vgui_menu const &that)
00127 {
00128   items.reserve(items.size() + that.items.size());
00129 
00130   for (unsigned i=0; i<that.size(); ++i)
00131     items.push_back( that.items[i] );
00132 }
00133 
00134 //--------------------------------------------------------------------------------
00135 
00136 // Helper function for operator<<. Apart from the menu to print and the
00137 // destination stream, the 'pre' argument is the prefix to print on every
00138 // new line (usually spaces for indentation).
00139 // This could be a member function, but that would just clutter
00140 // the interface even more.
00141 static void dump(vgui_menu const &This, vcl_ostream &os, vcl_string const &pre)
00142 {
00143   for (unsigned i=0;i<This.size();i++) {
00144     // name
00145     os << pre << " \"" << This[i].name << "\" ";
00146 
00147     // shortcut
00148     if (This[i].short_cut.mod & vgui_CTRL)
00149       os << "CTRL+";
00150     if (This[i].short_cut.mod & vgui_SHIFT)
00151       os << "SHIFT+";
00152     if (This[i].short_cut.mod & vgui_META)
00153       os << "META+";
00154     if (This[i].short_cut.mod & vgui_ALT)
00155       os << "ALT+";
00156     if (This[i].short_cut.key)
00157       os << '\'' << char(This[i].short_cut.key) << '\'';
00158     else
00159       os << "\'\'"; //"(none)";
00160     os << ' ';
00161 
00162     // what it does
00163     if (This[i].is_command())
00164       os << "command(" << static_cast<void*>(This[i].cmnd.as_pointer()) << ")\n";
00165     else if (This[i].is_submenu()) {
00166       os << "submenu:\n";
00167       dump(* This[i].menu,os,pre+"  ");
00168     }
00169     else if (This[i].is_toggle_button()) {
00170       vgui_command_toggle *c = static_cast<vgui_command_toggle*>(This[i].cmnd.as_pointer());
00171       os << "toggle (" << (c->state ? "on" : "off") << ")\n";
00172     }
00173     else if (This[i].is_separator())
00174       os << "(----- separator -----)\n";
00175     else
00176       os << "[unknown menuitem]\n"; //
00177   }
00178 }
00179 
00180 vcl_ostream &operator<<(vcl_ostream &os, vgui_menu const &m)
00181 {
00182   dump(m, os, "  ");
00183   return os;
00184 }
00185 
00186 //--------------------------------------------------------------------------------

Generated on Mon Mar 8 05:12:27 2010 for core/vgui by  doxygen 1.5.1