]> 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 ffd6c88c6006e5264d4bd48c9c856c242147e286..38a8fde2533d7fcd0c9190d0bbe339e43f2baf5b 100644 (file)
@@ -43,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
 // ----------------------------------------------------------------------------
@@ -52,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();
@@ -70,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;
 
@@ -118,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() );
@@ -167,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);
 }
 
@@ -219,15 +275,15 @@ bool wxToolBar::Create( wxWindow *parent,
         return FALSE;
     }
 
-    GtkOrientation orient = style & wxTB_VERTICAL ? GTK_ORIENTATION_VERTICAL
-                                                  : GTK_ORIENTATION_HORIZONTAL;
-
 #ifdef __WXGTK20__
     m_toolbar = GTK_TOOLBAR( gtk_toolbar_new() );
-    gtk_toolbar_set_orientation(m_toolbar, orient);
-    gtk_toolbar_set_style(m_toolbar, GTK_TOOLBAR_ICONS);
+    GtkSetStyle();
 #else
-    m_toolbar = GTK_TOOLBAR( gtk_toolbar_new( orient, GTK_TOOLBAR_ICONS ) );
+    GtkOrientation orient;
+    GtkToolbarStyle gtkStyle;
+    GetGtkStyle(style, &orient, &gtkStyle);
+
+    m_toolbar = GTK_TOOLBAR( gtk_toolbar_new(orient, gtkStyle) );
 #endif
 
     SetToolSeparation(7);
@@ -293,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;
@@ -302,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") );
@@ -334,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);
+                    }
+                }
 
-            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 );
+                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") );
+
+                    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: