make the orientation flipping much simpler by using the GtkOrientable

2009-02-19  Michael Natterer  <mitch@imendio.com>

	* gtk/gtkscalebutton.c: make the orientation flipping much simpler
	by using the GtkOrientable features of the involved widgets:

	(gtk_scale_button_init): create the frame, box and scale here,
	they never need to be recreated because they implement GtkOrientable.

	(gtk_scale_button_constructor): remove their construction here.

	(gtk_scale_button_set_orientation): don't destroy and re-create
	anything. Instead, simply set the orientation of the above created
	widgets and fiddle a bit with the "plus" and "minus" buttons'
	packing and the scale's "inverted" state.

	Remove separate internal GtkScaleButtonHScale and
	GtkScaleButtonVScale subclasses and simply have a
	GtkScaleButtonScale directly inherited from GtkScale.


svn path=/trunk/; revision=22375
This commit is contained in:
Michael Natterer 2009-02-19 15:10:34 +00:00 committed by Michael Natterer
parent 72e75a5d93
commit 9da282480f
2 changed files with 122 additions and 159 deletions

View File

@ -1,3 +1,22 @@
2009-02-19 Michael Natterer <mitch@imendio.com>
* gtk/gtkscalebutton.c: make the orientation flipping much simpler
by using the GtkOrientable features of the involved widgets:
(gtk_scale_button_init): create the frame, box and scale here,
they never need to be recreated because they implement GtkOrientable.
(gtk_scale_button_constructor): remove their construction here.
(gtk_scale_button_set_orientation): don't destroy and re-create
anything. Instead, simply set the orientation of the above created
widgets and fiddle a bit with the "plus" and "minus" buttons'
packing and the scale's "inverted" state.
Remove separate internal GtkScaleButtonHScale and
GtkScaleButtonVScale subclasses and simply have a
GtkScaleButtonScale directly inherited from GtkScale.
2009-02-19 Theppitak Karoonboonyanan <thep@linux.thai.net>
* modules/input/gtkimcontextthai.c (is_context_lost_key): Revert the

View File

@ -45,21 +45,19 @@
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk/gdkkeysyms.h>
#include "gtkmain.h"
#include "gtkintl.h"
#include "gtkbindings.h"
#include "gtkhscale.h"
#include "gtkvscale.h"
#include "gtkframe.h"
#include "gtkmain.h"
#include "gtkmarshalers.h"
#include "gtkorientable.h"
#include "gtkhbox.h"
#include "gtkprivate.h"
#include "gtkscale.h"
#include "gtkscalebutton.h"
#include "gtkstock.h"
#include "gtkvbox.h"
#include "gtkwindow.h"
#include "gtkmarshalers.h"
#include "gtkstock.h"
#include "gtkprivate.h"
#include "gtkscalebutton.h"
#include "gtkintl.h"
#include "gtkalias.h"
#define SCALE_SIZE 100
@ -90,6 +88,7 @@ enum
struct _GtkScaleButtonPrivate
{
GtkWidget *dock;
GtkWidget *box;
GtkWidget *scale;
GtkWidget *image;
@ -155,7 +154,7 @@ static void gtk_scale_button_update_icon (GtkScaleButton *button);
static void gtk_scale_button_scale_value_changed(GtkRange *range);
/* see below for scale definitions */
static GtkWidget *gtk_scale_button_scale_box_new(GtkScaleButton *button);
static GtkWidget *gtk_scale_button_scale_new (GtkScaleButton *button);
G_DEFINE_TYPE_WITH_CODE (GtkScaleButton, gtk_scale_button, GTK_TYPE_BUTTON,
G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE,
@ -188,6 +187,11 @@ gtk_scale_button_class_init (GtkScaleButtonClass *klass)
*
* 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,
@ -332,6 +336,7 @@ static void
gtk_scale_button_init (GtkScaleButton *button)
{
GtkScaleButtonPrivate *priv;
GtkWidget *frame;
button->priv = priv = GET_PRIVATE (button);
@ -361,6 +366,15 @@ gtk_scale_button_init (GtkScaleButton *button)
G_CALLBACK (cb_dock_grab_broken_event), button);
gtk_window_set_decorated (GTK_WINDOW (priv->dock), FALSE);
/* frame */
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 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 ("+");
gtk_button_set_relief (GTK_BUTTON (button->plus_button), GTK_RELIEF_NONE);
@ -368,6 +382,7 @@ gtk_scale_button_init (GtkScaleButton *button)
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 (priv->box), button->plus_button, FALSE, FALSE, 0);
/* - */
button->minus_button = gtk_button_new_with_label ("-");
@ -376,9 +391,14 @@ gtk_scale_button_init (GtkScaleButton *button)
G_CALLBACK (cb_button_press), button);
g_signal_connect (button->minus_button, "button-release-event",
G_CALLBACK (cb_button_release), button);
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 *
@ -388,7 +408,6 @@ gtk_scale_button_constructor (GType type,
{
GObject *object;
GtkScaleButton *button;
GtkWidget *frame, *box;
GtkScaleButtonPrivate *priv;
object = G_OBJECT_CLASS (gtk_scale_button_parent_class)->constructor (type, n_construct_properties, construct_params);
@ -397,15 +416,6 @@ gtk_scale_button_constructor (GType type,
priv = button->priv;
/* frame */
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 with scale and +/- buttons */
box = gtk_scale_button_scale_box_new (button);
gtk_container_add (GTK_CONTAINER (frame), box);
/* set button text and size */
priv->size = GTK_ICON_SIZE_SMALL_TOOLBAR;
gtk_scale_button_update_icon (button);
@ -739,30 +749,41 @@ gtk_scale_button_set_orientation (GtkScaleButton *button,
{
priv->orientation = orientation;
if (priv->scale)
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)
{
GtkWidget *box = priv->scale->parent;
GtkWidget *frame = box->parent;
g_object_ref (button->plus_button);
g_object_ref (button->minus_button);
gtk_container_remove (GTK_CONTAINER (box), button->plus_button);
gtk_container_remove (GTK_CONTAINER (box), button->minus_button);
gtk_container_remove (GTK_CONTAINER (box), priv->scale);
gtk_container_remove (GTK_CONTAINER (frame), box);
box = gtk_scale_button_scale_box_new (button);
gtk_container_add (GTK_CONTAINER (frame), box);
/* 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_unref (button->plus_button);
g_object_unref (button->minus_button);
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");
}
@ -1328,43 +1349,30 @@ cb_scale_grab_notify (GtkWidget *widget,
* Scale stuff.
*/
#define GTK_TYPE_SCALE_BUTTON_VSCALE (_gtk_scale_button_vscale_get_type ())
#define GTK_SCALE_BUTTON_VSCALE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SCALE_BUTTON_VSCALE, GtkScaleButtonVScale))
#define GTK_IS_SCALE_BUTTON_VSCALE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SCALE_BUTTON_VSCALE))
#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 _GtkScaleButtonVScale {
GtkVScale parent;
typedef struct _GtkScaleButtonScale
{
GtkScale parent_instance;
GtkScaleButton *button;
} GtkScaleButtonVScale;
} GtkScaleButtonScale;
typedef struct _GtkScaleButtonVScaleClass {
GtkVScaleClass parent_class;
} GtkScaleButtonVScaleClass;
#define GTK_TYPE_SCALE_BUTTON_HSCALE (_gtk_scale_button_hscale_get_type ())
#define GTK_SCALE_BUTTON_HSCALE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SCALE_BUTTON_HSCALE, GtkScaleButtonHScale))
#define GTK_IS_SCALE_BUTTON_HSCALE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SCALE_BUTTON_HSCALE))
typedef struct _GtkScaleButtonHScale {
GtkVScale parent;
GtkScaleButton *button;
} GtkScaleButtonHScale;
typedef struct _GtkScaleButtonHScaleClass {
GtkVScaleClass parent_class;
} GtkScaleButtonHScaleClass;
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 (GtkScaleButtonVScale, _gtk_scale_button_vscale, GTK_TYPE_VSCALE)
G_DEFINE_TYPE (GtkScaleButtonHScale, _gtk_scale_button_hscale, GTK_TYPE_HSCALE)
G_DEFINE_TYPE (GtkScaleButtonScale, _gtk_scale_button_scale, GTK_TYPE_SCALE)
static void
_gtk_scale_button_vscale_class_init (GtkScaleButtonVScaleClass *klass)
_gtk_scale_button_scale_class_init (GtkScaleButtonScaleClass *klass)
{
GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS (klass);
GtkRangeClass *gtkrange_class = GTK_RANGE_CLASS (klass);
@ -1375,121 +1383,62 @@ _gtk_scale_button_vscale_class_init (GtkScaleButtonVScaleClass *klass)
}
static void
_gtk_scale_button_hscale_class_init (GtkScaleButtonHScaleClass *klass)
{
GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS (klass);
GtkRangeClass *gtkrange_class = GTK_RANGE_CLASS (klass);
gtkwidget_class->button_press_event = gtk_scale_button_scale_press;
gtkwidget_class->button_release_event = gtk_scale_button_scale_release;
gtkrange_class->value_changed = gtk_scale_button_scale_value_changed;
}
static void
_gtk_scale_button_vscale_init (GtkScaleButtonVScale *scale)
{
}
static void
_gtk_scale_button_hscale_init (GtkScaleButtonHScale *scale)
_gtk_scale_button_scale_init (GtkScaleButtonScale *scale)
{
}
static GtkWidget *
gtk_scale_button_scale_box_new (GtkScaleButton *button)
gtk_scale_button_scale_new (GtkScaleButton *button)
{
GtkScaleButtonPrivate *priv = button->priv;
GtkScaleButtonVScale *scale;
GtkWidget *box;
GtkScaleButtonScale *scale;
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)
{
box = gtk_vbox_new (FALSE, 0);
scale = g_object_new (GTK_TYPE_SCALE_BUTTON_VSCALE, NULL);
priv->scale = GTK_WIDGET (scale);
gtk_widget_set_size_request (priv->scale, -1, SCALE_SIZE);
gtk_range_set_inverted (GTK_RANGE (priv->scale), TRUE);
gtk_box_pack_start (GTK_BOX (box), button->plus_button, TRUE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box), priv->scale, TRUE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box), button->minus_button, TRUE, FALSE, 0);
gtk_widget_set_size_request (GTK_WIDGET (scale), -1, SCALE_SIZE);
gtk_range_set_inverted (GTK_RANGE (scale), TRUE);
}
else
{
box = gtk_hbox_new (FALSE, 0);
scale = g_object_new (GTK_TYPE_SCALE_BUTTON_HSCALE, NULL);
priv->scale = GTK_WIDGET (scale);
gtk_widget_set_size_request (priv->scale, SCALE_SIZE, -1);
gtk_box_pack_start (GTK_BOX (box), button->minus_button, TRUE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box), priv->scale, TRUE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (box), button->plus_button, TRUE, FALSE, 0);
gtk_widget_set_size_request (GTK_WIDGET (scale), SCALE_SIZE, -1);
gtk_range_set_inverted (GTK_RANGE (scale), FALSE);
}
gtk_scale_set_draw_value (GTK_SCALE (priv->scale), FALSE);
gtk_range_set_adjustment (GTK_RANGE (scale),
GTK_ADJUSTMENT (priv->adjustment));
scale->button = button;
g_signal_connect (priv->scale, "grab-notify",
G_CALLBACK (cb_scale_grab_notify), button);
/* FIXME: without this, the popup window appears as a square
* after changing the orientation
*/
gtk_window_resize (GTK_WINDOW (priv->dock), 1, 1);
return box;
return GTK_WIDGET (scale);
}
static gboolean
gtk_scale_button_scale_press (GtkWidget *widget,
GdkEventButton *event)
{
GtkScaleButtonPrivate *priv;
GtkWidgetClass *widget_class;
if (GTK_IS_SCALE_BUTTON_VSCALE (widget))
{
priv = GTK_SCALE_BUTTON_VSCALE (widget)->button->priv;
widget_class = GTK_WIDGET_CLASS (_gtk_scale_button_vscale_parent_class);
}
else
{
priv = GTK_SCALE_BUTTON_HSCALE (widget)->button->priv;
widget_class = GTK_WIDGET_CLASS (_gtk_scale_button_hscale_parent_class);
}
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 widget_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)
{
GtkScaleButton *button;
GtkWidgetClass *widget_class;
GtkScaleButton *button = GTK_SCALE_BUTTON_SCALE (widget)->button;
gboolean res;
if (GTK_IS_SCALE_BUTTON_VSCALE (widget))
{
button = GTK_SCALE_BUTTON_VSCALE (widget)->button;
widget_class = GTK_WIDGET_CLASS (_gtk_scale_button_vscale_parent_class);
}
else
{
button = GTK_SCALE_BUTTON_HSCALE (widget)->button;
widget_class = GTK_WIDGET_CLASS (_gtk_scale_button_hscale_parent_class);
}
if (button->priv->timeout)
{
/* if we did a quick click, leave the window open; else, hide it */
@ -1497,7 +1446,7 @@ gtk_scale_button_scale_release (GtkWidget *widget,
{
gtk_scale_button_release_grab (button, event);
widget_class->button_release_event (widget, event);
GTK_WIDGET_CLASS (_gtk_scale_button_scale_parent_class)->button_release_event (widget, event);
return TRUE;
}
@ -1505,7 +1454,7 @@ gtk_scale_button_scale_release (GtkWidget *widget,
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,
@ -1597,14 +1546,9 @@ gtk_scale_button_update_icon (GtkScaleButton *button)
static void
gtk_scale_button_scale_value_changed (GtkRange *range)
{
GtkScaleButton *button;
GtkScaleButton *button = GTK_SCALE_BUTTON_SCALE (range)->button;
gdouble value;
if (GTK_IS_SCALE_BUTTON_VSCALE (range))
button = GTK_SCALE_BUTTON_VSCALE (range)->button;
else
button = GTK_SCALE_BUTTON_HSCALE (range)->button;
value = gtk_range_get_value (range);
gtk_scale_button_update_icon (button);