summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSoeren Sandmann <sandmann@daimi.au.dk>2003-06-29 23:34:20 +0000
committerSøren Sandmann Pedersen <ssp@src.gnome.org>2003-06-29 23:34:20 +0000
commitfa336d283ac1c4392a1452bb869b0e9f3466d9c9 (patch)
tree753b95902e0410e07364e20eedaf86b14d588f5e
parent8de177338402d899df856b74cbdc434f6cfda1e2 (diff)
downloadgtk+-fa336d283ac1c4392a1452bb869b0e9f3466d9c9.tar.gz
gtkradiotoolbutton.c gtkradiotoolbutton.h gtktoggletoolbutton.c
Mon Jun 30 01:20:19 2003 Soeren Sandmann <sandmann@daimi.au.dk> * gtkradiotoolbutton.c * gtkradiotoolbutton.h * gtktoggletoolbutton.c * gtktoggletoolbutton.h * gtktoolbutton.c * gtktoolbutton.h * gtktoolitem.c * gtktoolitem.h * gtktoolbar.c * gtktoolbar.h * gtkseparatortoolitem.c * gtkseparatortoolitem.h New toolbar.
-rw-r--r--ChangeLog17
-rw-r--r--ChangeLog.pre-2-1017
-rw-r--r--ChangeLog.pre-2-417
-rw-r--r--ChangeLog.pre-2-617
-rw-r--r--ChangeLog.pre-2-817
-rw-r--r--gtk/Makefile.am34
-rw-r--r--gtk/gtkmarshalers.list1
-rw-r--r--gtk/gtkradiotoolbutton.c147
-rw-r--r--gtk/gtkradiotoolbutton.h62
-rw-r--r--gtk/gtkseparatortoolitem.c90
-rw-r--r--gtk/gtkseparatortoolitem.h50
-rw-r--r--gtk/gtktoggletoolbutton.c244
-rw-r--r--gtk/gtktoggletoolbutton.h68
-rw-r--r--gtk/gtktoolbar.c3242
-rw-r--r--gtk/gtktoolbar.h179
-rw-r--r--gtk/gtktoolbutton.c812
-rw-r--r--gtk/gtktoolbutton.h92
-rw-r--r--gtk/gtktoolitem.c697
-rw-r--r--gtk/gtktoolitem.h110
19 files changed, 4654 insertions, 1259 deletions
diff --git a/ChangeLog b/ChangeLog
index e6b8609b28..19f002d3df 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+Mon Jun 30 01:20:19 2003 Soeren Sandmann <sandmann@daimi.au.dk>
+
+ * gtkradiotoolbutton.c
+ * gtkradiotoolbutton.h
+ * gtktoggletoolbutton.c
+ * gtktoggletoolbutton.h
+ * gtktoolbutton.c
+ * gtktoolbutton.h
+ * gtktoolitem.c
+ * gtktoolitem.h
+ * gtktoolbar.c
+ * gtktoolbar.h
+ * gtkseparatortoolitem.c
+ * gtkseparatortoolitem.h
+
+ New toolbar.
+
2003-06-29 Matthias Clasen <maclas@gmx.de>
* gtk/gtkwidget.c (gtk_widget_class_init): Remove a duplicate parameter from docs, some more formatting
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index e6b8609b28..19f002d3df 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,20 @@
+Mon Jun 30 01:20:19 2003 Soeren Sandmann <sandmann@daimi.au.dk>
+
+ * gtkradiotoolbutton.c
+ * gtkradiotoolbutton.h
+ * gtktoggletoolbutton.c
+ * gtktoggletoolbutton.h
+ * gtktoolbutton.c
+ * gtktoolbutton.h
+ * gtktoolitem.c
+ * gtktoolitem.h
+ * gtktoolbar.c
+ * gtktoolbar.h
+ * gtkseparatortoolitem.c
+ * gtkseparatortoolitem.h
+
+ New toolbar.
+
2003-06-29 Matthias Clasen <maclas@gmx.de>
* gtk/gtkwidget.c (gtk_widget_class_init): Remove a duplicate parameter from docs, some more formatting
diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4
index e6b8609b28..19f002d3df 100644
--- a/ChangeLog.pre-2-4
+++ b/ChangeLog.pre-2-4
@@ -1,3 +1,20 @@
+Mon Jun 30 01:20:19 2003 Soeren Sandmann <sandmann@daimi.au.dk>
+
+ * gtkradiotoolbutton.c
+ * gtkradiotoolbutton.h
+ * gtktoggletoolbutton.c
+ * gtktoggletoolbutton.h
+ * gtktoolbutton.c
+ * gtktoolbutton.h
+ * gtktoolitem.c
+ * gtktoolitem.h
+ * gtktoolbar.c
+ * gtktoolbar.h
+ * gtkseparatortoolitem.c
+ * gtkseparatortoolitem.h
+
+ New toolbar.
+
2003-06-29 Matthias Clasen <maclas@gmx.de>
* gtk/gtkwidget.c (gtk_widget_class_init): Remove a duplicate parameter from docs, some more formatting
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
index e6b8609b28..19f002d3df 100644
--- a/ChangeLog.pre-2-6
+++ b/ChangeLog.pre-2-6
@@ -1,3 +1,20 @@
+Mon Jun 30 01:20:19 2003 Soeren Sandmann <sandmann@daimi.au.dk>
+
+ * gtkradiotoolbutton.c
+ * gtkradiotoolbutton.h
+ * gtktoggletoolbutton.c
+ * gtktoggletoolbutton.h
+ * gtktoolbutton.c
+ * gtktoolbutton.h
+ * gtktoolitem.c
+ * gtktoolitem.h
+ * gtktoolbar.c
+ * gtktoolbar.h
+ * gtkseparatortoolitem.c
+ * gtkseparatortoolitem.h
+
+ New toolbar.
+
2003-06-29 Matthias Clasen <maclas@gmx.de>
* gtk/gtkwidget.c (gtk_widget_class_init): Remove a duplicate parameter from docs, some more formatting
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index e6b8609b28..19f002d3df 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,3 +1,20 @@
+Mon Jun 30 01:20:19 2003 Soeren Sandmann <sandmann@daimi.au.dk>
+
+ * gtkradiotoolbutton.c
+ * gtkradiotoolbutton.h
+ * gtktoggletoolbutton.c
+ * gtktoggletoolbutton.h
+ * gtktoolbutton.c
+ * gtktoolbutton.h
+ * gtktoolitem.c
+ * gtktoolitem.h
+ * gtktoolbar.c
+ * gtktoolbar.h
+ * gtkseparatortoolitem.c
+ * gtkseparatortoolitem.h
+
+ New toolbar.
+
2003-06-29 Matthias Clasen <maclas@gmx.de>
* gtk/gtkwidget.c (gtk_widget_class_init): Remove a duplicate parameter from docs, some more formatting
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index f7b54a4ff7..494a82d430 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -94,28 +94,27 @@ gtk_public_h_sources = \
gtkalignment.h \
gtkarrow.h \
gtkaspectframe.h \
+ gtkbbox.h \
gtkbin.h \
gtkbindings.h \
- gtkbbox.h \
gtkbox.h \
gtkbutton.h \
gtkcalendar.h \
+ gtkcelleditable.h \
+ gtkcellrenderer.h \
+ gtkcellrendererpixbuf.h \
+ gtkcellrenderertext.h \
+ gtkcellrenderertoggle.h \
gtkcheckbutton.h \
gtkcheckmenuitem.h \
- gtkseparatormenuitem.h \
- gtkclist.h \
gtkclipboard.h \
+ gtkclist.h \
gtkcolorsel.h \
gtkcolorseldialog.h \
gtkcombo.h \
gtkcontainer.h \
gtkctree.h \
gtkcurve.h \
- gtkcellrenderer.h \
- gtkcelleditable.h \
- gtkcellrenderertext.h \
- gtkcellrenderertoggle.h \
- gtkcellrendererpixbuf.h \
gtkdebug.h \
gtkdialog.h \
gtkdnd.h \
@@ -162,8 +161,8 @@ gtk_public_h_sources = \
gtkmessagedialog.h \
gtkmisc.h \
gtknotebook.h \
- gtkoldeditable.h \
gtkobject.h \
+ gtkoldeditable.h \
gtkoptionmenu.h \
gtkpaned.h \
gtkpixmap.h \
@@ -174,6 +173,7 @@ gtk_public_h_sources = \
gtkprogressbar.h \
gtkradiobutton.h \
gtkradiomenuitem.h \
+ gtkradiotoolbutton.h \
gtkrange.h \
gtkrc.h \
gtkruler.h \
@@ -182,16 +182,19 @@ gtk_public_h_sources = \
gtkscrolledwindow.h \
gtkselection.h \
gtkseparator.h \
+ gtkseparatormenuitem.h \
+ gtkseparatortoolitem.h \
gtksettings.h \
gtksignal.h \
gtksizegroup.h \
gtksocket.h \
gtkspinbutton.h \
- gtkstyle.h \
gtkstatusbar.h \
gtkstock.h \
+ gtkstyle.h \
gtktable.h \
gtktearoffmenuitem.h \
+ gtktext.h \
gtktextbuffer.h \
gtktextchild.h \
gtktextdisplay.h \
@@ -201,10 +204,12 @@ gtk_public_h_sources = \
gtktexttag.h \
gtktexttagtable.h \
gtktextview.h \
- gtktext.h \
gtktipsquery.h \
gtktogglebutton.h \
+ gtktoggletoolbutton.h \
gtktoolbar.h \
+ gtktoolbutton.h \
+ gtktoolitem.h \
gtktooltips.h \
gtktree.h \
gtktreednd.h \
@@ -249,6 +254,12 @@ gtk_c_sources = \
gtkaccelgroup.c \
gtkaccelmap.c \
gtkaccellabel.c \
+ gtkradiotoolbutton.c \
+ gtktoggletoolbutton.c \
+ gtktoolbar.c \
+ gtktoolbutton.c \
+ gtkseparatortoolitem.c \
+ gtktoolitem.c \
gtkaccessible.c \
gtkadjustment.c \
gtkalignment.c \
@@ -374,7 +385,6 @@ gtk_c_sources = \
gtkthemes.c \
gtktipsquery.c \
gtktogglebutton.c \
- gtktoolbar.c \
gtktooltips.c \
gtktree.c \
gtktreeitem.c \
diff --git a/gtk/gtkmarshalers.list b/gtk/gtkmarshalers.list
index a719713dc3..b59820745b 100644
--- a/gtk/gtkmarshalers.list
+++ b/gtk/gtkmarshalers.list
@@ -29,6 +29,7 @@ BOOLEAN:OBJECT,UINT,FLAGS
BOOLEAN:OBJECT,INT,INT,UINT
BOOLEAN:OBJECT,STRING,STRING,BOXED
BOOLEAN:OBJECT,BOXED,BOXED
+BOOLEAN:OBJECT,STRING,STRING
BOOLEAN:INT,INT
BOOLEAN:VOID
BOOLEAN:BOOLEAN
diff --git a/gtk/gtkradiotoolbutton.c b/gtk/gtkradiotoolbutton.c
new file mode 100644
index 0000000000..46cb83801c
--- /dev/null
+++ b/gtk/gtkradiotoolbutton.c
@@ -0,0 +1,147 @@
+/* gtkradiotoolbutton.c
+ *
+ * Copyright (C) 2002 Anders Carlsson <andersca@codefactory.se>
+ * Copyright (C) 2002 James Henstridge <james@daa.com.au>
+ * Copyright (C) 2003 Soeren Sandmann <sandmann@daimi.au.dk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "gtkradiotoolbutton.h"
+#include "gtkradiobutton.h"
+#include "gtkintl.h"
+
+static void gtk_radio_tool_button_init (GtkRadioToolButton *button);
+static void gtk_radio_tool_button_class_init (GtkRadioToolButtonClass *klass);
+
+GType
+gtk_radio_tool_button_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type)
+ {
+ static const GTypeInfo type_info =
+ {
+ sizeof (GtkRadioToolButtonClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gtk_radio_tool_button_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+ sizeof (GtkRadioToolButton),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) gtk_radio_tool_button_init
+ };
+
+ type = g_type_register_static (GTK_TYPE_TOGGLE_TOOL_BUTTON,
+ "GtkRadioToolButton", &type_info, 0);
+ }
+ return type;
+}
+
+
+static void
+gtk_radio_tool_button_class_init (GtkRadioToolButtonClass *klass)
+{
+ GtkToolButtonClass *toolbutton_class;
+
+ toolbutton_class = (GtkToolButtonClass *)klass;
+
+ toolbutton_class->button_type = GTK_TYPE_RADIO_BUTTON;
+}
+
+static void
+gtk_radio_tool_button_init (GtkRadioToolButton *button)
+{
+ gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (GTK_TOOL_BUTTON (button)->button), FALSE);
+}
+
+GtkToolItem *
+gtk_radio_tool_button_new (GSList *group)
+{
+ GtkRadioToolButton *button;
+
+ button = g_object_new (GTK_TYPE_RADIO_TOOL_BUTTON,
+ NULL);
+
+ gtk_radio_tool_button_set_group (button, group);
+
+ return GTK_TOOL_ITEM (button);
+}
+
+GtkToolItem *
+gtk_radio_tool_button_new_from_stock (GSList *group,
+ const gchar *stock_id)
+{
+ GtkRadioToolButton *button;
+
+ g_return_val_if_fail (stock_id != NULL, NULL);
+
+ button = g_object_new (GTK_TYPE_RADIO_TOOL_BUTTON,
+ "stock_id", stock_id,
+ NULL);
+
+
+ gtk_radio_tool_button_set_group (button, group);
+
+ return GTK_TOOL_ITEM (button);
+}
+
+GtkToolItem *
+gtk_radio_tool_button_new_from_widget (GtkWidget *group,
+ const gchar *stock_id)
+{
+ GSList *list = NULL;
+
+ g_return_val_if_fail (GTK_IS_RADIO_TOOL_BUTTON (group), NULL);
+
+ if (group)
+ list = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (group));
+
+ return gtk_radio_tool_button_new_from_stock (list, stock_id);
+}
+
+GtkToolItem *
+gtk_radio_tool_button_new_with_stock_from_widget (GtkWidget *group)
+{
+ GSList *list = NULL;
+
+ g_return_val_if_fail (GTK_IS_RADIO_TOOL_BUTTON (group), NULL);
+
+ if (group)
+ list = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (group));
+
+ return gtk_radio_tool_button_new (list);
+}
+
+GSList *
+gtk_radio_tool_button_get_group (GtkRadioToolButton *button)
+{
+ g_return_val_if_fail (GTK_IS_RADIO_TOOL_BUTTON (button), NULL);
+
+ return gtk_radio_button_get_group (GTK_RADIO_BUTTON (GTK_TOOL_BUTTON (button)->button));
+}
+
+void
+gtk_radio_tool_button_set_group (GtkRadioToolButton *button,
+ GSList *group)
+{
+ g_return_if_fail (GTK_IS_RADIO_TOOL_BUTTON (button));
+
+ gtk_radio_button_set_group (GTK_RADIO_BUTTON (GTK_TOOL_BUTTON (button)->button), group);
+}
+
diff --git a/gtk/gtkradiotoolbutton.h b/gtk/gtkradiotoolbutton.h
new file mode 100644
index 0000000000..93bc97b1bd
--- /dev/null
+++ b/gtk/gtkradiotoolbutton.h
@@ -0,0 +1,62 @@
+/* gtkradiotoolbutton.h
+ *
+ * Copyright (C) 2002 Anders Carlsson <andersca@codefactory.se>
+ * Copyright (C) 2002 James Henstridge <james@daa.com.au>
+ * Copyright (C) 2003 Soeren Sandmann <sandmann@daimi.au.dk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GTK_RADIO_TOOL_BUTTON_H__
+#define __GTK_RADIO_TOOL_BUTTON_H__
+
+#include "gtktoggletoolbutton.h"
+
+#define GTK_TYPE_RADIO_TOOL_BUTTON (gtk_radio_tool_button_get_type ())
+#define GTK_RADIO_TOOL_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_RADIO_TOOL_BUTTON, GtkRadioToolButton))
+#define GTK_RADIO_TOOL_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_RADIO_TOOL_BUTTON, GtkRadioToolButtonClass))
+#define GTK_IS_RADIO_TOOL_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_RADIO_TOOL_BUTTON))
+#define GTK_IS_RADIO_TOOL_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), GTK_TYPE_RADIO_TOOL_BUTTON))
+#define GTK_RADIO_TOOL_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_RADIO_TOOL_BUTTON, GtkRadioToolButtonClass))
+
+typedef struct _GtkRadioToolButton GtkRadioToolButton;
+typedef struct _GtkRadioToolButtonClass GtkRadioToolButtonClass;
+
+struct _GtkRadioToolButton
+{
+ GtkToggleToolButton parent;
+};
+
+struct _GtkRadioToolButtonClass
+{
+ GtkToggleToolButtonClass parent_class;
+};
+
+GType gtk_radio_tool_button_get_type (void) G_GNUC_CONST;
+
+GtkToolItem *gtk_radio_tool_button_new (GSList *group);
+GtkToolItem *gtk_radio_tool_button_new_from_stock (GSList *group,
+ const gchar *stock_id);
+GtkToolItem *gtk_radio_tool_button_new_from_widget (GtkWidget *group,
+ const gchar *stock_id);
+GtkToolItem *gtk_radio_tool_button_new_with_stock_from_widget (GtkWidget *group);
+GSList * gtk_radio_tool_button_get_group (GtkRadioToolButton *button);
+void gtk_radio_tool_button_set_group (GtkRadioToolButton *button,
+ GSList *group);
+
+
+
+#endif /* __GTK_RADIO_TOOL_BUTTON_H__ */
diff --git a/gtk/gtkseparatortoolitem.c b/gtk/gtkseparatortoolitem.c
new file mode 100644
index 0000000000..52051d6dd5
--- /dev/null
+++ b/gtk/gtkseparatortoolitem.c
@@ -0,0 +1,90 @@
+/* gtkseparatortoolitem.c
+ *
+ * Copyright (C) 2002 Anders Carlsson <andersca@codefactory.se>
+ * Copyright (C) 2002 James Henstridge <james@daa.com.au>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "gtkseparatormenuitem.h"
+#include "gtkseparatortoolitem.h"
+#include "gtkintl.h"
+
+static void gtk_separator_tool_item_class_init (GtkSeparatorToolItemClass*class);
+
+static void gtk_separator_tool_item_add (GtkContainer *container,
+ GtkWidget *child);
+
+static GObjectClass *parent_class = NULL;
+
+
+GType
+gtk_separator_tool_item_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type)
+ {
+ static const GTypeInfo type_info =
+ {
+ sizeof (GtkSeparatorToolItemClass),
+ (GBaseInitFunc) 0,
+ (GBaseFinalizeFunc) 0,
+ (GClassInitFunc) gtk_separator_tool_item_class_init,
+ (GClassFinalizeFunc) 0,
+ NULL,
+ sizeof (GtkSeparatorToolItem),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL,
+ };
+
+ type = g_type_register_static (GTK_TYPE_TOOL_ITEM,
+ "GtkSeparatorToolItem", &type_info, 0);
+ }
+ return type;
+}
+
+
+static void
+gtk_separator_tool_item_class_init (GtkSeparatorToolItemClass *class)
+{
+ GtkContainerClass *container_class;
+ GtkToolItemClass *toolitem_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ container_class = (GtkContainerClass *)class;
+ toolitem_class = (GtkToolItemClass *)class;
+
+ container_class->add = gtk_separator_tool_item_add;
+}
+
+static void
+gtk_separator_tool_item_add (GtkContainer *container,
+ GtkWidget *child)
+{
+ g_warning("attempt to add a child to an GtkSeparatorToolItem");
+}
+
+GtkToolItem *
+gtk_separator_tool_item_new (void)
+{
+ GtkToolItem *self;
+
+ self = g_object_new (GTK_TYPE_SEPARATOR_TOOL_ITEM,
+ NULL);
+
+ return self;
+}
diff --git a/gtk/gtkseparatortoolitem.h b/gtk/gtkseparatortoolitem.h
new file mode 100644
index 0000000000..dde478c81b
--- /dev/null
+++ b/gtk/gtkseparatortoolitem.h
@@ -0,0 +1,50 @@
+/* gtktoggletoolbutton.h
+ *
+ * Copyright (C) 2002 Anders Carlsson <andersca@codefactory.se>
+ * Copyright (C) 2002 James Henstridge <james@daa.com.au>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GTK_SEPARATOR_TOOL_ITEM_H__
+#define __GTK_SEPARATOR_TOOL_ITEM_H__
+
+#include "gtktoolitem.h"
+
+#define GTK_TYPE_SEPARATOR_TOOL_ITEM (gtk_separator_tool_item_get_type ())
+#define GTK_SEPARATOR_TOOL_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SEPARATOR_TOOL_ITEM, GtkSeparatorToolItem))
+#define GTK_SEPARATOR_TOOL_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SEPARATOR_TOOL_ITEM, GtkSeparatorToolItemClass))
+#define GTK_IS_SEPARATOR_TOOL_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SEPARATOR_TOOL_ITEM))
+#define GTK_IS_SEPARATOR_TOOL_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), GTK_TYPE_SEPARATOR_TOOL_ITEM))
+#define GTK_SEPARATOR_TOOL_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_SEPARATOR_TOOL_ITEM, GtkSeparatorToolItemClass))
+
+typedef struct _GtkSeparatorToolItem GtkSeparatorToolItem;
+typedef struct _GtkSeparatorToolItemClass GtkSeparatorToolItemClass;
+
+struct _GtkSeparatorToolItem
+{
+ GtkToolItem parent;
+};
+
+struct _GtkSeparatorToolItemClass
+{
+ GtkToolItemClass parent_class;
+};
+
+GType gtk_separator_tool_item_get_type (void) G_GNUC_CONST;
+GtkToolItem *gtk_separator_tool_item_new (void);
+
+#endif /* __GTK_SEPARATOR_TOOL_ITEM_H__ */
diff --git a/gtk/gtktoggletoolbutton.c b/gtk/gtktoggletoolbutton.c
new file mode 100644
index 0000000000..1841d9ff5e
--- /dev/null
+++ b/gtk/gtktoggletoolbutton.c
@@ -0,0 +1,244 @@
+/* gtktoggletoolbutton.c
+ *
+ * Copyright (C) 2002 Anders Carlsson <andersca@codefactory.se>
+ * Copyright (C) 2002 James Henstridge <james@daa.com.au>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "gtktoggletoolbutton.h"
+#include "gtkcheckmenuitem.h"
+#include "gtklabel.h"
+#include "gtktogglebutton.h"
+#include "gtkstock.h"
+#include "gtkintl.h"
+
+#define MENU_ID "gtk-toggle-tool-button-menu-id"
+
+enum {
+ TOGGLED,
+ LAST_SIGNAL
+};
+
+static void gtk_toggle_tool_button_init (GtkToggleToolButton *button);
+static void gtk_toggle_tool_button_class_init (GtkToggleToolButtonClass *klass);
+
+static gboolean gtk_toggle_tool_button_create_menu_proxy (GtkToolItem *button);
+
+static void button_toggled (GtkWidget *widget,
+ GtkToggleToolButton *button);
+static void menu_item_activated (GtkWidget *widget,
+ GtkToggleToolButton *button);
+
+static GObjectClass *parent_class = NULL;
+static guint toggle_signals[LAST_SIGNAL] = { 0 };
+
+GType
+gtk_toggle_tool_button_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type)
+ {
+ static const GTypeInfo type_info =
+ {
+ sizeof (GtkToggleToolButtonClass),
+ (GBaseInitFunc) 0,
+ (GBaseFinalizeFunc) 0,
+ (GClassInitFunc) gtk_toggle_tool_button_class_init,
+ (GClassFinalizeFunc) 0,
+ NULL,
+ sizeof (GtkToggleToolButton),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) gtk_toggle_tool_button_init
+ };
+
+ type = g_type_register_static (GTK_TYPE_TOOL_BUTTON,
+ "GtkToggleToolButton", &type_info, 0);
+ }
+ return type;
+}
+
+
+static void
+gtk_toggle_tool_button_class_init (GtkToggleToolButtonClass *klass)
+{
+ GObjectClass *object_class;
+ GtkToolItemClass *toolitem_class;
+ GtkToolButtonClass *toolbutton_class;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class = (GObjectClass *)klass;
+ toolitem_class = (GtkToolItemClass *)klass;
+ toolbutton_class = (GtkToolButtonClass *)klass;
+
+ toolitem_class->create_menu_proxy = gtk_toggle_tool_button_create_menu_proxy;
+ toolbutton_class->button_type = GTK_TYPE_TOGGLE_BUTTON;
+
+ toggle_signals[TOGGLED] =
+ g_signal_new ("toggled",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GtkToggleToolButtonClass, toggled),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+gtk_toggle_tool_button_init (GtkToggleToolButton *button)
+{
+ g_signal_connect_object (GTK_TOOL_BUTTON (button)->button, "toggled",
+ G_CALLBACK (button_toggled), button, 0);
+}
+
+static gboolean
+gtk_toggle_tool_button_create_menu_proxy (GtkToolItem *item)
+{
+ GtkToolButton *tool_button = GTK_TOOL_BUTTON (item);
+ GtkToggleToolButton *toggle_tool_button = GTK_TOGGLE_TOOL_BUTTON (item);
+ GtkWidget *menu_item = NULL;
+ GtkStockItem stock_item;
+ gboolean use_mnemonic = TRUE;
+ const char *label = "";
+
+ if (tool_button->label_widget && GTK_IS_LABEL (tool_button->label_widget))
+ label = gtk_label_get_label (GTK_LABEL (tool_button->label_widget));
+ else if (tool_button->label_text)
+ {
+ label = tool_button->label_text;
+ use_mnemonic = tool_button->use_underline;
+ }
+ else if (tool_button->stock_id && gtk_stock_lookup (tool_button->stock_id, &stock_item))
+ label = stock_item.label;
+
+ if (use_mnemonic)
+ menu_item = gtk_check_menu_item_new_with_mnemonic (label);
+ else
+ menu_item = gtk_check_menu_item_new_with_label (label);
+
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item),
+ toggle_tool_button->active);
+
+ g_signal_connect_closure_by_id (menu_item,
+ g_signal_lookup ("activate", G_OBJECT_TYPE (menu_item)), 0,
+ g_cclosure_new_object (G_CALLBACK (menu_item_activated),
+ G_OBJECT (toggle_tool_button)),
+ FALSE);
+
+ gtk_tool_item_set_proxy_menu_item (item, MENU_ID, menu_item);
+
+ return TRUE;
+}
+
+/* There are two activatable widgets, a toggle button and a menu item.
+ *
+ * If a widget is activated and the state of the tool button is the same as
+ * the new state of the activated widget, then the other widget was the one
+ * that was activated by the user and updated the tool button's state.
+ *
+ * If the state of the tool button is not the same as the new state of the
+ * activated widget, then the activation was activated by the user, and the
+ * widget needs to make sure the tool button is updated before the other
+ * widget is activated. This will make sure the other widget a tool button
+ * in a state that matches its own new state.
+ */
+static void
+menu_item_activated (GtkWidget *menu_item,
+ GtkToggleToolButton *toggle_tool_button)
+{
+ GtkToolButton *tool_button = GTK_TOOL_BUTTON (toggle_tool_button);
+ gboolean menu_active = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menu_item));
+
+ if (toggle_tool_button->active != menu_active)
+ {
+ toggle_tool_button->active = menu_active;
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tool_button->button),
+ toggle_tool_button->active);
+
+ g_signal_emit (G_OBJECT (toggle_tool_button), toggle_signals[TOGGLED], 0);
+ }
+}
+
+static void
+button_toggled (GtkWidget *widget,
+ GtkToggleToolButton *toggle_tool_button)
+{
+ gboolean toggle_active = GTK_TOGGLE_BUTTON (widget)->active;
+
+ if (toggle_tool_button->active != toggle_active)
+ {
+ GtkWidget *menu_item;
+
+ toggle_tool_button->active = toggle_active;
+
+ if ((menu_item =
+ gtk_tool_item_get_proxy_menu_item (GTK_TOOL_ITEM (toggle_tool_button), MENU_ID)))
+ {
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item),
+ toggle_tool_button->active);
+ }
+
+ g_signal_emit (G_OBJECT (toggle_tool_button), toggle_signals[TOGGLED], 0);
+ }
+}
+
+GtkToolItem *
+gtk_toggle_tool_button_new (void)
+{
+ GtkToolButton *button;
+
+ button = g_object_new (GTK_TYPE_TOGGLE_TOOL_BUTTON,
+ NULL);
+
+ return GTK_TOOL_ITEM (button);
+}
+
+GtkToolItem *
+gtk_toggle_tool_button_new_from_stock (const gchar *stock_id)
+{
+ GtkToolButton *button;
+
+ g_return_val_if_fail (stock_id != NULL, NULL);
+
+ button = g_object_new (GTK_TYPE_TOGGLE_TOOL_BUTTON,
+ "stock_id", stock_id,
+ NULL);
+
+ return GTK_TOOL_ITEM (button);
+}
+
+void
+gtk_toggle_tool_button_set_active (GtkToggleToolButton *button,
+ gboolean is_active)
+{
+ g_return_if_fail (GTK_IS_TOGGLE_TOOL_BUTTON (button));
+
+ is_active = is_active != FALSE;
+
+ if (button->active != is_active)
+ gtk_button_clicked (GTK_BUTTON (GTK_TOOL_BUTTON (button)->button));
+}
+
+gboolean
+gtk_toggle_tool_button_get_active (GtkToggleToolButton *button)
+{
+ g_return_val_if_fail (GTK_IS_TOGGLE_TOOL_BUTTON (button), FALSE);
+
+ return button->active;
+}
diff --git a/gtk/gtktoggletoolbutton.h b/gtk/gtktoggletoolbutton.h
new file mode 100644
index 0000000000..5d8e862167
--- /dev/null
+++ b/gtk/gtktoggletoolbutton.h
@@ -0,0 +1,68 @@
+/* gtktoggletoolbutton.h
+ *
+ * Copyright (C) 2002 Anders Carlsson <andersca@codefactory.se>
+ * Copyright (C) 2002 James Henstridge <james@daa.com.au>
+ * Copyright (C) 2003 Soeren Sandmann <sandmann@daimi.au.dk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GTK_TOGGLE_TOOL_BUTTON_H__
+#define __GTK_TOGGLE_TOOL_BUTTON_H__
+
+#include "gtktoolbutton.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_TOGGLE_TOOL_BUTTON (gtk_toggle_tool_button_get_type ())
+#define GTK_TOGGLE_TOOL_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TOGGLE_TOOL_BUTTON, GtkToggleToolButton))
+#define GTK_TOGGLE_TOOL_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_TOGGLE_TOOL_BUTTON, GtkToggleToolButtonClass))
+#define GTK_IS_TOGGLE_TOOL_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TOGGLE_TOOL_BUTTON))
+#define GTK_IS_TOGGLE_TOOL_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), GTK_TYPE_TOGGLE_TOOL_BUTTON))
+#define GTK_TOGGLE_TOOL_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_TOGGLE_TOOL_BUTTON, GtkToggleToolButtonClass))
+
+typedef struct _GtkToggleToolButton GtkToggleToolButton;
+typedef struct _GtkToggleToolButtonClass GtkToggleToolButtonClass;
+
+struct _GtkToggleToolButton
+{
+ GtkToolButton parent;
+
+ /*< private >*/
+ GtkWidget *menu_item;
+
+ guint active : 1;
+};
+
+struct _GtkToggleToolButtonClass
+{
+ GtkToolButtonClass parent_class;
+
+ /* signal */
+ void (* toggled) (GtkToggleToolButton *button);
+};
+
+GType gtk_toggle_tool_button_get_type (void) G_GNUC_CONST;
+GtkToolItem *gtk_toggle_tool_button_new (void);
+GtkToolItem *gtk_toggle_tool_button_new_from_stock (const gchar *stock_id);
+
+void gtk_toggle_tool_button_set_active (GtkToggleToolButton *button,
+ gboolean is_active);
+gboolean gtk_toggle_tool_button_get_active (GtkToggleToolButton *button);
+
+G_END_DECLS
+
+#endif /* __GTK_TOGGLE_TOOL_BUTTON_H__ */
diff --git a/gtk/gtktoolbar.c b/gtk/gtktoolbar.c
index df217b99e8..8b4096ed1b 100644
--- a/gtk/gtktoolbar.c
+++ b/gtk/gtktoolbar.c
@@ -2,6 +2,10 @@
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
* GtkToolbar copyright (C) Federico Mena
*
+ * Copyright (C) 2002 Anders Carlsson <andersca@codefactory.se>
+ * Copyright (C) 2002 James Henstridge <james@daa.com.au>
+ * Copyright (C) 2003 Soeren Sandmann <sandmann@daimi.au.dk>
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -25,22 +29,24 @@
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
-#include <string.h>
+#undef GTK_DISABLE_DEPRECATED
-#include "gtkbutton.h"
-#include "gtktogglebutton.h"
+#include "gtkarrow.h"
+#include "gtktoolbar.h"
+#include "gtkradiotoolbutton.h"
+#include "gtkseparatortoolitem.h"
+#include "gtkmenu.h"
#include "gtkradiobutton.h"
-#include "gtklabel.h"
-#include "gtkvbox.h"
-#include "gtkhbox.h"
#include "gtktoolbar.h"
+#include "gtkbindings.h"
+#include <gdk/gdkkeysyms.h>
+#include "gtkmarshalers.h"
+#include "gtkmain.h"
#include "gtkstock.h"
-#include "gtkiconfactory.h"
-#include "gtkimage.h"
-#include "gtksettings.h"
+#include "gtklabel.h"
+#include "gtkprivate.h"
#include "gtkintl.h"
-#include "gtkmarshalers.h"
-
+#include <string.h>
#define DEFAULT_IPADDING 0
#define DEFAULT_SPACE_SIZE 5
@@ -56,175 +62,298 @@
enum {
PROP_0,
PROP_ORIENTATION,
- PROP_TOOLBAR_STYLE
+ PROP_TOOLBAR_STYLE,
+ PROP_SHOW_ARROW
+};
+
+enum {
+ CHILD_PROP_0,
+ CHILD_PROP_EXPAND,
+ CHILD_PROP_HOMOGENEOUS,
+ CHILD_PROP_PACK_END,
};
enum {
ORIENTATION_CHANGED,
STYLE_CHANGED,
+ POPUP_CONTEXT_MENU,
+ MOVE_FOCUS,
+ FOCUS_ENDS,
LAST_SIGNAL
};
-typedef struct _GtkToolbarChildSpace GtkToolbarChildSpace;
-struct _GtkToolbarChildSpace
-{
- GtkToolbarChild child;
-
- gint alloc_x, alloc_y;
-};
-
-static void gtk_toolbar_class_init (GtkToolbarClass *class);
-static void gtk_toolbar_init (GtkToolbar *toolbar);
-static void gtk_toolbar_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gtk_toolbar_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-static void gtk_toolbar_destroy (GtkObject *object);
-static gint gtk_toolbar_expose (GtkWidget *widget,
- GdkEventExpose *event);
-static void gtk_toolbar_size_request (GtkWidget *widget,
- GtkRequisition *requisition);
-static void gtk_toolbar_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation);
-static void gtk_toolbar_style_set (GtkWidget *widget,
- GtkStyle *prev_style);
-static gboolean gtk_toolbar_focus (GtkWidget *widget,
- GtkDirectionType dir);
-static void gtk_toolbar_screen_changed (GtkWidget *widget,
- GdkScreen *previous_screen);
-static void gtk_toolbar_show_all (GtkWidget *widget);
-static void gtk_toolbar_hide_all (GtkWidget *widget);
-static void gtk_toolbar_add (GtkContainer *container,
- GtkWidget *widget);
-static void gtk_toolbar_remove (GtkContainer *container,
- GtkWidget *widget);
-static void gtk_toolbar_forall (GtkContainer *container,
- gboolean include_internals,
- GtkCallback callback,
- gpointer callback_data);
-
-static void gtk_real_toolbar_orientation_changed (GtkToolbar *toolbar,
+static void gtk_toolbar_init (GtkToolbar *toolbar);
+static void gtk_toolbar_class_init (GtkToolbarClass *klass);
+
+static void gtk_toolbar_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gtk_toolbar_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static gint gtk_toolbar_expose (GtkWidget *widget,
+ GdkEventExpose *event);
+static void gtk_toolbar_realize (GtkWidget *widget);
+static void gtk_toolbar_unrealize (GtkWidget *widget);
+static void gtk_toolbar_size_request (GtkWidget *widget,
+ GtkRequisition *requisition);
+static void gtk_toolbar_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+static void gtk_toolbar_style_set (GtkWidget *widget,
+ GtkStyle *prev_style);
+static void gtk_toolbar_direction_changed (GtkWidget *widget,
+ GtkTextDirection previous_direction);
+static gboolean gtk_toolbar_focus (GtkWidget *widget,
+ GtkDirectionType dir);
+static void gtk_toolbar_screen_changed (GtkWidget *widget,
+ GdkScreen *previous_screen);
+static void gtk_toolbar_map (GtkWidget *widget);
+static void gtk_toolbar_unmap (GtkWidget *widget);
+
+static void gtk_toolbar_drag_leave (GtkWidget *widget,
+ GdkDragContext *context,
+ guint time_);
+static gboolean gtk_toolbar_drag_motion (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time_);
+static void gtk_toolbar_set_child_property (GtkContainer *container,
+ GtkWidget *child,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gtk_toolbar_get_child_property (GtkContainer *container,
+ GtkWidget *child,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void gtk_toolbar_add (GtkContainer *container,
+ GtkWidget *widget);
+static void gtk_toolbar_remove (GtkContainer *container,
+ GtkWidget *widget);
+static void gtk_toolbar_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data);
+static GType gtk_toolbar_child_type (GtkContainer *container);
+
+static void gtk_toolbar_real_orientation_changed (GtkToolbar *toolbar,
GtkOrientation orientation);
-static void gtk_real_toolbar_style_changed (GtkToolbar *toolbar,
+static void gtk_toolbar_real_style_changed (GtkToolbar *toolbar,
GtkToolbarStyle style);
-static GtkWidget * gtk_toolbar_internal_insert_element (GtkToolbar *toolbar,
- GtkToolbarChildType type,
- GtkWidget *widget,
- const char *text,
- const char *tooltip_text,
- const char *tooltip_private_text,
- GtkWidget *icon,
- GtkSignalFunc callback,
- gpointer user_data,
- gint position);
-
-static GtkWidget * gtk_toolbar_internal_insert_item (GtkToolbar *toolbar,
- const char *text,
- const char *tooltip_text,
- const char *tooltip_private_text,
- GtkWidget *icon,
- GtkSignalFunc callback,
- gpointer user_data,
- gint position);
-
-static void gtk_toolbar_update_button_relief (GtkToolbar *toolbar);
-
-static GtkReliefStyle get_button_relief (GtkToolbar *toolbar);
-static gint get_space_size (GtkToolbar *toolbar);
-static GtkToolbarSpaceStyle get_space_style (GtkToolbar *toolbar);
-
+static gboolean gtk_toolbar_move_focus (GtkToolbar *toolbar,
+ GtkDirectionType dir);
+static gboolean gtk_toolbar_focus_ends (GtkToolbar *toolbar,
+ gboolean home);
+
+static gboolean gtk_toolbar_button_press (GtkWidget *toolbar,
+ GdkEventButton *event);
+static gboolean gtk_toolbar_arrow_button_press (GtkWidget *button,
+ GdkEventButton *event,
+ GtkToolbar *toolbar);
+static void gtk_toolbar_arrow_button_clicked (GtkWidget *button,
+ GtkToolbar *toolbar);
+static void gtk_toolbar_update_button_relief (GtkToolbar *toolbar);
+static GtkReliefStyle get_button_relief (GtkToolbar *toolbar);
+static gint get_space_size (GtkToolbar *toolbar);
+static GtkToolbarSpaceStyle get_space_style (GtkToolbar *toolbar);
+static gint get_internal_padding (GtkToolbar *toolbar);
+static void gtk_toolbar_remove_tool_item (GtkToolbar *toolbar,
+ GtkToolItem *item);
+
+static GtkWidget *gtk_toolbar_internal_insert_element (GtkToolbar *toolbar,
+ GtkToolbarChildType type,
+ GtkWidget *widget,
+ const char *text,
+ const char *tooltip_text,
+ const char *tooltip_private_text,
+ GtkWidget *icon,
+ GtkSignalFunc callback,
+ gpointer user_data,
+ gint position,
+ gboolean use_stock);
+
+
+typedef enum {
+ DONT_KNOW,
+ OLD_API,
+ NEW_API
+} ApiMode;
+
+struct _GtkToolbarPrivate
+{
+ GList *items;
+
+ GtkWidget *arrow;
+ GtkWidget *arrow_button;
+
+ gboolean show_arrow;
-static GtkContainerClass *parent_class;
+ gint drop_index;
+ GdkWindow *drag_highlight;
+ GtkMenu *menu;
-static guint toolbar_signals[LAST_SIGNAL] = { 0 };
+ GdkWindow *event_window;
+ ApiMode api_mode;
+ GtkSettings *settings;
+};
+static GtkContainerClass *parent_class = NULL;
+static guint toolbar_signals [LAST_SIGNAL] = { 0 };
GType
gtk_toolbar_get_type (void)
{
- static GType toolbar_type = 0;
+ static GtkType type = 0;
- if (!toolbar_type)
+ if (!type)
{
- static const GTypeInfo toolbar_info =
- {
- sizeof (GtkToolbarClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) gtk_toolbar_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (GtkToolbar),
- 0, /* n_preallocs */
- (GInstanceInitFunc) gtk_toolbar_init,
- };
-
- toolbar_type = g_type_register_static (GTK_TYPE_CONTAINER, "GtkToolbar",
- &toolbar_info, 0);
+ static const GTypeInfo type_info =
+ {
+ sizeof (GtkToolbarClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gtk_toolbar_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+ sizeof (GtkToolbar),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) gtk_toolbar_init,
+ };
+
+ type = g_type_register_static (GTK_TYPE_CONTAINER,
+ "GtkToolbar",
+ &type_info, 0);
}
+
+ return type;
+}
+
+static void
+add_arrow_bindings (GtkBindingSet *binding_set,
+ guint keysym,
+ GtkDirectionType dir)
+{
+ guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
+
+ gtk_binding_entry_add_signal (binding_set, keysym, 0,
+ "move_focus", 1,
+ GTK_TYPE_DIRECTION_TYPE, dir);
+ gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
+ "move_focus", 1,
+ GTK_TYPE_DIRECTION_TYPE, dir);
+}
- return toolbar_type;
+static void
+add_ctrl_tab_bindings (GtkBindingSet *binding_set,
+ GdkModifierType modifiers,
+ GtkDirectionType direction)
+{
+ gtk_binding_entry_add_signal (binding_set,
+ GDK_Tab, GDK_CONTROL_MASK | modifiers,
+ "move_focus", 1,
+ GTK_TYPE_DIRECTION_TYPE, direction);
+ gtk_binding_entry_add_signal (binding_set,
+ GDK_KP_Tab, GDK_CONTROL_MASK | modifiers,
+ "move_focus", 1,
+ GTK_TYPE_DIRECTION_TYPE, direction);
}
static void
-gtk_toolbar_class_init (GtkToolbarClass *class)
+gtk_toolbar_class_init (GtkToolbarClass *klass)
{
- GObjectClass *gobject_class;
- GtkObjectClass *object_class;
+ GObjectClass *gobject_class;
GtkWidgetClass *widget_class;
GtkContainerClass *container_class;
+ GtkBindingSet *binding_set;
- gobject_class = G_OBJECT_CLASS (class);
- object_class = (GtkObjectClass *) class;
- widget_class = (GtkWidgetClass *) class;
- container_class = (GtkContainerClass *) class;
-
- parent_class = g_type_class_peek_parent (class);
-
- object_class->destroy = gtk_toolbar_destroy;
+ parent_class = g_type_class_peek_parent (klass);
+
+ gobject_class = (GObjectClass *)klass;
+ widget_class = (GtkWidgetClass *)klass;
+ container_class = (GtkContainerClass *)klass;
+
gobject_class->set_property = gtk_toolbar_set_property;
gobject_class->get_property = gtk_toolbar_get_property;
+ widget_class->button_press_event = gtk_toolbar_button_press;
widget_class->expose_event = gtk_toolbar_expose;
widget_class->size_request = gtk_toolbar_size_request;
widget_class->size_allocate = gtk_toolbar_size_allocate;
widget_class->style_set = gtk_toolbar_style_set;
- widget_class->show_all = gtk_toolbar_show_all;
- widget_class->hide_all = gtk_toolbar_hide_all;
+ widget_class->direction_changed = gtk_toolbar_direction_changed;
widget_class->focus = gtk_toolbar_focus;
widget_class->screen_changed = gtk_toolbar_screen_changed;
+ widget_class->realize = gtk_toolbar_realize;
+ widget_class->unrealize = gtk_toolbar_unrealize;
+ widget_class->map = gtk_toolbar_map;
+ widget_class->unmap = gtk_toolbar_unmap;
+
+ widget_class->drag_leave = gtk_toolbar_drag_leave;
+ widget_class->drag_motion = gtk_toolbar_drag_motion;
- container_class->add = gtk_toolbar_add;
+ container_class->add = gtk_toolbar_add;
container_class->remove = gtk_toolbar_remove;
container_class->forall = gtk_toolbar_forall;
+ container_class->child_type = gtk_toolbar_child_type;
+ container_class->get_child_property = gtk_toolbar_get_child_property;
+ container_class->set_child_property = gtk_toolbar_set_child_property;
+
+ klass->orientation_changed = gtk_toolbar_real_orientation_changed;
+ klass->style_changed = gtk_toolbar_real_style_changed;
- class->orientation_changed = gtk_real_toolbar_orientation_changed;
- class->style_changed = gtk_real_toolbar_style_changed;
-
toolbar_signals[ORIENTATION_CHANGED] =
g_signal_new ("orientation_changed",
- G_OBJECT_CLASS_TYPE (gobject_class),
+ G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkToolbarClass, orientation_changed),
NULL, NULL,
- _gtk_marshal_VOID__ENUM,
+ g_cclosure_marshal_VOID__ENUM,
G_TYPE_NONE, 1,
GTK_TYPE_ORIENTATION);
toolbar_signals[STYLE_CHANGED] =
g_signal_new ("style_changed",
- G_OBJECT_CLASS_TYPE (gobject_class),
+ G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkToolbarClass, style_changed),
NULL, NULL,
- _gtk_marshal_VOID__ENUM,
+ g_cclosure_marshal_VOID__ENUM,
G_TYPE_NONE, 1,
GTK_TYPE_TOOLBAR_STYLE);
-
+ toolbar_signals[POPUP_CONTEXT_MENU] =
+ g_signal_new ("popup_context_menu",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GtkToolbarClass, popup_context_menu),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ toolbar_signals[MOVE_FOCUS] =
+ _gtk_binding_signal_new ("move_focus",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_CALLBACK (gtk_toolbar_move_focus),
+ NULL, NULL,
+ _gtk_marshal_BOOLEAN__ENUM,
+ G_TYPE_BOOLEAN, 1,
+ GTK_TYPE_DIRECTION_TYPE);
+ toolbar_signals[FOCUS_ENDS] =
+ _gtk_binding_signal_new ("focus_ends",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_CALLBACK (gtk_toolbar_focus_ends),
+ NULL, NULL,
+ _gtk_marshal_BOOLEAN__BOOLEAN,
+ G_TYPE_BOOLEAN, 1,
+ G_TYPE_BOOLEAN);
+
+ /* properties */
g_object_class_install_property (gobject_class,
PROP_ORIENTATION,
g_param_spec_enum ("orientation",
@@ -233,17 +362,49 @@ gtk_toolbar_class_init (GtkToolbarClass *class)
GTK_TYPE_ORIENTATION,
GTK_ORIENTATION_HORIZONTAL,
G_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class,
- PROP_TOOLBAR_STYLE,
- g_param_spec_enum ("toolbar_style",
+
+ g_object_class_install_property (gobject_class,
+ PROP_TOOLBAR_STYLE,
+ g_param_spec_enum ("toolbar_style",
_("Toolbar Style"),
_("How to draw the toolbar"),
GTK_TYPE_TOOLBAR_STYLE,
GTK_TOOLBAR_ICONS,
G_PARAM_READWRITE));
-
-
+ g_object_class_install_property (gobject_class,
+ PROP_SHOW_ARROW,
+ g_param_spec_boolean ("show_arrow",
+ _("Show Arrow"),
+ _("If an arrow should be shown if the toolbar doesn't fit"),
+ FALSE,
+ G_PARAM_READWRITE));
+
+ /* child properties */
+ gtk_container_class_install_child_property (container_class,
+ CHILD_PROP_EXPAND,
+ g_param_spec_boolean ("expand",
+ _("Expand"),
+ _("Whether the item should receive extra space when the toolbar grows"),
+ TRUE,
+ G_PARAM_READWRITE));
+
+ gtk_container_class_install_child_property (container_class,
+ CHILD_PROP_HOMOGENEOUS,
+ g_param_spec_boolean ("homogeneous",
+ _("Homogeneous"),
+ _("Whether the item should be the same size as other homogeneous items"),
+ TRUE,
+ G_PARAM_READWRITE));
+
+ gtk_container_class_install_child_property (container_class,
+ CHILD_PROP_PACK_END,
+ g_param_spec_uint ("pack_end",
+ _("Pack End"),
+ _("Whether the item is positioned at the end of the toolbar"),
+ 0, G_MAXINT, 0,
+ G_PARAM_READWRITE));
+
+ /* style properties */
gtk_widget_class_install_style_property (widget_class,
g_param_spec_int ("space_size",
_("Spacer size"),
@@ -252,7 +413,7 @@ gtk_toolbar_class_init (GtkToolbarClass *class)
G_MAXINT,
DEFAULT_SPACE_SIZE,
G_PARAM_READABLE));
-
+
gtk_widget_class_install_style_property (widget_class,
g_param_spec_int ("internal_padding",
_("Internal padding"),
@@ -261,24 +422,22 @@ gtk_toolbar_class_init (GtkToolbarClass *class)
G_MAXINT,
DEFAULT_IPADDING,
G_PARAM_READABLE));
-
+
gtk_widget_class_install_style_property (widget_class,
g_param_spec_enum ("space_style",
_("Space style"),
_("Whether spacers are vertical lines or just blank"),
GTK_TYPE_TOOLBAR_SPACE_STYLE,
DEFAULT_SPACE_STYLE,
-
G_PARAM_READABLE));
-
+
gtk_widget_class_install_style_property (widget_class,
g_param_spec_enum ("button_relief",
- _("Button relief"),
- _("Type of bevel around toolbar buttons"),
+ _("Button relief"),
+ _("Type of bevel around toolbar buttons"),
GTK_TYPE_RELIEF_STYLE,
GTK_RELIEF_NONE,
G_PARAM_READABLE));
-
gtk_widget_class_install_style_property (widget_class,
g_param_spec_enum ("shadow_type",
_("Shadow type"),
@@ -300,115 +459,113 @@ gtk_toolbar_class_init (GtkToolbarClass *class)
GTK_TYPE_ICON_SIZE,
DEFAULT_ICON_SIZE,
G_PARAM_READWRITE));
-}
-
-static void
-style_change_notify (GtkToolbar *toolbar)
-{
- if (!toolbar->style_set)
- {
- /* pretend it was set, then unset, thus reverting to new default */
- toolbar->style_set = TRUE;
- gtk_toolbar_unset_style (toolbar);
- }
-}
-
-static void
-icon_size_change_notify (GtkToolbar *toolbar)
-{
- if (!toolbar->icon_size_set)
- {
- /* pretend it was set, then unset, thus reverting to new default */
- toolbar->icon_size_set = TRUE;
- gtk_toolbar_unset_icon_size (toolbar);
- }
-}
-static GtkSettings *
-toolbar_get_settings (GtkToolbar *toolbar)
-{
- return g_object_get_data (G_OBJECT (toolbar), "gtk-toolbar-settings");
+ binding_set = gtk_binding_set_by_class (klass);
+
+ add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
+ add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
+ add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
+ add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_KP_Home, 0,
+ "focus_ends", 1,
+ G_TYPE_BOOLEAN, TRUE);
+ gtk_binding_entry_add_signal (binding_set, GDK_Home, 0,
+ "focus_ends", 1,
+ G_TYPE_BOOLEAN, TRUE);
+ gtk_binding_entry_add_signal (binding_set, GDK_KP_End, 0,
+ "focus_ends", 1,
+ G_TYPE_BOOLEAN, FALSE);
+ gtk_binding_entry_add_signal (binding_set, GDK_End, 0,
+ "focus_ends", 1,
+ G_TYPE_BOOLEAN, FALSE);
+
+ add_ctrl_tab_bindings (binding_set, 0, GTK_DIR_RIGHT);
+ add_ctrl_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_LEFT);
+
+ g_type_class_add_private (gobject_class, sizeof (GtkToolbarPrivate));
}
static void
-gtk_toolbar_screen_changed (GtkWidget *widget,
- GdkScreen *previous_screen)
+gtk_toolbar_init (GtkToolbar *toolbar)
{
- GtkToolbar *toolbar = GTK_TOOLBAR (widget);
- GtkSettings *old_settings = toolbar_get_settings (toolbar);
- GtkSettings *settings;
-
- if (gtk_widget_has_screen (GTK_WIDGET (toolbar)))
- settings = gtk_widget_get_settings (GTK_WIDGET (toolbar));
- else
- settings = NULL;
-
- if (settings == old_settings)
- return;
-
- if (old_settings)
- {
- g_signal_handler_disconnect (old_settings, toolbar->style_set_connection);
- g_signal_handler_disconnect (old_settings, toolbar->icon_size_connection);
+ GtkToolbarPrivate *priv;
+
+ GTK_WIDGET_UNSET_FLAGS (toolbar, GTK_CAN_FOCUS);
+ GTK_WIDGET_SET_FLAGS (toolbar, GTK_NO_WINDOW);
- g_object_unref (old_settings);
- }
+ priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
- if (settings)
- {
- toolbar->style_set_connection =
- g_signal_connect_swapped (settings,
- "notify::gtk-toolbar-style",
- G_CALLBACK (style_change_notify),
- toolbar);
-
- toolbar->icon_size_connection =
- g_signal_connect_swapped (settings,
- "notify::gtk-toolbar-icon-size",
- G_CALLBACK (icon_size_change_notify),
- toolbar);
+ toolbar->orientation = GTK_ORIENTATION_HORIZONTAL;
+ toolbar->style = DEFAULT_TOOLBAR_STYLE;
+ toolbar->icon_size = DEFAULT_ICON_SIZE;
+ toolbar->tooltips = gtk_tooltips_new ();
+ g_object_ref (toolbar->tooltips);
+ gtk_object_sink (GTK_OBJECT (toolbar->tooltips));
+
+ priv->arrow_button = gtk_toggle_button_new ();
+ g_signal_connect (priv->arrow_button, "button_press_event",
+ G_CALLBACK (gtk_toolbar_arrow_button_press), toolbar);
+ g_signal_connect (priv->arrow_button, "clicked",
+ G_CALLBACK (gtk_toolbar_arrow_button_clicked), toolbar);
+ gtk_button_set_relief (GTK_BUTTON (priv->arrow_button),
+ get_button_relief (toolbar));
+
+ priv->api_mode = DONT_KNOW;
+
+ gtk_button_set_focus_on_click (GTK_BUTTON (priv->arrow_button), FALSE);
+
+ priv->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
+ gtk_widget_show (priv->arrow);
+ gtk_container_add (GTK_CONTAINER (priv->arrow_button), priv->arrow);
+
+ gtk_widget_set_parent (priv->arrow_button, GTK_WIDGET (toolbar));
+ /* which child position a drop will occur at */
+ priv->drop_index = -1;
+ priv->drag_highlight = NULL;
- g_object_ref (settings);
- g_object_set_data (G_OBJECT (toolbar), "gtk-toolbar-settings", settings);
- }
- else
- g_object_set_data (G_OBJECT (toolbar), "gtk-toolbar-settings", NULL);
+ priv->menu = NULL;
- style_change_notify (toolbar);
- icon_size_change_notify (toolbar);
+ priv->settings = NULL;
}
-static void
-gtk_toolbar_init (GtkToolbar *toolbar)
+static gboolean
+toolbar_item_visible (GtkToolbar *toolbar,
+ GtkToolItem *item)
{
- GTK_WIDGET_SET_FLAGS (toolbar, GTK_NO_WINDOW);
- GTK_WIDGET_UNSET_FLAGS (toolbar, GTK_CAN_FOCUS);
-
- toolbar->num_children = 0;
- toolbar->children = NULL;
- toolbar->orientation = GTK_ORIENTATION_HORIZONTAL;
- toolbar->icon_size = DEFAULT_ICON_SIZE;
- toolbar->style = DEFAULT_TOOLBAR_STYLE;
- toolbar->tooltips = gtk_tooltips_new ();
- g_object_ref (toolbar->tooltips);
- gtk_object_sink (GTK_OBJECT (toolbar->tooltips));
+ if (GTK_WIDGET_VISIBLE (item) &&
+ ((toolbar->orientation == GTK_ORIENTATION_HORIZONTAL && item->visible_horizontal) ||
+ (toolbar->orientation == GTK_ORIENTATION_VERTICAL && item->visible_vertical)))
+ {
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+
+ /* With the old toolbar you could hide a button by calling gtk_widget_hide()
+ * on it. This doesn't work with the new API because the GtkToolItem will not be
+ * hidden.
+ */
+ if (priv->api_mode == OLD_API)
+ {
+ GtkWidget *bin_child = GTK_BIN (item)->child;
+
+ if (bin_child && !GTK_WIDGET_VISIBLE (bin_child))
+ return FALSE;
+ }
+
+ return TRUE;
+ }
- toolbar->button_maxw = 0;
- toolbar->button_maxh = 0;
-
- toolbar->style_set = FALSE;
- toolbar->icon_size_set = FALSE;
+ return FALSE;
}
static void
-gtk_toolbar_set_property (GObject *object,
- guint prop_id,
+gtk_toolbar_set_property (GObject *object,
+ guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkToolbar *toolbar = GTK_TOOLBAR (object);
-
+
switch (prop_id)
{
case PROP_ORIENTATION:
@@ -417,17 +574,24 @@ gtk_toolbar_set_property (GObject *object,
case PROP_TOOLBAR_STYLE:
gtk_toolbar_set_style (toolbar, g_value_get_enum (value));
break;
+ case PROP_SHOW_ARROW:
+ gtk_toolbar_set_show_arrow (toolbar, g_value_get_boolean (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
}
}
static void
-gtk_toolbar_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
+gtk_toolbar_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
GtkToolbar *toolbar = GTK_TOOLBAR (object);
-
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+
switch (prop_id)
{
case PROP_ORIENTATION:
@@ -436,122 +600,153 @@ gtk_toolbar_get_property (GObject *object,
case PROP_TOOLBAR_STYLE:
g_value_set_enum (value, toolbar->style);
break;
+ case PROP_SHOW_ARROW:
+ g_value_set_boolean (value, priv->show_arrow);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
-GtkWidget*
-gtk_toolbar_new (void)
+static void
+gtk_toolbar_map (GtkWidget *widget)
{
- GtkToolbar *toolbar;
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
- toolbar = g_object_new (GTK_TYPE_TOOLBAR, NULL);
+ GTK_WIDGET_CLASS (parent_class)->map (widget);
- return GTK_WIDGET (toolbar);
+ if (priv->event_window)
+ gdk_window_show_unraised (priv->event_window);
}
static void
-gtk_toolbar_destroy (GtkObject *object)
+gtk_toolbar_unmap (GtkWidget *widget)
{
- GtkToolbar *toolbar;
- GList *children;
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
- g_return_if_fail (GTK_IS_TOOLBAR (object));
+ if (priv->event_window)
+ gdk_window_hide (priv->event_window);
- toolbar = GTK_TOOLBAR (object);
-
- if (toolbar->tooltips)
- {
- g_object_unref (toolbar->tooltips);
- toolbar->tooltips = NULL;
- }
-
- for (children = toolbar->children; children; children = children->next)
- {
- GtkToolbarChild *child;
-
- child = children->data;
-
- if (child->type != GTK_TOOLBAR_CHILD_SPACE)
- {
- g_object_ref (child->widget);
- gtk_widget_unparent (child->widget);
- gtk_widget_destroy (child->widget);
- g_object_unref (child->widget);
- }
-
- g_free (child);
- }
- g_list_free (toolbar->children);
- toolbar->children = NULL;
-
- GTK_OBJECT_CLASS (parent_class)->destroy (object);
+ GTK_WIDGET_CLASS (parent_class)->unmap (widget);
}
static void
-gtk_toolbar_paint_space_line (GtkWidget *widget,
- GdkRectangle *area,
- GtkToolbarChild *child)
+gtk_toolbar_paint_space_line (GtkWidget *widget,
+ GdkRectangle *area,
+ GtkToolItem *item)
{
GtkToolbar *toolbar;
- GtkToolbarChildSpace *child_space;
+ GtkAllocation *allocation;
gint space_size;
- g_return_if_fail (GTK_IS_TOOLBAR (widget));
- g_return_if_fail (child != NULL);
- g_return_if_fail (child->type == GTK_TOOLBAR_CHILD_SPACE);
+ g_return_if_fail (GTK_BIN (item)->child == NULL);
toolbar = GTK_TOOLBAR (widget);
- child_space = (GtkToolbarChildSpace *) child;
+ allocation = &GTK_WIDGET (item)->allocation;
space_size = get_space_size (toolbar);
if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_paint_vline (widget->style, widget->window,
GTK_WIDGET_STATE (widget), area, widget,
"toolbar",
- child_space->alloc_y + toolbar->button_maxh *
+ allocation->y + allocation->height *
SPACE_LINE_START / SPACE_LINE_DIVISION,
- child_space->alloc_y + toolbar->button_maxh *
+ allocation->y + allocation->height *
SPACE_LINE_END / SPACE_LINE_DIVISION,
- child_space->alloc_x +
- (space_size -
- widget->style->xthickness) / 2);
- else
+ allocation->x + (space_size-widget->style->xthickness)/2);
+ else if (toolbar->orientation == GTK_ORIENTATION_VERTICAL)
gtk_paint_hline (widget->style, widget->window,
GTK_WIDGET_STATE (widget), area, widget,
"toolbar",
- child_space->alloc_x + toolbar->button_maxw *
+ allocation->x + allocation->width *
SPACE_LINE_START / SPACE_LINE_DIVISION,
- child_space->alloc_x + toolbar->button_maxw *
+ allocation->x + allocation->width *
SPACE_LINE_END / SPACE_LINE_DIVISION,
- child_space->alloc_y +
- (space_size -
- widget->style->ythickness) / 2);
+ allocation->y + (space_size-widget->style->ythickness)/2);
+}
+
+static void
+gtk_toolbar_realize (GtkWidget *widget)
+{
+ GtkToolbar *toolbar = GTK_TOOLBAR (widget);
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+
+ GdkWindowAttr attributes;
+ gint attributes_mask;
+ gint border_width;
+
+ GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+
+ border_width = GTK_CONTAINER (widget)->border_width;
+
+ attributes.wclass = GDK_INPUT_ONLY;
+ attributes.window_type = GDK_WINDOW_CHILD;
+ attributes.x = widget->allocation.x + border_width;
+ attributes.y = widget->allocation.y + border_width;
+ attributes.width = widget->allocation.width - border_width * 2;
+ attributes.height = widget->allocation.height - border_width * 2;
+ attributes.event_mask = gtk_widget_get_events (widget);
+ /* FIXME: does GDK_EXPOSURE_MASK make sense for an input-only window?
+ * If it doesn't, then it should be removed here and in gtkbutton.c,
+ * gtkmenuitem.c, and maybe other places
+ */
+ attributes.event_mask |= (GDK_EXPOSURE_MASK |
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_ENTER_NOTIFY_MASK |
+ GDK_LEAVE_NOTIFY_MASK);
+
+ attributes_mask = GDK_WA_X | GDK_WA_Y;
+
+ widget->window = gtk_widget_get_parent_window (widget);
+ g_object_ref (widget->window);
+
+ priv->event_window = gdk_window_new (gtk_widget_get_parent_window (widget),
+ &attributes, attributes_mask);
+ gdk_window_set_user_data (priv->event_window, toolbar);
+}
+
+static void
+gtk_toolbar_unrealize (GtkWidget *widget)
+{
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
+
+ if (priv->drag_highlight)
+ {
+ gdk_window_set_user_data (priv->drag_highlight, NULL);
+ gdk_window_destroy (priv->drag_highlight);
+ priv->drag_highlight = NULL;
+ }
+
+ if (priv->event_window)
+ {
+ gdk_window_set_user_data (priv->event_window, NULL);
+ gdk_window_destroy (priv->event_window);
+ priv->event_window = NULL;
+ }
+
+ if (GTK_WIDGET_CLASS (parent_class)->unrealize)
+ (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
}
static gint
gtk_toolbar_expose (GtkWidget *widget,
GdkEventExpose *event)
{
- GtkToolbar *toolbar;
- GList *children;
- GtkToolbarChild *child;
+ GtkToolbar *toolbar = GTK_TOOLBAR (widget);
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+
+ GList *items;
gint border_width;
- g_return_val_if_fail (GTK_IS_TOOLBAR (widget), FALSE);
- g_return_val_if_fail (event != NULL, FALSE);
-
border_width = GTK_CONTAINER (widget)->border_width;
if (GTK_WIDGET_DRAWABLE (widget))
{
GtkShadowType shadow_type;
- toolbar = GTK_TOOLBAR (widget);
-
gtk_widget_style_get (widget, "shadow_type", &shadow_type, NULL);
gtk_paint_box (widget->style,
@@ -559,27 +754,31 @@ gtk_toolbar_expose (GtkWidget *widget,
GTK_WIDGET_STATE (widget),
shadow_type,
&event->area, widget, "toolbar",
- widget->allocation.x + border_width,
- widget->allocation.y + border_width,
+ border_width + widget->allocation.x,
+ border_width + widget->allocation.y,
widget->allocation.width - 2 * border_width,
widget->allocation.height - 2 * border_width);
-
- for (children = toolbar->children; children; children = children->next)
- {
- child = children->data;
+ }
- if (child->type == GTK_TOOLBAR_CHILD_SPACE)
- {
- if (get_space_style (toolbar) == GTK_TOOLBAR_SPACE_LINE)
- gtk_toolbar_paint_space_line (widget, &event->area, child);
- }
- else
- gtk_container_propagate_expose (GTK_CONTAINER (widget),
- child->widget,
- event);
- }
+ items = priv->items;
+ while (items)
+ {
+ GtkToolItem *item = GTK_TOOL_ITEM (items->data);
+
+ if (GTK_BIN (item)->child)
+ gtk_container_propagate_expose (GTK_CONTAINER (widget),
+ GTK_WIDGET (item),
+ event);
+ else if (GTK_WIDGET_MAPPED (item) && get_space_style (toolbar) == GTK_TOOLBAR_SPACE_LINE)
+ gtk_toolbar_paint_space_line (widget, &event->area, item);
+
+ items = items->next;
}
+ gtk_container_propagate_expose (GTK_CONTAINER (widget),
+ priv->arrow_button,
+ event);
+
return FALSE;
}
@@ -587,297 +786,928 @@ static void
gtk_toolbar_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
- GtkToolbar *toolbar;
- GList *children;
- GtkToolbarChild *child;
- gint nbuttons;
- gint button_maxw, button_maxh;
- gint widget_maxw, widget_maxh;
- GtkRequisition child_requisition;
- gint space_size;
+ GtkToolbar *toolbar = GTK_TOOLBAR (widget);
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+ gint space_size = get_space_size (toolbar);
+ GList *list;
+ gint max_child_height;
+ gint max_child_width;
+ gint max_homogeneous_child_width;
+ gint max_homogeneous_child_height;
+ gint homogeneous_size;
+ gint long_req;
+ gint pack_end_size;
+ gint pack_front_size;
gint ipadding;
-
- g_return_if_fail (GTK_IS_TOOLBAR (widget));
- g_return_if_fail (requisition != NULL);
+ GtkRequisition arrow_requisition;
- toolbar = GTK_TOOLBAR (widget);
+ max_homogeneous_child_width = 0;
+ max_homogeneous_child_height = 0;
+ max_child_width = 0;
+ max_child_height = 0;
+ for (list = priv->items; list != NULL; list = list->next)
+ {
+ GtkRequisition requisition;
+ GtkToolItem *item = list->data;
+
+ if (!toolbar_item_visible (toolbar, item))
+ continue;
- requisition->width = GTK_CONTAINER (toolbar)->border_width * 2;
- requisition->height = GTK_CONTAINER (toolbar)->border_width * 2;
- nbuttons = 0;
- button_maxw = 0;
- button_maxh = 0;
- widget_maxw = 0;
- widget_maxh = 0;
+ gtk_widget_size_request (GTK_WIDGET (item), &requisition);
+
+ max_child_width = MAX (max_child_width, requisition.width);
+ max_child_height = MAX (max_child_height, requisition.height);
- space_size = get_space_size (toolbar);
+ if (GTK_TOOL_ITEM (item)->homogeneous && GTK_BIN (item)->child)
+ {
+ max_homogeneous_child_width = MAX (max_homogeneous_child_width, requisition.width);
+ max_homogeneous_child_height = MAX (max_homogeneous_child_height, requisition.height);
+ }
+ }
+
+ if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
+ homogeneous_size = max_homogeneous_child_width;
+ else
+ homogeneous_size = max_homogeneous_child_height;
- for (children = toolbar->children; children; children = children->next)
+ pack_end_size = 0;
+ pack_front_size = 0;
+ for (list = priv->items; list != NULL; list = list->next)
{
- child = children->data;
-
- switch (child->type)
+ GtkToolItem *item = list->data;
+ guint size;
+
+ if (!toolbar_item_visible (toolbar, item))
+ continue;
+
+ if (!GTK_BIN (item)->child)
+ {
+ size = space_size;
+ }
+ else if (item->homogeneous)
+ {
+ size = homogeneous_size;
+ }
+ else
{
- case GTK_TOOLBAR_CHILD_SPACE:
+ GtkRequisition requisition;
+
+ gtk_widget_size_request (GTK_WIDGET (item), &requisition);
+
if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
- requisition->width += space_size;
+ size = requisition.width;
else
- requisition->height += space_size;
-
- break;
-
- case GTK_TOOLBAR_CHILD_BUTTON:
- case GTK_TOOLBAR_CHILD_RADIOBUTTON:
- case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
- if (GTK_WIDGET_VISIBLE (child->widget))
- {
- gtk_widget_size_request (child->widget, &child_requisition);
-
- nbuttons++;
- button_maxw = MAX (button_maxw, child_requisition.width);
- button_maxh = MAX (button_maxh, child_requisition.height);
- }
+ size = requisition.height;
+ }
+
+ if (item->pack_end)
+ pack_end_size += size;
+ else
+ pack_front_size += size;
+ }
+
+ if (priv->show_arrow)
+ {
+ gtk_widget_size_request (priv->arrow_button, &arrow_requisition);
+
+ if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
+ long_req = arrow_requisition.width;
+ else
+ long_req = arrow_requisition.height;
- break;
+ /* There is no point requesting space for the arrow if that would take
+ * up more space than all the items combined
+ */
+ long_req = MIN (long_req, pack_front_size + pack_end_size);
+ }
+ else
+ {
+ arrow_requisition.height = 0;
+ arrow_requisition.width = 0;
+
+ long_req = pack_end_size + pack_front_size;
+ }
+
+ if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ requisition->width = long_req;
+ requisition->height = MAX (max_child_height, arrow_requisition.height);
+ }
+ else
+ {
+ requisition->height = long_req;
+ requisition->width = MAX (max_child_width, arrow_requisition.width);
+ }
+
+ /* Extra spacing */
+ ipadding = get_internal_padding (toolbar);
- case GTK_TOOLBAR_CHILD_WIDGET:
- if (GTK_WIDGET_VISIBLE (child->widget))
- {
- gtk_widget_size_request (child->widget, &child_requisition);
+ requisition->width += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width);
+ requisition->height += 2 * (ipadding + GTK_CONTAINER (toolbar)->border_width);
+
+ toolbar->button_maxw = max_homogeneous_child_width;
+ toolbar->button_maxh = max_homogeneous_child_height;
+}
- widget_maxw = MAX (widget_maxw, child_requisition.width);
- widget_maxh = MAX (widget_maxh, child_requisition.height);
+static void
+fixup_allocation_for_rtl (gint total_size,
+ GtkAllocation *allocation)
+{
+ allocation->x += (total_size - (2 * allocation->x + allocation->width));
+}
- if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
- requisition->width += child_requisition.width;
- else
- requisition->height += child_requisition.height;
- }
+static void
+fixup_allocation_for_vertical (GtkAllocation *allocation)
+{
+ gint tmp;
+
+ tmp = allocation->x;
+ allocation->x = allocation->y;
+ allocation->y = tmp;
+
+ tmp = allocation->width;
+ allocation->width = allocation->height;
+ allocation->height = tmp;
+}
- break;
+static gint
+get_item_size (GtkToolbar *toolbar,
+ GtkWidget *child)
+{
+ GtkRequisition requisition;
+ GtkToolItem *item = GTK_TOOL_ITEM (child);
- default:
- g_assert_not_reached ();
- }
- }
+ if (!GTK_BIN (item)->child)
+ return get_space_size (toolbar);
+ gtk_widget_get_child_requisition (child, &requisition);
+
if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
{
- requisition->width += nbuttons * button_maxw;
- requisition->height += MAX (button_maxh, widget_maxh);
+ if (item->homogeneous)
+ return toolbar->button_maxw;
+ else
+ return requisition.width;
}
else
{
- requisition->width += MAX (button_maxw, widget_maxw);
- requisition->height += nbuttons * button_maxh;
+ if (item->homogeneous)
+ return toolbar->button_maxh;
+ else
+ return requisition.height;
}
-
- /* Extra spacing */
- gtk_widget_style_get (widget, "internal_padding", &ipadding, NULL);
-
- requisition->width += 2 * ipadding;
- requisition->height += 2 * ipadding;
-
- toolbar->button_maxw = button_maxw;
- toolbar->button_maxh = button_maxh;
}
static void
gtk_toolbar_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
- GtkToolbar *toolbar;
- GList *children;
- GtkToolbarChild *child;
- GtkToolbarChildSpace *child_space;
- GtkAllocation alloc;
- GtkRequisition child_requisition;
- gint x_border_width, y_border_width;
+ GtkToolbar *toolbar = GTK_TOOLBAR (widget);
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
gint space_size;
- gint ipadding;
- GtkTextDirection direction;
- gint ltr_x = 0; /* Quiet GCC */
-
- g_return_if_fail (GTK_IS_TOOLBAR (widget));
- g_return_if_fail (allocation != NULL);
+ GtkAllocation *allocations;
+ GtkAllocation arrow_allocation;
+ gint arrow_size;
+ gint size, pos, short_size;
+ GList *list;
+ gint i;
+ gboolean need_arrow;
+ gint n_expand_items;
+ gint border_width;
+ gint available_size;
+ gint n_items;
+ gint needed_size;
+ GList *items;
+ GtkRequisition arrow_requisition;
- toolbar = GTK_TOOLBAR (widget);
widget->allocation = *allocation;
-
- direction = gtk_widget_get_direction (widget);
- x_border_width = GTK_CONTAINER (toolbar)->border_width;
- y_border_width = GTK_CONTAINER (toolbar)->border_width;
+ space_size = get_space_size (toolbar);
+
+ border_width = GTK_CONTAINER (toolbar)->border_width;
- gtk_widget_style_get (widget, "internal_padding", &ipadding, NULL);
+ if (GTK_WIDGET_REALIZED (widget))
+ {
+ gdk_window_move_resize (priv->event_window,
+ allocation->x + border_width,
+ allocation->y + border_width,
+ allocation->width - border_width * 2,
+ allocation->height - border_width * 2);
+ }
+
+ border_width += get_internal_padding (toolbar);
- x_border_width += ipadding;
- y_border_width += ipadding;
+ gtk_widget_get_child_requisition (GTK_WIDGET (priv->arrow_button),
+ &arrow_requisition);
if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
- ltr_x = allocation->x + x_border_width;
+ {
+ available_size = size = allocation->width - 2 * border_width;
+ short_size = allocation->height - 2 * border_width;
+ arrow_size = arrow_requisition.width;
+ }
else
- alloc.y = allocation->y + y_border_width;
+ {
+ available_size = size = allocation->height - 2 * border_width;
+ short_size = allocation->width - 2 * border_width;
+ arrow_size = arrow_requisition.height;
+ }
- space_size = get_space_size (toolbar);
-
- for (children = toolbar->children; children; children = children->next)
+ n_items = g_list_length (priv->items);
+ allocations = g_new0 (GtkAllocation, n_items);
+
+ needed_size = 0;
+ for (list = priv->items; list != NULL; list = list->next)
{
- child = children->data;
+ GtkToolItem *item = list->data;
+
+ if (toolbar_item_visible (toolbar, item))
+ needed_size += get_item_size (toolbar, GTK_WIDGET (item));
+ }
- switch (child->type)
- {
- case GTK_TOOLBAR_CHILD_SPACE:
+ need_arrow = (needed_size > available_size) && priv->show_arrow;
- child_space = (GtkToolbarChildSpace *) child;
+ if (need_arrow)
+ size = available_size - arrow_size;
+ else
+ size = available_size;
- if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
- {
- if (direction == GTK_TEXT_DIR_LTR)
- child_space->alloc_x = ltr_x;
- else
- child_space->alloc_x = allocation->width - ltr_x - space_size;
- child_space->alloc_y = allocation->y + (allocation->height - toolbar->button_maxh) / 2;
- ltr_x += space_size;
- }
- else
+ items = g_list_copy (priv->items);
+
+ /* calculate widths of pack end items */
+ for (list = g_list_last (items), i = 0; list != NULL; list = list->prev, ++i)
+ {
+ GtkToolItem *item = list->data;
+ GtkAllocation *allocation = &(allocations[n_items - i - 1]);
+ gint item_size;
+
+ if (!item->pack_end || !toolbar_item_visible (toolbar, item))
+ continue;
+
+ item_size = get_item_size (toolbar, GTK_WIDGET (item));
+ if (item_size <= size)
+ {
+ size -= item_size;
+ allocation->width = item_size;
+ item->overflow_item = FALSE;
+ }
+ else
+ {
+ while (list)
{
- child_space->alloc_x = allocation->x + (allocation->width - toolbar->button_maxw) / 2;
- child_space->alloc_y = alloc.y;
- alloc.y += space_size;
+ item = list->data;
+ if (item->pack_end)
+ item->overflow_item = TRUE;
+
+ list = list->prev;
}
-
break;
+ }
+ }
- case GTK_TOOLBAR_CHILD_BUTTON:
- case GTK_TOOLBAR_CHILD_RADIOBUTTON:
- case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
- if (!GTK_WIDGET_VISIBLE (child->widget))
- break;
+ /* calculate widths of pack front items */
+ for (list = items, i = 0; list != NULL; list = list->next, ++i)
+ {
+ GtkToolItem *item = list->data;
+ gint item_size;
- alloc.width = toolbar->button_maxw;
- alloc.height = toolbar->button_maxh;
+ if (item->pack_end || !toolbar_item_visible (toolbar, item))
+ continue;
- if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
+ item_size = get_item_size (toolbar, GTK_WIDGET (item));
+ if (item_size <= size)
+ {
+ size -= item_size;
+ allocations[i].width = item_size;
+ item->overflow_item = FALSE;
+ }
+ else
+ {
+ while (list)
{
- if (direction == GTK_TEXT_DIR_LTR)
- alloc.x = ltr_x;
- else
- alloc.x = allocation->width - ltr_x - alloc.width;
- alloc.y = allocation->y + (allocation->height - toolbar->button_maxh) / 2;
+ item = list->data;
+ if (!item->pack_end)
+ item->overflow_item = TRUE;
+ list = list->next;
}
- else
- alloc.x = allocation->x + (allocation->width - toolbar->button_maxw) / 2;
-
- gtk_widget_size_allocate (child->widget, &alloc);
+ break;
+ }
+ }
- if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
- ltr_x += toolbar->button_maxw;
- else
- alloc.y += toolbar->button_maxh;
+ if (need_arrow)
+ {
+ arrow_allocation.width = arrow_size;
+ arrow_allocation.height = short_size;
+ }
+
+ /* expand expandable items */
+ n_expand_items = 0;
+ for (list = priv->items; list != NULL; list = list->next)
+ {
+ GtkToolItem *item = list->data;
+
+ if (toolbar_item_visible (toolbar, item) && item->expand &&
+ !item->overflow_item && GTK_BIN (item)->child)
+ {
+ n_expand_items++;
+ }
+ }
+
+ for (list = items, i = 0; list != NULL; list = list->next, ++i)
+ {
+ GtkToolItem *item = list->data;
+
+ if (toolbar_item_visible (toolbar, item) && item->expand &&
+ !item->overflow_item && GTK_BIN (item)->child)
+ {
+ gint extra = size / n_expand_items;
+ if (size % n_expand_items != 0)
+ extra++;
- break;
+ allocations[i].width += extra;
+ size -= extra;
+ n_expand_items--;
+ }
+ }
- case GTK_TOOLBAR_CHILD_WIDGET:
- if (!GTK_WIDGET_VISIBLE (child->widget))
- break;
+ g_assert (n_expand_items == 0);
+
+ /* position pack front items */
+ pos = border_width;
+ for (list = items, i = 0; list != NULL; list = list->next, ++i)
+ {
+ GtkToolItem *item = list->data;
+
+ if (toolbar_item_visible (toolbar, item) && !item->overflow_item && !item->pack_end)
+ {
+ allocations[i].x = pos;
+ allocations[i].y = border_width;
+ allocations[i].height = short_size;
- gtk_widget_get_child_requisition (child->widget, &child_requisition);
-
- alloc.width = child_requisition.width;
- alloc.height = child_requisition.height;
+ pos += allocations[i].width;
+ }
+ }
- if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
- {
- if (direction == GTK_TEXT_DIR_LTR)
- alloc.x = ltr_x;
- else
- alloc.x = allocation->width - ltr_x - alloc.width;
- alloc.y = allocation->y + (allocation->height - child_requisition.height) / 2;
- }
- else
- alloc.x = allocation->x + (allocation->width - child_requisition.width) / 2;
+ /* position pack end items */
+ pos = available_size + border_width;
+ for (list = g_list_last (items), i = 0; list != NULL; list = list->prev, ++i)
+ {
+ GtkToolItem *item = list->data;
+
+ if (toolbar_item_visible (toolbar, item) && !item->overflow_item && item->pack_end)
+ {
+ GtkAllocation *allocation = &(allocations[n_items - i - 1]);
- gtk_widget_size_allocate (child->widget, &alloc);
+ allocation->x = pos - allocation->width;
+ allocation->y = border_width;
+ allocation->height = short_size;
+
+ pos -= allocation->width;
+ }
+ }
- if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
- ltr_x += child_requisition.width;
- else
- alloc.y += child_requisition.height;
+ /* position arrow */
+ if (need_arrow)
+ {
+ arrow_allocation.x = pos - arrow_allocation.width;
+ arrow_allocation.y = border_width;
+ }
+
+ /* fix up allocations in the vertical or RTL cases */
+ if (toolbar->orientation == GTK_ORIENTATION_VERTICAL)
+ {
+ for (i = 0; i < n_items; ++i)
+ fixup_allocation_for_vertical (&(allocations[i]));
+
+ if (need_arrow)
+ fixup_allocation_for_vertical (&arrow_allocation);
+ }
+ else if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
+ {
+ for (i = 0; i < n_items; ++i)
+ fixup_allocation_for_rtl (available_size, &(allocations[i]));
- break;
+ if (need_arrow)
+ fixup_allocation_for_rtl (available_size, &arrow_allocation);
+ }
+
+ /* translate the items by allocation->(x,y) */
+ for (i = 0; i < n_items; ++i)
+ {
+ allocations[i].x += allocation->x;
+ allocations[i].y += allocation->y;
+ }
- default:
- g_assert_not_reached ();
+ if (need_arrow)
+ {
+ arrow_allocation.x += allocation->x;
+ arrow_allocation.y += allocation->y;
+ }
+
+ /* finally allocate the items */
+ for (list = items, i = 0; list != NULL; list = list->next, i++)
+ {
+ GtkToolItem *item = list->data;
+
+ if (toolbar_item_visible (toolbar, item) && !item->overflow_item)
+ {
+ gtk_widget_size_allocate (GTK_WIDGET (item), &(allocations[i]));
+ gtk_widget_set_child_visible (GTK_WIDGET (item), TRUE);
+ }
+ else
+ {
+ gtk_widget_set_child_visible (GTK_WIDGET (item), FALSE);
}
}
+
+ if (need_arrow)
+ {
+ gtk_widget_size_allocate (GTK_WIDGET (priv->arrow_button),
+ &arrow_allocation);
+ gtk_widget_show (GTK_WIDGET (priv->arrow_button));
+ }
+ else
+ {
+ gtk_widget_hide (GTK_WIDGET (priv->arrow_button));
+ }
+
+ g_free (allocations);
+ g_list_free (items);
}
static void
-gtk_toolbar_style_set (GtkWidget *widget,
- GtkStyle *prev_style)
+gtk_toolbar_style_set (GtkWidget *widget,
+ GtkStyle *prev_style)
{
+ if (GTK_WIDGET_REALIZED (widget))
+ gtk_style_set_background (widget->style, widget->window, widget->state);
+
if (prev_style)
gtk_toolbar_update_button_relief (GTK_TOOLBAR (widget));
}
+static void
+gtk_toolbar_direction_changed (GtkWidget *widget,
+ GtkTextDirection previous_dir)
+{
+ GtkToolbar *toolbar = GTK_TOOLBAR (widget);
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+
+ if (toolbar->orientation == GTK_ORIENTATION_VERTICAL)
+ {
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
+ gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
+ else
+ gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_LEFT, GTK_SHADOW_NONE);
+ }
+
+ GTK_WIDGET_CLASS (parent_class)->direction_changed (widget, previous_dir);
+}
+
+static GList *
+gtk_toolbar_list_children_in_focus_order (GtkToolbar *toolbar,
+ GtkDirectionType dir)
+{
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+ GList *result = NULL;
+ GList *list;
+
+ for (list = priv->items; list != NULL; list = list->next)
+ {
+ GtkToolItem *item = list->data;
+ if (!item->pack_end)
+ result = g_list_prepend (result, item);
+ }
+
+ for (list = priv->items; list != NULL; list = list->next)
+ {
+ GtkToolItem *item = list->data;
+
+ if (item->pack_end)
+ result = g_list_prepend (result, item);
+ }
+
+ result = g_list_prepend (result, priv->arrow_button);
+
+ if (dir == GTK_DIR_RIGHT || dir == GTK_DIR_DOWN || dir == GTK_DIR_TAB_FORWARD)
+ result = g_list_reverse (result);
+
+ if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
+ result = g_list_reverse (result);
+
+ return result;
+}
+
+static gboolean
+gtk_toolbar_focus_ends (GtkToolbar *toolbar,
+ gboolean home)
+{
+ GList *children, *list;
+ GtkDirectionType dir = home? GTK_DIR_RIGHT : GTK_DIR_LEFT;
+
+ children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
+
+ if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_RTL)
+ {
+ children = g_list_reverse (children);
+ if (dir == GTK_DIR_RIGHT)
+ dir = GTK_DIR_LEFT;
+ else
+ dir = GTK_DIR_RIGHT;
+ }
+
+ for (list = children; list != NULL; list = list->next)
+ {
+ GtkWidget *child = list->data;
+
+ if (GTK_CONTAINER (toolbar)->focus_child == child)
+ break;
+
+ if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
+ break;
+ }
+
+ g_list_free (children);
+
+ return TRUE;
+}
+
+static gboolean
+gtk_toolbar_move_focus (GtkToolbar *toolbar,
+ GtkDirectionType dir)
+{
+ GList *list;
+ gboolean try_focus = FALSE;
+ GList *children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
+
+ for (list = children; list != NULL; list = list->next)
+ {
+ GtkWidget *child = list->data;
+
+ if (try_focus && GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
+ break;
+
+ if (child == GTK_CONTAINER (toolbar)->focus_child)
+ try_focus = TRUE;
+ }
+
+ g_list_free (children);
+
+ return TRUE;
+}
+
+/* The focus handler for the toolbar. It called when the user presses TAB or otherwise
+ * tries to focus the toolbar.
+ */
static gboolean
-gtk_toolbar_focus (GtkWidget *widget,
- GtkDirectionType dir)
+gtk_toolbar_focus (GtkWidget *widget,
+ GtkDirectionType dir)
{
- /* Focus can't go in toolbars */
+ GtkToolbar *toolbar = GTK_TOOLBAR (widget);
+ GList *children, *list;
+
+ /* if focus is already somewhere inside the toolbar then return FALSE.
+ * The only way focus can stay inside the toolbar is when the user presses
+ * arrow keys or Ctrl TAB (both of which are handled by the
+ * gtk_toolbar_move_focus() keybinding function.
+ */
+ if (GTK_CONTAINER (widget)->focus_child)
+ return FALSE;
+
+ children = gtk_toolbar_list_children_in_focus_order (toolbar, dir);
+
+ for (list = children; list != NULL; list = list->next)
+ {
+ GtkWidget *child = list->data;
+
+ if (GTK_WIDGET_MAPPED (child) && gtk_widget_child_focus (child, dir))
+ return TRUE;
+ }
+
+ g_list_free (children);
return FALSE;
}
static void
-child_show_all (GtkWidget *widget)
+style_change_notify (GtkToolbar *toolbar)
{
- /* Don't show our own children, since that would
- * show labels we may intend to hide in icons-only mode
- */
- if (!g_object_get_data (G_OBJECT (widget),
- "gtk-toolbar-is-child"))
- gtk_widget_show_all (widget);
+ if (!toolbar->style_set)
+ {
+ /* pretend it was set, then unset, thus reverting to new default */
+ toolbar->style_set = TRUE;
+ gtk_toolbar_unset_style (toolbar);
+ }
}
static void
-gtk_toolbar_show_all (GtkWidget *widget)
+icon_size_change_notify (GtkToolbar *toolbar)
+{
+ if (!toolbar->icon_size_set)
+ {
+ /* pretend it was set, then unset, thus reverting to new default */
+ toolbar->icon_size_set = TRUE;
+ gtk_toolbar_unset_icon_size (toolbar);
+ }
+}
+
+static GtkSettings *
+toolbar_get_settings (GtkToolbar *toolbar)
{
- gtk_container_foreach (GTK_CONTAINER (widget),
- (GtkCallback) child_show_all,
- NULL);
- gtk_widget_show (widget);
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+ return priv->settings;
}
static void
-child_hide_all (GtkWidget *widget)
+gtk_toolbar_screen_changed (GtkWidget *widget,
+ GdkScreen *previous_screen)
{
- /* Don't hide our own children, since that would also hide
- * widgets that won't be shown again by gtk_toolbar_show_all().
- */
- if (!g_object_get_data (G_OBJECT (widget),
- "gtk-toolbar-is-child"))
- gtk_widget_hide_all (widget);
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget);
+ GtkToolbar *toolbar = GTK_TOOLBAR (widget);
+ GtkSettings *old_settings = toolbar_get_settings (toolbar);
+ GtkSettings *settings;
+
+ if (gtk_widget_has_screen (GTK_WIDGET (toolbar)))
+ settings = gtk_widget_get_settings (GTK_WIDGET (toolbar));
+ else
+ settings = NULL;
+
+ if (settings == old_settings)
+ return;
+
+ if (old_settings)
+ {
+ g_signal_handler_disconnect (old_settings, toolbar->style_set_connection);
+ g_signal_handler_disconnect (old_settings, toolbar->icon_size_connection);
+
+ g_object_unref (old_settings);
+ }
+
+ if (settings)
+ {
+ toolbar->style_set_connection =
+ g_signal_connect_swapped (settings,
+ "notify::gtk-toolbar-style",
+ G_CALLBACK (style_change_notify),
+ toolbar);
+ toolbar->icon_size_connection =
+ g_signal_connect_swapped (settings,
+ "notify::gtk-toolbar-icon-size",
+ G_CALLBACK (icon_size_change_notify),
+ toolbar);
+
+ g_object_ref (settings);
+ priv->settings = settings;
+ }
+ else
+ priv->settings = NULL;
+
+ style_change_notify (toolbar);
+ icon_size_change_notify (toolbar);
+}
+
+static void
+find_drop_pos (GtkToolbar *toolbar,
+ gint x,
+ gint y,
+ gint *drop_index,
+ gint *drop_pos)
+{
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+ GtkOrientation orientation;
+ GtkTextDirection direction;
+ GList *items;
+ GtkToolItem *item;
+ gint border_width;
+ gint best_distance, best_pos, best_index, index;
+
+ orientation = toolbar->orientation;
+ direction = gtk_widget_get_direction (GTK_WIDGET (toolbar));
+ border_width = GTK_CONTAINER (toolbar)->border_width + get_internal_padding (toolbar);
+
+ items = priv->items;
+ if (!items)
+ {
+ *drop_index = 0;
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ if (direction == GTK_TEXT_DIR_LTR)
+ *drop_pos = border_width;
+ else
+ *drop_pos = GTK_WIDGET (toolbar)->allocation.width - border_width;
+ }
+ else
+ {
+ *drop_pos = border_width;
+ }
+ return;
+ }
+
+ /* initial conditions */
+ item = GTK_TOOL_ITEM (items->data);
+ best_index = 0;
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ if (direction == GTK_TEXT_DIR_LTR)
+ best_pos = GTK_WIDGET (item)->allocation.x;
+ else
+ best_pos = GTK_WIDGET (item)->allocation.x +
+ GTK_WIDGET (item)->allocation.width;
+ best_distance = ABS (best_pos - x);
+ }
+ else
+ {
+ best_pos = GTK_WIDGET (item)->allocation.y;
+ best_distance = ABS (best_pos - y);
+ }
+
+ index = 0;
+ while (items)
+ {
+ item = GTK_TOOL_ITEM (items->data);
+ index++;
+ if (GTK_WIDGET_DRAWABLE (item) && !item->pack_end)
+ {
+ gint pos, distance;
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ if (direction == GTK_TEXT_DIR_LTR)
+ pos = GTK_WIDGET (item)->allocation.x +
+ GTK_WIDGET (item)->allocation.width;
+ else
+ pos = GTK_WIDGET (item)->allocation.x;
+ distance = ABS (pos - x);
+ }
+ else
+ {
+ pos = GTK_WIDGET (item)->allocation.y +
+ GTK_WIDGET (item)->allocation.height;
+ distance = ABS (pos - y);
+ }
+ if (distance < best_distance)
+ {
+ best_index = index;
+ best_pos = pos;
+ best_distance = distance;
+ }
+ }
+ items = items->next;
+ }
+ *drop_index = best_index;
+ *drop_pos = best_pos;
}
static void
-gtk_toolbar_hide_all (GtkWidget *widget)
+gtk_toolbar_drag_leave (GtkWidget *widget,
+ GdkDragContext *context,
+ guint time_)
+{
+ GtkToolbar *toolbar = GTK_TOOLBAR (widget);
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+
+ if (priv->drag_highlight)
+ {
+ gdk_window_set_user_data (priv->drag_highlight, NULL);
+ gdk_window_destroy (priv->drag_highlight);
+ priv->drag_highlight = NULL;
+ }
+
+ priv->drop_index = -1;
+}
+
+static gboolean
+gtk_toolbar_drag_motion (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time_)
{
- gtk_container_foreach (GTK_CONTAINER (widget),
- (GtkCallback) child_hide_all,
- NULL);
- gtk_widget_hide (widget);
+ GtkToolbar *toolbar = GTK_TOOLBAR (widget);
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+ gint new_index, new_pos;
+
+ find_drop_pos(toolbar, x, y, &new_index, &new_pos);
+
+ if (!priv->drag_highlight)
+ {
+ GdkWindowAttr attributes;
+ guint attributes_mask;
+
+ attributes.window_type = GDK_WINDOW_CHILD;
+ attributes.wclass = GDK_INPUT_OUTPUT;
+ attributes.visual = gtk_widget_get_visual (widget);
+ attributes.colormap = gtk_widget_get_colormap (widget);
+ attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK;
+ attributes.width = 1;
+ attributes.height = 1;
+ attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
+ priv->drag_highlight = gdk_window_new (widget->window,
+ &attributes, attributes_mask);
+ gdk_window_set_user_data (priv->drag_highlight, widget);
+ gdk_window_set_background (priv->drag_highlight,
+ &widget->style->fg[widget->state]);
+ }
+
+ if (priv->drop_index < 0 ||
+ priv->drop_index != new_index)
+ {
+ gint border_width = GTK_CONTAINER (toolbar)->border_width;
+ priv->drop_index = new_index;
+ if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ gdk_window_move_resize (priv->drag_highlight,
+ widget->allocation.x + new_pos - 1,
+ widget->allocation.y + border_width,
+ 2, widget->allocation.height-border_width*2);
+ }
+ else
+ {
+ gdk_window_move_resize (priv->drag_highlight,
+ widget->allocation.x + border_width,
+ widget->allocation.y + new_pos - 1,
+ widget->allocation.width-border_width*2, 2);
+ }
+ }
+
+ gdk_window_show (priv->drag_highlight);
+
+ gdk_drag_status (context, context->suggested_action, time_);
+
+ return TRUE;
+}
+
+static void
+gtk_toolbar_get_child_property (GtkContainer *container,
+ GtkWidget *child,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkToolItem *item = GTK_TOOL_ITEM (child);
+
+ switch (property_id)
+ {
+ case CHILD_PROP_PACK_END:
+ g_value_set_boolean (value, item->pack_end);
+ break;
+
+ case CHILD_PROP_HOMOGENEOUS:
+ g_value_set_boolean (value, item->homogeneous);
+ break;
+
+ case CHILD_PROP_EXPAND:
+ g_value_set_boolean (value, item->expand);
+ break;
+
+ default:
+ GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_toolbar_set_child_property (GtkContainer *container,
+ GtkWidget *child,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id)
+ {
+ case CHILD_PROP_PACK_END:
+ gtk_tool_item_set_pack_end (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
+ break;
+
+ case CHILD_PROP_HOMOGENEOUS:
+ gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
+ break;
+
+ case CHILD_PROP_EXPAND:
+ gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (child), g_value_get_boolean (value));
+ break;
+
+ default:
+ GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
+ break;
+ }
}
static void
gtk_toolbar_add (GtkContainer *container,
GtkWidget *widget)
{
+ GtkToolbar *toolbar;
+
g_return_if_fail (GTK_IS_TOOLBAR (container));
g_return_if_fail (widget != NULL);
- gtk_toolbar_append_widget (GTK_TOOLBAR (container), widget, NULL, NULL);
+ toolbar = GTK_TOOLBAR (container);
+
+ if (GTK_IS_TOOL_ITEM (widget))
+ gtk_toolbar_insert (toolbar, GTK_TOOL_ITEM (widget), 0);
+ else
+ gtk_toolbar_append_widget (toolbar, widget, NULL, NULL);
}
static void
@@ -885,187 +1715,568 @@ gtk_toolbar_remove (GtkContainer *container,
GtkWidget *widget)
{
GtkToolbar *toolbar;
- GList *children;
- GtkToolbarChild *child;
-
+ GtkToolItem *item = NULL;
+
g_return_if_fail (GTK_IS_TOOLBAR (container));
- g_return_if_fail (widget != NULL);
toolbar = GTK_TOOLBAR (container);
- for (children = toolbar->children; children; children = children->next)
+ if (GTK_IS_TOOL_ITEM (widget))
+ {
+ item = GTK_TOOL_ITEM (widget);
+ }
+ else
+ {
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+ GList *list;
+
+ for (list = priv->items; list != NULL; list = list->next)
+ {
+ if (GTK_BIN (list->data)->child == widget)
+ {
+ item = list->data;
+ break;
+ }
+ }
+ }
+
+ g_return_if_fail (item != NULL);
+
+ gtk_toolbar_remove_tool_item (GTK_TOOLBAR (container), item);
+}
+
+static void
+gtk_toolbar_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ GtkToolbar *toolbar = GTK_TOOLBAR (container);
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+ GList *items;
+
+ g_return_if_fail (callback != NULL);
+
+ items = priv->items;
+
+ while (items)
+ {
+ GtkToolItem *item = GTK_TOOL_ITEM (items->data);
+
+ items = items->next;
+
+ (*callback) (GTK_WIDGET (item), callback_data);
+ }
+
+ if (include_internals)
+ (* callback) (priv->arrow_button, callback_data);
+}
+
+static GType
+gtk_toolbar_child_type (GtkContainer *container)
+{
+ return GTK_TYPE_TOOL_ITEM;
+}
+
+static void
+gtk_toolbar_reconfigured (GtkToolbar *toolbar)
+{
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+ GList *items;
+
+ items = priv->items;
+ while (items)
+ {
+ GtkToolItem *item = GTK_TOOL_ITEM (items->data);
+
+ gtk_tool_item_toolbar_reconfigured (item);
+
+ items = items->next;
+ }
+}
+
+static void
+gtk_toolbar_real_orientation_changed (GtkToolbar *toolbar,
+ GtkOrientation orientation)
+{
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+ if (toolbar->orientation != orientation)
+ {
+ toolbar->orientation = orientation;
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_DOWN, GTK_SHADOW_NONE);
+ else if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
+ gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
+ else
+ gtk_arrow_set (GTK_ARROW (priv->arrow), GTK_ARROW_LEFT, GTK_SHADOW_NONE);
+
+ gtk_toolbar_reconfigured (toolbar);
+
+ gtk_widget_queue_resize (GTK_WIDGET (toolbar));
+ g_object_notify (G_OBJECT (toolbar), "orientation");
+ }
+}
+
+static void
+gtk_toolbar_real_style_changed (GtkToolbar *toolbar,
+ GtkToolbarStyle style)
+{
+ if (toolbar->style != style)
+ {
+ toolbar->style = style;
+
+ gtk_toolbar_reconfigured (toolbar);
+
+ gtk_widget_queue_resize (GTK_WIDGET (toolbar));
+ g_object_notify (G_OBJECT (toolbar), "toolbar_style");
+ }
+}
+
+static void
+menu_position_func (GtkMenu *menu,
+ gint *x,
+ gint *y,
+ gboolean *push_in,
+ gpointer user_data)
+{
+ GtkToolbar *toolbar = GTK_TOOLBAR (user_data);
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+ GtkRequisition req;
+ GtkRequisition menu_req;
+
+ gdk_window_get_origin (GTK_BUTTON (priv->arrow_button)->event_window, x, y);
+ gtk_widget_size_request (priv->arrow_button, &req);
+ gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
+
+ if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ *y += priv->arrow_button->allocation.height;
+ if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
+ *x += priv->arrow_button->allocation.width - req.width;
+ else
+ *x += req.width - menu_req.width;
+ }
+ else
+ {
+ if (gtk_widget_get_direction (GTK_WIDGET (toolbar)) == GTK_TEXT_DIR_LTR)
+ *x += priv->arrow_button->allocation.width;
+ else
+ *x -= menu_req.width;
+ *y += priv->arrow_button->allocation.height - req.height;
+ }
+
+ *push_in = TRUE;
+}
+
+static void
+menu_deactivated (GtkWidget *menu,
+ GtkToolbar *toolbar)
+{
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->arrow_button), FALSE);
+}
+
+static void
+remove_item (GtkWidget *menu_item,
+ gpointer data)
+{
+ gtk_container_remove (GTK_CONTAINER (menu_item->parent), menu_item);
+}
+
+static void
+show_menu (GtkToolbar *toolbar,
+ GdkEventButton *event)
+{
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+ GList *list;
+
+ if (priv->menu)
+ {
+ gtk_container_foreach (GTK_CONTAINER (priv->menu), remove_item, NULL);
+ gtk_widget_destroy (GTK_WIDGET (priv->menu));
+ }
+
+ priv->menu = GTK_MENU (gtk_menu_new ());
+ g_signal_connect (priv->menu, "deactivate", G_CALLBACK (menu_deactivated), toolbar);
+
+ for (list = priv->items; list != NULL; list = list->next)
{
- child = children->data;
+ GtkToolItem *item = list->data;
- if ((child->type != GTK_TOOLBAR_CHILD_SPACE) && (child->widget == widget))
+ if (toolbar_item_visible (toolbar, item) && item->overflow_item)
{
- gboolean was_visible;
+ GtkWidget *menu_item = gtk_tool_item_retrieve_proxy_menu_item (item);
+
+ if (menu_item)
+ {
+ g_assert (GTK_IS_MENU_ITEM (menu_item));
+ gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), menu_item);
+ }
+ }
+ }
+
+ gtk_widget_show_all (GTK_WIDGET (priv->menu));
+
+ gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL,
+ menu_position_func, toolbar,
+ event? event->button : 0, event? event->time : gtk_get_current_event_time());
+}
+
+static void
+gtk_toolbar_arrow_button_clicked (GtkWidget *button,
+ GtkToolbar *toolbar)
+{
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->arrow_button)) &&
+ (!priv->menu || !GTK_WIDGET_VISIBLE (GTK_WIDGET (priv->menu))))
+ {
+ /* We only get here when the button is clicked with the keybaord,
+ * because mouse button presses result in the menu being shown so
+ * that priv->menu would be non-NULL and visible.
+ */
+ show_menu (toolbar, NULL);
+ gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->menu), FALSE);
+ }
+}
+
+static gboolean
+gtk_toolbar_arrow_button_press (GtkWidget *button,
+ GdkEventButton *event,
+ GtkToolbar *toolbar)
+{
+ show_menu (toolbar, event);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+
+ return TRUE;
+}
+
+static gboolean
+gtk_toolbar_button_press (GtkWidget *toolbar,
+ GdkEventButton *event)
+{
+ if (event->button == 3)
+ g_signal_emit (toolbar, toolbar_signals[POPUP_CONTEXT_MENU], 0, NULL);
+
+ return FALSE;
+}
+
+static void
+gtk_toolbar_update_button_relief (GtkToolbar *toolbar)
+{
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+
+ gtk_toolbar_reconfigured (toolbar);
+
+ gtk_button_set_relief (GTK_BUTTON (priv->arrow_button), get_button_relief (toolbar));
+}
+
+static GtkReliefStyle
+get_button_relief (GtkToolbar *toolbar)
+{
+ GtkReliefStyle button_relief = GTK_RELIEF_NORMAL;
+
+ gtk_widget_ensure_style (GTK_WIDGET (toolbar));
+
+ gtk_widget_style_get (GTK_WIDGET (toolbar),
+ "button_relief", &button_relief,
+ NULL);
+
+ return button_relief;
+}
+
+static gint
+get_space_size (GtkToolbar *toolbar)
+{
+ gint space_size = DEFAULT_SPACE_SIZE;
+
+ gtk_widget_style_get (GTK_WIDGET (toolbar),
+ "space_size", &space_size,
+ NULL);
+
+ return space_size;
+}
+
+static GtkToolbarSpaceStyle
+get_space_style (GtkToolbar *toolbar)
+{
+ GtkToolbarSpaceStyle space_style = DEFAULT_SPACE_STYLE;
+
+ gtk_widget_style_get (GTK_WIDGET (toolbar),
+ "space_style", &space_style,
+ NULL);
+
+
+ return space_style;
+}
+
+static gint
+get_internal_padding (GtkToolbar *toolbar)
+{
+ gint ipadding = 0;
+
+ gtk_widget_style_get (GTK_WIDGET (toolbar),
+ "internal_padding", &ipadding,
+ NULL);
+
+ return ipadding;
+}
+
+static gboolean
+gtk_toolbar_check_old_api (GtkToolbar *toolbar)
+{
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+
+ if (priv->api_mode == NEW_API)
+ {
+ g_warning ("mixing deprecated and non-deprecated GtkToolbar API is not allowed");
+ return FALSE;
+ }
+
+ priv->api_mode = OLD_API;
+ return TRUE;
+}
+
+static gboolean
+gtk_toolbar_check_new_api (GtkToolbar *toolbar)
+{
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+
+ if (priv->api_mode == OLD_API)
+ {
+ g_warning ("mixing deprecated and non-deprecated GtkToolbar API is not allowed");
+ return FALSE;
+ }
+
+ priv->api_mode = NEW_API;
+ return TRUE;
+}
+
+static void
+gtk_toolbar_insert_tool_item (GtkToolbar *toolbar,
+ GtkToolItem *item,
+ gint pos)
+{
+ GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+
+ priv->items = g_list_insert (priv->items, item, pos);
+ toolbar->num_children++;
+
+ gtk_widget_set_parent (GTK_WIDGET (item), GTK_WIDGET (toolbar));
+}
+
+static void
+gtk_toolbar_remove_tool_item (GtkToolbar *toolbar,
+ GtkToolItem *item)
+{
+ GtkToolbarPrivate *priv;
+ GList *tmp;
- was_visible = GTK_WIDGET_VISIBLE (widget);
- gtk_widget_unparent (widget);
+ g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
+ g_return_if_fail (GTK_IS_TOOL_ITEM (item));
+
+ priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+
+ for (tmp = priv->items; tmp != NULL; tmp = tmp->next)
+ {
+ GtkWidget *child = tmp->data;
+
+ if (child == GTK_WIDGET (item))
+ {
+ gboolean was_visible;
+
+ was_visible = GTK_WIDGET_VISIBLE (item);
+ gtk_widget_unparent (GTK_WIDGET (item));
- toolbar->children = g_list_remove_link (toolbar->children, children);
- g_free (child);
- g_list_free (children);
+ priv->items = g_list_remove_link (priv->items, tmp);
toolbar->num_children--;
- if (was_visible && GTK_WIDGET_VISIBLE (container))
- gtk_widget_queue_resize (GTK_WIDGET (container));
+ if (was_visible && GTK_WIDGET_VISIBLE (toolbar))
+ gtk_widget_queue_resize (GTK_WIDGET (toolbar));
break;
}
}
}
-static void
-gtk_toolbar_forall (GtkContainer *container,
- gboolean include_internals,
- GtkCallback callback,
- gpointer callback_data)
+GtkWidget *
+gtk_toolbar_new (void)
{
GtkToolbar *toolbar;
- GList *children;
- GtkToolbarChild *child;
- g_return_if_fail (GTK_IS_TOOLBAR (container));
- g_return_if_fail (callback != NULL);
+ toolbar = g_object_new (GTK_TYPE_TOOLBAR, NULL);
- toolbar = GTK_TOOLBAR (container);
+ return GTK_WIDGET (toolbar);
+}
+
+void
+gtk_toolbar_insert (GtkToolbar *toolbar,
+ GtkToolItem *item,
+ gint pos)
+{
+ g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
+ g_return_if_fail (GTK_IS_TOOL_ITEM (item));
+
+ if (!gtk_toolbar_check_new_api (toolbar))
+ return;
+
+ gtk_toolbar_insert_tool_item (toolbar, item, pos);
+}
+
+gint
+gtk_toolbar_get_item_index (GtkToolbar *toolbar,
+ GtkToolItem *item)
+{
+ GtkToolbarPrivate *priv;
+
+ g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
+ g_return_val_if_fail (GTK_IS_TOOL_ITEM (item), -1);
+
+ if (!gtk_toolbar_check_new_api (toolbar))
+ return -1;
+
+ priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+ g_return_val_if_fail (g_list_find (priv->items, item) != NULL, -1);
+
+ return g_list_index (priv->items, item);
+}
+
+void
+gtk_toolbar_set_orientation (GtkToolbar *toolbar,
+ GtkOrientation orientation)
+{
+ g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
+
+ g_signal_emit (toolbar, toolbar_signals[ORIENTATION_CHANGED], 0, orientation);
+}
+
+GtkOrientation
+gtk_toolbar_get_orientation (GtkToolbar *toolbar)
+{
+ g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_ORIENTATION_HORIZONTAL);
+
+ return toolbar->orientation;
+}
+
+void
+gtk_toolbar_set_style (GtkToolbar *toolbar,
+ GtkToolbarStyle style)
+{
+ g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
- for (children = toolbar->children; children; children = children->next)
+ toolbar->style_set = TRUE;
+ g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
+
+
+}
+
+GtkToolbarStyle
+gtk_toolbar_get_style (GtkToolbar *toolbar)
+{
+ g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), DEFAULT_TOOLBAR_STYLE);
+
+ return toolbar->style;
+}
+
+void
+gtk_toolbar_unset_style (GtkToolbar *toolbar)
+{
+ GtkToolbarStyle style;
+
+ g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
+
+ if (toolbar->style_set)
{
- child = children->data;
+ GtkSettings *settings = toolbar_get_settings (toolbar);
- if (child->type != GTK_TOOLBAR_CHILD_SPACE)
- (*callback) (child->widget, callback_data);
+ if (settings)
+ g_object_get (settings,
+ "gtk-toolbar-style", &style,
+ NULL);
+ else
+ style = DEFAULT_TOOLBAR_STYLE;
+
+ if (style != toolbar->style)
+ g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
+
+ toolbar->style_set = FALSE;
}
}
-GtkWidget *
-gtk_toolbar_append_item (GtkToolbar *toolbar,
- const char *text,
- const char *tooltip_text,
- const char *tooltip_private_text,
- GtkWidget *icon,
- GtkSignalFunc callback,
- gpointer user_data)
+void
+gtk_toolbar_set_tooltips (GtkToolbar *toolbar,
+ gboolean enable)
{
- return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
- NULL, text,
- tooltip_text, tooltip_private_text,
- icon, callback, user_data,
- toolbar->num_children);
+ g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
+
+ if (enable)
+ gtk_tooltips_enable (toolbar->tooltips);
+ else
+ gtk_tooltips_disable (toolbar->tooltips);
}
-GtkWidget *
-gtk_toolbar_prepend_item (GtkToolbar *toolbar,
- const char *text,
- const char *tooltip_text,
- const char *tooltip_private_text,
- GtkWidget *icon,
- GtkSignalFunc callback,
- gpointer user_data)
+gboolean
+gtk_toolbar_get_tooltips (GtkToolbar *toolbar)
{
- return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
- NULL, text,
- tooltip_text, tooltip_private_text,
- icon, callback, user_data,
- 0);
+ g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
+
+ return toolbar->tooltips->enabled;
}
-static GtkWidget *
-gtk_toolbar_internal_insert_item (GtkToolbar *toolbar,
- const char *text,
- const char *tooltip_text,
- const char *tooltip_private_text,
- GtkWidget *icon,
- GtkSignalFunc callback,
- gpointer user_data,
- gint position)
+gint
+gtk_toolbar_get_n_items (GtkToolbar *toolbar)
{
- return gtk_toolbar_internal_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
- NULL, text,
- tooltip_text, tooltip_private_text,
- icon, callback, user_data,
- position);
+ GtkToolbarPrivate *priv;
+
+ g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1);
+
+ if (!gtk_toolbar_check_new_api (toolbar))
+ return -1;
+
+ priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+
+ return g_list_length (priv->items);
}
-
-GtkWidget *
-gtk_toolbar_insert_item (GtkToolbar *toolbar,
- const char *text,
- const char *tooltip_text,
- const char *tooltip_private_text,
- GtkWidget *icon,
- GtkSignalFunc callback,
- gpointer user_data,
- gint position)
+
+/*
+ * returns NULL if n is out of range
+ */
+GtkToolItem *
+gtk_toolbar_get_nth_item (GtkToolbar *toolbar,
+ gint n)
{
- return gtk_toolbar_internal_insert_item (toolbar,
- text, tooltip_text, tooltip_private_text,
- icon, callback, user_data,
- position);
+ GtkToolbarPrivate *priv;
+
+ g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
+
+ if (!gtk_toolbar_check_new_api (toolbar))
+ return NULL;
+
+ priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+
+ return g_list_nth_data (priv->items, n);
}
-/**
- * gtk_toolbar_set_icon_size:
- * @toolbar: A #GtkToolbar
- * @icon_size: The #GtkIconSize that stock icons in the toolbar shall have.
- *
- * This function sets the size of stock icons in the toolbar. You
- * can call it both before you add the icons and after they've been
- * added. The size you set will override user preferences for the default
- * icon size.
- **/
void
gtk_toolbar_set_icon_size (GtkToolbar *toolbar,
GtkIconSize icon_size)
{
- GList *children;
- GtkToolbarChild *child;
- GtkImage *image;
- gchar *stock_id;
-
g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
toolbar->icon_size_set = TRUE;
-
+
if (toolbar->icon_size == icon_size)
return;
-
+
toolbar->icon_size = icon_size;
- for (children = toolbar->children; children; children = children->next)
- {
- child = children->data;
- if ((child->type == GTK_TOOLBAR_CHILD_BUTTON ||
- child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON ||
- child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON) &&
- GTK_IS_IMAGE (child->icon))
- {
- image = GTK_IMAGE (child->icon);
- if (gtk_image_get_storage_type (image) == GTK_IMAGE_STOCK)
- {
- gtk_image_get_stock (image, &stock_id, NULL);
- stock_id = g_strdup (stock_id);
- gtk_image_set_from_stock (image,
- stock_id,
- icon_size);
- g_free (stock_id);
- }
- }
- }
-
+ gtk_toolbar_reconfigured (toolbar);
+
gtk_widget_queue_resize (GTK_WIDGET (toolbar));
}
-/**
- * gtk_toolbar_get_icon_size:
- * @toolbar: a #GtkToolbar
- *
- * Retrieves the icon size fo the toolbar. See gtk_toolbar_set_icon_size().
- *
- * Return value: the current icon size for the icons on the toolbar.
- **/
GtkIconSize
gtk_toolbar_get_icon_size (GtkToolbar *toolbar)
{
@@ -1074,79 +2285,145 @@ gtk_toolbar_get_icon_size (GtkToolbar *toolbar)
return toolbar->icon_size;
}
-/**
- * gtk_toolbar_unset_icon_size:
- * @toolbar: a #GtkToolbar
- *
- * Unsets toolbar icon size set with gtk_toolbar_set_icon_size(), so that
- * user preferences will be used to determine the icon size.
- **/
+GtkReliefStyle
+gtk_toolbar_get_relief_style (GtkToolbar *toolbar)
+{
+ g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_RELIEF_NONE);
+
+ return get_button_relief (toolbar);
+}
+
void
-gtk_toolbar_unset_icon_size (GtkToolbar *toolbar)
+gtk_toolbar_unset_icon_size (GtkToolbar *toolbar)
{
GtkIconSize size;
+ g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
+
if (toolbar->icon_size_set)
{
GtkSettings *settings = toolbar_get_settings (toolbar);
if (settings)
- g_object_get (settings,
- "gtk-toolbar-icon-size", &size,
- NULL);
+ {
+ g_object_get (settings,
+ "gtk-toolbar-icon-size", &size,
+ NULL);
+ }
else
size = DEFAULT_ICON_SIZE;
if (size != toolbar->icon_size)
- gtk_toolbar_set_icon_size (toolbar, size);
+ gtk_toolbar_set_icon_size (toolbar, size);
toolbar->icon_size_set = FALSE;
}
}
-static gchar *
-elide_underscores (const gchar *original)
+void
+gtk_toolbar_set_show_arrow (GtkToolbar *toolbar,
+ gboolean show_arrow)
{
- gchar *q, *result;
- const gchar *p;
- gboolean last_underscore;
-
- q = result = g_malloc (strlen (original) + 1);
- last_underscore = FALSE;
+ GtkToolbarPrivate *priv;
- for (p = original; *p; p++)
+ g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
+
+ priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+ show_arrow = show_arrow != FALSE;
+
+ if (priv->show_arrow != show_arrow)
{
- if (!last_underscore && *p == '_')
- last_underscore = TRUE;
- else
- {
- last_underscore = FALSE;
- *q++ = *p;
- }
+ priv->show_arrow = show_arrow;
+
+ if (!priv->show_arrow)
+ gtk_widget_hide (priv->arrow_button);
+
+ gtk_widget_queue_resize (GTK_WIDGET (toolbar));
+ g_object_notify (G_OBJECT (toolbar), "show_arrow");
}
+}
+
+gboolean
+gtk_toolbar_get_show_arrow (GtkToolbar *toolbar)
+{
+ GtkToolbarPrivate *priv;
+
+ g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
+
+ if (!gtk_toolbar_check_new_api (toolbar))
+ return FALSE;
- *q = '\0';
+ priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
- return result;
+ return priv->show_arrow;
+}
+
+gint
+gtk_toolbar_get_drop_index (GtkToolbar *toolbar,
+ gint x,
+ gint y)
+{
+ gint drop_index, drop_pos;
+
+ g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
+
+ if (!gtk_toolbar_check_new_api (toolbar))
+ return -1;
+
+ find_drop_pos (toolbar, x, y, &drop_index, &drop_pos);
+
+ return drop_index;
+}
+
+GtkWidget *
+gtk_toolbar_append_item (GtkToolbar *toolbar,
+ const char *text,
+ const char *tooltip_text,
+ const char *tooltip_private_text,
+ GtkWidget *icon,
+ GtkSignalFunc callback,
+ gpointer user_data)
+{
+ return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
+ NULL, text,
+ tooltip_text, tooltip_private_text,
+ icon, callback, user_data,
+ toolbar->num_children);
+}
+
+GtkWidget *
+gtk_toolbar_prepend_item (GtkToolbar *toolbar,
+ const char *text,
+ const char *tooltip_text,
+ const char *tooltip_private_text,
+ GtkWidget *icon,
+ GtkSignalFunc callback,
+ gpointer user_data)
+{
+ return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
+ NULL, text,
+ tooltip_text, tooltip_private_text,
+ icon, callback, user_data,
+ 0);
+}
+
+GtkWidget *
+gtk_toolbar_insert_item (GtkToolbar *toolbar,
+ const char *text,
+ const char *tooltip_text,
+ const char *tooltip_private_text,
+ GtkWidget *icon,
+ GtkSignalFunc callback,
+ gpointer user_data,
+ gint position)
+{
+ return gtk_toolbar_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
+ NULL, text,
+ tooltip_text, tooltip_private_text,
+ icon, callback, user_data,
+ position);
}
-/**
- * gtk_toolbar_insert_stock:
- * @toolbar: A #GtkToolbar
- * @stock_id: The id of the stock item you want to insert
- * @tooltip_text: The text in the tooltip of the toolbar button
- * @tooltip_private_text: The private text of the tooltip
- * @callback: The callback called when the toolbar button is clicked.
- * @user_data: user data passed to callback
- * @position: The position the button shall be inserted at.
- * -1 means at the end.
- *
- * Inserts a stock item at the specified position of the toolbar. If
- * @stock_id is not a known stock item ID, it's inserted verbatim,
- * except that underscores used to mark mnemonics are removed.
- *
- * Returns: the inserted widget
- */
GtkWidget*
gtk_toolbar_insert_stock (GtkToolbar *toolbar,
const gchar *stock_id,
@@ -1156,38 +2433,13 @@ gtk_toolbar_insert_stock (GtkToolbar *toolbar,
gpointer user_data,
gint position)
{
- GtkStockItem item;
- GtkWidget *image = NULL;
- const gchar *label;
- gchar *label_no_mnemonic;
- GtkWidget *retval;
-
- if (gtk_stock_lookup (stock_id, &item))
- {
- image = gtk_image_new_from_stock (stock_id, toolbar->icon_size);
- label = item.label;
- }
- else
- label = stock_id;
-
- label_no_mnemonic = elide_underscores (label);
-
- retval = gtk_toolbar_internal_insert_item (toolbar,
- label_no_mnemonic,
- tooltip_text,
- tooltip_private_text,
- image,
- callback,
- user_data,
- position);
-
- g_free (label_no_mnemonic);
-
- return retval;
+ return gtk_toolbar_internal_insert_element (toolbar, GTK_TOOLBAR_CHILD_BUTTON,
+ NULL, stock_id,
+ tooltip_text, tooltip_private_text,
+ NULL, callback, user_data,
+ position, TRUE);
}
-
-
void
gtk_toolbar_append_space (GtkToolbar *toolbar)
{
@@ -1219,62 +2471,33 @@ gtk_toolbar_insert_space (GtkToolbar *toolbar,
position);
}
-/**
- * gtk_toolbar_remove_space:
- * @toolbar: a #GtkToolbar.
- * @position: the index of the space to remove.
- *
- * Removes a space from the specified position.
- **/
void
gtk_toolbar_remove_space (GtkToolbar *toolbar,
- gint position)
+ gint position)
{
- GList *children;
- GtkToolbarChild *child;
- gint i;
-
+ GtkToolItem *item;
+
g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
-
- i = 0;
- for (children = toolbar->children; children; children = children->next)
- {
- child = children->data;
- if (i == position)
- {
- if (child->type == GTK_TOOLBAR_CHILD_SPACE)
- {
- toolbar->children = g_list_remove_link (toolbar->children, children);
- g_free (child);
- g_list_free (children);
- toolbar->num_children--;
-
- gtk_widget_queue_resize (GTK_WIDGET (toolbar));
- }
- else
- {
- g_warning ("Toolbar position %d is not a space", position);
- }
+ if (!gtk_toolbar_check_old_api (toolbar))
+ return;
+
+ item = g_list_nth_data (toolbar->children, position);
- return;
- }
+ if (!item)
+ {
+ g_warning ("Toolbar position %d doesn't exist", position);
+ return;
+ }
- ++i;
+ if (GTK_BIN (item)->child)
+ {
+ g_warning ("Toolbar position %d is not a space", position);
}
- g_warning ("Toolbar position %d doesn't exist", position);
+ gtk_toolbar_remove_tool_item (toolbar, item);
}
-/**
- * gtk_toolbar_append_widget:
- * @toolbar: a #GtkToolbar.
- * @widget: a #GtkWidget to add to the toolbar.
- * @tooltip_text: the element's tooltip.
- * @tooltip_private_text: used for context-sensitive help about this toolbar element.
- *
- * Adds a widget to the end of the given toolbar.
- **/
void
gtk_toolbar_append_widget (GtkToolbar *toolbar,
GtkWidget *widget,
@@ -1288,15 +2511,6 @@ gtk_toolbar_append_widget (GtkToolbar *toolbar,
toolbar->num_children);
}
-/**
- * gtk_toolbar_prepend_widget:
- * @toolbar: a #GtkToolbar.
- * @widget: a #GtkWidget to add to the toolbar.
- * @tooltip_text: the element's tooltip.
- * @tooltip_private_text: used for context-sensitive help about this toolbar element.
- *
- * Adds a widget to the beginning of the given toolbar.
- **/
void
gtk_toolbar_prepend_widget (GtkToolbar *toolbar,
GtkWidget *widget,
@@ -1310,16 +2524,6 @@ gtk_toolbar_prepend_widget (GtkToolbar *toolbar,
0);
}
-/**
- * gtk_toolbar_insert_widget:
- * @toolbar: a #GtkToolbar.
- * @widget: a #GtkWidget to add to the toolbar.
- * @tooltip_text: the element's tooltip.
- * @tooltip_private_text: used for context-sensitive help about this toolbar element.
- * @position: the number of widgets to insert this widget after.
- *
- * Inserts a widget in the toolbar at the given position.
- **/
void
gtk_toolbar_insert_widget (GtkToolbar *toolbar,
GtkWidget *widget,
@@ -1367,29 +2571,6 @@ gtk_toolbar_prepend_element (GtkToolbar *toolbar,
icon, callback, user_data, 0);
}
-/**
- * gtk_toolbar_insert_element:
- * @toolbar: a #GtkToolbar.
- * @type: a value of type #GtkToolbarChildType that determines what @widget
- * will be.
- * @widget: a #GtkWidget, or %NULL.
- * @text: the element's label.
- * @tooltip_text: the element's tooltip.
- * @tooltip_private_text: used for context-sensitive help about this toolbar element.
- * @icon: a #GtkWidget that provides pictorial representation of the element's function.
- * @callback: the function to be executed when the button is pressed.
- * @user_data: any data you wish to pass to the callback.
- * @position: the number of widgets to insert this element after.
- *
- * Inserts a new element in the toolbar at the given position.
- *
- * If @type == %GTK_TOOLBAR_CHILD_WIDGET, @widget is used as the new element.
- * If @type == %GTK_TOOLBAR_CHILD_RADIOBUTTON, @widget is used to determine
- * the radio group for the new element. In all other cases, @widget must
- * be %NULL.
- *
- * Return value: the new toolbar element as a #GtkWidget.
- **/
GtkWidget *
gtk_toolbar_insert_element (GtkToolbar *toolbar,
GtkToolbarChildType type,
@@ -1402,85 +2583,64 @@ gtk_toolbar_insert_element (GtkToolbar *toolbar,
gpointer user_data,
gint position)
{
- g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
- if (type == GTK_TOOLBAR_CHILD_WIDGET)
- {
- g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
- }
- else if (type != GTK_TOOLBAR_CHILD_RADIOBUTTON)
- g_return_val_if_fail (widget == NULL, NULL);
-
return gtk_toolbar_internal_insert_element (toolbar, type, widget, text,
- tooltip_text, tooltip_private_text,
- icon, callback, user_data,
- position);
+ tooltip_text, tooltip_private_text,
+ icon, callback, user_data, position, FALSE);
}
-static void
-set_child_packing_and_visibility(GtkToolbar *toolbar,
- GtkToolbarChild *child)
+static gchar *
+elide_underscores (const gchar *original)
{
- GtkWidget *box;
- gboolean expand;
-
- box = gtk_bin_get_child (GTK_BIN (child->widget));
-
- g_return_if_fail (GTK_IS_BOX (box));
-
- if (child->label)
- {
- expand = (toolbar->style != GTK_TOOLBAR_BOTH);
-
- gtk_box_set_child_packing (GTK_BOX (box), child->label,
- expand, expand, 0, GTK_PACK_END);
-
- if (toolbar->style != GTK_TOOLBAR_ICONS)
- gtk_widget_show (child->label);
- else
- gtk_widget_hide (child->label);
- }
+ gchar *q, *result;
+ const gchar *p;
+ gboolean last_underscore;
- if (child->icon)
+ q = result = g_malloc (strlen (original) + 1);
+ last_underscore = FALSE;
+
+ for (p = original; *p; p++)
{
- expand = (toolbar->style != GTK_TOOLBAR_BOTH_HORIZ);
-
- gtk_box_set_child_packing (GTK_BOX (box), child->icon,
- expand, expand, 0, GTK_PACK_END);
-
- if (toolbar->style != GTK_TOOLBAR_TEXT)
- gtk_widget_show (child->icon);
+ if (!last_underscore && *p == '_')
+ last_underscore = TRUE;
else
- gtk_widget_hide (child->icon);
+ {
+ last_underscore = FALSE;
+ *q++ = *p;
+ }
}
+
+ *q = '\0';
+
+ return result;
}
static GtkWidget *
gtk_toolbar_internal_insert_element (GtkToolbar *toolbar,
- GtkToolbarChildType type,
- GtkWidget *widget,
- const char *text,
- const char *tooltip_text,
- const char *tooltip_private_text,
- GtkWidget *icon,
- GtkSignalFunc callback,
- gpointer user_data,
- gint position)
+ GtkToolbarChildType type,
+ GtkWidget *widget,
+ const char *text,
+ const char *tooltip_text,
+ const char *tooltip_private_text,
+ GtkWidget *icon,
+ GtkSignalFunc callback,
+ gpointer user_data,
+ gint position,
+ gboolean use_stock)
{
GtkToolbarChild *child;
- GtkWidget *box;
-
+ GtkToolItem *item = NULL;
+
g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL);
+
+ if (!gtk_toolbar_check_old_api (toolbar))
+ return NULL;
+
if (type == GTK_TOOLBAR_CHILD_WIDGET)
- {
- g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
- }
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
else if (type != GTK_TOOLBAR_CHILD_RADIOBUTTON)
g_return_val_if_fail (widget == NULL, NULL);
- if (type == GTK_TOOLBAR_CHILD_SPACE)
- child = (GtkToolbarChild *) g_new (GtkToolbarChildSpace, 1);
- else
- child = g_new (GtkToolbarChild, 1);
+ child = g_new (GtkToolbarChild, 1);
child->type = type;
child->icon = NULL;
@@ -1489,343 +2649,87 @@ gtk_toolbar_internal_insert_element (GtkToolbar *toolbar,
switch (type)
{
case GTK_TOOLBAR_CHILD_SPACE:
+ item = gtk_separator_tool_item_new ();
child->widget = NULL;
- ((GtkToolbarChildSpace *) child)->alloc_x =
- ((GtkToolbarChildSpace *) child)->alloc_y = 0;
break;
case GTK_TOOLBAR_CHILD_WIDGET:
+ item = gtk_tool_item_new ();
child->widget = widget;
+ gtk_container_add (GTK_CONTAINER (item), child->widget);
break;
case GTK_TOOLBAR_CHILD_BUTTON:
- case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
- case GTK_TOOLBAR_CHILD_RADIOBUTTON:
- if (type == GTK_TOOLBAR_CHILD_BUTTON)
- {
- child->widget = gtk_button_new ();
- gtk_button_set_relief (GTK_BUTTON (child->widget), get_button_relief (toolbar));
- }
- else if (type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
- {
- child->widget = gtk_toggle_button_new ();
- gtk_button_set_relief (GTK_BUTTON (child->widget), get_button_relief (toolbar));
- gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (child->widget),
- FALSE);
- }
- else
- {
- child->widget = gtk_radio_button_new (widget
- ? gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget))
- : NULL);
- gtk_button_set_relief (GTK_BUTTON (child->widget), get_button_relief (toolbar));
- gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (child->widget), FALSE);
- }
-
- GTK_WIDGET_UNSET_FLAGS (child->widget, GTK_CAN_FOCUS);
-
- if (callback)
- g_signal_connect (child->widget, "clicked",
- callback, user_data);
-
- if (toolbar->style == GTK_TOOLBAR_BOTH_HORIZ)
- box = gtk_hbox_new (FALSE, 0);
- else
- box = gtk_vbox_new (FALSE, 0);
- gtk_container_add (GTK_CONTAINER (child->widget), box);
- gtk_widget_show (box);
-
- if (text)
- {
- child->label = gtk_label_new (text);
- gtk_container_add (GTK_CONTAINER (box), child->label);
- }
-
- if (icon)
- {
- child->icon = GTK_WIDGET (icon);
- gtk_container_add (GTK_CONTAINER (box), child->icon);
- }
-
- set_child_packing_and_visibility (toolbar, child);
-
- /* Mark child as ours */
- g_object_set_data (G_OBJECT (child->widget),
- "gtk-toolbar-is-child",
- GINT_TO_POINTER (TRUE));
-
- gtk_widget_show (child->widget);
+ item = gtk_tool_button_new ();
+ child->widget = GTK_TOOL_BUTTON (item)->button;
break;
-
- default:
- g_assert_not_reached ();
- }
-
- if ((type != GTK_TOOLBAR_CHILD_SPACE) && tooltip_text)
- gtk_tooltips_set_tip (toolbar->tooltips, child->widget,
- tooltip_text, tooltip_private_text);
-
- toolbar->children = g_list_insert (toolbar->children, child, position);
- toolbar->num_children++;
-
- if (type != GTK_TOOLBAR_CHILD_SPACE)
- gtk_widget_set_parent (child->widget, GTK_WIDGET (toolbar));
- else
- gtk_widget_queue_resize (GTK_WIDGET (toolbar));
-
- return child->widget;
-}
-
-void
-gtk_toolbar_set_orientation (GtkToolbar *toolbar,
- GtkOrientation orientation)
-{
- g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
-
- g_signal_emit (toolbar, toolbar_signals[ORIENTATION_CHANGED], 0, orientation);
-}
-
-/**
- * gtk_toolbar_get_orientation:
- * @toolbar: a #GtkToolbar
- *
- * Retrieves the current orientation of the toolbar. See
- * gtk_toolbar_set_orientation().
- *
- * Return value: the orientation
- **/
-GtkOrientation
-gtk_toolbar_get_orientation (GtkToolbar *toolbar)
-{
- g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), GTK_ORIENTATION_HORIZONTAL);
-
- return toolbar->orientation;
-}
-
-void
-gtk_toolbar_set_style (GtkToolbar *toolbar,
- GtkToolbarStyle style)
-{
- g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
-
- toolbar->style_set = TRUE;
- g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
-}
-
-/**
- * gtk_toolbar_get_style:
- * @toolbar: a #GtkToolbar
- *
- * Retrieves whether the toolbar has text, icons, or both . See
- * gtk_toolbar_set_style().
-
- * Return value: the current style of @toolbar
- **/
-GtkToolbarStyle
-gtk_toolbar_get_style (GtkToolbar *toolbar)
-{
- g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), DEFAULT_TOOLBAR_STYLE);
-
- return toolbar->style;
-}
-
-/**
- * gtk_toolbar_unset_style:
- * @toolbar: a #GtkToolbar
- *
- * Unsets a toolbar style set with gtk_toolbar_set_style(), so that
- * user preferences will be used to determine the toolbar style.
- **/
-void
-gtk_toolbar_unset_style (GtkToolbar *toolbar)
-{
- GtkToolbarStyle style;
-
- g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
-
- if (toolbar->style_set)
- {
- GtkSettings *settings = toolbar_get_settings (toolbar);
-
- if (settings)
- g_object_get (settings,
- "gtk-toolbar-style", &style,
- NULL);
- else
- style = DEFAULT_TOOLBAR_STYLE;
-
- if (style != toolbar->style)
- g_signal_emit (toolbar, toolbar_signals[STYLE_CHANGED], 0, style);
- toolbar->style_set = FALSE;
- }
-}
-
-void
-gtk_toolbar_set_tooltips (GtkToolbar *toolbar,
- gboolean enable)
-{
- g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
-
- if (enable)
- gtk_tooltips_enable (toolbar->tooltips);
- else
- gtk_tooltips_disable (toolbar->tooltips);
-}
-
-/**
- * gtk_toolbar_get_tooltips:
- * @toolbar: a #GtkToolbar
- *
- * Retrieves whether tooltips are enabled. See
- * gtk_toolbar_set_tooltips().
- *
- * Return value: %TRUE if tooltips are enabled
- **/
-gboolean
-gtk_toolbar_get_tooltips (GtkToolbar *toolbar)
-{
- g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE);
-
- return toolbar->tooltips->enabled;
-}
-
-static void
-gtk_toolbar_update_button_relief (GtkToolbar *toolbar)
-{
- GList *children;
- GtkToolbarChild *child;
- GtkReliefStyle relief;
-
- g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
-
- relief = get_button_relief (toolbar);
-
- for (children = toolbar->children; children; children = children->next)
- {
- child = children->data;
- if (child->type == GTK_TOOLBAR_CHILD_BUTTON ||
- child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
- child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
- gtk_button_set_relief (GTK_BUTTON (child->widget), relief);
- }
-}
-
-static void
-gtk_real_toolbar_orientation_changed (GtkToolbar *toolbar,
- GtkOrientation orientation)
-{
- g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
+ case GTK_TOOLBAR_CHILD_TOGGLEBUTTON:
+ item = gtk_toggle_tool_button_new ();
+ child->widget = GTK_TOOL_BUTTON (item)->button;
+ break;
- if (toolbar->orientation != orientation)
- {
- toolbar->orientation = orientation;
- gtk_widget_queue_resize (GTK_WIDGET (toolbar));
- g_object_notify (G_OBJECT (toolbar), "orientation");
+ case GTK_TOOLBAR_CHILD_RADIOBUTTON:
+ item = gtk_radio_tool_button_new (widget
+ ? gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget))
+ : NULL);
+ child->widget = GTK_TOOL_BUTTON (item)->button;
+ break;
}
-}
-static void
-gtk_real_toolbar_style_changed (GtkToolbar *toolbar,
- GtkToolbarStyle style)
-{
- GList *children;
- GtkToolbarChild *child;
- GtkWidget* box;
+ gtk_widget_show (GTK_WIDGET (item));
- g_return_if_fail (GTK_IS_TOOLBAR (toolbar));
-
- if (toolbar->style != style)
+ if (type == GTK_TOOLBAR_CHILD_BUTTON ||
+ type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
+ type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
{
- toolbar->style = style;
-
- for (children = toolbar->children; children; children = children->next)
+ if (text)
{
- child = children->data;
-
- if (child->type == GTK_TOOLBAR_CHILD_BUTTON ||
- child->type == GTK_TOOLBAR_CHILD_RADIOBUTTON ||
- child->type == GTK_TOOLBAR_CHILD_TOGGLEBUTTON)
- {
- box = gtk_bin_get_child (GTK_BIN (child->widget));
-
- if (style == GTK_TOOLBAR_BOTH && GTK_IS_HBOX (box))
- {
- GtkWidget *vbox;
-
- vbox = gtk_vbox_new (FALSE, 0);
-
- if (child->label)
- gtk_widget_reparent (child->label, vbox);
- if (child->icon)
- gtk_widget_reparent (child->icon, vbox);
-
- gtk_widget_destroy (box);
- gtk_container_add (GTK_CONTAINER (child->widget), vbox);
-
- gtk_widget_show (vbox);
- }
- else if (style == GTK_TOOLBAR_BOTH_HORIZ && GTK_IS_VBOX (box))
- {
- GtkWidget *hbox;
-
- hbox = gtk_hbox_new (FALSE, 0);
+ if (use_stock)
+ {
+ GtkStockItem stock_item;
+ gchar *label_text;
- if (child->label)
- gtk_widget_reparent (child->label, hbox);
- if (child->icon)
- gtk_widget_reparent (child->icon, hbox);
+ gtk_tool_button_set_stock_id (GTK_TOOL_BUTTON (item), text);
- gtk_widget_destroy (box);
- gtk_container_add (GTK_CONTAINER (child->widget), hbox);
+ gtk_stock_lookup (text, &stock_item);
+ label_text = elide_underscores (stock_item.label);
+ child->label = GTK_WIDGET (gtk_label_new (label_text));
+ g_free (label_text);
+ }
+ else
+ {
+ child->label = gtk_label_new (text);
+ }
+ gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (item), child->label);
+ gtk_widget_show (child->label);
+ }
- gtk_widget_show (hbox);
- }
+ if (icon)
+ {
+ child->icon = icon;
+ gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (item), icon);
- set_child_packing_and_visibility (toolbar, child);
- }
+ /* Applications depend on the toolbar showing the widget for them */
+ gtk_widget_show (GTK_WIDGET (icon));
}
- gtk_widget_queue_resize (GTK_WIDGET (toolbar));
- g_object_notify (G_OBJECT (toolbar), "toolbar_style");
+ /*
+ * We need to connect to the button's clicked callback because some
+ * programs may rely on that the widget in the callback is a GtkButton
+ */
+ if (callback)
+ g_signal_connect (child->widget, "clicked",
+ callback, user_data);
}
-}
-
-
-static GtkReliefStyle
-get_button_relief (GtkToolbar *toolbar)
-{
- GtkReliefStyle button_relief = GTK_RELIEF_NORMAL;
- gtk_widget_ensure_style (GTK_WIDGET (toolbar));
- gtk_widget_style_get (GTK_WIDGET (toolbar),
- "button_relief", &button_relief,
- NULL);
-
- return button_relief;
-}
-
-static gint
-get_space_size (GtkToolbar *toolbar)
-{
- gint space_size = DEFAULT_SPACE_SIZE;
-
- gtk_widget_style_get (GTK_WIDGET (toolbar),
- "space_size", &space_size,
- NULL);
-
- return space_size;
-}
-
-static GtkToolbarSpaceStyle
-get_space_style (GtkToolbar *toolbar)
-{
- GtkToolbarSpaceStyle space_style = DEFAULT_SPACE_STYLE;
-
- gtk_widget_style_get (GTK_WIDGET (toolbar),
- "space_style", &space_style,
- NULL);
+ if ((type != GTK_TOOLBAR_CHILD_SPACE) && tooltip_text)
+ gtk_tool_item_set_tooltip (item, toolbar->tooltips,
+ tooltip_text, tooltip_private_text);
+
+ toolbar->children = g_list_insert (toolbar->children, child, position);
+ gtk_toolbar_insert_tool_item (toolbar, item, position);
- return space_style;
+ return child->widget;
}
diff --git a/gtk/gtktoolbar.h b/gtk/gtktoolbar.h
index dc3f6d9ddb..87d570383a 100644
--- a/gtk/gtktoolbar.h
+++ b/gtk/gtktoolbar.h
@@ -2,6 +2,10 @@
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
* GtkToolbar copyright (C) Federico Mena
*
+ * Copyright (C) 2002 Anders Carlsson <andersca@codefactory.se>
+ * Copyright (C) 2002 James Henstridge <james@daa.com.au>
+ * Copyright (C) 2003 Soeren Sandmann <sandmann@daimi.au.dk>
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -28,30 +32,33 @@
#ifndef __GTK_TOOLBAR_H__
#define __GTK_TOOLBAR_H__
-
#include <gdk/gdk.h>
#include <gtk/gtkcontainer.h>
#include <gtk/gtkenums.h>
#include <gtk/gtktooltips.h>
+#include "gtktoolitem.h"
+
+#ifndef GTK_DISABLE_DEPRECATED
+
/* Not needed, retained for compatibility -Yosh */
#include <gtk/gtkpixmap.h>
#include <gtk/gtksignal.h>
+#endif
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
+G_BEGIN_DECLS
-#define GTK_TYPE_TOOLBAR (gtk_toolbar_get_type ())
-#define GTK_TOOLBAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TOOLBAR, GtkToolbar))
-#define GTK_TOOLBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_TOOLBAR, GtkToolbarClass))
-#define GTK_IS_TOOLBAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TOOLBAR))
-#define GTK_IS_TOOLBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_TOOLBAR))
-#define GTK_TOOLBAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_TOOLBAR, GtkToolbarClass))
+#define GTK_TYPE_TOOLBAR (gtk_toolbar_get_type ())
+#define GTK_TOOLBAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TOOLBAR, GtkToolbar))
+#define GTK_TOOLBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_TOOLBAR, GtkToolbarClass))
+#define GTK_IS_TOOLBAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TOOLBAR))
+#define GTK_IS_TOOLBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_TOOLBAR))
+#define GTK_TOOLBAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_TOOLBAR, GtkToolbarClass))
+#define GTK_TOOLBAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_TOOLBAR, GtkToolbarPrivate))
+#ifndef GTK_DISABLE_DEPRECATED
typedef enum
{
GTK_TOOLBAR_CHILD_SPACE,
@@ -61,15 +68,7 @@ typedef enum
GTK_TOOLBAR_CHILD_WIDGET
} GtkToolbarChildType;
-typedef enum
-{
- GTK_TOOLBAR_SPACE_EMPTY,
- GTK_TOOLBAR_SPACE_LINE
-} GtkToolbarSpaceStyle;
-
-typedef struct _GtkToolbarChild GtkToolbarChild;
-typedef struct _GtkToolbar GtkToolbar;
-typedef struct _GtkToolbarClass GtkToolbarClass;
+typedef struct _GtkToolbarChild GtkToolbarChild;
struct _GtkToolbarChild
{
@@ -79,6 +78,18 @@ struct _GtkToolbarChild
GtkWidget *label;
};
+typedef enum
+{
+ GTK_TOOLBAR_SPACE_EMPTY,
+ GTK_TOOLBAR_SPACE_LINE
+} GtkToolbarSpaceStyle;
+
+#endif /* GTK_DISABLE_DEPRECATED */
+
+typedef struct _GtkToolbar GtkToolbar;
+typedef struct _GtkToolbarClass GtkToolbarClass;
+typedef struct _GtkToolbarPrivate GtkToolbarPrivate;
+
struct _GtkToolbar
{
GtkContainer container;
@@ -90,13 +101,13 @@ struct _GtkToolbar
GtkIconSize icon_size;
GtkTooltips *tooltips;
-
- gint button_maxw;
- gint button_maxh;
+
+ gint button_maxw; /* maximum width of homogeneous children */
+ gint button_maxh; /* maximum height of homogeneous children */
guint style_set_connection;
guint icon_size_connection;
-
+
guint style_set : 1;
guint icon_size_set : 1;
};
@@ -105,45 +116,76 @@ struct _GtkToolbarClass
{
GtkContainerClass parent_class;
- void (* orientation_changed) (GtkToolbar *toolbar,
- GtkOrientation orientation);
- void (* style_changed) (GtkToolbar *toolbar,
- GtkToolbarStyle style);
+ /* signals */
+ void (* orientation_changed) (GtkToolbar *toolbar,
+ GtkOrientation orientation);
+ void (* style_changed) (GtkToolbar *toolbar,
+ GtkToolbarStyle style);
+ void (* popup_context_menu) (GtkToolbar *toolbar);
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
- void (*_gtk_reserved4) (void);
};
-
-GType gtk_toolbar_get_type (void) G_GNUC_CONST;
-GtkWidget* gtk_toolbar_new (void);
-
+GType gtk_toolbar_get_type (void) G_GNUC_CONST;
+GtkWidget* gtk_toolbar_new (void);
+
+void gtk_toolbar_insert (GtkToolbar *toolbar,
+ GtkToolItem *item,
+ gint pos);
+gint gtk_toolbar_get_item_index (GtkToolbar *toolbar,
+ GtkToolItem *item);
+gint gtk_toolbar_get_n_items (GtkToolbar *toolbar);
+GtkToolItem * gtk_toolbar_get_nth_item (GtkToolbar *toolbar,
+ gint n);
+gint gtk_toolbar_get_drop_index (GtkToolbar *toolbar,
+ gint x,
+ gint y);
+void gtk_toolbar_set_show_arrow (GtkToolbar *toolbar,
+ gboolean show_arrow);
+void gtk_toolbar_set_orientation (GtkToolbar *toolbar,
+ GtkOrientation orientation);
+void gtk_toolbar_set_tooltips (GtkToolbar *toolbar,
+ gboolean enable);
+void gtk_toolbar_unset_icon_size (GtkToolbar *toolbar);
+gboolean gtk_toolbar_get_show_arrow (GtkToolbar *toolbar);
+GtkOrientation gtk_toolbar_get_orientation (GtkToolbar *toolbar);
+GtkToolbarStyle gtk_toolbar_get_style (GtkToolbar *toolbar);
+GtkIconSize gtk_toolbar_get_icon_size (GtkToolbar *toolbar);
+gboolean gtk_toolbar_get_tooltips (GtkToolbar *toolbar);
+GtkReliefStyle gtk_toolbar_get_relief_style (GtkToolbar *toolbar);
+
+#ifndef GTK_DISABLE_DEPRECATED
/* Simple button items */
-GtkWidget* gtk_toolbar_append_item (GtkToolbar *toolbar,
- const char *text,
- const char *tooltip_text,
- const char *tooltip_private_text,
- GtkWidget *icon,
- GtkSignalFunc callback,
- gpointer user_data);
-GtkWidget* gtk_toolbar_prepend_item (GtkToolbar *toolbar,
- const char *text,
- const char *tooltip_text,
- const char *tooltip_private_text,
- GtkWidget *icon,
- GtkSignalFunc callback,
- gpointer user_data);
-GtkWidget* gtk_toolbar_insert_item (GtkToolbar *toolbar,
- const char *text,
- const char *tooltip_text,
- const char *tooltip_private_text,
- GtkWidget *icon,
- GtkSignalFunc callback,
- gpointer user_data,
- gint position);
+void gtk_toolbar_set_style (GtkToolbar *toolbar,
+ GtkToolbarStyle style);
+void gtk_toolbar_set_icon_size (GtkToolbar *toolbar,
+ GtkIconSize icon_size);
+void gtk_toolbar_unset_style (GtkToolbar *toolbar);
+GtkWidget* gtk_toolbar_append_item (GtkToolbar *toolbar,
+ const char *text,
+ const char *tooltip_text,
+ const char *tooltip_private_text,
+ GtkWidget *icon,
+ GtkSignalFunc callback,
+ gpointer user_data);
+GtkWidget* gtk_toolbar_prepend_item (GtkToolbar *toolbar,
+ const char *text,
+ const char *tooltip_text,
+ const char *tooltip_private_text,
+ GtkWidget *icon,
+ GtkSignalFunc callback,
+ gpointer user_data);
+GtkWidget* gtk_toolbar_insert_item (GtkToolbar *toolbar,
+ const char *text,
+ const char *tooltip_text,
+ const char *tooltip_private_text,
+ GtkWidget *icon,
+ GtkSignalFunc callback,
+ gpointer user_data,
+ gint position);
/* Stock Items */
GtkWidget* gtk_toolbar_insert_stock (GtkToolbar *toolbar,
@@ -154,8 +196,6 @@ GtkWidget* gtk_toolbar_insert_stock (GtkToolbar *toolbar,
gpointer user_data,
gint position);
-
-
/* Space Items */
void gtk_toolbar_append_space (GtkToolbar *toolbar);
void gtk_toolbar_prepend_space (GtkToolbar *toolbar);
@@ -163,7 +203,6 @@ void gtk_toolbar_insert_space (GtkToolbar *toolbar,
gint position);
void gtk_toolbar_remove_space (GtkToolbar *toolbar,
gint position);
-
/* Any element type */
GtkWidget* gtk_toolbar_append_element (GtkToolbar *toolbar,
GtkToolbarChildType type,
@@ -211,25 +250,9 @@ void gtk_toolbar_insert_widget (GtkToolbar *toolbar,
const char *tooltip_private_text,
gint position);
-/* Style functions */
-void gtk_toolbar_set_orientation (GtkToolbar *toolbar,
- GtkOrientation orientation);
-void gtk_toolbar_set_style (GtkToolbar *toolbar,
- GtkToolbarStyle style);
-void gtk_toolbar_set_icon_size (GtkToolbar *toolbar,
- GtkIconSize icon_size);
-void gtk_toolbar_set_tooltips (GtkToolbar *toolbar,
- gboolean enable);
-void gtk_toolbar_unset_style (GtkToolbar *toolbar);
-void gtk_toolbar_unset_icon_size (GtkToolbar *toolbar);
-
-GtkOrientation gtk_toolbar_get_orientation (GtkToolbar *toolbar);
-GtkToolbarStyle gtk_toolbar_get_style (GtkToolbar *toolbar);
-GtkIconSize gtk_toolbar_get_icon_size (GtkToolbar *toolbar);
-gboolean gtk_toolbar_get_tooltips (GtkToolbar *toolbar);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+#endif /* GTK_DISABLE_DEPRECATED */
+
+
+G_END_DECLS
#endif /* __GTK_TOOLBAR_H__ */
diff --git a/gtk/gtktoolbutton.c b/gtk/gtktoolbutton.c
new file mode 100644
index 0000000000..a5fa3be88e
--- /dev/null
+++ b/gtk/gtktoolbutton.c
@@ -0,0 +1,812 @@
+/* gtktoolbutton.c
+ *
+ * Copyright (C) 2002 Anders Carlsson <andersca@codefactory.se>
+ * Copyright (C) 2002 James Henstridge <james@daa.com.au>
+ * Copyright (C) 2003 Soeren Sandmann <sandmann@daimi.au.dk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "gtktoolbutton.h"
+#include "gtkbutton.h"
+#include "gtkhbox.h"
+#include "gtkiconfactory.h"
+#include "gtkimage.h"
+#include "gtkimagemenuitem.h"
+#include "gtklabel.h"
+#include "gtkstock.h"
+#include "gtkvbox.h"
+#include "gtkintl.h"
+
+#include <string.h>
+
+#define MENU_ID "gtk-tool-button-menu-id"
+
+enum {
+ CLICKED,
+ LAST_SIGNAL
+};
+
+enum {
+ PROP_0,
+ PROP_LABEL,
+ PROP_USE_UNDERLINE,
+ PROP_LABEL_WIDGET,
+ PROP_STOCK_ID,
+ PROP_ICON_SET,
+ PROP_ICON_WIDGET,
+};
+
+static void gtk_tool_button_init (GtkToolButton *button,
+ GtkToolButtonClass *klass);
+static void gtk_tool_button_class_init (GtkToolButtonClass *klass);
+static void gtk_tool_button_size_request (GtkWidget *widget,
+ GtkRequisition *requisition);
+static void gtk_tool_button_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+static void gtk_tool_button_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gtk_tool_button_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void gtk_tool_button_finalize (GObject *object);
+
+static void gtk_tool_button_toolbar_reconfigured (GtkToolItem *tool_item);
+static gboolean gtk_tool_button_create_menu_proxy (GtkToolItem *item);
+static void button_clicked (GtkWidget *widget,
+ GtkToolButton *button);
+
+static void gtk_tool_button_construct_contents (GtkToolItem *tool_item);
+
+static GObjectClass *parent_class = NULL;
+static guint toolbutton_signals[LAST_SIGNAL] = { 0 };
+
+GType
+gtk_tool_button_get_type (void)
+{
+ static GtkType type = 0;
+
+ if (!type)
+ {
+ static const GTypeInfo type_info =
+ {
+ sizeof (GtkToolButtonClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gtk_tool_button_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+ sizeof (GtkToolButton),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) gtk_tool_button_init,
+ };
+
+ type = g_type_register_static (GTK_TYPE_TOOL_ITEM,
+ "GtkToolButton",
+ &type_info, 0);
+ }
+ return type;
+}
+
+static void
+gtk_tool_button_class_init (GtkToolButtonClass *klass)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+ GtkToolItemClass *tool_item_class;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class = (GObjectClass *)klass;
+ widget_class = (GtkWidgetClass *)klass;
+ tool_item_class = (GtkToolItemClass *)klass;
+
+ object_class->set_property = gtk_tool_button_set_property;
+ object_class->get_property = gtk_tool_button_get_property;
+ object_class->finalize = gtk_tool_button_finalize;
+
+ widget_class->size_request = gtk_tool_button_size_request;
+ widget_class->size_allocate = gtk_tool_button_size_allocate;
+
+ tool_item_class->create_menu_proxy = gtk_tool_button_create_menu_proxy;
+ tool_item_class->toolbar_reconfigured = gtk_tool_button_toolbar_reconfigured;
+
+ klass->button_type = GTK_TYPE_BUTTON;
+
+ g_object_class_install_property (object_class,
+ PROP_LABEL,
+ g_param_spec_string ("label",
+ _("Label"),
+ _("Text to show in the item."),
+ NULL,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_USE_UNDERLINE,
+ g_param_spec_boolean ("use_underline",
+ _("Use underline"),
+ _("Interpret underlines in the item label"),
+ FALSE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_LABEL_WIDGET,
+ g_param_spec_object ("label_widget",
+ _("Label widget"),
+ _("Widget to use as the item label"),
+ GTK_TYPE_WIDGET,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_STOCK_ID,
+ g_param_spec_string ("stock_id",
+ _("Stock Id"),
+ _("The stock icon displayed on the item"),
+ NULL,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_ICON_SET,
+ g_param_spec_boxed ("icon_set",
+ _("Icon set"),
+ _("Icon set to use to draw the item's icon"),
+ GTK_TYPE_ICON_SET,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_ICON_WIDGET,
+ g_param_spec_object ("icon_widget",
+ _("Icon widget"),
+ _("Icon widget to display in the item"),
+ GTK_TYPE_WIDGET,
+ G_PARAM_READWRITE));
+
+ toolbutton_signals[CLICKED] =
+ g_signal_new ("clicked",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GtkToolButtonClass, clicked),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+gtk_tool_button_init (GtkToolButton *button,
+ GtkToolButtonClass *klass)
+{
+ GtkToolItem *toolitem = GTK_TOOL_ITEM (button);
+
+ toolitem->homogeneous = TRUE;
+
+ /* create button */
+ button->button = g_object_new (klass->button_type, NULL);
+ gtk_button_set_focus_on_click (button->button, FALSE);
+ g_signal_connect_object (button->button, "clicked",
+ G_CALLBACK (button_clicked), button, 0);
+
+ gtk_container_add (GTK_CONTAINER (button), button->button);
+ gtk_widget_show (button->button);
+}
+
+static void
+gtk_tool_button_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ GtkWidget *child = GTK_BIN (widget)->child;
+
+ if (child && GTK_WIDGET_VISIBLE (child))
+ {
+ gtk_widget_size_request (child, requisition);
+ }
+ else
+ {
+ requisition->width = 0;
+ requisition->height = 0;
+ }
+
+ requisition->width += GTK_CONTAINER (widget)->border_width * 2;
+ requisition->height += GTK_CONTAINER (widget)->border_width * 2;
+}
+
+static void
+gtk_tool_button_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ GtkToolItem *toolitem = GTK_TOOL_ITEM (widget);
+ GtkAllocation child_allocation;
+ gint border_width;
+ GtkWidget *child = GTK_BIN (widget)->child;
+
+ widget->allocation = *allocation;
+ border_width = GTK_CONTAINER (widget)->border_width;
+
+ if (toolitem->drag_window && GTK_WIDGET_REALIZED (widget))
+ gdk_window_move_resize (toolitem->drag_window,
+ widget->allocation.x + border_width,
+ widget->allocation.y + border_width,
+ widget->allocation.width - border_width * 2,
+ widget->allocation.height - border_width * 2);
+
+ if (child && GTK_WIDGET_VISIBLE (child))
+ {
+ child_allocation.x = allocation->x + border_width;
+ child_allocation.y = allocation->y + border_width;
+ child_allocation.width = allocation->width - 2 * border_width;
+ child_allocation.height = allocation->height - 2 * border_width;
+
+ gtk_widget_size_allocate (child, &child_allocation);
+ }
+}
+
+static gchar *
+elide_underscores (const gchar *original)
+{
+ gchar *q, *result;
+ const gchar *p;
+ gboolean last_underscore;
+
+ q = result = g_malloc (strlen (original) + 1);
+ last_underscore = FALSE;
+
+ for (p = original; *p; p++)
+ {
+ if (!last_underscore && *p == '_')
+ last_underscore = TRUE;
+ else
+ {
+ last_underscore = FALSE;
+ *q++ = *p;
+ }
+ }
+
+ *q = '\0';
+
+ return result;
+}
+
+static void
+gtk_tool_button_construct_contents (GtkToolItem *tool_item)
+{
+ GtkToolButton *button = GTK_TOOL_BUTTON (tool_item);
+ GtkWidget *label = NULL;
+ GtkWidget *icon = NULL;
+ GtkToolbarStyle style;
+ gboolean need_label = FALSE;
+ gboolean need_icon = FALSE;
+ GtkIconSize icon_size;
+ GtkWidget *box = NULL;
+
+ if (gtk_tool_item_get_proxy_menu_item (tool_item, MENU_ID))
+ {
+ /* Remove item, so it will be recreated on the next
+ * create_proxy_menu_item()
+ */
+ gtk_tool_item_set_proxy_menu_item (tool_item, MENU_ID, NULL);
+ }
+
+ if (button->icon_widget && button->icon_widget->parent)
+ {
+ gtk_container_remove (GTK_CONTAINER (button->icon_widget->parent),
+ button->icon_widget);
+ }
+
+ if (button->label_widget && button->label_widget->parent)
+ {
+ gtk_container_remove (GTK_CONTAINER (button->label_widget->parent),
+ button->label_widget);
+ }
+
+ if (GTK_BIN (button->button)->child)
+ {
+ gtk_container_remove (GTK_CONTAINER (button->button),
+ GTK_BIN (button->button)->child);
+ }
+
+ style = gtk_tool_item_get_toolbar_style (GTK_TOOL_ITEM (button));
+
+ if (style != GTK_TOOLBAR_TEXT)
+ need_icon = TRUE;
+
+ if (style != GTK_TOOLBAR_ICONS)
+ need_label = TRUE;
+
+ if (need_label)
+ {
+ if (button->label_widget)
+ {
+ label = button->label_widget;
+ }
+ else
+ {
+ GtkStockItem stock_item;
+ gboolean elide = TRUE;
+ gchar *label_text;
+
+ if (button->label_text)
+ {
+ label_text = button->label_text;
+ elide = button->use_underline;
+ }
+ else if (button->stock_id && gtk_stock_lookup (button->stock_id, &stock_item))
+ label_text = stock_item.label;
+ else
+ label_text = "";
+
+ if (elide)
+ label_text = elide_underscores (label_text);
+ else
+ label_text = g_strdup (label_text);
+
+ label = gtk_label_new (label_text);
+
+ g_free (label_text);
+
+ gtk_widget_show (label);
+ }
+ }
+
+ icon_size = gtk_tool_item_get_icon_size (GTK_TOOL_ITEM (button));
+ if (need_icon)
+ {
+ if (button->icon_set)
+ {
+ icon = gtk_image_new_from_icon_set (button->icon_set, icon_size);
+ gtk_widget_show (icon);
+ }
+ else if (button->icon_widget)
+ {
+ icon = button->icon_widget;
+
+ if (GTK_IS_IMAGE (icon))
+ {
+ GtkImage *image = GTK_IMAGE (icon);
+ GtkImageType storage_type = gtk_image_get_storage_type (image);
+
+ if (storage_type == GTK_IMAGE_STOCK)
+ {
+ gchar *stock_id;
+ gtk_image_get_stock (image, &stock_id, NULL);
+
+ icon = gtk_image_new_from_stock (stock_id, icon_size);
+ gtk_widget_show (icon);
+ }
+ else if (storage_type == GTK_IMAGE_ICON_SET)
+ {
+ GtkIconSet *icon_set;
+ gtk_image_get_icon_set (image, &icon_set, NULL);
+
+ icon = gtk_image_new_from_icon_set (icon_set, icon_size);
+ gtk_widget_show (icon);
+ }
+ }
+ }
+ else if (button->stock_id)
+ {
+ icon = gtk_image_new_from_stock (button->stock_id, icon_size);
+ gtk_widget_show (icon);
+ }
+ }
+
+ switch (style)
+ {
+ case GTK_TOOLBAR_ICONS:
+ if (icon)
+ gtk_container_add (GTK_CONTAINER (button->button), icon);
+ break;
+
+ case GTK_TOOLBAR_BOTH:
+ box = gtk_vbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (box), icon, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (box), label, FALSE, TRUE, 0);
+ gtk_container_add (GTK_CONTAINER (button->button), box);
+ break;
+
+ case GTK_TOOLBAR_BOTH_HORIZ:
+ box = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (box), icon, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
+ gtk_container_add (GTK_CONTAINER (button->button), box);
+ break;
+
+ case GTK_TOOLBAR_TEXT:
+ gtk_container_add (GTK_CONTAINER (button->button), label);
+ break;
+ }
+
+ if (box)
+ gtk_widget_show (box);
+
+ gtk_button_set_relief (GTK_BUTTON (button->button),
+ gtk_tool_item_get_relief_style (GTK_TOOL_ITEM (button)));
+
+ gtk_widget_queue_resize (GTK_WIDGET (button));
+}
+
+static void
+gtk_tool_button_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkToolButton *button = GTK_TOOL_BUTTON (object);
+
+ switch (prop_id)
+ {
+ case PROP_LABEL:
+ gtk_tool_button_set_label (button, g_value_get_string (value));
+ break;
+ case PROP_USE_UNDERLINE:
+ gtk_tool_button_set_use_underline (button, g_value_get_boolean (value));
+ break;
+ case PROP_LABEL_WIDGET:
+ gtk_tool_button_set_label_widget (button, g_value_get_object (value));
+ break;
+ case PROP_STOCK_ID:
+ gtk_tool_button_set_stock_id (button, g_value_get_string (value));
+ break;
+ case PROP_ICON_SET:
+ gtk_tool_button_set_icon_set (button, g_value_get_boxed (value));
+ break;
+ case PROP_ICON_WIDGET:
+ gtk_tool_button_set_icon_widget (button, g_value_get_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gtk_tool_button_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkToolButton *button = GTK_TOOL_BUTTON (object);
+
+ switch (prop_id)
+ {
+ case PROP_LABEL:
+ g_value_set_string (value, gtk_tool_button_get_label (button));
+ break;
+ case PROP_LABEL_WIDGET:
+ g_value_set_object (value, gtk_tool_button_get_label_widget (button));
+ break;
+ case PROP_USE_UNDERLINE:
+ g_value_set_boolean (value, gtk_tool_button_get_use_underline (button));
+ break;
+ case PROP_STOCK_ID:
+ g_value_set_string (value, button->stock_id);
+ break;
+ case PROP_ICON_SET:
+ g_value_set_boxed (value, gtk_tool_button_get_icon_set (button));
+ break;
+ case PROP_ICON_WIDGET:
+ g_value_set_object (value, button->icon_widget);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gtk_tool_button_finalize (GObject *object)
+{
+ GtkToolButton *button = GTK_TOOL_BUTTON (object);
+
+ g_free (button->stock_id);
+ button->stock_id = NULL;
+
+ parent_class->finalize (object);
+}
+
+static gboolean
+gtk_tool_button_create_menu_proxy (GtkToolItem *item)
+{
+ GtkToolButton *button = GTK_TOOL_BUTTON (item);
+ GtkWidget *menu_item;
+ GtkWidget *menu_image = NULL;
+ GtkStockItem stock_item;
+ gboolean use_mnemonic = TRUE;
+ const char *label = "";
+
+ if (button->label_widget && GTK_IS_LABEL (button->label_widget))
+ label = gtk_label_get_label (GTK_LABEL (button->label_widget));
+ else if (button->label_text)
+ {
+ label = button->label_text;
+ use_mnemonic = button->use_underline;
+ }
+ else if (button->stock_id && gtk_stock_lookup (button->stock_id, &stock_item))
+ label = stock_item.label;
+
+ if (use_mnemonic)
+ menu_item = gtk_image_menu_item_new_with_mnemonic (label);
+ else
+ menu_item = gtk_image_menu_item_new_with_label (label);
+
+ if (button->icon_set)
+ {
+ menu_image = gtk_image_new_from_icon_set (button->icon_set, GTK_ICON_SIZE_MENU);
+ }
+ else if (button->icon_widget && GTK_IS_IMAGE (button->icon_widget))
+ {
+ GtkImage *image = GTK_IMAGE (button->icon_widget);
+ GtkImageType storage_type = gtk_image_get_storage_type (image);
+
+ if (storage_type == GTK_IMAGE_STOCK)
+ {
+ gchar *stock_id;
+ gtk_image_get_stock (image, &stock_id, NULL);
+ menu_image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_MENU);
+ }
+ else if (storage_type == GTK_IMAGE_ICON_SET)
+ {
+ GtkIconSet *icon_set;
+ gtk_image_get_icon_set (image, &icon_set, NULL);
+ menu_image = gtk_image_new_from_icon_set (icon_set, GTK_ICON_SIZE_MENU);
+ }
+ }
+ else if (button->stock_id)
+ {
+ menu_image = gtk_image_new_from_stock (button->stock_id, GTK_ICON_SIZE_MENU);
+ }
+
+ if (menu_image)
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), menu_image);
+
+ g_signal_connect_closure_by_id (menu_item,
+ g_signal_lookup ("activate", G_OBJECT_TYPE (menu_item)), 0,
+ g_cclosure_new_object_swap (G_CALLBACK (gtk_button_clicked),
+ G_OBJECT (GTK_TOOL_BUTTON (button)->button)),
+ FALSE);
+
+ gtk_tool_item_set_proxy_menu_item (GTK_TOOL_ITEM (button), MENU_ID, menu_item);
+
+ return TRUE;
+}
+
+static void
+button_clicked (GtkWidget *widget,
+ GtkToolButton *button)
+{
+ g_signal_emit_by_name (button, "clicked");
+}
+
+static void
+gtk_tool_button_toolbar_reconfigured (GtkToolItem *tool_item)
+{
+ gtk_tool_button_construct_contents (tool_item);
+}
+
+GtkToolItem *
+gtk_tool_button_new_from_stock (const gchar *stock_id)
+{
+ GtkToolButton *button;
+
+ g_return_val_if_fail (stock_id != NULL, NULL);
+
+ button = g_object_new (GTK_TYPE_TOOL_BUTTON,
+ "stock_id", stock_id,
+ NULL);
+
+ return GTK_TOOL_ITEM (button);
+}
+
+GtkToolItem *
+gtk_tool_button_new (void)
+{
+ GtkToolButton *button;
+
+ button = g_object_new (GTK_TYPE_TOOL_BUTTON,
+ NULL);
+
+ return GTK_TOOL_ITEM (button);
+}
+
+void
+gtk_tool_button_set_label (GtkToolButton *button,
+ const gchar *label)
+{
+ gchar *old_label;
+
+ g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
+
+ old_label = button->label_text;
+
+ button->label_text = g_strdup (label);
+ gtk_tool_button_construct_contents (GTK_TOOL_ITEM (button));
+
+ g_object_notify (G_OBJECT (button), "label");
+
+ if (old_label)
+ g_free (old_label);
+}
+
+G_CONST_RETURN gchar *
+gtk_tool_button_get_label (GtkToolButton *button)
+{
+ g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), NULL);
+
+ return button->label_text;
+}
+
+void
+gtk_tool_button_set_use_underline (GtkToolButton *button,
+ gboolean use_underline)
+{
+ g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
+
+ use_underline = use_underline != FALSE;
+
+ if (use_underline != button->use_underline)
+ {
+ button->use_underline = use_underline;
+
+ gtk_tool_button_construct_contents (GTK_TOOL_ITEM (button));
+
+ g_object_notify (G_OBJECT (button), "use_underline");
+ }
+}
+
+gboolean
+gtk_tool_button_get_use_underline (GtkToolButton *button)
+{
+ g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), FALSE);
+
+ return button->use_underline;
+}
+
+void
+gtk_tool_button_set_stock_id (GtkToolButton *button,
+ const gchar *stock_id)
+{
+ gchar *old_stock_id;
+
+ g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
+
+ old_stock_id = button->stock_id;
+
+ button->stock_id = g_strdup (stock_id);
+ gtk_tool_button_construct_contents (GTK_TOOL_ITEM (button));
+
+ g_object_notify (G_OBJECT (button), "stock_id");
+
+ g_free (old_stock_id);
+}
+
+G_CONST_RETURN gchar *
+gtk_tool_button_get_stock_id (GtkToolButton *button)
+{
+ g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), NULL);
+
+ return button->stock_id;
+}
+
+void
+gtk_tool_button_set_icon_widget (GtkToolButton *button,
+ GtkWidget *icon)
+{
+ g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
+ g_return_if_fail (icon == NULL || GTK_IS_WIDGET (icon));
+
+ if (icon != button->icon_widget)
+ {
+ g_object_freeze_notify (G_OBJECT (button));
+
+ if (button->icon_widget)
+ g_object_unref (G_OBJECT (button->icon_widget));
+
+ if (icon)
+ {
+ g_object_ref (icon);
+ gtk_object_sink (GTK_OBJECT (icon));
+ }
+
+ button->icon_widget = icon;
+
+ if (button->icon_widget && button->icon_set)
+ {
+ gtk_icon_set_unref (button->icon_set);
+ button->icon_set = NULL;
+
+ g_object_notify (G_OBJECT (button), "icon_set");
+ }
+
+ gtk_tool_button_construct_contents (GTK_TOOL_ITEM (button));
+
+ g_object_notify (G_OBJECT (button), "icon_widget");
+ g_object_thaw_notify (G_OBJECT (button));
+ }
+}
+
+void
+gtk_tool_button_set_label_widget (GtkToolButton *button,
+ GtkWidget *label_widget)
+{
+ g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
+ g_return_if_fail (label_widget == NULL || GTK_IS_WIDGET (label_widget));
+
+ if (label_widget != button->label_widget)
+ {
+ if (button->label_widget)
+ g_object_unref (button->label_widget);
+
+ if (label_widget)
+ {
+ g_object_ref (label_widget);
+ gtk_object_sink (GTK_OBJECT (label_widget));
+ }
+
+ button->label_widget = label_widget;
+
+ gtk_tool_button_construct_contents (GTK_TOOL_ITEM (button));
+
+ g_object_notify (G_OBJECT (button), "label_widget");
+ }
+}
+
+GtkWidget *
+gtk_tool_button_get_label_widget (GtkToolButton *button)
+{
+ g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), NULL);
+
+ return button->label_widget;
+}
+
+GtkWidget *
+gtk_tool_button_get_icon_widget (GtkToolButton *button)
+{
+ g_return_val_if_fail (GTK_IS_BUTTON (button), NULL);
+
+ return button->icon_widget;
+}
+
+void
+gtk_tool_button_set_icon_set (GtkToolButton *button,
+ GtkIconSet *icon_set)
+{
+ g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
+
+ if (icon_set != button->icon_set)
+ {
+ g_object_freeze_notify (G_OBJECT (button));
+
+ if (button->icon_set)
+ gtk_icon_set_unref (button->icon_set);
+
+ button->icon_set = icon_set;
+
+ if (button->icon_set && button->icon_widget)
+ {
+ g_object_unref (button->icon_widget);
+ button->icon_widget = NULL;
+
+ g_object_notify (G_OBJECT (button->icon_widget), "icon_widget");
+ }
+
+ gtk_tool_button_construct_contents (GTK_TOOL_ITEM (button));
+
+ g_object_notify (G_OBJECT (button), "icon_set");
+ g_object_thaw_notify (G_OBJECT (button));
+ }
+}
+
+GtkIconSet *
+gtk_tool_button_get_icon_set (GtkToolButton *button)
+{
+ g_return_val_if_fail (GTK_IS_TOOL_BUTTON (button), NULL);
+
+ return button->icon_set;
+}
diff --git a/gtk/gtktoolbutton.h b/gtk/gtktoolbutton.h
new file mode 100644
index 0000000000..72456e894e
--- /dev/null
+++ b/gtk/gtktoolbutton.h
@@ -0,0 +1,92 @@
+/* gtktoolbutton.h
+ *
+ * Copyright (C) 2002 Anders Carlsson <andersca@codefactory.se>
+ * Copyright (C) 2002 James Henstridge <james@daa.com.au>
+ * Copyright (C) 2003 Soeren Sandmann <sandmann@daimi.au.dk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GTK_TOOL_BUTTON_H__
+#define __GTK_TOOL_BUTTON_H__
+
+#include "gtktoolitem.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_TOOL_BUTTON (gtk_tool_button_get_type ())
+#define GTK_TOOL_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TOOL_BUTTON, GtkToolButton))
+#define GTK_TOOL_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_TOOL_BUTTON, GtkToolButtonClass))
+#define GTK_IS_TOOL_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TOOL_BUTTON))
+#define GTK_IS_TOOL_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), GTK_TYPE_TOOL_BUTTON))
+#define GTK_TOOL_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_TOOL_BUTTON, GtkToolButtonClass))
+
+typedef struct _GtkToolButton GtkToolButton;
+typedef struct _GtkToolButtonClass GtkToolButtonClass;
+typedef struct _GtkToolButtonPrivate GtkToolButtonPrivate;
+
+struct _GtkToolButton
+{
+ GtkToolItem parent;
+
+ GtkWidget *button;
+
+ gchar *stock_id;
+ gchar *label_text;
+ GtkWidget *label_widget;
+ GtkWidget *icon_widget;
+ GtkIconSet *icon_set;
+
+ guint use_underline : 1;
+};
+
+struct _GtkToolButtonClass
+{
+ GtkToolItemClass parent_class;
+
+ GType button_type;
+
+ /* signal */
+ void (* clicked) (GtkToolButton *tool_item);
+};
+
+GType gtk_tool_button_get_type (void);
+GtkToolItem *gtk_tool_button_new (void);
+GtkToolItem *gtk_tool_button_new_from_stock (const gchar *stock_id);
+
+void gtk_tool_button_set_label (GtkToolButton *button,
+ const gchar *label);
+G_CONST_RETURN gchar *gtk_tool_button_get_label (GtkToolButton *button);
+void gtk_tool_button_set_use_underline (GtkToolButton *button,
+ gboolean use_underline);
+gboolean gtk_tool_button_get_use_underline (GtkToolButton *button);
+void gtk_tool_button_set_stock_id (GtkToolButton *button,
+ const gchar *stock_id);
+G_CONST_RETURN gchar *gtk_tool_button_get_stock_id (GtkToolButton *button);
+void gtk_tool_button_set_icon_set (GtkToolButton *button,
+ GtkIconSet *icon_set);
+GtkIconSet * gtk_tool_button_get_icon_set (GtkToolButton *button);
+void gtk_tool_button_set_icon_widget (GtkToolButton *button,
+ GtkWidget *icon);
+GtkWidget * gtk_tool_button_get_icon_widget (GtkToolButton *button);
+
+void gtk_tool_button_set_label_widget (GtkToolButton *button,
+ GtkWidget *label_widget);
+GtkWidget * gtk_tool_button_get_label_widget (GtkToolButton *button);
+
+G_END_DECLS
+
+#endif /* __GTK_TOOL_BUTTON_H__ */
diff --git a/gtk/gtktoolitem.c b/gtk/gtktoolitem.c
new file mode 100644
index 0000000000..37007e06a7
--- /dev/null
+++ b/gtk/gtktoolitem.c
@@ -0,0 +1,697 @@
+/* gtktoolitem.c
+ *
+ * Copyright (C) 2002 Anders Carlsson <andersca@codefactory.se>
+ * Copyright (C) 2002 James Henstridge <james@daa.com.au>
+ * Copyright (C) 2003 Soeren Sandmann <sandmann@daimi.au.dk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "gtktoolitem.h"
+#include "gtkmarshalers.h"
+#include "gtktoolbar.h"
+#include "gtkseparatormenuitem.h"
+#include "gtkintl.h"
+#include "gtkmain.h"
+
+#include <string.h>
+
+#define MENU_ID "gtk-tool-item-menu-id"
+
+enum {
+ CREATE_MENU_PROXY,
+ TOOLBAR_RECONFIGURED,
+ SET_TOOLTIP,
+ LAST_SIGNAL
+};
+
+enum {
+ PROP_0,
+ PROP_VISIBLE_HORIZONTAL,
+ PROP_VISIBLE_VERTICAL,
+};
+
+static void gtk_tool_item_init (GtkToolItem *toolitem);
+static void gtk_tool_item_class_init (GtkToolItemClass *class);
+static void gtk_tool_item_finalize (GObject *object);
+static void gtk_tool_item_parent_set (GtkWidget *toolitem,
+ GtkWidget *parent);
+static void gtk_tool_item_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gtk_tool_item_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void gtk_tool_item_realize (GtkWidget *widget);
+static void gtk_tool_item_unrealize (GtkWidget *widget);
+static void gtk_tool_item_map (GtkWidget *widget);
+static void gtk_tool_item_unmap (GtkWidget *widget);
+static void gtk_tool_item_size_request (GtkWidget *widget,
+ GtkRequisition *requisition);
+static void gtk_tool_item_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+static gboolean gtk_tool_item_real_set_tooltip (GtkToolItem *tool_item,
+ GtkTooltips *tooltips,
+ const gchar *tip_text,
+ const gchar *tip_private);
+
+static gboolean gtk_tool_item_create_menu_proxy (GtkToolItem *item);
+
+
+static GObjectClass *parent_class = NULL;
+static guint toolitem_signals[LAST_SIGNAL] = { 0 };
+
+GType
+gtk_tool_item_get_type (void)
+{
+ static GtkType type = 0;
+
+ if (!type)
+ {
+ static const GTypeInfo type_info =
+ {
+ sizeof (GtkToolItemClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gtk_tool_item_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+
+ sizeof (GtkToolItem),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) gtk_tool_item_init,
+ };
+
+ type = g_type_register_static (GTK_TYPE_BIN,
+ "GtkToolItem",
+ &type_info, 0);
+ }
+ return type;
+}
+
+static void
+gtk_tool_item_class_init (GtkToolItemClass *klass)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ parent_class = g_type_class_peek_parent (klass);
+ object_class = (GObjectClass *)klass;
+ widget_class = (GtkWidgetClass *)klass;
+
+ object_class->set_property = gtk_tool_item_set_property;
+ object_class->get_property = gtk_tool_item_get_property;
+ object_class->finalize = gtk_tool_item_finalize;
+
+ widget_class->realize = gtk_tool_item_realize;
+ widget_class->unrealize = gtk_tool_item_unrealize;
+ widget_class->map = gtk_tool_item_map;
+ widget_class->unmap = gtk_tool_item_unmap;
+ widget_class->size_request = gtk_tool_item_size_request;
+ widget_class->size_allocate = gtk_tool_item_size_allocate;
+ widget_class->parent_set = gtk_tool_item_parent_set;
+
+ klass->create_menu_proxy = gtk_tool_item_create_menu_proxy;
+ klass->set_tooltip = gtk_tool_item_real_set_tooltip;
+
+ g_object_class_install_property (object_class,
+ PROP_VISIBLE_HORIZONTAL,
+ g_param_spec_boolean ("visible_horizontal",
+ _("Visible when horizontal"),
+ _("Whether the toolbar item is visible when the toolbar is in a horizontal orientation."),
+ TRUE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_VISIBLE_VERTICAL,
+ g_param_spec_boolean ("visible_vertical",
+ _("Visible when vertical"),
+ _("Whether the toolbar item is visible when the toolbar is in a vertical orientation."),
+ TRUE,
+ G_PARAM_READWRITE));
+ toolitem_signals[CREATE_MENU_PROXY] =
+ g_signal_new ("create_menu_proxy",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtkToolItemClass, create_menu_proxy),
+ _gtk_boolean_handled_accumulator, NULL, /* FIXME: use gtk_boolean_handled() when
+ * we are added to gtk+
+ */
+ _gtk_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN, 0);
+ toolitem_signals[TOOLBAR_RECONFIGURED] =
+ g_signal_new ("toolbar_reconfigured",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtkToolItemClass, toolbar_reconfigured),
+ NULL, NULL,
+ _gtk_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ toolitem_signals[SET_TOOLTIP] =
+ g_signal_new ("set_tooltip",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtkToolItemClass, set_tooltip),
+ _gtk_boolean_handled_accumulator, NULL, /* FIXME: use gtk_boolean_handled() when
+ * we are added to gtk+
+ */
+ _gtk_marshal_BOOLEAN__OBJECT_STRING_STRING,
+ G_TYPE_BOOLEAN, 3,
+ GTK_TYPE_TOOLTIPS,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
+}
+
+static void
+gtk_tool_item_init (GtkToolItem *toolitem)
+{
+ GTK_WIDGET_UNSET_FLAGS (toolitem, GTK_CAN_FOCUS);
+
+ toolitem->visible_horizontal = TRUE;
+ toolitem->visible_vertical = TRUE;
+ toolitem->homogeneous = FALSE;
+ toolitem->expand = FALSE;
+}
+
+static void
+gtk_tool_item_finalize (GObject *object)
+{
+ GtkToolItem *item = GTK_TOOL_ITEM (object);
+
+ if (item->menu_item)
+ g_object_unref (item->menu_item);
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gtk_tool_item_parent_set (GtkWidget *toolitem,
+ GtkWidget *prev_parent)
+{
+ gtk_tool_item_toolbar_reconfigured (GTK_TOOL_ITEM (toolitem));
+}
+
+static void
+gtk_tool_item_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkToolItem *toolitem = GTK_TOOL_ITEM (object);
+
+ switch (prop_id)
+ {
+ case PROP_VISIBLE_HORIZONTAL:
+ gtk_tool_item_set_visible_horizontal (toolitem, g_value_get_boolean (value));
+ break;
+ case PROP_VISIBLE_VERTICAL:
+ gtk_tool_item_set_visible_horizontal (toolitem, g_value_get_boolean (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gtk_tool_item_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkToolItem *toolitem = GTK_TOOL_ITEM (object);
+
+ switch (prop_id)
+ {
+ case PROP_VISIBLE_HORIZONTAL:
+ g_value_set_boolean (value, toolitem->visible_horizontal);
+ break;
+ case PROP_VISIBLE_VERTICAL:
+ g_value_set_boolean (value, toolitem->visible_vertical);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+create_drag_window (GtkToolItem *toolitem)
+{
+ GtkWidget *widget;
+ GdkWindowAttr attributes;
+ gint attributes_mask, border_width;
+
+ g_return_if_fail (toolitem->use_drag_window == TRUE);
+
+ widget = GTK_WIDGET (toolitem);
+ border_width = GTK_CONTAINER (toolitem)->border_width;
+
+ attributes.window_type = GDK_WINDOW_CHILD;
+ attributes.x = widget->allocation.x + border_width;
+ attributes.y = widget->allocation.y + border_width;
+ attributes.width = widget->allocation.width - border_width * 2;
+ attributes.height = widget->allocation.height - border_width * 2;
+ attributes.wclass = GDK_INPUT_ONLY;
+ attributes.event_mask = gtk_widget_get_events (widget);
+ attributes.event_mask |= (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+
+ attributes_mask = GDK_WA_X | GDK_WA_Y;
+
+ toolitem->drag_window = gdk_window_new (gtk_widget_get_parent_window (widget),
+ &attributes, attributes_mask);
+ gdk_window_set_user_data (toolitem->drag_window, toolitem);
+}
+
+static void
+gtk_tool_item_realize (GtkWidget *widget)
+{
+ GtkToolItem *toolitem;
+
+ toolitem = GTK_TOOL_ITEM (widget);
+ GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+
+ widget->window = gtk_widget_get_parent_window (widget);
+ g_object_ref (widget->window);
+
+ if (toolitem->use_drag_window)
+ create_drag_window(toolitem);
+
+ widget->style = gtk_style_attach (widget->style, widget->window);
+}
+
+static void
+destroy_drag_window (GtkToolItem *toolitem)
+{
+ if (toolitem->drag_window)
+ {
+ gdk_window_set_user_data (toolitem->drag_window, NULL);
+ gdk_window_destroy (toolitem->drag_window);
+ toolitem->drag_window = NULL;
+ }
+}
+
+static void
+gtk_tool_item_unrealize (GtkWidget *widget)
+{
+ GtkToolItem *toolitem;
+
+ toolitem = GTK_TOOL_ITEM (widget);
+
+ destroy_drag_window (toolitem);
+
+ GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
+}
+
+static void
+gtk_tool_item_map (GtkWidget *widget)
+{
+ GtkToolItem *toolitem;
+
+ toolitem = GTK_TOOL_ITEM (widget);
+ GTK_WIDGET_CLASS (parent_class)->map (widget);
+ if (toolitem->drag_window)
+ gdk_window_show (toolitem->drag_window);
+}
+
+static void
+gtk_tool_item_unmap (GtkWidget *widget)
+{
+ GtkToolItem *toolitem;
+
+ toolitem = GTK_TOOL_ITEM (widget);
+ if (toolitem->drag_window)
+ gdk_window_hide (toolitem->drag_window);
+ GTK_WIDGET_CLASS (parent_class)->unmap (widget);
+}
+
+static void
+gtk_tool_item_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ GtkWidget *child = GTK_BIN (widget)->child;
+ gint xthickness = widget->style->xthickness;
+ gint ythickness = widget->style->ythickness;
+
+ if (child && GTK_WIDGET_VISIBLE (child))
+ {
+ gtk_widget_size_request (child, requisition);
+ }
+ else
+ {
+ requisition->height = 0;
+ requisition->width = 0;
+ }
+
+ requisition->width += (xthickness + GTK_CONTAINER (widget)->border_width) * 2;
+ requisition->height += (ythickness + GTK_CONTAINER (widget)->border_width) * 2;
+}
+
+static void
+gtk_tool_item_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ GtkToolItem *toolitem = GTK_TOOL_ITEM (widget);
+ GtkAllocation child_allocation;
+ gint border_width;
+ GtkWidget *child = GTK_BIN (widget)->child;
+
+ widget->allocation = *allocation;
+ border_width = GTK_CONTAINER (widget)->border_width;
+
+ if (toolitem->drag_window)
+ gdk_window_move_resize (toolitem->drag_window,
+ widget->allocation.x + border_width,
+ widget->allocation.y + border_width,
+ widget->allocation.width - border_width * 2,
+ widget->allocation.height - border_width * 2);
+
+ if (child && GTK_WIDGET_VISIBLE (child))
+ {
+ gint xthickness = widget->style->xthickness;
+ gint ythickness = widget->style->ythickness;
+
+ child_allocation.x = allocation->x + border_width + xthickness;
+ child_allocation.y = allocation->y + border_width + ythickness;
+ child_allocation.width = allocation->width - 2 * (xthickness + border_width);
+ child_allocation.height = allocation->height - 2 * (ythickness + border_width);
+
+ gtk_widget_size_allocate (child, &child_allocation);
+ }
+}
+
+static gboolean
+gtk_tool_item_create_menu_proxy (GtkToolItem *item)
+{
+ if (!GTK_BIN (item)->child)
+ {
+ GtkWidget *menu_item = NULL;
+
+ menu_item = gtk_separator_menu_item_new();
+
+ gtk_tool_item_set_proxy_menu_item (item, MENU_ID, menu_item);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+GtkToolItem *
+gtk_tool_item_new (void)
+{
+ GtkToolItem *item;
+
+ item = g_object_new (GTK_TYPE_TOOL_ITEM, NULL);
+
+ return item;
+}
+
+GtkIconSize
+gtk_tool_item_get_icon_size (GtkToolItem *tool_item)
+{
+ GtkWidget *parent;
+
+ g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ICON_SIZE_LARGE_TOOLBAR);
+
+ parent = GTK_WIDGET (tool_item)->parent;
+ if (!parent || !GTK_IS_TOOLBAR (parent))
+ return GTK_ICON_SIZE_LARGE_TOOLBAR;
+
+ return gtk_toolbar_get_icon_size (GTK_TOOLBAR (parent));
+}
+
+GtkOrientation
+gtk_tool_item_get_orientation (GtkToolItem *tool_item)
+{
+ GtkWidget *parent;
+
+ g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_ORIENTATION_HORIZONTAL);
+
+ parent = GTK_WIDGET (tool_item)->parent;
+ if (!parent || !GTK_IS_TOOLBAR (parent))
+ return GTK_ORIENTATION_HORIZONTAL;
+
+ return gtk_toolbar_get_orientation (GTK_TOOLBAR (parent));
+}
+
+GtkToolbarStyle
+gtk_tool_item_get_toolbar_style (GtkToolItem *tool_item)
+{
+ GtkWidget *parent;
+
+ g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_TOOLBAR_ICONS);
+
+ parent = GTK_WIDGET (tool_item)->parent;
+ if (!parent || !GTK_IS_TOOLBAR (parent))
+ return GTK_TOOLBAR_ICONS;
+
+ return gtk_toolbar_get_style (GTK_TOOLBAR (parent));
+}
+
+GtkReliefStyle
+gtk_tool_item_get_relief_style (GtkToolItem *tool_item)
+{
+ GtkWidget *parent;
+
+ g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), GTK_RELIEF_NONE);
+
+ parent = GTK_WIDGET (tool_item)->parent;
+ if (!parent || !GTK_IS_TOOLBAR (parent))
+ return GTK_RELIEF_NONE;
+
+ return gtk_toolbar_get_relief_style (GTK_TOOLBAR (parent));
+}
+
+void
+gtk_tool_item_toolbar_reconfigured (GtkToolItem *tool_item)
+{
+ g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
+
+ g_signal_emit (tool_item, toolitem_signals[TOOLBAR_RECONFIGURED], 0);
+}
+
+void
+gtk_tool_item_set_expand (GtkToolItem *tool_item,
+ gboolean expand)
+{
+ g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
+
+ expand = expand != FALSE;
+
+ if (tool_item->expand != expand)
+ {
+ tool_item->expand = expand;
+ gtk_widget_child_notify (GTK_WIDGET (tool_item), "expand");
+ gtk_widget_queue_resize (GTK_WIDGET (tool_item));
+ }
+}
+
+void
+gtk_tool_item_set_pack_end (GtkToolItem *tool_item,
+ gboolean pack_end)
+{
+ g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
+
+ pack_end = pack_end != FALSE;
+
+ if (tool_item->pack_end != pack_end)
+ {
+ tool_item->pack_end = pack_end;
+ gtk_widget_child_notify (GTK_WIDGET (tool_item), "pack_end");
+ gtk_widget_queue_resize (GTK_WIDGET (tool_item));
+ }
+}
+
+void
+gtk_tool_item_set_homogeneous (GtkToolItem *tool_item,
+ gboolean homogeneous)
+{
+ g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
+
+ homogeneous = homogeneous != FALSE;
+
+ if (tool_item->homogeneous != homogeneous)
+ {
+ tool_item->homogeneous = homogeneous;
+ gtk_widget_child_notify (GTK_WIDGET (tool_item), "homogeneous");
+ gtk_widget_queue_resize (GTK_WIDGET (tool_item));
+ }
+}
+
+static gboolean
+gtk_tool_item_real_set_tooltip (GtkToolItem *tool_item,
+ GtkTooltips *tooltips,
+ const gchar *tip_text,
+ const gchar *tip_private)
+{
+ GtkWidget *child = GTK_BIN (tool_item)->child;
+
+ if (!child)
+ return FALSE;
+
+ gtk_tooltips_set_tip (tooltips, child, tip_text, tip_private);
+
+ return TRUE;
+}
+
+void
+gtk_tool_item_set_tooltip (GtkToolItem *tool_item,
+ GtkTooltips *tooltips,
+ const gchar *tip_text,
+ const gchar *tip_private)
+{
+ gboolean retval;
+
+ g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
+
+ g_signal_emit (tool_item, toolitem_signals[SET_TOOLTIP], 0,
+ tooltips, tip_text, tip_private, &retval);
+}
+
+void
+gtk_tool_item_set_use_drag_window (GtkToolItem *toolitem,
+ gboolean use_drag_window)
+{
+ g_return_if_fail (GTK_IS_TOOL_ITEM (toolitem));
+
+ use_drag_window = use_drag_window != FALSE;
+
+ if (toolitem->use_drag_window != use_drag_window)
+ {
+ toolitem->use_drag_window = use_drag_window;
+
+ if (use_drag_window)
+ {
+ if (!toolitem->drag_window && GTK_WIDGET_REALIZED (toolitem))
+ {
+ create_drag_window(toolitem);
+ if (GTK_WIDGET_MAPPED (toolitem))
+ gdk_window_show (toolitem->drag_window);
+ }
+ }
+ else
+ {
+ destroy_drag_window (toolitem);
+ }
+ }
+}
+
+void
+gtk_tool_item_set_visible_horizontal (GtkToolItem *toolitem,
+ gboolean visible_horizontal)
+{
+ g_return_if_fail (GTK_IS_TOOL_ITEM (toolitem));
+
+ visible_horizontal = visible_horizontal != FALSE;
+
+ if (toolitem->visible_horizontal != visible_horizontal)
+ {
+ toolitem->visible_horizontal = visible_horizontal;
+
+ g_object_notify (G_OBJECT (toolitem), "visible_horizontal");
+
+ gtk_widget_queue_resize (GTK_WIDGET (toolitem));
+ }
+}
+
+gboolean
+gtk_tool_item_get_visible_horizontal (GtkToolItem *toolitem)
+{
+ g_return_val_if_fail (GTK_IS_TOOL_ITEM (toolitem), FALSE);
+
+ return toolitem->visible_horizontal;
+}
+
+void
+gtk_tool_item_set_visible_vertical (GtkToolItem *toolitem,
+ gboolean visible_vertical)
+{
+ g_return_if_fail (GTK_IS_TOOL_ITEM (toolitem));
+
+ visible_vertical = visible_vertical != FALSE;
+
+ if (toolitem->visible_vertical != visible_vertical)
+ {
+ toolitem->visible_vertical = visible_vertical;
+
+ g_object_notify (G_OBJECT (toolitem), "visible_vertical");
+
+ gtk_widget_queue_resize (GTK_WIDGET (toolitem));
+ }
+}
+
+gboolean
+gtk_tool_item_get_visible_vertical (GtkToolItem *toolitem)
+{
+ g_return_val_if_fail (GTK_IS_TOOL_ITEM (toolitem), FALSE);
+
+ return toolitem->visible_vertical;
+}
+
+GtkWidget *
+gtk_tool_item_retrieve_proxy_menu_item (GtkToolItem *tool_item)
+{
+ gboolean retval;
+
+ g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
+
+ g_signal_emit (tool_item, toolitem_signals[CREATE_MENU_PROXY], 0, &retval);
+
+ return tool_item->menu_item;
+}
+
+GtkWidget *
+gtk_tool_item_get_proxy_menu_item (GtkToolItem *tool_item,
+ const gchar *menu_item_id)
+{
+ g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
+ g_return_val_if_fail (menu_item_id != NULL, NULL);
+
+ if (tool_item->menu_item_id && strcmp (tool_item->menu_item_id, menu_item_id) == 0)
+ return tool_item->menu_item;
+
+ return NULL;
+}
+
+void
+gtk_tool_item_set_proxy_menu_item (GtkToolItem *tool_item,
+ const gchar *menu_item_id,
+ GtkWidget *menu_item)
+{
+ g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
+ g_return_if_fail (menu_item == NULL || GTK_IS_MENU_ITEM (menu_item));
+ g_return_if_fail (menu_item_id != NULL);
+
+ if (tool_item->menu_item_id)
+ g_free (tool_item->menu_item_id);
+
+ tool_item->menu_item_id = g_strdup (menu_item_id);
+
+ if (tool_item->menu_item != menu_item)
+ {
+ if (tool_item->menu_item)
+ g_object_unref (G_OBJECT (tool_item->menu_item));
+
+ if (menu_item)
+ {
+ g_object_ref (menu_item);
+ gtk_object_sink (GTK_OBJECT (menu_item));
+ }
+
+ tool_item->menu_item = menu_item;
+ }
+}
diff --git a/gtk/gtktoolitem.h b/gtk/gtktoolitem.h
new file mode 100644
index 0000000000..d48a7113c7
--- /dev/null
+++ b/gtk/gtktoolitem.h
@@ -0,0 +1,110 @@
+/* gtktoolitem.c
+ *
+ * Copyright (C) 2002 Anders Carlsson <andersca@codefactory.se>
+ * Copyright (C) 2002 James Henstridge <james@daa.com.au>
+ * Copyright (C) 2003 Soeren Sandmann <sandmann@daimi.au.dk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GTK_TOOL_ITEM_H__
+#define __GTK_TOOL_ITEM_H__
+
+#include <gtk/gtkbin.h>
+#include <gtk/gtktooltips.h>
+#include <gtk/gtkmenuitem.h>
+
+#define GTK_TYPE_TOOL_ITEM (gtk_tool_item_get_type ())
+#define GTK_TOOL_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TOOL_ITEM, GtkToolItem))
+#define GTK_TOOL_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_TOOL_ITEM, GtkToolItemClass))
+#define GTK_IS_TOOL_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TOOL_ITEM))
+#define GTK_IS_TOOL_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), GTK_TYPE_TOOL_ITEM))
+#define GTK_TOOL_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_TOOL_ITEM, GtkToolItemClass))
+
+typedef struct _GtkToolItem GtkToolItem;
+typedef struct _GtkToolItemClass GtkToolItemClass;
+typedef struct _GtkToolItemPrivate GtkToolItemPrivate;
+
+struct _GtkToolItem
+{
+ GtkBin parent;
+
+ /*< private >*/
+ gchar *tip_text;
+ gchar *tip_private;
+
+ GdkWindow *drag_window;
+
+ guint visible_horizontal : 1;
+ guint visible_vertical : 1;
+ guint homogeneous : 1;
+ guint expand : 1;
+ guint pack_end : 1;
+ guint use_drag_window : 1;
+ guint overflow_item : 1;
+
+ GtkWidget *menu_item;
+ gchar *menu_item_id;
+};
+
+struct _GtkToolItemClass
+{
+ GtkBinClass parent_class;
+
+ /* signals */
+ gboolean (* create_menu_proxy) (GtkToolItem *tool_item);
+ void (* toolbar_reconfigured) (GtkToolItem *tool_item);
+ gboolean (* set_tooltip) (GtkToolItem *tool_item,
+ GtkTooltips *tooltips,
+ const gchar *tip_text,
+ const gchar *tip_private);
+};
+
+GType gtk_tool_item_get_type (void);
+GtkToolItem *gtk_tool_item_new (void);
+
+void gtk_tool_item_toolbar_reconfigured (GtkToolItem *tool_item);
+void gtk_tool_item_set_homogeneous (GtkToolItem *tool_item,
+ gboolean homogeneous);
+void gtk_tool_item_set_expand (GtkToolItem *tool_item,
+ gboolean expand);
+void gtk_tool_item_set_pack_end (GtkToolItem *tool_item,
+ gboolean pack_end);
+void gtk_tool_item_set_tooltip (GtkToolItem *tool_item,
+ GtkTooltips *tooltips,
+ const gchar *tip_text,
+ const gchar *tip_private);
+void gtk_tool_item_set_use_drag_window (GtkToolItem *toolitem,
+ gboolean use_drag_window);
+void gtk_tool_item_set_visible_horizontal (GtkToolItem *toolitem,
+ gboolean visible_horizontal);
+gboolean gtk_tool_item_get_visible_horizontal (GtkToolItem *toolitem);
+void gtk_tool_item_set_visible_vertical (GtkToolItem *toolitem,
+ gboolean visible_horizontal);
+gboolean gtk_tool_item_get_visible_vertical (GtkToolItem *toolitem);
+GtkIconSize gtk_tool_item_get_icon_size (GtkToolItem *tool_item);
+GtkOrientation gtk_tool_item_get_orientation (GtkToolItem *tool_item);
+GtkToolbarStyle gtk_tool_item_get_toolbar_style (GtkToolItem *tool_item);
+GtkReliefStyle gtk_tool_item_get_relief_style (GtkToolItem *tool_item);
+GtkWidget * gtk_tool_item_retrieve_proxy_menu_item (GtkToolItem *tool_item);
+GtkWidget * gtk_tool_item_get_proxy_menu_item (GtkToolItem *tool_item,
+ const gchar *menu_item_id);
+void gtk_tool_item_set_proxy_menu_item (GtkToolItem *tool_item,
+ const gchar *menu_item_id,
+ GtkWidget *menu_item);
+
+
+#endif /* __GTK_TOOL_ITEM_H__ */