]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk1/tbargtk.cpp
cleaned up the checkbox creation code (~70 lines of code became 3)
[wxWidgets.git] / src / gtk1 / tbargtk.cpp
index 81e71e29d11715a06dcb08af1db076255ee12f53..38a8fde2533d7fcd0c9190d0bbe339e43f2baf5b 100644 (file)
@@ -26,9 +26,8 @@
 
 #include "wx/frame.h"
 
-#include "glib.h"
-#include "gdk/gdk.h"
-#include "gtk/gtk.h"
+#include <glib.h>
+#include "wx/gtk/private.h"
 
 extern GdkFont *GtkGetDefaultGuiFont();
 
@@ -44,6 +43,28 @@ extern bool g_isIdle;
 extern bool       g_blockEventsOnDrag;
 extern wxCursor   g_globalCursor;
 
+// ----------------------------------------------------------------------------
+// private functions
+// ----------------------------------------------------------------------------
+
+// translate wxWindows toolbar style flags to GTK orientation and style
+static void GetGtkStyle(long style,
+                        GtkOrientation *orient, GtkToolbarStyle *gtkStyle)
+{
+    *orient = style & wxTB_VERTICAL ? GTK_ORIENTATION_VERTICAL
+                                    : GTK_ORIENTATION_HORIZONTAL;
+
+
+    if ( style & wxTB_TEXT )
+    {
+        *gtkStyle = style & wxTB_NOICONS ? GTK_TOOLBAR_TEXT : GTK_TOOLBAR_BOTH;
+    }
+    else // no text, hence we must have the icons or what would we show?
+    {
+        *gtkStyle = GTK_TOOLBAR_ICONS;
+    }
+}
+
 // ----------------------------------------------------------------------------
 // wxToolBarTool
 // ----------------------------------------------------------------------------
@@ -53,13 +74,14 @@ class wxToolBarTool : public wxToolBarToolBase
 public:
     wxToolBarTool(wxToolBar *tbar,
                   int id,
+                  const wxString& label,
                   const wxBitmap& bitmap1,
                   const wxBitmap& bitmap2,
-                  bool toggle,
+                  wxItemKind kind,
                   wxObject *clientData,
                   const wxString& shortHelpString,
                   const wxString& longHelpString)
-        : wxToolBarToolBase(tbar, id, bitmap1, bitmap2, toggle,
+        : wxToolBarToolBase(tbar, id, label, bitmap1, bitmap2, kind,
                             clientData, shortHelpString, longHelpString)
     {
         Init();
@@ -71,6 +93,32 @@ public:
         Init();
     }
 
+    // is this a radio button?
+    //
+    // unlike GetKind(), can be called for any kind of tools, not just buttons
+    bool IsRadio() const { return IsButton() && GetKind() == wxITEM_RADIO; }
+
+    // this is only called for the normal buttons, i.e. not separators nor
+    // controls
+    GtkToolbarChildType GetGtkChildType() const
+    {
+        switch ( GetKind() )
+        {
+            case wxITEM_CHECK:
+                return GTK_TOOLBAR_CHILD_TOGGLEBUTTON;
+
+            case wxITEM_RADIO:
+                return GTK_TOOLBAR_CHILD_RADIOBUTTON;
+
+            default:
+                wxFAIL_MSG( _T("unknown toolbar child type") );
+                // fall through
+
+            case wxITEM_NORMAL:
+                return GTK_TOOLBAR_CHILD_BUTTON;
+        }
+    }
+
     GtkWidget            *m_item;
     GtkWidget            *m_pixmap;
 
@@ -119,6 +167,12 @@ static void gtk_toolbar_callback( GtkWidget *WXUNUSED(widget),
 
             gtk_pixmap_set( pixmap, bitmap.GetPixmap(), mask );
         }
+
+        if ( tool->IsRadio() && !tool->IsToggled() )
+        {
+            // radio button went up, don't report this as a wxWin event
+            return;
+        }
     }
 
     tbar->OnLeftClick( tool->GetId(), tool->IsToggled() );
@@ -168,14 +222,15 @@ void wxToolBarTool::Init()
 }
 
 wxToolBarToolBase *wxToolBar::CreateTool(int id,
+                                         const wxString& text,
                                          const wxBitmap& bitmap1,
                                          const wxBitmap& bitmap2,
-                                         bool toggle,
+                                         wxItemKind kind,
                                          wxObject *clientData,
                                          const wxString& shortHelpString,
                                          const wxString& longHelpString)
 {
-    return new wxToolBarTool(this, id, bitmap1, bitmap2, toggle,
+    return new wxToolBarTool(this, id, text, bitmap1, bitmap2, kind,
                              clientData, shortHelpString, longHelpString);
 }
 
@@ -220,9 +275,16 @@ bool wxToolBar::Create( wxWindow *parent,
         return FALSE;
     }
 
-    GtkOrientation orient = style & wxTB_VERTICAL ? GTK_ORIENTATION_VERTICAL
-                                                  : GTK_ORIENTATION_HORIZONTAL;
-    m_toolbar = GTK_TOOLBAR( gtk_toolbar_new( orient, GTK_TOOLBAR_ICONS ) );
+#ifdef __WXGTK20__
+    m_toolbar = GTK_TOOLBAR( gtk_toolbar_new() );
+    GtkSetStyle();
+#else
+    GtkOrientation orient;
+    GtkToolbarStyle gtkStyle;
+    GetGtkStyle(style, &orient, &gtkStyle);
+
+    m_toolbar = GTK_TOOLBAR( gtk_toolbar_new(orient, gtkStyle) );
+#endif
 
     SetToolSeparation(7);
 
@@ -242,8 +304,11 @@ bool wxToolBar::Create( wxWindow *parent,
 
     gtk_toolbar_set_tooltips( GTK_TOOLBAR(m_toolbar), TRUE );
 
+    // FIXME: there is no such function for toolbars in 2.0
+#ifndef __WXGTK20__
     if (style & wxTB_FLAT)
         gtk_toolbar_set_button_relief( GTK_TOOLBAR(m_toolbar), GTK_RELIEF_NONE );
+#endif
 
 
     m_fg = new GdkColor;
@@ -270,8 +335,9 @@ bool wxToolBar::Create( wxWindow *parent,
                     GTK_TOOLBAR(m_toolbar)->tooltips->tip_window ) );
 
     g_style->bg[GTK_STATE_NORMAL] = *m_bg;
-    gdk_font_unref( g_style->font );
-       g_style->font = gdk_font_ref( GtkGetDefaultGuiFont() );
+
+    SET_STYLE_FONT(g_style, GtkGetDefaultGuiFont());
+
     gtk_widget_set_style( GTK_TOOLBAR(m_toolbar)->tooltips->tip_window, g_style );
 
     m_parent->DoAddChild( this );
@@ -283,6 +349,24 @@ bool wxToolBar::Create( wxWindow *parent,
     return TRUE;
 }
 
+void wxToolBar::GtkSetStyle()
+{
+    GtkOrientation orient;
+    GtkToolbarStyle style;
+    GetGtkStyle(GetWindowStyle(), &orient, &style);
+
+    gtk_toolbar_set_orientation(m_toolbar, orient);
+    gtk_toolbar_set_style(m_toolbar, style);
+}
+
+void wxToolBar::SetWindowStyleFlag( long style )
+{
+    wxToolBarBase::SetWindowStyleFlag(style);
+
+    if ( m_toolbar )
+        GtkSetStyle();
+}
+
 bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase)
 {
     wxToolBarTool *tool = (wxToolBarTool *)toolBase;
@@ -292,7 +376,7 @@ bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase)
     
     if ( tool->IsButton() )
     {
-        wxBitmap bitmap = tool->GetBitmap1();
+        wxBitmap bitmap = tool->GetNormalBitmap();
 
         wxCHECK_MSG( bitmap.Ok(), FALSE,
                      wxT("invalid bitmap for wxToolBar icon") );
@@ -324,37 +408,70 @@ bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase)
     switch ( tool->GetStyle() )
     {
         case wxTOOL_STYLE_BUTTON:
-            tool->m_item = gtk_toolbar_insert_element
-                           (
-                              m_toolbar,
-                              tool->CanBeToggled()
-                                ? GTK_TOOLBAR_CHILD_TOGGLEBUTTON
-                                : GTK_TOOLBAR_CHILD_BUTTON,
-                              (GtkWidget *)NULL,
-                              (const char *)NULL,
-                              tool->GetShortHelp().mbc_str(),
-                              "", // tooltip_private_text (?)
-                              tool->m_pixmap,
-                              (GtkSignalFunc)gtk_toolbar_callback,
-                              (gpointer)tool,
-                              pos
-                           );
-
-            if ( !tool->m_item )
+            // for a radio button we need the widget which starts the radio
+            // group it belongs to, i.e. the first radio button immediately
+            // preceding this one
             {
-                wxFAIL_MSG( _T("gtk_toolbar_insert_element() failed") );
+                GtkWidget *widget = NULL;
 
-                return FALSE;
-            }
+                if ( tool->IsRadio() )
+                {
+                    wxToolBarToolsList::Node *node = pos ? m_tools.Item(pos - 1)
+                                                         : NULL;
+                    while ( node )
+                    {
+                        wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
+                        if ( !tool->IsRadio() )
+                            break;
+
+                        widget = tool->m_item;
+
+                        node = node->GetPrevious();
+                    }
+
+                    if ( !widget )
+                    {
+                        // this is the first button in the radio button group,
+                        // it will be toggled automatically by GTK so bring the
+                        // internal flag in sync
+                        tool->Toggle(TRUE);
+                    }
+                }
+
+                tool->m_item = gtk_toolbar_insert_element
+                               (
+                                  m_toolbar,
+                                  tool->GetGtkChildType(),
+                                  widget,
+                                  tool->GetLabel().empty()
+                                    ? NULL
+                                    : tool->GetLabel().mbc_str(),
+                                  tool->GetShortHelp().empty()
+                                    ? NULL
+                                    : tool->GetShortHelp().mbc_str(),
+                                  "", // tooltip_private_text (?)
+                                  tool->m_pixmap,
+                                  (GtkSignalFunc)gtk_toolbar_callback,
+                                  (gpointer)tool,
+                                  pos
+                               );
+
+                if ( !tool->m_item )
+                {
+                    wxFAIL_MSG( _T("gtk_toolbar_insert_element() failed") );
 
-            gtk_signal_connect( GTK_OBJECT(tool->m_item),
-                                "enter_notify_event", 
-                                GTK_SIGNAL_FUNC(gtk_toolbar_tool_callback),
-                                (gpointer)tool );
-            gtk_signal_connect( GTK_OBJECT(tool->m_item),
-                                "leave_notify_event", 
-                                GTK_SIGNAL_FUNC(gtk_toolbar_tool_callback),
-                                (gpointer)tool );
+                    return FALSE;
+                }
+
+                gtk_signal_connect( GTK_OBJECT(tool->m_item),
+                                    "enter_notify_event", 
+                                    GTK_SIGNAL_FUNC(gtk_toolbar_tool_callback),
+                                    (gpointer)tool );
+                gtk_signal_connect( GTK_OBJECT(tool->m_item),
+                                    "leave_notify_event", 
+                                    GTK_SIGNAL_FUNC(gtk_toolbar_tool_callback),
+                                    (gpointer)tool );
+            }
             break;
 
         case wxTOOL_STYLE_SEPARATOR:
@@ -478,7 +595,11 @@ void wxToolBar::SetMargins( int x, int y )
 
 void wxToolBar::SetToolSeparation( int separation )
 {
+    // FIXME: this function disappeared
+#ifndef __WXGTK20__
     gtk_toolbar_set_space_size( m_toolbar, separation );
+#endif
+
     m_toolSeparation = separation;
 }