#include "gtkmarshalers.h"
#include "gtkimage.h"
#include "gtkhbox.h"
+#include "gtkvbox.h"
#include "gtkstock.h"
#include "gtkiconfactory.h"
#include "gtkprivate.h"
PROP_FOCUS_ON_CLICK,
PROP_XALIGN,
PROP_YALIGN,
+ PROP_IMAGE_POSITION
};
#define GTK_BUTTON_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_BUTTON, GtkButtonPrivate))
struct _GtkButtonPrivate
{
- gfloat xalign;
- gfloat yalign;
- GtkWidget *image;
- guint align_set : 1;
- guint image_is_stock : 1;
- guint has_grab : 1;
- guint32 grab_time;
+ gfloat xalign;
+ gfloat yalign;
+ GtkWidget *image;
+ guint align_set : 1;
+ guint image_is_stock : 1;
+ guint has_grab : 1;
+ guint32 grab_time;
+ GtkPositionType image_position;
};
static void gtk_button_destroy (GtkObject *object);
static void gtk_button_unrealize (GtkWidget *widget);
static void gtk_button_map (GtkWidget *widget);
static void gtk_button_unmap (GtkWidget *widget);
+static void gtk_button_style_set (GtkWidget *widget,
+ GtkStyle *prev_style);
static void gtk_button_size_request (GtkWidget *widget,
GtkRequisition *requisition);
static void gtk_button_size_allocate (GtkWidget *widget,
widget_class->unrealize = gtk_button_unrealize;
widget_class->map = gtk_button_map;
widget_class->unmap = gtk_button_unmap;
+ widget_class->style_set = gtk_button_style_set;
widget_class->size_request = gtk_button_size_request;
widget_class->size_allocate = gtk_button_size_allocate;
widget_class->expose_event = gtk_button_expose;
GTK_TYPE_WIDGET,
GTK_PARAM_READWRITE));
+ /**
+ * GtkButton:image-position:
+ *
+ * The position of the image relative to the text inside the button.
+ *
+ * Since: 2.10
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_IMAGE_POSITION,
+ g_param_spec_enum ("image-position",
+ P_("Image position"),
+ P_("The position of the image relative to the text"),
+ GTK_TYPE_POSITION_TYPE,
+ GTK_POS_LEFT,
+ GTK_PARAM_READWRITE));
+
/**
* GtkButton::pressed:
* @button: the object that received the signal
GTK_TYPE_BORDER,
GTK_PARAM_READABLE));
+ /**
+ * GtkButton::image-spacing:
+ *
+ * Spacing in pixels between the image and label.
+ *
+ * Since: 2.10
+ */
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_int ("image-spacing",
+ P_("Image spacing"),
+ P_("Spacing in pixels between the image and label"),
+ 0,
+ G_MAXINT,
+ 2,
+ GTK_PARAM_READABLE));
+
+
gtk_settings_install_property (g_param_spec_boolean ("gtk-button-images",
P_("Show button images"),
P_("Whether stock icons should be shown in buttons"),
priv->yalign = 0.5;
priv->align_set = 0;
priv->image_is_stock = TRUE;
+ priv->image_position = GTK_POS_LEFT;
}
static void
case PROP_YALIGN:
gtk_button_set_alignment (button, priv->xalign, g_value_get_float (value));
break;
+ case PROP_IMAGE_POSITION:
+ gtk_button_set_image_position (button, g_value_get_enum (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
case PROP_YALIGN:
g_value_set_float (value, priv->yalign);
break;
+ case PROP_IMAGE_POSITION:
+ g_value_set_enum (value, priv->image_position);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
GtkButtonPrivate *priv = GTK_BUTTON_GET_PRIVATE (button);
GtkStockItem item;
GtkWidget *label;
- GtkWidget *hbox;
+ GtkWidget *box;
GtkWidget *align;
GtkWidget *image = NULL;
gchar *label_text = NULL;
+ gint image_spacing;
if (!button->constructed)
return;
if (!button->label_text && !priv->image)
return;
+ gtk_widget_style_get (GTK_WIDGET (button),
+ "image-spacing", &image_spacing,
+ NULL);
+
if (priv->image && !priv->image_is_stock)
{
image = g_object_ref (priv->image);
if (image)
{
priv->image = image;
-
g_object_set (priv->image,
"visible", show_image (button),
"no-show-all", TRUE,
NULL);
- hbox = gtk_hbox_new (FALSE, 2);
+
+ if (priv->image_position == GTK_POS_LEFT ||
+ priv->image_position == GTK_POS_RIGHT)
+ box = gtk_hbox_new (FALSE, image_spacing);
+ else
+ box = gtk_vbox_new (FALSE, image_spacing);
if (priv->align_set)
align = gtk_alignment_new (priv->xalign, priv->yalign, 0.0, 0.0);
else
align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
-
- gtk_box_pack_start (GTK_BOX (hbox), priv->image, FALSE, FALSE, 0);
+
+ if (priv->image_position == GTK_POS_LEFT ||
+ priv->image_position == GTK_POS_TOP)
+ gtk_box_pack_start (GTK_BOX (box), priv->image, FALSE, FALSE, 0);
+ else
+ gtk_box_pack_end (GTK_BOX (box), priv->image, FALSE, FALSE, 0);
if (label_text)
{
gtk_label_set_mnemonic_widget (GTK_LABEL (label),
GTK_WIDGET (button));
- gtk_box_pack_end (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ if (priv->image_position == GTK_POS_RIGHT ||
+ priv->image_position == GTK_POS_BOTTOM)
+ gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
+ else
+ gtk_box_pack_end (GTK_BOX (box), label, FALSE, FALSE, 0);
}
gtk_container_add (GTK_CONTAINER (button), align);
- gtk_container_add (GTK_CONTAINER (align), hbox);
+ gtk_container_add (GTK_CONTAINER (align), box);
gtk_widget_show_all (align);
g_object_unref (image);
GTK_WIDGET_CLASS (gtk_button_parent_class)->unmap (widget);
}
+static void
+gtk_button_update_image_spacing (GtkButton *button)
+{
+ GtkButtonPrivate *priv = GTK_BUTTON_GET_PRIVATE (button);
+ GtkWidget *child;
+ gint spacing;
+
+ /* Keep in sync with gtk_button_construct_child,
+ * we only want to update the spacing if the box
+ * was constructed there.
+ */
+ if (!button->constructed || !priv->image)
+ return;
+
+ child = GTK_BIN (button)->child;
+ if (GTK_IS_ALIGNMENT (child))
+ {
+ child = GTK_BIN (child)->child;
+ if (GTK_IS_BOX (child))
+ {
+ gtk_widget_style_get (GTK_WIDGET (button),
+ "image-spacing", &spacing,
+ NULL);
+
+ gtk_box_set_spacing (GTK_BOX (child), spacing);
+ }
+ }
+}
+
+static void
+gtk_button_style_set (GtkWidget *widget,
+ GtkStyle *prev_style)
+{
+ gtk_button_update_image_spacing (GTK_BUTTON (widget));
+}
+
static void
gtk_button_get_props (GtkButton *button,
GtkBorder *default_border,
show_image_connection =
g_signal_connect (settings, "notify::gtk-button-images",
- G_CALLBACK (gtk_button_setting_changed), 0);
+ G_CALLBACK (gtk_button_setting_changed), NULL);
g_object_set_data (G_OBJECT (settings),
I_("gtk-button-connection"),
GUINT_TO_POINTER (show_image_connection));
return priv->image;
}
+
+/**
+ * gtk_button_set_image_position:
+ * @button: a #GtkButton
+ * @position: the position
+ *
+ * Sets the position of the image relative to the text
+ * inside the button.
+ *
+ * Since: 2.10
+ */
+void
+gtk_button_set_image_position (GtkButton *button,
+ GtkPositionType position)
+{
+
+ GtkButtonPrivate *priv;
+
+ g_return_if_fail (GTK_IS_BUTTON (button));
+ g_return_if_fail (position >= GTK_POS_LEFT && position <= GTK_POS_BOTTOM);
+
+ priv = GTK_BUTTON_GET_PRIVATE (button);
+
+ if (priv->image_position != position)
+ {
+ priv->image_position = position;
+
+ gtk_button_construct_child (button);
+
+ g_object_notify (G_OBJECT (button), "image-position");
+ }
+}
+
+/**
+ * gtk_button_get_image_position:
+ * @button: a #GtkButton
+ *
+ * Gets the position of the image relative to the text
+ * inside the button.
+ *
+ * Return value: the position
+ *
+ * Since: 2.10
+ */
+GtkPositionType
+gtk_button_get_image_position (GtkButton *button)
+{
+ GtkButtonPrivate *priv;
+
+ g_return_val_if_fail (GTK_IS_BUTTON (button), GTK_POS_LEFT);
+
+ priv = GTK_BUTTON_GET_PRIVATE (button);
+ return priv->image_position;
+}
+
+
#define __GTK_BUTTON_C__
#include "gtkaliasdef.c"