#include "gdk/gdk.h"
#include "gtk/gtk.h"
+//-----------------------------------------------------------------------------
+// idle system
+//-----------------------------------------------------------------------------
+
+extern void wxapp_install_idle_handler();
+extern bool g_isIdle;
+
//-----------------------------------------------------------------------------
// wxMenuBar
//-----------------------------------------------------------------------------
wxMenuBar::wxMenuBar( long style )
{
- m_needParent = FALSE; // hmmm
+ /* the parent window is known after wxFrame::SetMenu() */
+ m_needParent = FALSE;
PreCreation( (wxWindow *) NULL, -1, wxDefaultPosition, wxDefaultSize, style, "menu" );
m_menus.DeleteContents( TRUE );
+ /* GTK 1.2.0 doesn't have gtk_item_factory_get_item(), but GTK 1.2.1 has. */
+#if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
+ m_accel = gtk_accel_group_new();
+ m_factory = gtk_item_factory_new( GTK_TYPE_MENU_BAR, "<main>", m_accel );
+ m_menubar = gtk_item_factory_get_widget( m_factory, "<main>" );
+#else
m_menubar = gtk_menu_bar_new();
+#endif
if (style & wxMB_DOCKABLE)
{
wxMenuBar::wxMenuBar()
{
- m_needParent = FALSE; // hmmm
+ /* the parent window is known after wxFrame::SetMenu() */
+ m_needParent = FALSE;
PreCreation( (wxWindow *) NULL, -1, wxDefaultPosition, wxDefaultSize, 0, "menu" );
m_menus.DeleteContents( TRUE );
+ /* GTK 1.2.0 doesn't have gtk_item_factory_get_item(), but GTK 1.2.1 has. */
+#if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
+ m_accel = gtk_accel_group_new();
+ m_factory = gtk_item_factory_new( GTK_TYPE_MENU_BAR, "<main>", m_accel );
+ m_menubar = gtk_item_factory_get_widget( m_factory, "<main>" );
+#else
m_menubar = gtk_menu_bar_new();
+#endif
m_widget = GTK_WIDGET(m_menubar);
Show( TRUE );
}
+wxMenuBar::~wxMenuBar()
+{
+ // how to destroy a GtkItemFactory ?
+}
+
void wxMenuBar::Append( wxMenu *menu, const wxString &title )
{
m_menus.Append( menu );
- wxString s = _T("");
+ /* GTK 1.2 wants to have "_" instead of "&" for accelerators */
+ wxString str;
for ( const wxChar *pc = title; *pc != _T('\0'); pc++ )
{
if (*pc == _T('&'))
{
- pc++; /* skip it */
-#if (GTK_MINOR_VERSION > 0)
- // s << '_'; not yet
+#if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
+ str << _T('_');
+ } else
+ if (*pc == _T('/'))
+ {
+ str << _T('\\');
#endif
- }
- s << *pc;
+ }
+ else
+ str << *pc;
+ }
+
+ /* this doesn't have much effect right now */
+ menu->SetTitle( str );
+
+ /* GTK 1.2.0 doesn't have gtk_item_factory_get_item(), but GTK 1.2.1 has. */
+#if (GTK_MINOR_VERSION > 0) && (GTK_MICRO_VERSION > 0)
+
+ /* local buffer in multibyte form */
+ char buf[200];
+ strcpy( buf, "/" );
+ strcat( buf, str.mb_str() );
+
+ GtkItemFactoryEntry entry;
+ entry.path = buf;
+ entry.accelerator = (gchar*) NULL;
+ entry.callback = (GtkItemFactoryCallback) NULL;
+ entry.callback_action = 0;
+ entry.item_type = "<Branch>";
+
+ gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */
+
+ /* in order to get the pointer to the item we need the item text _without_ underscores */
+ wxString tmp = _T("<main>/");
+ for ( const wxChar *pc = str; *pc != _T('\0'); pc++ )
+ {
+ if (*pc == _T('_')) pc++; /* skip it */
+ tmp << *pc;
}
+
+ menu->m_owner = gtk_item_factory_get_item( m_factory, tmp.mb_str() );
+
+ gtk_menu_item_set_submenu( GTK_MENU_ITEM(menu->m_owner), menu->m_menu );
+
+#else
- menu->SetTitle(s);
- menu->m_owner = gtk_menu_item_new_with_label( MBSTRINGCAST s.mbc_str() );
+ menu->m_owner = gtk_menu_item_new_with_label( str.mb_str() );
gtk_widget_show( menu->m_owner );
gtk_menu_item_set_submenu( GTK_MENU_ITEM(menu->m_owner), menu->m_menu );
gtk_menu_bar_append( GTK_MENU_BAR(m_menubar), menu->m_owner );
+
+#endif
}
static int FindMenuItemRecursive( const wxMenu *menu, const wxString &menuString, const wxString &itemString )
return wxNOT_FOUND;
}
-wxMenuItem *wxMenuBar::FindItemForId(int itemId, wxMenu **menuForItem = NULL) const
+wxMenuItem *wxMenuBar::FindItemForId(int itemId, wxMenu **menuForItem ) const
{
if ( menuForItem )
{
static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu )
{
+ if (g_isIdle) wxapp_install_idle_handler();
+
int id = menu->FindMenuIdByMenuItem(widget);
/* should find it for normal (not popup) menu */
static void gtk_menu_hilight_callback( GtkWidget *widget, wxMenu *menu )
{
+ if (g_isIdle) wxapp_install_idle_handler();
+
int id = menu->FindMenuIdByMenuItem(widget);
wxASSERT( id != -1 ); // should find it!
static void gtk_menu_nolight_callback( GtkWidget *widget, wxMenu *menu )
{
+ if (g_isIdle) wxapp_install_idle_handler();
+
int id = menu->FindMenuIdByMenuItem(widget);
wxASSERT( id != -1 ); // should find it!
// it's valid for this function to be called even if m_menuItem == NULL
void wxMenuItem::SetName( const wxString& str )
{
+ /* '\t' is the deliminator indicating a hot key */
m_text = _T("");
- for ( const wxChar *pc = str; *pc != _T('\0'); pc++ )
+ const wxChar *pc = str;
+ for (; (*pc != _T('\0')) && (*pc != _T('\t')); pc++ )
{
if (*pc == _T('&'))
{
- pc++; /* skip it */
#if (GTK_MINOR_VERSION > 0)
m_text << _T('_');
+ } else
+ if (*pc == _T('/'))
+ {
+ m_text << _T('\\');
#endif
}
- m_text << *pc;
+ else
+ m_text << *pc;
+ }
+
+ /* only GTK 1.2 know about hot keys */
+ m_hotKey = _T("");
+#if (GTK_MINOR_VERSION > 0)
+ if(*pc == _T('\t'))
+ {
+ pc++;
+ m_hotKey = pc;
}
+#endif
if (m_menuItem)
{
GtkLabel *label = GTK_LABEL( GTK_BIN(m_menuItem)->child );
- gtk_label_set( label, m_text.mbc_str());
+ gtk_label_set( label, m_text.mb_str());
}
}
wxMenuItem *mitem = new wxMenuItem();
mitem->SetId(ID_SEPARATOR);
+#if (GTK_MINOR_VERSION > 0)
+ GtkItemFactoryEntry entry;
+ entry.path = "/sep";
+ entry.callback = (GtkItemFactoryCallback) NULL;
+ entry.callback_action = 0;
+ entry.item_type = "<Separator>";
+ entry.accelerator = (gchar*) NULL;
+
+ gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */
+
+ /* this will be wrong for more than one separator. do we care? */
+ GtkWidget *menuItem = gtk_item_factory_get_widget( m_factory, "<main>/sep" );
+#else
GtkWidget *menuItem = gtk_menu_item_new();
gtk_menu_append( GTK_MENU(m_menu), menuItem );
gtk_widget_show( menuItem );
+#endif
mitem->SetMenuItem(menuItem);
m_items.Append( mitem );
mitem->SetText(item);
mitem->SetHelp(helpStr);
mitem->SetCheckable(checkable);
- const wxChar *text = mitem->GetText();
#if (GTK_MINOR_VERSION > 0)
- wxChar buf[100];
- wxStrcpy( buf, _T("/") );
- wxStrcat( buf, text );
+ /* text has "_" instead of "&" after mitem->SetText() */
+ wxString text( mitem->GetText() );
+
+ /* local buffer in multibyte form */
+ char buf[200];
+ strcpy( buf, "/" );
+ strcat( buf, text.mb_str() );
- const wxWX2MBbuf pbuf = wxConv_current->cWX2MB(buf);
GtkItemFactoryEntry entry;
- entry.path = MBSTRINGCAST pbuf;
- entry.accelerator = (gchar*) NULL;
+ entry.path = buf;
entry.callback = (GtkItemFactoryCallback) gtk_menu_clicked_callback;
entry.callback_action = 0;
if (checkable)
else
entry.item_type = "<Item>";
+ entry.accelerator = (gchar*) NULL;
+ char hotbuf[50];
+ wxString hotkey( mitem->GetHotKey() );
+ if (!hotkey.IsEmpty())
+ {
+ switch (hotkey[0])
+ {
+ case _T('a'): /* Alt */
+ case _T('A'):
+ case _T('m'): /* Meta */
+ case _T('M'):
+ {
+ strcpy( hotbuf, "<alt>" );
+ wxString last = hotkey.Right(1);
+ strcat( hotbuf, last.mb_str() );
+ entry.accelerator = hotbuf;
+ break;
+ }
+ case _T('c'): /* Ctrl */
+ case _T('C'):
+ case _T('s'): /* Strg, yeah man, I'm German */
+ case _T('S'):
+ {
+ strcpy( hotbuf, "<control>" );
+ wxString last = hotkey.Right(1);
+ strcat( hotbuf, last.mb_str() );
+ entry.accelerator = hotbuf;
+ break;
+ }
+ default:
+ {
+ }
+ }
+ }
+
gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */
/* in order to get the pointer to the item we need the item text _without_ underscores */
s << *pc;
}
- GtkWidget *menuItem = gtk_item_factory_get_widget( m_factory, s.mbc_str() );
+ GtkWidget *menuItem = gtk_item_factory_get_widget( m_factory, s.mb_str() );
#else
- GtkWidget *menuItem = checkable ? gtk_check_menu_item_new_with_label(text)
- : gtk_menu_item_new_with_label(text);
+ GtkWidget *menuItem = checkable ? gtk_check_menu_item_new_with_label( mitem->GetText().mb_str() )
+ : gtk_menu_item_new_with_label( mitem->GetText().mb_str() );
gtk_signal_connect( GTK_OBJECT(menuItem), "activate",
GTK_SIGNAL_FUNC(gtk_menu_clicked_callback),