#include "wx/toolbar.h"
+#include <gtk/gtk.h>
#include "wx/gtk/private.h"
+#include "wx/gtk/private/gtk2-compat.h"
// ----------------------------------------------------------------------------
// globals
}
}
-//-----------------------------------------------------------------------------
-// "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;
}
}
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);
}
// ----------------------------------------------------------------------------
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),
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))
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,
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)
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()
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);
}
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:
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
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())
{
}
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)
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);
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));
// 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();
(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
+ }
}
}
}
}
}
-// ----------------------------------------------------------------------------
-// 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