X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkcellrenderertoggle.c;h=efce7708be0a6dccbbd941cc56271179f7258578;hb=7b29d57a352efaa80f9abb42a90ff8ec0ed9459d;hp=66f20eccae27107b36c8e3f52f3055656acdc33c;hpb=35af5c4eba6c95646a5719bae796ece1dbf92275;p=~andy%2Fgtk diff --git a/gtk/gtkcellrenderertoggle.c b/gtk/gtkcellrenderertoggle.c index 66f20ecca..efce7708b 100644 --- a/gtk/gtkcellrenderertoggle.c +++ b/gtk/gtkcellrenderertoggle.c @@ -18,9 +18,10 @@ */ #include -#include -#include +#include "gtkcellrenderertoggle.h" #include "gtkintl.h" +#include "gtkmarshalers.h" +#include "gtktreeprivate.h" static void gtk_cell_renderer_toggle_get_property (GObject *object, guint param_id, @@ -34,6 +35,9 @@ static void gtk_cell_renderer_toggle_init (GtkCellRendererToggle *cel static void gtk_cell_renderer_toggle_class_init (GtkCellRendererToggleClass *class); static void gtk_cell_renderer_toggle_get_size (GtkCellRenderer *cell, GtkWidget *widget, + GdkRectangle *cell_area, + gint *x_offset, + gint *y_offset, gint *width, gint *height); static void gtk_cell_renderer_toggle_render (GtkCellRenderer *cell, @@ -42,14 +46,14 @@ static void gtk_cell_renderer_toggle_render (GtkCellRenderer *cel GdkRectangle *background_area, GdkRectangle *cell_area, GdkRectangle *expose_area, - guint flags); -static gint gtk_cell_renderer_toggle_event (GtkCellRenderer *cell, - GdkEvent *event, - GtkWidget *widget, - gchar *path, - GdkRectangle *background_area, - GdkRectangle *cell_area, - guint flags); + GtkCellRendererState flags); +static gboolean gtk_cell_renderer_toggle_activate (GtkCellRenderer *cell, + GdkEvent *event, + GtkWidget *widget, + const gchar *path, + GdkRectangle *background_area, + GdkRectangle *cell_area, + GtkCellRendererState flags); enum { @@ -59,20 +63,29 @@ enum { enum { PROP_ZERO, + PROP_ACTIVATABLE, PROP_ACTIVE, - PROP_RADIO + PROP_RADIO, + PROP_INCONSISTENT }; - #define TOGGLE_WIDTH 12 static guint toggle_cell_signals[LAST_SIGNAL] = { 0 }; +#define GTK_CELL_RENDERER_TOGGLE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_CELL_RENDERER_TOGGLE, GtkCellRendererTogglePrivate)) + +typedef struct _GtkCellRendererTogglePrivate GtkCellRendererTogglePrivate; +struct _GtkCellRendererTogglePrivate +{ + guint inconsistent : 1; +}; + -GtkType +GType gtk_cell_renderer_toggle_get_type (void) { - static GtkType cell_toggle_type = 0; + static GType cell_toggle_type = 0; if (!cell_toggle_type) { @@ -89,7 +102,9 @@ gtk_cell_renderer_toggle_get_type (void) (GInstanceInitFunc) gtk_cell_renderer_toggle_init, }; - cell_toggle_type = g_type_register_static (GTK_TYPE_CELL_RENDERER, "GtkCellRendererToggle", &cell_toggle_info, 0); + cell_toggle_type = + g_type_register_static (GTK_TYPE_CELL_RENDERER, "GtkCellRendererToggle", + &cell_toggle_info, 0); } return cell_toggle_type; @@ -98,8 +113,10 @@ gtk_cell_renderer_toggle_get_type (void) static void gtk_cell_renderer_toggle_init (GtkCellRendererToggle *celltoggle) { + celltoggle->activatable = TRUE; celltoggle->active = FALSE; celltoggle->radio = FALSE; + GTK_CELL_RENDERER (celltoggle)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE; GTK_CELL_RENDERER (celltoggle)->xpad = 2; GTK_CELL_RENDERER (celltoggle)->ypad = 2; } @@ -115,35 +132,56 @@ gtk_cell_renderer_toggle_class_init (GtkCellRendererToggleClass *class) cell_class->get_size = gtk_cell_renderer_toggle_get_size; cell_class->render = gtk_cell_renderer_toggle_render; - cell_class->event = gtk_cell_renderer_toggle_event; + cell_class->activate = gtk_cell_renderer_toggle_activate; g_object_class_install_property (object_class, PROP_ACTIVE, g_param_spec_boolean ("active", - _("Toggle state"), - _("The toggle state of the button"), + P_("Toggle state"), + P_("The toggle state of the button"), + FALSE, + G_PARAM_READABLE | + G_PARAM_WRITABLE)); + + g_object_class_install_property (object_class, + PROP_INCONSISTENT, + g_param_spec_boolean ("inconsistent", + P_("Inconsistent state"), + P_("The inconsistent state of the button"), FALSE, G_PARAM_READABLE | G_PARAM_WRITABLE)); + g_object_class_install_property (object_class, + PROP_ACTIVATABLE, + g_param_spec_boolean ("activatable", + P_("Activatable"), + P_("The toggle button can be activated"), + TRUE, + G_PARAM_READABLE | + G_PARAM_WRITABLE)); + g_object_class_install_property (object_class, PROP_RADIO, g_param_spec_boolean ("radio", - _("Radio state"), - _("Draw the toggle button as a radio button"), + P_("Radio state"), + P_("Draw the toggle button as a radio button"), FALSE, G_PARAM_READABLE | G_PARAM_WRITABLE)); toggle_cell_signals[TOGGLED] = - gtk_signal_new ("toggled", - GTK_RUN_LAST, - GTK_CLASS_TYPE (object_class), - GTK_SIGNAL_OFFSET (GtkCellRendererToggleClass, toggled), - gtk_marshal_VOID__POINTER, - GTK_TYPE_NONE, 1, - GTK_TYPE_POINTER); + g_signal_new ("toggled", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GtkCellRendererToggleClass, toggled), + NULL, NULL, + _gtk_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); + + g_type_class_add_private (object_class, sizeof (GtkCellRendererTogglePrivate)); } static void @@ -153,12 +191,21 @@ gtk_cell_renderer_toggle_get_property (GObject *object, GParamSpec *pspec) { GtkCellRendererToggle *celltoggle = GTK_CELL_RENDERER_TOGGLE (object); + GtkCellRendererTogglePrivate *priv; + + priv = GTK_CELL_RENDERER_TOGGLE_GET_PRIVATE (object); switch (param_id) { case PROP_ACTIVE: g_value_set_boolean (value, celltoggle->active); break; + case PROP_INCONSISTENT: + g_value_set_boolean (value, priv->inconsistent); + break; + case PROP_ACTIVATABLE: + g_value_set_boolean (value, celltoggle->activatable); + break; case PROP_RADIO: g_value_set_boolean (value, celltoggle->radio); break; @@ -176,6 +223,9 @@ gtk_cell_renderer_toggle_set_property (GObject *object, GParamSpec *pspec) { GtkCellRendererToggle *celltoggle = GTK_CELL_RENDERER_TOGGLE (object); + GtkCellRendererTogglePrivate *priv; + + priv = GTK_CELL_RENDERER_TOGGLE_GET_PRIVATE (object); switch (param_id) { @@ -183,6 +233,14 @@ gtk_cell_renderer_toggle_set_property (GObject *object, celltoggle->active = g_value_get_boolean (value); g_object_notify (G_OBJECT(object), "active"); break; + case PROP_INCONSISTENT: + priv->inconsistent = g_value_get_boolean (value); + g_object_notify (G_OBJECT (object), "inconsistent"); + break; + case PROP_ACTIVATABLE: + celltoggle->activatable = g_value_get_boolean (value); + g_object_notify (G_OBJECT(object), "activatable"); + break; case PROP_RADIO: celltoggle->radio = g_value_get_boolean (value); g_object_notify (G_OBJECT(object), "radio"); @@ -209,105 +267,134 @@ gtk_cell_renderer_toggle_set_property (GObject *object, GtkCellRenderer * gtk_cell_renderer_toggle_new (void) { - return GTK_CELL_RENDERER (gtk_type_new (gtk_cell_renderer_toggle_get_type ())); + return g_object_new (GTK_TYPE_CELL_RENDERER_TOGGLE, NULL); } static void gtk_cell_renderer_toggle_get_size (GtkCellRenderer *cell, GtkWidget *widget, + GdkRectangle *cell_area, + gint *x_offset, + gint *y_offset, gint *width, gint *height) { + gint calc_width; + gint calc_height; + + calc_width = (gint) cell->xpad * 2 + TOGGLE_WIDTH; + calc_height = (gint) cell->ypad * 2 + TOGGLE_WIDTH; + if (width) - *width = (gint) cell->xpad * 2 + TOGGLE_WIDTH; + *width = calc_width; if (height) - *height = (gint) cell->ypad * 2 + TOGGLE_WIDTH; + *height = calc_height; + + if (cell_area) + { + if (x_offset) + { + *x_offset = ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ? + (1.0 - cell->xalign) : cell->xalign) * (cell_area->width - calc_width); + *x_offset = MAX (*x_offset, 0); + } + if (y_offset) + { + *y_offset = cell->yalign * (cell_area->height - calc_height); + *y_offset = MAX (*y_offset, 0); + } + } } static void -gtk_cell_renderer_toggle_render (GtkCellRenderer *cell, - GdkWindow *window, - GtkWidget *widget, - GdkRectangle *background_area, - GdkRectangle *cell_area, - GdkRectangle *expose_area, - guint flags) +gtk_cell_renderer_toggle_render (GtkCellRenderer *cell, + GdkDrawable *window, + GtkWidget *widget, + GdkRectangle *background_area, + GdkRectangle *cell_area, + GdkRectangle *expose_area, + GtkCellRendererState flags) { GtkCellRendererToggle *celltoggle = (GtkCellRendererToggle *) cell; + GtkCellRendererTogglePrivate *priv; gint width, height; - gint real_xoffset, real_yoffset; + gint x_offset, y_offset; GtkShadowType shadow; - GtkStateType state; - - width = MIN (TOGGLE_WIDTH, cell_area->width - cell->xpad * 2); - height = MIN (TOGGLE_WIDTH, cell_area->height - cell->ypad * 2); + GtkStateType state = 0; + + priv = GTK_CELL_RENDERER_TOGGLE_GET_PRIVATE (cell); + + gtk_cell_renderer_toggle_get_size (cell, widget, cell_area, + &x_offset, &y_offset, + &width, &height); + width -= cell->xpad*2; + height -= cell->ypad*2; if (width <= 0 || height <= 0) return; - real_xoffset = cell->xalign * (cell_area->width - width - (2 * cell->xpad)); - real_xoffset = MAX (real_xoffset, 0) + cell->xpad; - real_yoffset = cell->yalign * (cell_area->height - height - (2 * cell->ypad)); - real_yoffset = MAX (real_yoffset, 0) + cell->ypad; - - shadow = celltoggle->active ? GTK_SHADOW_IN : GTK_SHADOW_OUT; + if (priv->inconsistent) + shadow = GTK_SHADOW_ETCHED_IN; + else + shadow = celltoggle->active ? GTK_SHADOW_IN : GTK_SHADOW_OUT; if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED) - state = GTK_STATE_SELECTED; + { + if (GTK_WIDGET_HAS_FOCUS (widget)) + state = GTK_STATE_SELECTED; + else + state = GTK_STATE_ACTIVE; + } else - state = GTK_STATE_NORMAL; - + { + if (celltoggle->activatable) + state = GTK_STATE_NORMAL; + else + state = GTK_STATE_INSENSITIVE; + } + if (celltoggle->radio) { gtk_paint_option (widget->style, window, state, shadow, - cell_area, widget, "cellradio", - cell_area->x + real_xoffset, - cell_area->y + real_yoffset, - width, height); + expose_area, widget, "cellradio", + cell_area->x + x_offset + cell->xpad, + cell_area->y + y_offset + cell->ypad, + width - 1, height - 1); } else { gtk_paint_check (widget->style, window, state, shadow, - cell_area, widget, "cellcheck", - cell_area->x + real_xoffset, - cell_area->y + real_yoffset, - width, height); + expose_area, widget, "cellcheck", + cell_area->x + x_offset + cell->xpad, + cell_area->y + y_offset + cell->ypad, + width - 1, height - 1); } } static gint -gtk_cell_renderer_toggle_event (GtkCellRenderer *cell, - GdkEvent *event, - GtkWidget *widget, - gchar *path, - GdkRectangle *background_area, - GdkRectangle *cell_area, - guint flags) +gtk_cell_renderer_toggle_activate (GtkCellRenderer *cell, + GdkEvent *event, + GtkWidget *widget, + const gchar *path, + GdkRectangle *background_area, + GdkRectangle *cell_area, + GtkCellRendererState flags) { GtkCellRendererToggle *celltoggle; - gint retval = FALSE; celltoggle = GTK_CELL_RENDERER_TOGGLE (cell); - - switch (event->type) + if (celltoggle->activatable) { - case GDK_BUTTON_PRESS: - { - gtk_signal_emit (GTK_OBJECT (cell), toggle_cell_signals[TOGGLED], path); - retval = TRUE; - } - break; - - default: - break; + g_signal_emit (cell, toggle_cell_signals[TOGGLED], 0, path); + return TRUE; } - - return retval; + + return FALSE; } /** @@ -335,6 +422,8 @@ gtk_cell_renderer_toggle_set_radio (GtkCellRendererToggle *toggle, /** * gtk_cell_renderer_toggle_get_radio: * @toggle: a #GtkCellRendererToggle + * + * Returns wether we're rendering radio toggles rather than checkboxes. * * Return value: %TRUE if we're rendering radio toggles rather than checkboxes **/ @@ -346,6 +435,15 @@ gtk_cell_renderer_toggle_get_radio (GtkCellRendererToggle *toggle) return toggle->radio; } +/** + * gtk_cell_renderer_toggle_get_active: + * @toggle: a #GtkCellRendererToggle + * + * Returns whether the cell renderer is active. See + * gtk_cell_renderer_toggle_set_active(). + * + * Return value: %TRUE if the cell renderer is active. + **/ gboolean gtk_cell_renderer_toggle_get_active (GtkCellRendererToggle *toggle) { @@ -354,11 +452,18 @@ gtk_cell_renderer_toggle_get_active (GtkCellRendererToggle *toggle) return toggle->active; } +/** + * gtk_cell_renderer_toggle_set_active: + * @toggle: a #GtkCellRendererToggle. + * @setting: the value to set. + * + * Activates or deactivates a cell renderer. + **/ void gtk_cell_renderer_toggle_set_active (GtkCellRendererToggle *toggle, gboolean setting) { g_return_if_fail (GTK_IS_CELL_RENDERER_TOGGLE (toggle)); - g_object_set (G_OBJECT (toggle), "active", !! setting, NULL); + g_object_set (toggle, "active", setting ? TRUE : FALSE, NULL); }