1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Robert Roebling 
   7 // Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem 
   8 // Licence:     wxWindows licence 
   9 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "menu.h" 
  18 //----------------------------------------------------------------------------- 
  20 //----------------------------------------------------------------------------- 
  22 IMPLEMENT_DYNAMIC_CLASS(wxMenuBar
,wxWindow
) 
  24 wxMenuBar::wxMenuBar(void) 
  26   m_needParent 
= FALSE
; // hmmm 
  28   PreCreation( NULL
, -1, wxDefaultPosition
, wxDefaultSize
, 0, "menu" ); 
  30   m_menus
.DeleteContents( TRUE 
); 
  32   m_widget 
= gtk_handle_box_new(); 
  34   m_menubar 
= gtk_menu_bar_new(); 
  36   gtk_container_add( GTK_CONTAINER(m_widget
), m_menubar 
); 
  38   gtk_widget_show( m_menubar 
); 
  45 void wxMenuBar::Append( wxMenu 
*menu
, const wxString 
&title 
) 
  47   m_menus
.Append( menu 
); 
  48   menu
->m_title 
= title
;    // ?????? 
  52     pos 
= menu
->m_title
.First( '&' ); 
  53     if (pos 
!= wxString::npos
) menu
->m_title
.Remove( pos
, 1 ); 
  54   } while (pos 
!= wxString::npos
); 
  57   root_menu 
= gtk_menu_item_new_with_label( WXSTRINGCAST(menu
->m_title
) ); 
  58   gtk_widget_show( root_menu 
); 
  59   gtk_menu_item_set_submenu( GTK_MENU_ITEM(root_menu
), menu
->m_menu 
); 
  61   gtk_menu_bar_append( GTK_MENU_BAR(m_menubar
), root_menu 
); 
  64 static int FindMenuItemRecursive( const wxMenu 
*menu
, const wxString 
&menuString
, const wxString 
&itemString 
) 
  66   if (menu
->m_title 
== menuString
) 
  68     int res 
= menu
->FindItem( itemString 
); 
  69     if (res 
!= -1) return res
; 
  71   wxNode 
*node 
= menu
->m_items
.First(); 
  74     wxMenuItem 
*item 
= (wxMenuItem
*)node
->Data(); 
  75     if (item
->m_subMenu
) return FindMenuItemRecursive( item
->m_subMenu
, menuString
, itemString 
); 
  81 int wxMenuBar::FindMenuItem( const wxString 
&menuString
, const wxString 
&itemString 
) const 
  83   wxNode 
*node 
= m_menus
.First(); 
  86     wxMenu 
*menu 
= (wxMenu
*)node
->Data(); 
  87     int res 
= FindMenuItemRecursive( menu
, menuString
, itemString
); 
  88     if (res 
!= -1) return res
; 
  94 // Find a wxMenuItem using its id. Recurses down into sub-menus 
  95 static wxMenuItem
* FindMenuItemByIdRecursive( const wxMenu
* menu
, int id 
) 
  97   wxMenuItem
* result 
= menu
->FindItemForId( id 
); 
  99   wxNode 
*node 
= menu
->m_items
.First(); 
 100   while (node 
&& result 
== 0) 
 102     wxMenuItem 
*item 
= (wxMenuItem
*)node
->Data(); 
 103     if (item
->m_subMenu
) result 
= FindMenuItemByIdRecursive( item
->m_subMenu
, id 
); 
 109 wxMenuItem
* wxMenuBar::FindMenuItemById( int id 
) const 
 111   wxMenuItem
* result 
= 0; 
 112   wxNode 
*node 
= m_menus
.First(); 
 113   while (node 
&& result 
== 0) 
 115     wxMenu 
*menu 
= (wxMenu
*)node
->Data(); 
 116     result 
= FindMenuItemByIdRecursive( menu
, id 
); 
 122 bool wxMenuBar::IsChecked( int id 
) const 
 124   wxMenuItem
* item 
= FindMenuItemById( id 
); 
 125   if (item
) return item
->IsChecked(); 
 129 bool wxMenuBar::IsEnabled( int id 
) const 
 131   wxMenuItem
* item 
= FindMenuItemById( id 
); 
 132   if (item
) return item
->IsEnabled(); 
 136 //----------------------------------------------------------------------------- 
 138 //----------------------------------------------------------------------------- 
 140 void gtk_menu_clicked_callback( GtkWidget 
*widget
, gpointer data 
) 
 142   wxMenu 
*menu 
= (wxMenu
*)data
; 
 143   int id 
= menu
->FindMenuIdByMenuItem(widget
); 
 145   if (!menu
->Enabled(id
)) return; 
 147   wxCommandEvent 
event( wxEVENT_TYPE_MENU_COMMAND
, id 
); 
 148   event
.SetEventObject( menu 
); 
 150   wxWindow 
*win 
= menu
->GetInvokingWindow(); 
 151   if (win
) win
->ProcessEvent( event 
); 
 154 IMPLEMENT_DYNAMIC_CLASS(wxMenuItem
,wxObject
) 
 156 wxMenuItem::wxMenuItem(void) 
 160   m_isCheckMenu 
= FALSE
; 
 168 void wxMenuItem::Check( bool check 
) 
 173     gtk_check_menu_item_set_state( (GtkCheckMenuItem
*)m_menuItem
, (gint
)check 
); 
 177 bool wxMenuItem::IsChecked() const 
 181     return ((GtkCheckMenuItem
*)m_menuItem
)->active 
!= 0; 
 186 void wxMenuItem::Enable( bool enable 
) 
 188   m_isEnabled 
= enable
; 
 191 IMPLEMENT_DYNAMIC_CLASS(wxMenu
,wxEvtHandler
) 
 193 wxMenu::wxMenu( const wxString 
&title 
) 
 196   m_items
.DeleteContents( TRUE 
); 
 197   m_invokingWindow 
= NULL
; 
 198   m_menu 
= gtk_menu_new();  // Do not show! 
 201 void wxMenu::AppendSeparator(void) 
 203   wxMenuItem 
*mitem 
= new wxMenuItem(); 
 204   mitem
->m_id 
= ID_SEPARATOR
; 
 206   mitem
->m_helpStr 
= ""; 
 207   mitem
->m_isCheckMenu 
= FALSE
; 
 208   mitem
->m_isEnabled 
= TRUE
; 
 209   mitem
->m_menuItem 
= gtk_menu_item_new(); 
 210   gtk_menu_append( GTK_MENU(m_menu
), mitem
->m_menuItem 
); 
 211   gtk_widget_show( mitem
->m_menuItem 
); 
 212   m_items
.Append( mitem 
); 
 215 void wxMenu::Append( int id
, const wxString 
&item
, const wxString 
&helpStr
, bool checkable 
) 
 217   wxMenuItem 
*mitem 
= new wxMenuItem(); 
 220   mitem
->m_text 
= item
; 
 223     pos 
= mitem
->m_text
.First( '&' ); 
 224     if (pos 
!= wxString::npos
) mitem
->m_text
.Remove( pos
, 1 ); 
 225   } while (pos 
!= wxString::npos
); 
 227   mitem
->m_helpStr 
= helpStr
; 
 228   mitem
->m_isCheckMenu 
= checkable
; 
 229   mitem
->m_isEnabled 
= TRUE
; 
 231     mitem
->m_menuItem 
= gtk_check_menu_item_new_with_label( WXSTRINGCAST(mitem
->m_text
) ); 
 233     mitem
->m_menuItem 
= gtk_menu_item_new_with_label( WXSTRINGCAST(mitem
->m_text
) ); 
 235   gtk_signal_connect( GTK_OBJECT(mitem
->m_menuItem
), "activate",  
 236     GTK_SIGNAL_FUNC(gtk_menu_clicked_callback
), (gpointer
*)this ); 
 238   gtk_menu_append( GTK_MENU(m_menu
), mitem
->m_menuItem 
); 
 239   gtk_widget_show( mitem
->m_menuItem 
); 
 240   m_items
.Append( mitem 
); 
 243 void wxMenu::Append( int id
, const wxString 
&item
, wxMenu 
*subMenu
, const wxString 
&helpStr 
) 
 245   wxMenuItem 
*mitem 
= new wxMenuItem(); 
 247   mitem
->m_text 
= item
; 
 248   mitem
->m_isEnabled 
= TRUE
; 
 252     pos 
= mitem
->m_text
.First( '&' ); 
 253     if (pos 
!= wxString::npos
) mitem
->m_text
.Remove( pos
, 1 ); 
 254   } while (pos 
!= wxString::npos
); 
 256   mitem
->m_helpStr 
= helpStr
; 
 257   mitem
->m_menuItem 
= gtk_menu_item_new_with_label( WXSTRINGCAST(mitem
->m_text
) ); 
 259   mitem
->m_subMenu 
= subMenu
; 
 260   gtk_menu_item_set_submenu( GTK_MENU_ITEM(mitem
->m_menuItem
), subMenu
->m_menu 
); 
 261   gtk_menu_append( GTK_MENU(m_menu
), mitem
->m_menuItem 
); 
 262   gtk_widget_show( mitem
->m_menuItem 
); 
 263   m_items
.Append( mitem 
); 
 266 int wxMenu::FindItem( const wxString itemString 
) const 
 268   wxString 
s( itemString 
); 
 272     pos 
= s
.First( '&' ); 
 273     if (pos 
!= wxString::npos
) s
.Remove( pos
, 1 ); 
 274   } while (pos 
!= wxString::npos
); 
 276   wxNode 
*node 
= m_items
.First(); 
 279     wxMenuItem 
*item 
= (wxMenuItem
*)node
->Data(); 
 280     if (item
->m_text 
== s
) return item
->m_id
; 
 286 wxMenuItem
* wxMenu::FindItemForId( int id 
) const 
 288   wxNode 
*node 
= m_items
.First(); 
 291     wxMenuItem 
*item 
= (wxMenuItem
*)node
->Data(); 
 292     if (item
->m_id 
== id
) return item
; 
 298 void wxMenu::Check( int id
, bool Flag 
) 
 300   wxMenuItem
* item 
= FindItemForId( id 
); 
 301   if (item
) item
->Check(Flag
); 
 304 void wxMenu::Enable( int id
, bool enable 
) 
 306   wxNode 
*node 
= m_items
.First(); 
 309     wxMenuItem 
*item 
= (wxMenuItem
*)node
->Data(); 
 310     if (item
->m_id 
== id
) 
 312       item
->m_isEnabled 
= enable
; 
 319 bool wxMenu::Enabled( int id 
) const 
 321   wxNode 
*node 
= m_items
.First(); 
 324     wxMenuItem 
*item 
= (wxMenuItem
*)node
->Data(); 
 325     if (item
->m_id 
== id
) return item
->m_isEnabled
; 
 331 void wxMenu::SetLabel( int id
, const wxString 
&label 
) 
 336     pos 
= s
.First( '&' ); 
 337     if (pos 
!= wxString::npos
) s
.Remove( pos
, 1 ); 
 338   } while (pos 
!= wxString::npos
); 
 340   wxNode 
*node 
= m_items
.First(); 
 343     wxMenuItem 
*item 
= (wxMenuItem
*)node
->Data(); 
 345     if (item
->m_id 
== id
) 
 347       gtk_label_set( GTK_LABEL( GTK_BIN(item
->m_menuItem
)->child 
), WXSTRINGCAST(s
) ); 
 353 int wxMenu::FindMenuIdByMenuItem( GtkWidget 
*menuItem 
) const 
 355   wxNode 
*node 
= m_items
.First(); 
 358     wxMenuItem 
*item 
= (wxMenuItem
*)node
->Data(); 
 359     if (item
->m_menuItem 
== menuItem
) return item
->m_id
; 
 365 void wxMenu::SetInvokingWindow( wxWindow 
*win 
) 
 367   m_invokingWindow 
= win
; 
 370 wxWindow 
*wxMenu::GetInvokingWindow(void) 
 372   return m_invokingWindow
;