]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/toolbar.cpp
Add wxTranslations::GetTranslatedString().
[wxWidgets.git] / src / gtk / toolbar.cpp
index 701ec64a8451abc73bbb15df3a939dbc13105ce1..f19f11d5b26b51dda716ac54e316d4638d9c47f2 100644 (file)
@@ -3,7 +3,6 @@
 // Purpose:     GTK toolbar
 // Author:      Robert Roebling
 // Modified:    13.12.99 by VZ to derive from wxToolBarBase
-// RCS-ID:      $Id$
 // Copyright:   (c) Robert Roebling
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
@@ -15,7 +14,9 @@
 
 #include "wx/toolbar.h"
 
+#include <gtk/gtk.h>
 #include "wx/gtk/private.h"
+#include "wx/gtk/private/gtk2-compat.h"
 
 // ----------------------------------------------------------------------------
 // globals
@@ -168,40 +169,37 @@ enter_notify_event(GtkWidget*, GdkEventCrossing* event, wxToolBarTool* tool)
 }
 }
 
-//-----------------------------------------------------------------------------
-// "size_request" from m_toolbar
-//-----------------------------------------------------------------------------
-
-extern "C" {
-static void
-size_request(GtkWidget*, GtkRequisition* req, wxToolBar* win)
-{
-    const wxSize margins = win->GetMargins();
-    req->width  += margins.x;
-    req->height += 2 * margins.y;
-}
-}
-
 //-----------------------------------------------------------------------------
 // "expose_event" from GtkImage inside m_item
 //-----------------------------------------------------------------------------
 
 extern "C" {
 static gboolean
+#ifdef __WXGTK3__
+image_draw(GtkWidget* widget, cairo_t* cr, wxToolBarTool* tool)
+#else
 image_expose_event(GtkWidget* widget, GdkEventExpose*, wxToolBarTool* tool)
+#endif
 {
     const wxBitmap& bitmap = tool->GetDisabledBitmap();
     if (tool->IsEnabled() || !bitmap.IsOk())
         return false;
 
     // draw disabled bitmap ourselves, GtkImage has no way to specify it
-    const GtkAllocation& alloc = widget->allocation;
+    GtkAllocation alloc;
+    gtk_widget_get_allocation(widget, &alloc);
+    GtkRequisition req;
+    gtk_widget_get_requisition(widget, &req);
+    const int x = alloc.x + (alloc.width - req.width) / 2;
+    const int y = alloc.y + (alloc.height - req.height) / 2;
+#ifdef __WXGTK3__
+    bitmap.Draw(cr, x, y);
+#else
     gdk_draw_pixbuf(
-        widget->window, widget->style->black_gc, bitmap.GetPixbuf(),
-        0, 0,
-        alloc.x + (alloc.width - widget->requisition.width) / 2,
-        alloc.y + (alloc.height - widget->requisition.height) / 2,
+        gtk_widget_get_window(widget), gtk_widget_get_style(widget)->black_gc, bitmap.GetPixbuf(),
+        0, 0, x, y,
         -1, -1, GDK_RGB_DITHER_NORMAL, 0, 0);
+#endif
     return true;
 }
 }
@@ -250,7 +248,7 @@ void wxToolBar::AddChildGTK(wxWindowGTK* child)
     GtkToolItem* item = gtk_tool_item_new();
     gtk_container_add(GTK_CONTAINER(item), align);
     // position will be corrected in DoInsertTool if necessary
-    gtk_toolbar_insert(GTK_TOOLBAR(GTK_BIN(m_widget)->child), item, -1);
+    gtk_toolbar_insert(GTK_TOOLBAR(gtk_bin_get_child(GTK_BIN(m_widget))), item, -1);
 }
 
 // ----------------------------------------------------------------------------
@@ -272,19 +270,16 @@ void wxToolBarTool::SetImage()
 void wxToolBarTool::CreateDropDown()
 {
     gtk_tool_item_set_homogeneous(m_item, false);
-    GtkWidget* box;
-    GtkWidget* arrow;
+    GtkOrientation orient = GTK_ORIENTATION_HORIZONTAL;
+    GtkArrowType arrowType = GTK_ARROW_DOWN;
     if (GetToolBar()->HasFlag(wxTB_LEFT | wxTB_RIGHT))
     {
-        box = gtk_vbox_new(false, 0);
-        arrow = gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
-    }
-    else
-    {
-        box = gtk_hbox_new(false, 0);
-        arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE);
+        orient = GTK_ORIENTATION_VERTICAL;
+        arrowType = GTK_ARROW_RIGHT;
     }
-    GtkWidget* tool_button = GTK_BIN(m_item)->child;
+    GtkWidget* box = gtk_box_new(orient, 0);
+    GtkWidget* arrow = gtk_arrow_new(arrowType, GTK_SHADOW_NONE);
+    GtkWidget* tool_button = gtk_bin_get_child(GTK_BIN(m_item));
     gtk_widget_reparent(tool_button, box);
     GtkWidget* arrow_button = gtk_toggle_button_new();
     gtk_button_set_relief(GTK_BUTTON(arrow_button),
@@ -302,13 +297,14 @@ void wxToolBarTool::CreateDropDown()
 void wxToolBarTool::ShowDropdown(GtkToggleButton* button)
 {
     wxToolBarBase* toolbar = GetToolBar();
-    wxCommandEvent event(wxEVT_COMMAND_TOOL_DROPDOWN_CLICKED, GetId());
+    wxCommandEvent event(wxEVT_TOOL_DROPDOWN, GetId());
     if (!toolbar->HandleWindowEvent(event))
     {
         wxMenu* menu = GetDropdownMenu();
         if (menu)
         {
-            const GtkAllocation& alloc = GTK_WIDGET(button)->allocation;
+            GtkAllocation alloc;
+            gtk_widget_get_allocation(GTK_WIDGET(button), &alloc);
             int x = alloc.x;
             int y = alloc.y;
             if (toolbar->HasFlag(wxTB_LEFT | wxTB_RIGHT))
@@ -351,11 +347,13 @@ void wxToolBar::Init()
 
 wxToolBar::~wxToolBar()
 {
-    if (m_tooltips)
+#ifndef __WXGTK3__
+    if (m_tooltips) // always NULL if GTK >= 2.12
     {
         gtk_object_destroy(GTK_OBJECT(m_tooltips));
         g_object_unref(m_tooltips);
     }
+#endif
 }
 
 bool wxToolBar::Create( wxWindow *parent,
@@ -376,9 +374,14 @@ bool wxToolBar::Create( wxWindow *parent,
     FixupStyle();
 
     m_toolbar = GTK_TOOLBAR( gtk_toolbar_new() );
-    m_tooltips = gtk_tooltips_new();
-    g_object_ref(m_tooltips);
-    gtk_object_sink(GTK_OBJECT(m_tooltips));
+#ifndef __WXGTK3__
+    if (gtk_check_version(2, 12, 0))
+    {
+        m_tooltips = gtk_tooltips_new();
+        g_object_ref(m_tooltips);
+        gtk_object_sink(GTK_OBJECT(m_tooltips));
+    }
+#endif
     GtkSetStyle();
 
     if (style & wxTB_DOCKABLE)
@@ -406,15 +409,12 @@ bool wxToolBar::Create( wxWindow *parent,
 
     PostCreation(size);
 
-    g_signal_connect_after(m_toolbar, "size_request",
-        G_CALLBACK(size_request), this);
-
     return true;
 }
 
 GdkWindow *wxToolBar::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
 {
-    return GTK_WIDGET(m_toolbar)->window;
+    return gtk_widget_get_window(GTK_WIDGET(m_toolbar));
 }
 
 void wxToolBar::GtkSetStyle()
@@ -433,7 +433,11 @@ void wxToolBar::GtkSetStyle()
             style = GTK_TOOLBAR_BOTH_HORIZ;
     }
 
+#ifdef __WXGTK3__
+    gtk_orientable_set_orientation(GTK_ORIENTABLE(m_toolbar), orient);
+#else
     gtk_toolbar_set_orientation(m_toolbar, orient);
+#endif
     gtk_toolbar_set_style(m_toolbar, style);
 }
 
@@ -445,11 +449,38 @@ void wxToolBar::SetWindowStyleFlag( long style )
         GtkSetStyle();
 }
 
+bool wxToolBar::Realize()
+{
+    if ( !wxToolBarBase::Realize() )
+        return false;
+
+    // bring the initial state of all the toolbar items in line with the
+    // internal state if the latter was changed by calling wxToolBarTool::
+    // Enable(): this works under MSW, where the toolbar items are only created
+    // in Realize() which uses the internal state to determine the initial
+    // button state, so make it work under GTK too
+    for ( wxToolBarToolsList::const_iterator i = m_tools.begin();
+          i != m_tools.end();
+          ++i )
+    {
+        // by default the toolbar items are enabled and not toggled, so we only
+        // have to do something if their internal state doesn't correspond to
+        // this
+        if ( !(*i)->IsEnabled() )
+            DoEnableTool(*i, false);
+        if ( (*i)->IsToggled() )
+            DoToggleTool(*i, true);
+    }
+
+    return true;
+}
+
 bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase)
 {
     wxToolBarTool* tool = static_cast<wxToolBarTool*>(toolBase);
 
     GSList* radioGroup;
+    GtkWidget* bin_child;
     switch ( tool->GetStyle() )
     {
         case wxTOOL_STYLE_BUTTON:
@@ -462,7 +493,7 @@ bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase)
                     break;
                 case wxITEM_RADIO:
                     radioGroup = GetRadioGroup(pos);
-                    if (radioGroup)
+                    if (!radioGroup)
                     {
                         // this is the first button in the radio button group,
                         // it will be toggled automatically by GTK so bring the
@@ -490,8 +521,13 @@ bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase)
                     GTK_TOOL_BUTTON(tool->m_item), image);
                 tool->SetImage();
                 gtk_widget_show(image);
+#ifdef __WXGTK3__
+                g_signal_connect(image, "draw",
+                    G_CALLBACK(image_draw), tool);
+#else
                 g_signal_connect(image, "expose_event",
                     G_CALLBACK(image_expose_event), tool);
+#endif
             }
             if (!tool->GetLabel().empty())
             {
@@ -502,14 +538,27 @@ bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase)
             }
             if (!HasFlag(wxTB_NO_TOOLTIPS) && !tool->GetShortHelp().empty())
             {
-                gtk_tool_item_set_tooltip(tool->m_item,
-                    m_tooltips, wxGTK_CONV(tool->GetShortHelp()), "");
+#if GTK_CHECK_VERSION(2, 12, 0)
+                if (GTK_CHECK_VERSION(3,0,0) || gtk_check_version(2,12,0) == NULL)
+                {
+                    gtk_tool_item_set_tooltip_text(tool->m_item,
+                        wxGTK_CONV(tool->GetShortHelp()));
+                }
+                else
+#endif
+                {
+#ifndef __WXGTK3__
+                    gtk_tool_item_set_tooltip(tool->m_item,
+                        m_tooltips, wxGTK_CONV(tool->GetShortHelp()), "");
+#endif
+                }
             }
-            g_signal_connect(GTK_BIN(tool->m_item)->child, "button_press_event",
+            bin_child = gtk_bin_get_child(GTK_BIN(tool->m_item));
+            g_signal_connect(bin_child, "button_press_event",
                 G_CALLBACK(button_press_event), tool);
-            g_signal_connect(tool->m_item, "enter_notify_event",
+            g_signal_connect(bin_child, "enter_notify_event",
                 G_CALLBACK(enter_notify_event), tool);
-            g_signal_connect(tool->m_item, "leave_notify_event",
+            g_signal_connect(bin_child, "leave_notify_event",
                 G_CALLBACK(enter_notify_event), tool);
 
             if (tool->GetKind() == wxITEM_DROPDOWN)
@@ -519,14 +568,23 @@ bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase)
 
         case wxTOOL_STYLE_SEPARATOR:
             tool->m_item = gtk_separator_tool_item_new();
+            if ( tool->IsStretchable() )
+            {
+                gtk_separator_tool_item_set_draw
+                (
+                    GTK_SEPARATOR_TOOL_ITEM(tool->m_item),
+                    FALSE
+                );
+                gtk_tool_item_set_expand(tool->m_item, TRUE);
+            }
             gtk_toolbar_insert(m_toolbar, tool->m_item, int(pos));
             break;
 
         case wxTOOL_STYLE_CONTROL:
             wxWindow* control = tool->GetControl();
-            if (control->m_widget->parent == NULL)
+            if (gtk_widget_get_parent(control->m_widget) == NULL)
                 AddChildGTK(control);
-            tool->m_item = GTK_TOOL_ITEM(control->m_widget->parent->parent);
+            tool->m_item = GTK_TOOL_ITEM(gtk_widget_get_parent(gtk_widget_get_parent(control->m_widget)));
             if (gtk_toolbar_get_item_index(m_toolbar, tool->m_item) != int(pos))
             {
                 g_object_ref(tool->m_item);
@@ -535,12 +593,6 @@ bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase)
                 gtk_toolbar_insert(m_toolbar, tool->m_item, int(pos));
                 g_object_unref(tool->m_item);
             }
-            // Inserted items "slide" into place using an animated effect that
-            // causes multiple size events on the item. Must set size request
-            // to keep item size from getting permanently set too small by the
-            // first of these size events.
-            const wxSize size = control->GetSize();
-            gtk_widget_set_size_request(control->m_widget, size.x, size.y);
             break;
     }
     gtk_widget_show(GTK_WIDGET(tool->m_item));
@@ -561,9 +613,9 @@ bool wxToolBar::DoDeleteTool(size_t /* pos */, wxToolBarToolBase* toolBase)
         // while if we're called from DeleteTool() the control will
         // be destroyed when wxToolBarToolBase itself is deleted
         GtkWidget* widget = tool->GetControl()->m_widget;
-        gtk_container_remove(GTK_CONTAINER(widget->parent), widget);
+        gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget);
     }
-    gtk_object_destroy(GTK_OBJECT(tool->m_item));
+    gtk_widget_destroy(GTK_WIDGET(tool->m_item));
     tool->m_item = NULL;
 
     InvalidateBestSize();
@@ -660,8 +712,20 @@ void wxToolBar::SetToolShortHelp( int id, const wxString& helpString )
         (void)tool->SetShortHelp(helpString);
         if (tool->m_item)
         {
-            gtk_tool_item_set_tooltip(tool->m_item,
-                m_tooltips, wxGTK_CONV(helpString), "");
+#if GTK_CHECK_VERSION(2, 12, 0)
+            if (GTK_CHECK_VERSION(3,0,0) || gtk_check_version(2,12,0) == NULL)
+            {
+                gtk_tool_item_set_tooltip_text(tool->m_item,
+                    wxGTK_CONV(helpString));
+            }
+            else
+#endif
+            {
+#ifndef __WXGTK3__
+                gtk_tool_item_set_tooltip(tool->m_item,
+                    m_tooltips, wxGTK_CONV(helpString), "");
+#endif
+            }
         }
     }
 }
@@ -689,66 +753,13 @@ void wxToolBar::SetToolDisabledBitmap( int id, const wxBitmap& bitmap )
     }
 }
 
-// ----------------------------------------------------------------------------
-// wxToolBar idle handling
-// ----------------------------------------------------------------------------
-
-void wxToolBar::OnInternalIdle()
-{
-    // Check if we have to show window now
-    if (GTKShowFromOnIdle()) return;
-
-    wxCursor cursor = m_cursor;
-    if (g_globalCursor.Ok()) cursor = g_globalCursor;
-
-    if (cursor.Ok())
-    {
-        /* I now set the cursor the anew in every OnInternalIdle call
-           as setting the cursor in a parent window also effects the
-           windows above so that checking for the current cursor is
-           not possible. */
-
-        if (HasFlag(wxTB_DOCKABLE) && (m_widget->window))
-        {
-            /* if the toolbar is dockable, then m_widget stands for the
-               GtkHandleBox widget, which uses its own window so that we
-               can set the cursor for it. if the toolbar is not dockable,
-               m_widget comes from m_toolbar which uses its parent's
-               window ("windowless windows") and thus we cannot set the
-               cursor. */
-            gdk_window_set_cursor( m_widget->window, cursor.GetCursor() );
-        }
-
-        wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
-        while ( node )
-        {
-            wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
-            node = node->GetNext();
-
-            if (tool->m_item)
-            {
-                GdkWindow* window = GTK_WIDGET(tool->m_item)->window;
-
-                if ( window )
-                {
-                    gdk_window_set_cursor( window, cursor.GetCursor() );
-                }
-            }
-        }
-    }
-
-    if (wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen())
-        UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
-}
-
-
 // ----------------------------------------------------------------------------
 
 // static
 wxVisualAttributes
 wxToolBar::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
 {
-    return GetDefaultAttributesFromGTKWidget(gtk_toolbar_new);
+    return GetDefaultAttributesFromGTKWidget(gtk_toolbar_new());
 }
 
 #endif // wxUSE_TOOLBAR_NATIVE