]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/tbargtk.cpp
Applied patch from Bo, WIP
[wxWidgets.git] / src / gtk / tbargtk.cpp
index 55c3ba4f9470ce396b2369ad042dc6f37a1d9120..cb6c98f1c57dde76ae6d5545e73c30fb1dd25395 100644 (file)
@@ -35,7 +35,6 @@
 #endif
 
 #include "wx/gtk/private.h"
-#include "wx/crt.h"
 #include "wx/menu.h"
 
 
@@ -138,6 +137,7 @@ public:
                 wxFAIL_MSG( _T("unknown toolbar child type") );
                 // fall through
 
+            case wxITEM_DROPDOWN:
             case wxITEM_NORMAL:
                 return GTK_TOOLBAR_CHILD_BUTTON;
         }
@@ -174,7 +174,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl)
 //-----------------------------------------------------------------------------
 
 extern "C" {
-static void gtk_toolbar_callback( GtkWidget *WXUNUSED(widget),
+static void gtk_toolbar_callback( GtkWidget *widget,
                                   wxToolBarTool *tool )
 {
     wxToolBar *tbar = (wxToolBar *)tool->GetToolBar();
@@ -186,6 +186,14 @@ static void gtk_toolbar_callback( GtkWidget *WXUNUSED(widget),
 
     if (tool->CanBeToggled())
     {
+        if (tool->IsRadio() &&
+            gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget)) &&
+            tool->IsToggled())
+        {
+            // pressed an already pressed radio button
+            return;
+        }
+
         tool->Toggle();
 
         tool->SetImage(tool->GetBitmap());
@@ -258,7 +266,7 @@ static gint gtk_toolbar_buddy_leave_callback( GtkWidget *WXUNUSED(widget),
 }
 
 //-----------------------------------------------------------------------------
-// "left-click" on dropdown 
+// "left-click" on dropdown
 //-----------------------------------------------------------------------------
 
 extern "C"
@@ -287,22 +295,22 @@ static gboolean gtk_toolbar_dropdown_lclick_callback(GtkWidget *widget,
     {
         return TRUE;
     }
-    
+
     wxMenu * const menu = tool->GetDropdownMenu();
     if (!menu)
         return TRUE;
 
     // simulate press
     gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(widget), TRUE );
-    
+
     g_signal_connect (menu->m_menu, "hide",
                                     G_CALLBACK (gtk_pop_tb_hide_callback),
                                     widget);
-    
-    tbar->PopupMenu( menu, widget->allocation.x, 
+
+    tbar->PopupMenu( menu, widget->allocation.x,
                            widget->allocation.y + widget->allocation.height );
-                           
-    
+
+
     return TRUE;
 }
 }
@@ -355,10 +363,12 @@ void gtktoolwidget_size_callback( GtkWidget *widget,
 // InsertChild callback for wxToolBar
 //-----------------------------------------------------------------------------
 
-static void wxInsertChildInToolBar( wxToolBar* WXUNUSED(parent),
-                                    wxWindow* WXUNUSED(child) )
+static void wxInsertChildInToolBar( wxWindow* WXUNUSED(parent),
+                                    wxWindow* child)
 {
-    // we don't do anything here
+    // Child widget will be inserted into GtkToolbar by DoInsertTool. Ref it
+    // here so reparenting into wxToolBar doesn't delete it.
+    g_object_ref(child->m_widget);
 }
 
 // ----------------------------------------------------------------------------
@@ -413,7 +423,7 @@ bool wxToolBar::Create( wxWindow *parent,
                         long style,
                         const wxString& name )
 {
-    m_insertCallback = (wxInsertChildFunction)wxInsertChildInToolBar;
+    m_insertCallback = wxInsertChildInToolBar;
 
     if ( !PreCreation( parent, pos, size ) ||
          !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
@@ -509,24 +519,21 @@ bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase)
     }
 
     int posGtk = 0;
-    if (pos > 0)
-    {    
-        size_t i;
-        for (i = 0; i < pos; i++)
+    if ( pos > 0 )
+    {
+        for ( size_t i = 0; i < pos; i++ )
         {
             posGtk++;
-            
-        
-            // if we have a dropdown menu, we use 2 GTK tools
-            // internally
+
+            // if we have a dropdown menu, we use 2 GTK tools internally
             wxToolBarToolsList::compatibility_iterator node = m_tools.Item( i );
             wxToolBarTool *tool = (wxToolBarTool*) node->GetData();
-            if (tool->IsButton() && (tool->GetKind() == wxITEM_DROPDOWN))
+            if ( tool->IsButton() && (tool->GetKind() == wxITEM_DROPDOWN) )
                 posGtk++;
         }
     }
-    
-    
+
+
     switch ( tool->GetStyle() )
     {
         case wxTOOL_STYLE_BUTTON:
@@ -600,12 +607,12 @@ bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase)
                     GtkWidget *image = gtk_image_new_from_pixbuf( pixbuf );
                     gtk_widget_show( image );
                     gtk_container_add( GTK_CONTAINER(dropdown), image );
-                    
+
                     if (GetWindowStyle() & wxTB_FLAT)
                         gtk_button_set_relief( GTK_BUTTON(dropdown), GTK_RELIEF_NONE );
-                       GTK_WIDGET_UNSET_FLAGS (dropdown, GTK_CAN_FOCUS);
+                    GTK_WIDGET_UNSET_FLAGS (dropdown, GTK_CAN_FOCUS);
                     gtk_widget_show( dropdown );
-                
+
                     g_signal_connect (dropdown, "enter_notify_event",
                                   G_CALLBACK (gtk_toolbar_buddy_enter_callback),
                                   tool->m_item);
@@ -615,12 +622,12 @@ bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase)
                     g_signal_connect(dropdown, "button-press-event",
                                   G_CALLBACK (gtk_toolbar_dropdown_lclick_callback),
                                   tool);
-                                  
+
                     GtkRequisition req;
                     (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(tool->m_item) )->size_request )
                         (tool->m_item, &req );
-                    gtk_widget_set_size_request( dropdown, -1, req.height );     
-                                  
+                    gtk_widget_set_size_request( dropdown, -1, req.height );
+
                     gtk_toolbar_insert_widget(
                                        m_toolbar,
                                        dropdown,
@@ -646,6 +653,8 @@ bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase)
                                        (const char *) NULL,
                                        posGtk
                                       );
+            // release reference obtained by wxInsertChildInToolBar
+            g_object_unref(tool->GetControl()->m_widget);
 
             // connect after in order to correct size_allocate events
             g_signal_connect_after (tool->GetControl()->m_widget, "size_allocate",