#include "config.h"
+#ifndef _WIN32
#define _GNU_SOURCE
+#endif
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk/gdkkeysyms.h>
-#include "gtkmain.h"
-#include "gtkintl.h"
#include "gtkbindings.h"
-#include "gtkvscale.h"
#include "gtkframe.h"
-#include "gtkvbox.h"
-#include "gtkwindow.h"
+#include "gtkmain.h"
#include "gtkmarshalers.h"
-#include "gtkstock.h"
+#include "gtkorientable.h"
#include "gtkprivate.h"
+#include "gtkscale.h"
#include "gtkscalebutton.h"
+#include "gtkstock.h"
+#include "gtkvbox.h"
+#include "gtkwindow.h"
+#include "gtkintl.h"
#include "gtkalias.h"
#define SCALE_SIZE 100
{
PROP_0,
+ PROP_ORIENTATION,
PROP_VALUE,
PROP_SIZE,
PROP_ADJUSTMENT,
struct _GtkScaleButtonPrivate
{
GtkWidget *dock;
+ GtkWidget *box;
GtkWidget *scale;
GtkWidget *image;
GtkIconSize size;
+ GtkOrientation orientation;
guint click_id;
gint click_timeout;
guint32 pop_time;
gchar **icon_list;
+
+ GtkAdjustment *adjustment; /* needed because it must be settable in init() */
};
+static GObject* gtk_scale_button_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_params);
static void gtk_scale_button_dispose (GObject *object);
static void gtk_scale_button_finalize (GObject *object);
static void gtk_scale_button_set_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
+static void gtk_scale_button_set_orientation_private (GtkScaleButton *button,
+ GtkOrientation orientation);
static gboolean gtk_scale_button_scroll (GtkWidget *widget,
GdkEventScroll *event);
static void gtk_scale_button_screen_changed (GtkWidget *widget,
GdkEventButton *event);
static gboolean gtk_scale_button_key_release (GtkWidget *widget,
GdkEventKey *event);
-static void gtk_scale_button_popup_from_bindings (GtkWidget *widget);
-static void gtk_scale_button_popdown_from_bindings (GtkWidget *widget);
+static void gtk_scale_button_popup (GtkWidget *widget);
+static void gtk_scale_button_popdown (GtkWidget *widget);
static gboolean cb_dock_button_press (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data);
static void gtk_scale_button_scale_value_changed(GtkRange *range);
/* see below for scale definitions */
-static GtkWidget *gtk_scale_button_scale_new (GtkScaleButton *button,
- gdouble min,
- gdouble max,
- gdouble step);
+static GtkWidget *gtk_scale_button_scale_new (GtkScaleButton *button);
-static guint signals[LAST_SIGNAL] = { 0, };
+G_DEFINE_TYPE_WITH_CODE (GtkScaleButton, gtk_scale_button, GTK_TYPE_BUTTON,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE,
+ NULL))
-G_DEFINE_TYPE (GtkScaleButton, gtk_scale_button, GTK_TYPE_BUTTON)
+static guint signals[LAST_SIGNAL] = { 0, };
static void
gtk_scale_button_class_init (GtkScaleButtonClass *klass)
g_type_class_add_private (klass, sizeof (GtkScaleButtonPrivate));
+ gobject_class->constructor = gtk_scale_button_constructor;
gobject_class->finalize = gtk_scale_button_finalize;
gobject_class->dispose = gtk_scale_button_dispose;
gobject_class->set_property = gtk_scale_button_set_property;
widget_class->scroll_event = gtk_scale_button_scroll;
widget_class->screen_changed = gtk_scale_button_screen_changed;
+ /**
+ * GtkScaleButton:orientation:
+ *
+ * The orientation of the #GtkScaleButton's popup window.
+ *
+ * Note that since GTK+ 2.16, #GtkScaleButton implements the
+ * #GtkOrientable interface which has its own @orientation
+ * property. However we redefine the property here in order to
+ * override its default horizontal orientation.
+ *
+ * Since: 2.14
+ **/
+ g_object_class_override_property (gobject_class,
+ PROP_ORIENTATION,
+ "orientation");
+
g_object_class_install_property (gobject_class,
PROP_VALUE,
g_param_spec_double ("value",
* Since: 2.12
*/
signals[POPUP] =
- _gtk_binding_signal_new (I_("popup"),
- G_OBJECT_CLASS_TYPE (klass),
- G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
- G_CALLBACK (gtk_scale_button_popup_from_bindings),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ g_signal_new_class_handler (I_("popup"),
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_CALLBACK (gtk_scale_button_popup),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
/**
* GtkScaleButton::popdown:
* Since: 2.12
*/
signals[POPDOWN] =
- _gtk_binding_signal_new (I_("popdown"),
- G_OBJECT_CLASS_TYPE (klass),
- G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
- G_CALLBACK (gtk_scale_button_popdown_from_bindings),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ g_signal_new_class_handler (I_("popdown"),
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_CALLBACK (gtk_scale_button_popdown),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
/* Key bindings */
binding_set = gtk_binding_set_by_class (widget_class);
static void
gtk_scale_button_init (GtkScaleButton *button)
{
- GtkWidget *frame, *box;
GtkScaleButtonPrivate *priv;
+ GtkWidget *frame;
button->priv = priv = GET_PRIVATE (button);
priv->timeout = FALSE;
priv->click_id = 0;
priv->click_timeout = CLICK_TIMEOUT;
+ priv->orientation = GTK_ORIENTATION_VERTICAL;
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE);
/* window */
priv->dock = gtk_window_new (GTK_WINDOW_POPUP);
+ gtk_widget_set_name (priv->dock, "gtk-scalebutton-popup-window");
g_signal_connect (priv->dock, "button-press-event",
G_CALLBACK (cb_dock_button_press), button);
g_signal_connect (priv->dock, "key-release-event",
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
gtk_container_add (GTK_CONTAINER (priv->dock), frame);
- box = gtk_vbox_new (FALSE, 0);
- gtk_container_add (GTK_CONTAINER (frame), box);
+
+ /* box for scale and +/- buttons */
+ priv->box = gtk_vbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (frame), priv->box);
/* + */
button->plus_button = gtk_button_new_with_label ("+");
G_CALLBACK (cb_button_press), button);
g_signal_connect (button->plus_button, "button-release-event",
G_CALLBACK (cb_button_release), button);
- gtk_box_pack_start (GTK_BOX (box), button->plus_button, TRUE, FALSE, 0);
-
- /* scale */
- priv->scale = gtk_scale_button_scale_new (button, 0., 100., 2.);
- gtk_widget_set_size_request (priv->scale, -1, SCALE_SIZE);
- gtk_scale_set_draw_value (GTK_SCALE (priv->scale), FALSE);
- gtk_range_set_inverted (GTK_RANGE (priv->scale), TRUE);
- gtk_box_pack_start (GTK_BOX (box), priv->scale, TRUE, FALSE, 0);
- g_signal_connect (priv->scale, "grab-notify",
- G_CALLBACK (cb_scale_grab_notify), button);
+ gtk_box_pack_start (GTK_BOX (priv->box), button->plus_button, FALSE, FALSE, 0);
/* - */
button->minus_button = gtk_button_new_with_label ("-");
G_CALLBACK (cb_button_press), button);
g_signal_connect (button->minus_button, "button-release-event",
G_CALLBACK (cb_button_release), button);
- gtk_box_pack_start (GTK_BOX (box), button->minus_button, TRUE, FALSE, 0);
+ gtk_box_pack_end (GTK_BOX (priv->box), button->minus_button, FALSE, FALSE, 0);
+
+ priv->adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 100.0, 2, 20, 0));
+ g_object_ref_sink (priv->adjustment);
+
+ /* the scale */
+ priv->scale = gtk_scale_button_scale_new (button);
+ gtk_container_add (GTK_CONTAINER (priv->box), priv->scale);
+}
+
+static GObject *
+gtk_scale_button_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_params)
+{
+ GObject *object;
+ GtkScaleButton *button;
+ GtkScaleButtonPrivate *priv;
+
+ object = G_OBJECT_CLASS (gtk_scale_button_parent_class)->constructor (type, n_construct_properties, construct_params);
+
+ button = GTK_SCALE_BUTTON (object);
+
+ priv = button->priv;
/* set button text and size */
priv->size = GTK_ICON_SIZE_SMALL_TOOLBAR;
gtk_scale_button_update_icon (button);
+
+ return object;
}
static void
const GValue *value,
GParamSpec *pspec)
{
- GtkScaleButton *button;
-
- button = GTK_SCALE_BUTTON (object);
+ GtkScaleButton *button = GTK_SCALE_BUTTON (object);
switch (prop_id)
{
+ case PROP_ORIENTATION:
+ gtk_scale_button_set_orientation_private (button, g_value_get_enum (value));
+ break;
case PROP_VALUE:
gtk_scale_button_set_value (button, g_value_get_double (value));
break;
GValue *value,
GParamSpec *pspec)
{
- GtkScaleButton *button;
- GtkScaleButtonPrivate *priv;
-
- button = GTK_SCALE_BUTTON (object);
- priv = button->priv;
+ GtkScaleButton *button = GTK_SCALE_BUTTON (object);
+ GtkScaleButtonPrivate *priv = button->priv;
switch (prop_id)
{
+ case PROP_ORIENTATION:
+ g_value_set_enum (value, priv->orientation);
+ break;
case PROP_VALUE:
g_value_set_double (value, gtk_scale_button_get_value (button));
break;
priv->icon_list = NULL;
}
+ if (priv->adjustment)
+ {
+ g_object_unref (priv->adjustment);
+ priv->adjustment = NULL;
+ }
+
G_OBJECT_CLASS (gtk_scale_button_parent_class)->finalize (object);
}
/**
* gtk_scale_button_new:
- * @size: a stock icon size
+ * @size: (int): a stock icon size
* @min: the minimum value of the scale (usually 0)
* @max: the maximum value of the scale (usually 100)
* @step: the stepping of value when a scroll-wheel event,
* or up/down arrow event occurs (usually 2)
- * @icons: a %NULL-terminated array of icon names, or %NULL if
+ * @icons: (allow-none): a %NULL-terminated array of icon names, or %NULL if
* you want to set the list later with gtk_scale_button_set_icons()
*
* Creates a #GtkScaleButton, with a range between @min and @max, with
priv = button->priv;
- return gtk_range_get_value (GTK_RANGE (priv->scale));
+ return gtk_adjustment_get_value (priv->adjustment);
}
/**
GtkAdjustment*
gtk_scale_button_get_adjustment (GtkScaleButton *button)
{
- GtkRange *range;
-
g_return_val_if_fail (GTK_IS_SCALE_BUTTON (button), NULL);
- range = GTK_RANGE (button->priv->scale);
- g_return_val_if_fail (range != NULL, NULL);
-
- return gtk_range_get_adjustment (range);
+ return button->priv->adjustment;
}
/**
GtkAdjustment *adjustment)
{
g_return_if_fail (GTK_IS_SCALE_BUTTON (button));
- g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
+ if (!adjustment)
+ adjustment = (GtkAdjustment*) gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+ else
+ g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
+
+ if (button->priv->adjustment != adjustment)
+ {
+ if (button->priv->adjustment)
+ g_object_unref (button->priv->adjustment);
+ button->priv->adjustment = g_object_ref_sink (adjustment);
- gtk_range_set_adjustment (GTK_RANGE (button->priv->scale),
- adjustment);
+ if (button->priv->scale)
+ gtk_range_set_adjustment (GTK_RANGE (button->priv->scale), adjustment);
- g_object_notify (G_OBJECT (button), "adjustment");
+ g_object_notify (G_OBJECT (button), "adjustment");
+ }
+}
+
+/**
+ * gtk_scale_button_get_orientation:
+ * @button: a #GtkScaleButton
+ *
+ * Gets the orientation of the #GtkScaleButton's popup window.
+ *
+ * Returns: the #GtkScaleButton's orientation.
+ *
+ * Since: 2.14
+ *
+ * Deprecated: 2.16: Use gtk_orientable_get_orientation() instead.
+ **/
+GtkOrientation
+gtk_scale_button_get_orientation (GtkScaleButton *button)
+{
+ g_return_val_if_fail (GTK_IS_SCALE_BUTTON (button), GTK_ORIENTATION_VERTICAL);
+
+ return button->priv->orientation;
+}
+
+/**
+ * gtk_scale_button_set_orientation:
+ * @button: a #GtkScaleButton
+ * @orientation: the new orientation
+ *
+ * Sets the orientation of the #GtkScaleButton's popup window.
+ *
+ * Since: 2.14
+ *
+ * Deprecated: 2.16: Use gtk_orientable_set_orientation() instead.
+ **/
+void
+gtk_scale_button_set_orientation (GtkScaleButton *button,
+ GtkOrientation orientation)
+{
+ g_return_if_fail (GTK_IS_SCALE_BUTTON (button));
+
+ gtk_scale_button_set_orientation_private (button, orientation);
+}
+
+/**
+ * gtk_scale_button_get_plus_button:
+ * @button: a #GtkScaleButton
+ *
+ * Retrieves the plus button of the #GtkScaleButton.
+ *
+ * Returns: the plus button of the #GtkScaleButton.
+ *
+ * Since: 2.14
+ */
+GtkWidget *
+gtk_scale_button_get_plus_button (GtkScaleButton *button)
+{
+ g_return_val_if_fail (GTK_IS_SCALE_BUTTON (button), NULL);
+
+ return button->plus_button;
+}
+
+/**
+ * gtk_scale_button_get_minus_button:
+ * @button: a #GtkScaleButton
+ *
+ * Retrieves the minus button of the #GtkScaleButton.
+ *
+ * Returns: the minus button of the #GtkScaleButton.
+ *
+ * Since: 2.14
+ */
+GtkWidget *
+gtk_scale_button_get_minus_button (GtkScaleButton *button)
+{
+ g_return_val_if_fail (GTK_IS_SCALE_BUTTON (button), NULL);
+
+ return button->minus_button;
+}
+
+/**
+ * gtk_scale_button_get_popup:
+ * @button: a #GtkScaleButton
+ *
+ * Retrieves the popup of the #GtkScaleButton.
+ *
+ * Returns: the popup of the #GtkScaleButton
+ *
+ * Since: 2.14
+ */
+GtkWidget *
+gtk_scale_button_get_popup (GtkScaleButton *button)
+{
+ g_return_val_if_fail (GTK_IS_SCALE_BUTTON (button), NULL);
+
+ return button->priv->dock;
+}
+
+static void
+gtk_scale_button_set_orientation_private (GtkScaleButton *button,
+ GtkOrientation orientation)
+{
+ GtkScaleButtonPrivate *priv = button->priv;
+
+ if (orientation != priv->orientation)
+ {
+ priv->orientation = orientation;
+
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (priv->box),
+ orientation);
+ gtk_container_child_set (GTK_CONTAINER (priv->box),
+ button->plus_button,
+ "pack-type",
+ orientation == GTK_ORIENTATION_VERTICAL ?
+ GTK_PACK_START : GTK_PACK_END,
+ NULL);
+ gtk_container_child_set (GTK_CONTAINER (priv->box),
+ button->minus_button,
+ "pack-type",
+ orientation == GTK_ORIENTATION_VERTICAL ?
+ GTK_PACK_END : GTK_PACK_START,
+ NULL);
+
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (priv->scale),
+ orientation);
+
+ if (orientation == GTK_ORIENTATION_VERTICAL)
+ {
+ gtk_widget_set_size_request (GTK_WIDGET (priv->scale),
+ -1, SCALE_SIZE);
+ gtk_range_set_inverted (GTK_RANGE (priv->scale), TRUE);
+ }
+ else
+ {
+ gtk_widget_set_size_request (GTK_WIDGET (priv->scale),
+ SCALE_SIZE, -1);
+ gtk_range_set_inverted (GTK_RANGE (priv->scale), FALSE);
+ }
+
+ /* FIXME: without this, the popup window appears as a square
+ * after changing the orientation
+ */
+ gtk_window_resize (GTK_WINDOW (priv->dock), 1, 1);
+
+ g_object_notify (G_OBJECT (button), "orientation");
+ }
}
/*
button = GTK_SCALE_BUTTON (widget);
priv = button->priv;
- adj = gtk_range_get_adjustment (GTK_RANGE (priv->scale));
+ adj = priv->adjustment;
if (event->type != GDK_SCROLL)
return FALSE;
GtkScaleButton *button;
GtkScaleButtonPrivate *priv;
GtkAdjustment *adj;
- gint x, y, m, dx, dy, sx, sy, ystartoff;
+ gint x, y, m, dx, dy, sx, sy, startoff;
gdouble v;
GdkDisplay *display;
GdkScreen *screen;
+ gboolean is_moved;
+ is_moved = FALSE;
button = GTK_SCALE_BUTTON (widget);
priv = button->priv;
- adj = gtk_range_get_adjustment (GTK_RANGE (priv->scale));
+ adj = priv->adjustment;
display = gtk_widget_get_display (widget);
screen = gtk_widget_get_screen (widget);
gdk_window_get_origin (widget->window, &x, &y);
x += widget->allocation.x;
y += widget->allocation.y;
- gtk_window_move (GTK_WINDOW (priv->dock), x, y - (SCALE_SIZE / 2));
+
+ if (priv->orientation == GTK_ORIENTATION_VERTICAL)
+ gtk_window_move (GTK_WINDOW (priv->dock), x, y - (SCALE_SIZE / 2));
+ else
+ gtk_window_move (GTK_WINDOW (priv->dock), x - (SCALE_SIZE / 2), y);
+
gtk_widget_show_all (priv->dock);
+
gdk_window_get_origin (priv->dock->window, &dx, &dy);
+ dx += priv->dock->allocation.x;
dy += priv->dock->allocation.y;
+
gdk_window_get_origin (priv->scale->window, &sx, &sy);
+ sx += priv->scale->allocation.x;
sy += priv->scale->allocation.y;
- ystartoff = sy - dy;
+
priv->timeout = TRUE;
/* position (needs widget to be shown already) */
v = gtk_scale_button_get_value (button) / (adj->upper - adj->lower);
- x += (widget->allocation.width - priv->dock->allocation.width) / 2;
- y -= ystartoff;
- y -= GTK_RANGE (priv->scale)->min_slider_size / 2;
- m = priv->scale->allocation.height -
- GTK_RANGE (priv->scale)->min_slider_size;
- y -= m * (1.0 - v);
+
+ if (priv->orientation == GTK_ORIENTATION_VERTICAL)
+ {
+ startoff = sy - dy;
+
+ x += (widget->allocation.width - priv->dock->allocation.width) / 2;
+ y -= startoff;
+ y -= GTK_RANGE (priv->scale)->min_slider_size / 2;
+ m = priv->scale->allocation.height -
+ GTK_RANGE (priv->scale)->min_slider_size;
+ y -= m * (1.0 - v);
+ }
+ else
+ {
+ startoff = sx - dx;
+
+ x -= startoff;
+ y += (widget->allocation.height - priv->dock->allocation.height) / 2;
+ x -= GTK_RANGE (priv->scale)->min_slider_size / 2;
+ m = priv->scale->allocation.width -
+ GTK_RANGE (priv->scale)->min_slider_size;
+ x -= m * v;
+ }
/* Make sure the dock stays inside the monitor */
if (event->type == GDK_BUTTON_PRESS)
button_event->y_root);
gdk_screen_get_monitor_geometry (screen, monitor, &rect);
- y += button_event->y;
- if (y < rect.y)
+ if (priv->orientation == GTK_ORIENTATION_VERTICAL)
+ y += button_event->y;
+ else
+ x += button_event->x;
+
+ /* Move the dock, but set is_moved so we
+ * don't forward the first click later on,
+ * as it could make the scale go to the bottom */
+ if (y < rect.y) {
y = rect.y;
- else if (y + d->allocation.height > rect.height + rect.y)
+ is_moved = TRUE;
+ } else if (y + d->allocation.height > rect.height + rect.y) {
y = rect.y + rect.height - d->allocation.height;
+ is_moved = TRUE;
+ }
- if (x < rect.x)
+ if (x < rect.x) {
x = rect.x;
- else if (x + d->allocation.width > rect.width + rect.x)
+ is_moved = TRUE;
+ } else if (x + d->allocation.width > rect.width + rect.x) {
x = rect.x + rect.width - d->allocation.width;
+ is_moved = TRUE;
+ }
}
gtk_window_move (GTK_WINDOW (priv->dock), x, y);
gtk_widget_grab_focus (priv->dock);
- if (event->type == GDK_BUTTON_PRESS)
+ if (event->type == GDK_BUTTON_PRESS && !is_moved)
{
GdkEventButton *e;
GdkEventButton *button_event = (GdkEventButton *) event;
/* position: the X position isn't relevant, halfway will work just fine.
* The vertical position should be *exactly* in the middle of the slider
* of the scale; if we don't do that correctly, it'll move from its current
- * position, which means a position change on-click, which is bad. */
- e->x = priv->scale->allocation.width / 2;
- m = priv->scale->allocation.height -
- GTK_RANGE (priv->scale)->min_slider_size;
- e->y = ((1.0 - v) * m) + GTK_RANGE (priv->scale)->min_slider_size / 2;
+ * position, which means a position change on-click, which is bad.
+ */
+ if (priv->orientation == GTK_ORIENTATION_VERTICAL)
+ {
+ e->x = priv->scale->allocation.width / 2;
+ m = priv->scale->allocation.height -
+ GTK_RANGE (priv->scale)->min_slider_size;
+ e->y = ((1.0 - v) * m) + GTK_RANGE (priv->scale)->min_slider_size / 2;
+ }
+ else
+ {
+ e->y = priv->scale->allocation.height / 2;
+ m = priv->scale->allocation.width -
+ GTK_RANGE (priv->scale)->min_slider_size;
+ e->x = (v * m) + GTK_RANGE (priv->scale)->min_slider_size / 2;
+ }
+
gtk_widget_event (priv->scale, (GdkEvent *) e);
e->window = button_event->window;
gdk_event_free ((GdkEvent *) e);
}
static void
-gtk_scale_button_popup_from_bindings (GtkWidget *widget)
+gtk_scale_button_popup (GtkWidget *widget)
{
GdkEvent *ev;
priv = button->priv;
- if (!GTK_WIDGET_HAS_GRAB (priv->dock))
+ if (!gtk_widget_has_grab (priv->dock))
return;
if (gtk_widget_is_ancestor (gtk_grab_get_current (), priv->dock))
if (priv->click_id == 0)
return FALSE;
- adj = gtk_range_get_adjustment (GTK_RANGE (priv->scale));
+ adj = priv->adjustment;
val = gtk_scale_button_get_value (button);
val += priv->direction;
button = GTK_SCALE_BUTTON (user_data);
priv = button->priv;
- adj = gtk_range_get_adjustment (GTK_RANGE (priv->scale));
+ adj = priv->adjustment;
if (priv->click_id != 0)
g_source_remove (priv->click_id);
}
static void
-gtk_scale_button_popdown_from_bindings (GtkWidget *widget)
+gtk_scale_button_popdown (GtkWidget *widget)
{
GtkScaleButton *button;
GtkScaleButtonPrivate *priv;
{
if (event->keyval == GDK_Escape)
{
- gtk_scale_button_popdown_from_bindings (GTK_WIDGET (user_data));
+ gtk_scale_button_popdown (GTK_WIDGET (user_data));
return TRUE;
}
* Scale stuff.
*/
-#define GTK_TYPE_SCALE_BUTTON_SCALE \
- (gtk_scale_button_scale_get_type ())
-#define GTK_SCALE_BUTTON_SCALE(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SCALE_BUTTON_SCALE, \
- GtkScaleButtonScale))
-
-typedef struct _GtkScaleButtonScaleClass {
- GtkVScaleClass parent_class;
-} GtkScaleButtonScaleClass;
+#define GTK_TYPE_SCALE_BUTTON_SCALE (_gtk_scale_button_scale_get_type ())
+#define GTK_SCALE_BUTTON_SCALE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SCALE_BUTTON_SCALE, GtkScaleButtonScale))
+#define GTK_IS_SCALE_BUTTON_SCALE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SCALE_BUTTON_SCALE))
-typedef struct _GtkScaleButtonScale {
- GtkVScale parent;
+typedef struct _GtkScaleButtonScale
+{
+ GtkScale parent_instance;
GtkScaleButton *button;
} GtkScaleButtonScale;
-static gboolean gtk_scale_button_scale_press (GtkWidget *widget,
+typedef struct _GtkScaleButtonScaleClass
+{
+ GtkScaleClass parent_class;
+} GtkScaleButtonScaleClass;
+
+static gboolean gtk_scale_button_scale_press (GtkWidget *widget,
GdkEventButton *event);
static gboolean gtk_scale_button_scale_release (GtkWidget *widget,
GdkEventButton *event);
-G_DEFINE_TYPE (GtkScaleButtonScale, gtk_scale_button_scale, GTK_TYPE_VSCALE)
+G_DEFINE_TYPE (GtkScaleButtonScale, _gtk_scale_button_scale, GTK_TYPE_SCALE)
static void
-gtk_scale_button_scale_class_init (GtkScaleButtonScaleClass *klass)
+_gtk_scale_button_scale_class_init (GtkScaleButtonScaleClass *klass)
{
GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS (klass);
GtkRangeClass *gtkrange_class = GTK_RANGE_CLASS (klass);
}
static void
-gtk_scale_button_scale_init (GtkScaleButtonScale *scale)
+_gtk_scale_button_scale_init (GtkScaleButtonScale *scale)
{
}
static GtkWidget *
-gtk_scale_button_scale_new (GtkScaleButton *button,
- gdouble min,
- gdouble max,
- gdouble step)
+gtk_scale_button_scale_new (GtkScaleButton *button)
{
+ GtkScaleButtonPrivate *priv = button->priv;
GtkScaleButtonScale *scale;
- GtkScaleButtonPrivate *priv;
- GtkObject *adj;
- priv = button->priv;
- scale = g_object_new (GTK_TYPE_SCALE_BUTTON_SCALE, NULL);
- adj = gtk_adjustment_new (min, min, max, step, 10 * step, 0);
- gtk_range_set_adjustment (GTK_RANGE (scale), GTK_ADJUSTMENT (adj));
+ scale = g_object_new (GTK_TYPE_SCALE_BUTTON_SCALE,
+ "orientation", priv->orientation,
+ "adjustment", priv->adjustment,
+ "draw-value", FALSE,
+ NULL);
+
scale->button = button;
+ g_signal_connect (scale, "grab-notify",
+ G_CALLBACK (cb_scale_grab_notify), button);
+
+ if (priv->orientation == GTK_ORIENTATION_VERTICAL)
+ {
+ gtk_widget_set_size_request (GTK_WIDGET (scale), -1, SCALE_SIZE);
+ gtk_range_set_inverted (GTK_RANGE (scale), TRUE);
+ }
+ else
+ {
+ gtk_widget_set_size_request (GTK_WIDGET (scale), SCALE_SIZE, -1);
+ gtk_range_set_inverted (GTK_RANGE (scale), FALSE);
+ }
+
return GTK_WIDGET (scale);
}
gtk_scale_button_scale_press (GtkWidget *widget,
GdkEventButton *event)
{
- GtkScaleButtonScale *scale;
- GtkScaleButtonPrivate *priv;
-
- scale = GTK_SCALE_BUTTON_SCALE (widget);
- priv = scale->button->priv;
+ GtkScaleButtonPrivate *priv = GTK_SCALE_BUTTON_SCALE (widget)->button->priv;
/* the scale will grab input; if we have input grabbed, all goes
- * horribly wrong, so let's not do that. */
+ * horribly wrong, so let's not do that.
+ */
gtk_grab_remove (priv->dock);
- return GTK_WIDGET_CLASS (gtk_scale_button_scale_parent_class)->button_press_event (widget, event);
+ return GTK_WIDGET_CLASS (_gtk_scale_button_scale_parent_class)->button_press_event (widget, event);
}
static gboolean
gtk_scale_button_scale_release (GtkWidget *widget,
GdkEventButton *event)
{
- GtkScaleButtonScale *scale;
- GtkScaleButtonPrivate *priv;
- GtkWidgetClass *widget_class;
+ GtkScaleButton *button = GTK_SCALE_BUTTON_SCALE (widget)->button;
gboolean res;
- scale = GTK_SCALE_BUTTON_SCALE (widget);
- priv = scale->button->priv;
-
- widget_class = GTK_WIDGET_CLASS (gtk_scale_button_scale_parent_class);
-
- if (priv->timeout)
+ if (button->priv->timeout)
{
/* if we did a quick click, leave the window open; else, hide it */
- if (event->time > priv->pop_time + priv->click_timeout)
+ if (event->time > button->priv->pop_time + button->priv->click_timeout)
{
- gtk_scale_button_release_grab (scale->button, event);
- widget_class->button_release_event (widget, event);
+ gtk_scale_button_release_grab (button, event);
+ GTK_WIDGET_CLASS (_gtk_scale_button_scale_parent_class)->button_release_event (widget, event);
return TRUE;
}
- priv->timeout = FALSE;
+ button->priv->timeout = FALSE;
}
- res = widget_class->button_release_event (widget, event);
+ res = GTK_WIDGET_CLASS (_gtk_scale_button_scale_parent_class)->button_release_event (widget, event);
/* the scale will release input; right after that, we *have to* grab
* it back so we can catch out-of-scale clicks and hide the popup,
* so I basically want a g_signal_connect_after_always(), but I can't
* find that, so we do this complex 'first-call-parent-then-do-actual-
- * action' thingy... */
- gtk_grab_add (priv->dock);
+ * action' thingy...
+ */
+ gtk_grab_add (button->priv->dock);
return res;
}
}
range = GTK_RANGE (priv->scale);
- adj = gtk_range_get_adjustment (range);
+ adj = priv->adjustment;
value = gtk_scale_button_get_value (button);
/* The 2-icons special case */
static void
gtk_scale_button_scale_value_changed (GtkRange *range)
{
- GtkScaleButtonScale *scale = GTK_SCALE_BUTTON_SCALE (range);
- GtkScaleButton *button = scale->button;
+ GtkScaleButton *button = GTK_SCALE_BUTTON_SCALE (range)->button;
gdouble value;
value = gtk_range_get_value (range);