521 lines
18 KiB
Diff
521 lines
18 KiB
Diff
--- gtk+-2.6.4/gtk/gtkcheckbutton.c 2004-08-09 19:59:51.000000000 +0300
|
|
+++ gtk+-2.6.4/gtk/gtkcheckbutton.c 2005-04-06 16:19:36.317017336 +0300
|
|
@@ -31,27 +31,44 @@
|
|
#include "gtklabel.h"
|
|
|
|
|
|
-#define INDICATOR_SIZE 13
|
|
+#define INDICATOR_SIZE 24
|
|
#define INDICATOR_SPACING 2
|
|
|
|
+/* maJiK numbers for indicator */
|
|
+#define INDICATOR_SIDE_PADDING 5
|
|
+#define FOCUS_TOP_PADDING 7
|
|
+#define FOCUS_DOWN_PADDING 1
|
|
+
|
|
+/* spacing to take account of the 1 pixel
|
|
+ transparency of the widgetfocus.png
|
|
+*/
|
|
+#define HILDON_SPACING 1
|
|
+
|
|
+#define TOGGLE_ON_CLICK "toggle-on-click"
|
|
|
|
-static void gtk_check_button_class_init (GtkCheckButtonClass *klass);
|
|
-static void gtk_check_button_init (GtkCheckButton *check_button);
|
|
-static void gtk_check_button_size_request (GtkWidget *widget,
|
|
- GtkRequisition *requisition);
|
|
-static void gtk_check_button_size_allocate (GtkWidget *widget,
|
|
- GtkAllocation *allocation);
|
|
-static gint gtk_check_button_expose (GtkWidget *widget,
|
|
- GdkEventExpose *event);
|
|
-static void gtk_check_button_paint (GtkWidget *widget,
|
|
- GdkRectangle *area);
|
|
-static void gtk_check_button_draw_indicator (GtkCheckButton *check_button,
|
|
- GdkRectangle *area);
|
|
-static void gtk_real_check_button_draw_indicator (GtkCheckButton *check_button,
|
|
- GdkRectangle *area);
|
|
+static void gtk_check_button_class_init (GtkCheckButtonClass *klass);
|
|
+static void gtk_check_button_init (GtkCheckButton *check_button);
|
|
+static void gtk_check_button_size_request (GtkWidget *widget,
|
|
+ GtkRequisition *requisition);
|
|
+static void gtk_check_button_size_allocate (GtkWidget *widget,
|
|
+ GtkAllocation *allocation);
|
|
+static gint gtk_check_button_expose (GtkWidget *widget,
|
|
+ GdkEventExpose *event);
|
|
+static void gtk_check_button_paint (GtkWidget *widget,
|
|
+ GdkRectangle *area);
|
|
+static void gtk_check_button_draw_indicator (GtkCheckButton *check_button,
|
|
+ GdkRectangle *area);
|
|
+static void gtk_real_check_button_draw_indicator
|
|
+ (GtkCheckButton *check_button,
|
|
+ GdkRectangle *area);
|
|
|
|
-static GtkToggleButtonClass *parent_class = NULL;
|
|
+static void gtk_check_button_calc_indicator_size( GtkCheckButton *button,
|
|
+ GdkRectangle *rect );
|
|
+
|
|
+static void gtk_check_button_clicked (GtkButton *button);
|
|
+static void gtk_check_button_update_state (GtkButton *button);
|
|
|
|
+static GtkToggleButtonClass *parent_class = NULL;
|
|
|
|
GType
|
|
gtk_check_button_get_type (void)
|
|
@@ -85,32 +102,36 @@
|
|
gtk_check_button_class_init (GtkCheckButtonClass *class)
|
|
{
|
|
GtkWidgetClass *widget_class;
|
|
-
|
|
+ GtkButtonClass *button_class;
|
|
+
|
|
widget_class = (GtkWidgetClass*) class;
|
|
+ button_class = (GtkButtonClass*) class;
|
|
parent_class = g_type_class_peek_parent (class);
|
|
|
|
widget_class->size_request = gtk_check_button_size_request;
|
|
widget_class->size_allocate = gtk_check_button_size_allocate;
|
|
widget_class->expose_event = gtk_check_button_expose;
|
|
|
|
+ button_class->clicked = gtk_check_button_clicked;
|
|
+
|
|
class->draw_indicator = gtk_real_check_button_draw_indicator;
|
|
|
|
gtk_widget_class_install_style_property (widget_class,
|
|
g_param_spec_int ("indicator_size",
|
|
- P_("Indicator Size"),
|
|
- P_("Size of check or radio indicator"),
|
|
- 0,
|
|
- G_MAXINT,
|
|
- INDICATOR_SIZE,
|
|
- G_PARAM_READABLE));
|
|
+ P_("Indicator Size"),
|
|
+ P_("Size of check or radio indicator"),
|
|
+ 0,
|
|
+ G_MAXINT,
|
|
+ INDICATOR_SIZE,
|
|
+ G_PARAM_READABLE));
|
|
gtk_widget_class_install_style_property (widget_class,
|
|
g_param_spec_int ("indicator_spacing",
|
|
- P_("Indicator Spacing"),
|
|
- P_("Spacing around check or radio indicator"),
|
|
- 0,
|
|
- G_MAXINT,
|
|
- INDICATOR_SPACING,
|
|
- G_PARAM_READABLE));
|
|
+ P_("Indicator Spacing"),
|
|
+ P_("Spacing around check or radio indicator"),
|
|
+ 0,
|
|
+ G_MAXINT,
|
|
+ INDICATOR_SPACING,
|
|
+ G_PARAM_READABLE));
|
|
}
|
|
|
|
static void
|
|
@@ -148,7 +169,8 @@
|
|
GtkWidget*
|
|
gtk_check_button_new_with_mnemonic (const gchar *label)
|
|
{
|
|
- return g_object_new (GTK_TYPE_CHECK_BUTTON, "label", label, "use_underline", TRUE, NULL);
|
|
+ return g_object_new (GTK_TYPE_CHECK_BUTTON, "label", label,
|
|
+ "use_underline", TRUE, NULL);
|
|
}
|
|
|
|
|
|
@@ -163,39 +185,70 @@
|
|
|
|
if (GTK_WIDGET_DRAWABLE (widget))
|
|
{
|
|
- gint border_width;
|
|
- gint interior_focus;
|
|
- gint focus_width;
|
|
- gint focus_pad;
|
|
-
|
|
+ gint border_width = 0;
|
|
+ gint interior_focus = 0;
|
|
+ gint focus_width = 0;
|
|
+ gint focus_pad = 0;
|
|
+ gint indicator_size = 0;
|
|
+ gint indicator_spacing = 0;
|
|
+
|
|
gtk_widget_style_get (widget,
|
|
"interior-focus", &interior_focus,
|
|
"focus-line-width", &focus_width,
|
|
"focus-padding", &focus_pad,
|
|
+ "indicator-size", &indicator_size,
|
|
+ "indicator-spacing", &indicator_spacing,
|
|
NULL);
|
|
-
|
|
- gtk_check_button_draw_indicator (check_button, area);
|
|
|
|
border_width = GTK_CONTAINER (widget)->border_width;
|
|
+
|
|
+ /* Hildon: change the focus so that it draws around the entire
|
|
+ * widget - including both the indicator *and* the label
|
|
+ */
|
|
if (GTK_WIDGET_HAS_FOCUS (widget))
|
|
{
|
|
GtkWidget *child = GTK_BIN (widget)->child;
|
|
|
|
+ int w = indicator_size + 2 * indicator_spacing +
|
|
+ 2 * (focus_width + focus_pad);
|
|
+ int h = indicator_size + 2 * indicator_spacing +
|
|
+ 2 * (focus_width + focus_pad) + 2 * HILDON_SPACING
|
|
+ - FOCUS_TOP_PADDING;
|
|
+ int x = widget->allocation.x;
|
|
+ int y = widget->allocation.y + (widget->allocation.height - h)/2
|
|
+ + FOCUS_DOWN_PADDING;
|
|
+
|
|
+ if (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL)
|
|
+ x = widget->allocation.x + widget->allocation.width -
|
|
+ (2 * HILDON_SPACING) - (indicator_size + 2) -
|
|
+ (indicator_spacing + 2);
|
|
+
|
|
if (interior_focus && child && GTK_WIDGET_VISIBLE (child))
|
|
- gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget),
|
|
- NULL, widget, "checkbutton",
|
|
- child->allocation.x - focus_width - focus_pad,
|
|
- child->allocation.y - focus_width - focus_pad,
|
|
- child->allocation.width + 2 * (focus_width + focus_pad),
|
|
- child->allocation.height + 2 * (focus_width + focus_pad));
|
|
+ {
|
|
+ if (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL)
|
|
+ {
|
|
+ /* Move the "x" to the left, and enlarge the width,
|
|
+ both accounting for the child
|
|
+ */
|
|
+ x += - child->allocation.width - HILDON_SPACING -
|
|
+ (widget->style->xthickness);
|
|
+ w += child->allocation.width + HILDON_SPACING +
|
|
+ (widget->style->xthickness);
|
|
+ } else {
|
|
+ w = child->allocation.x + child->allocation.width +
|
|
+ 2 * widget->style->xthickness - x;
|
|
+ }
|
|
+
|
|
+ gtk_paint_focus (widget->style, widget->window,
|
|
+ GTK_WIDGET_STATE (widget),
|
|
+ NULL, widget, "checkbutton", x, y, w, h);
|
|
+ }
|
|
else
|
|
- gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget),
|
|
- NULL, widget, "checkbutton",
|
|
- border_width + widget->allocation.x,
|
|
- border_width + widget->allocation.y,
|
|
- widget->allocation.width - 2 * border_width,
|
|
- widget->allocation.height - 2 * border_width);
|
|
+ gtk_paint_focus (widget->style, widget->window,
|
|
+ GTK_WIDGET_STATE (widget),
|
|
+ NULL, widget, "checkbutton", x, y, w, h);
|
|
}
|
|
+ gtk_check_button_draw_indicator (check_button, area);
|
|
}
|
|
}
|
|
|
|
@@ -205,10 +258,10 @@
|
|
gint *indicator_spacing)
|
|
{
|
|
GtkWidget *widget = GTK_WIDGET (check_button);
|
|
-
|
|
+
|
|
if (indicator_size)
|
|
gtk_widget_style_get (widget, "indicator_size", indicator_size, NULL);
|
|
-
|
|
+
|
|
if (indicator_spacing)
|
|
gtk_widget_style_get (widget, "indicator_spacing", indicator_spacing, NULL);
|
|
}
|
|
@@ -233,7 +286,7 @@
|
|
"focus-line-width", &focus_width,
|
|
"focus-padding", &focus_pad,
|
|
NULL);
|
|
-
|
|
+
|
|
requisition->width = border_width * 2;
|
|
requisition->height = border_width * 2;
|
|
|
|
@@ -246,15 +299,19 @@
|
|
GtkRequisition child_requisition;
|
|
|
|
gtk_widget_size_request (child, &child_requisition);
|
|
-
|
|
- requisition->width += child_requisition.width + indicator_spacing;
|
|
+
|
|
+ requisition->width += child_requisition.width +
|
|
+ 2 * widget->style->xthickness;
|
|
requisition->height += child_requisition.height;
|
|
+ requisition->width += 2 * widget->style->xthickness;
|
|
}
|
|
|
|
- requisition->width += (indicator_size + indicator_spacing * 2 + 2 * (focus_width + focus_pad));
|
|
+ requisition->width += (indicator_size + indicator_spacing * 2 +
|
|
+ 2 * (focus_width + focus_pad));
|
|
|
|
temp = indicator_size + indicator_spacing * 2;
|
|
- requisition->height = MAX (requisition->height, temp) + 2 * (focus_width + focus_pad);
|
|
+ requisition->height = MAX (requisition->height, temp) +
|
|
+ 2 * (focus_width + focus_pad);
|
|
}
|
|
else
|
|
(* GTK_WIDGET_CLASS (parent_class)->size_request) (widget, requisition);
|
|
@@ -280,45 +337,59 @@
|
|
gint focus_width;
|
|
gint focus_pad;
|
|
|
|
- _gtk_check_button_get_props (check_button, &indicator_size, &indicator_spacing);
|
|
+ _gtk_check_button_get_props (check_button,
|
|
+ &indicator_size, &indicator_spacing);
|
|
gtk_widget_style_get (widget,
|
|
"focus-line-width", &focus_width,
|
|
"focus-padding", &focus_pad,
|
|
NULL);
|
|
-
|
|
+
|
|
widget->allocation = *allocation;
|
|
if (GTK_WIDGET_REALIZED (widget))
|
|
gdk_window_move_resize (button->event_window,
|
|
allocation->x, allocation->y,
|
|
allocation->width, allocation->height);
|
|
|
|
- if (GTK_BIN (button)->child && GTK_WIDGET_VISIBLE (GTK_BIN (button)->child))
|
|
+ if (GTK_BIN (button)->child &&
|
|
+ GTK_WIDGET_VISIBLE (GTK_BIN (button)->child))
|
|
{
|
|
GtkRequisition child_requisition;
|
|
gint border_width = GTK_CONTAINER (widget)->border_width;
|
|
-
|
|
- gtk_widget_get_child_requisition (GTK_BIN (button)->child, &child_requisition);
|
|
+
|
|
+ gtk_widget_get_child_requisition (GTK_BIN (button)->child,
|
|
+ &child_requisition);
|
|
|
|
- child_allocation.width = MIN (child_requisition.width,
|
|
+ child_allocation.width = MIN (
|
|
+ child_requisition.width,
|
|
allocation->width -
|
|
- ((border_width + focus_width + focus_pad) * 2
|
|
- + indicator_size + indicator_spacing * 3));
|
|
- child_allocation.width = MAX (child_allocation.width, 1);
|
|
+ ((border_width + focus_width +
|
|
+ focus_pad) * 2
|
|
+ - 2 * widget->style->xthickness +
|
|
+ indicator_size +
|
|
+ indicator_spacing * 2 ) );
|
|
|
|
+ child_allocation.width = MAX (child_allocation.width, 1);
|
|
+
|
|
child_allocation.height = MIN (child_requisition.height,
|
|
- allocation->height - (border_width + focus_width + focus_pad) * 2);
|
|
+ allocation->height -
|
|
+ (border_width + focus_width +
|
|
+ focus_pad) * 2);
|
|
child_allocation.height = MAX (child_allocation.height, 1);
|
|
|
|
- child_allocation.x = (border_width + indicator_size + indicator_spacing * 3 +
|
|
- widget->allocation.x + focus_width + focus_pad);
|
|
+ child_allocation.x = (border_width + indicator_size +
|
|
+ indicator_spacing * 2 +
|
|
+ widget->style->xthickness +
|
|
+ widget->allocation.x +
|
|
+ focus_width + focus_pad);
|
|
child_allocation.y = widget->allocation.y +
|
|
- (allocation->height - child_allocation.height) / 2;
|
|
-
|
|
+ (allocation->height - child_allocation.height) / 2;
|
|
+
|
|
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
|
|
- child_allocation.x = allocation->x + allocation->width
|
|
- - (child_allocation.x - allocation->x + child_allocation.width);
|
|
+ child_allocation.x = allocation->x + allocation->width -
|
|
+ (child_allocation.x - allocation->x + child_allocation.width);
|
|
|
|
- gtk_widget_size_allocate (GTK_BIN (button)->child, &child_allocation);
|
|
+ gtk_widget_size_allocate (GTK_BIN (button)->child,
|
|
+ &child_allocation);
|
|
}
|
|
}
|
|
else
|
|
@@ -375,45 +446,33 @@
|
|
GdkRectangle *area)
|
|
{
|
|
GtkWidget *widget;
|
|
- GtkWidget *child;
|
|
GtkButton *button;
|
|
GtkToggleButton *toggle_button;
|
|
GtkStateType state_type;
|
|
GtkShadowType shadow_type;
|
|
- gint x, y;
|
|
- gint indicator_size;
|
|
- gint indicator_spacing;
|
|
- gint focus_width;
|
|
- gint focus_pad;
|
|
- gboolean interior_focus;
|
|
+
|
|
+ GdkRectangle indicator = {0, 0, 0, 0};
|
|
|
|
if (GTK_WIDGET_DRAWABLE (check_button))
|
|
{
|
|
widget = GTK_WIDGET (check_button);
|
|
button = GTK_BUTTON (check_button);
|
|
toggle_button = GTK_TOGGLE_BUTTON (check_button);
|
|
-
|
|
- gtk_widget_style_get (widget, "interior_focus", &interior_focus,
|
|
- "focus-line-width", &focus_width,
|
|
- "focus-padding", &focus_pad, NULL);
|
|
-
|
|
- _gtk_check_button_get_props (check_button, &indicator_size, &indicator_spacing);
|
|
-
|
|
- x = widget->allocation.x + indicator_spacing + GTK_CONTAINER (widget)->border_width;
|
|
- y = widget->allocation.y + (widget->allocation.height - indicator_size) / 2;
|
|
-
|
|
- child = GTK_BIN (check_button)->child;
|
|
- if (!interior_focus || !(child && GTK_WIDGET_VISIBLE (child)))
|
|
- x += focus_width + focus_pad;
|
|
-
|
|
+ gtk_check_button_calc_indicator_size( check_button, &indicator );
|
|
+
|
|
+ /* move indicator to root coordinates */
|
|
+ indicator.x += widget->allocation.x;
|
|
+ indicator.y += widget->allocation.y;
|
|
+
|
|
if (toggle_button->inconsistent)
|
|
shadow_type = GTK_SHADOW_ETCHED_IN;
|
|
else if (toggle_button->active)
|
|
shadow_type = GTK_SHADOW_IN;
|
|
else
|
|
shadow_type = GTK_SHADOW_OUT;
|
|
-
|
|
- if (button->activate_timeout || (button->button_down && button->in_button))
|
|
+
|
|
+ if (button->activate_timeout ||
|
|
+ (button->button_down && button->in_button))
|
|
state_type = GTK_STATE_ACTIVE;
|
|
else if (button->in_button)
|
|
state_type = GTK_STATE_PRELIGHT;
|
|
@@ -422,32 +481,107 @@
|
|
else
|
|
state_type = GTK_STATE_NORMAL;
|
|
|
|
- if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
|
|
- x = widget->allocation.x + widget->allocation.width - (indicator_size + x - widget->allocation.x);
|
|
+ /* Hildon change. We want to draw active image always when we have
|
|
+ * focus. */
|
|
+ if (GTK_WIDGET_HAS_FOCUS (widget))
|
|
+ state_type = GTK_STATE_ACTIVE;
|
|
|
|
- if (GTK_WIDGET_STATE (toggle_button) == GTK_STATE_PRELIGHT)
|
|
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
|
|
{
|
|
- GdkRectangle restrict_area;
|
|
- GdkRectangle new_area;
|
|
-
|
|
- restrict_area.x = widget->allocation.x + GTK_CONTAINER (widget)->border_width;
|
|
- restrict_area.y = widget->allocation.y + GTK_CONTAINER (widget)->border_width;
|
|
- restrict_area.width = widget->allocation.width - (2 * GTK_CONTAINER (widget)->border_width);
|
|
- restrict_area.height = widget->allocation.height - (2 * GTK_CONTAINER (widget)->border_width);
|
|
+ indicator.x = widget->allocation.x + widget->allocation.width
|
|
+ - (indicator.width + indicator.x - widget->allocation.x);
|
|
|
|
- if (gdk_rectangle_intersect (area, &restrict_area, &new_area))
|
|
- {
|
|
- gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_PRELIGHT,
|
|
- GTK_SHADOW_ETCHED_OUT,
|
|
- area, widget, "checkbutton",
|
|
- new_area.x, new_area.y,
|
|
- new_area.width, new_area.height);
|
|
- }
|
|
}
|
|
|
|
gtk_paint_check (widget->style, widget->window,
|
|
state_type, shadow_type,
|
|
area, widget, "checkbutton",
|
|
- x, y, indicator_size, indicator_size);
|
|
+ indicator.x, indicator.y,
|
|
+ indicator.width, indicator.height);
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+/* calculates the size and position of the indicator
|
|
+ * relative to the origin of the check button.
|
|
+ */
|
|
+static void gtk_check_button_calc_indicator_size( GtkCheckButton *button,
|
|
+ GdkRectangle *rect )
|
|
+{
|
|
+ gint indicator_size;
|
|
+ gint indicator_spacing;
|
|
+ gint focus_width;
|
|
+ gint focus_pad;
|
|
+ gboolean interior_focus;
|
|
+ GtkWidget *child;
|
|
+ GtkWidget *widget = GTK_WIDGET(button);
|
|
+
|
|
+
|
|
+ gtk_widget_style_get (widget, "interior_focus", &interior_focus,
|
|
+ "focus-line-width", &focus_width,
|
|
+ "focus-padding", &focus_pad,
|
|
+ "indicator-size", &indicator_size,
|
|
+ "indicator-spacing", &indicator_spacing,
|
|
+ NULL
|
|
+ );
|
|
+
|
|
+
|
|
+ /* HILDON: We want the indicator to be positioned according to the spec.
|
|
+ *
|
|
+ * NOTE: INDICATOR_SIDE_PADDING and INDICATOR_TOP_PADDING
|
|
+ * are maJiKal numbers that make the indicator to be drawn
|
|
+ * to correct coordinates, 1337 \o/
|
|
+ */
|
|
+ rect->x = INDICATOR_SIDE_PADDING;
|
|
+ rect->y = ( widget->allocation.height - indicator_size ) / 2;
|
|
+
|
|
+ /* Hildon: we always add space for the focus */
|
|
+ rect->x += focus_width + focus_pad;
|
|
+
|
|
+ child = GTK_BIN (widget)->child;
|
|
+ if (interior_focus && child && GTK_WIDGET_VISIBLE (child))
|
|
+ {
|
|
+ rect->y += HILDON_SPACING;
|
|
}
|
|
+
|
|
+ rect->width = indicator_size;
|
|
+ rect->height = indicator_size;
|
|
}
|
|
+
|
|
+static void
|
|
+gtk_check_button_clicked (GtkButton *button)
|
|
+{
|
|
+ GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (button);
|
|
+
|
|
+ toggle_button->active = !toggle_button->active;
|
|
+ gtk_toggle_button_toggled (toggle_button);
|
|
+
|
|
+ gtk_check_button_update_state (button);
|
|
+
|
|
+ g_object_notify (G_OBJECT (toggle_button), "active");
|
|
+}
|
|
+
|
|
+static void
|
|
+gtk_check_button_update_state (GtkButton *button)
|
|
+{
|
|
+ GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (button);
|
|
+ gboolean depressed;
|
|
+ GtkStateType new_state;
|
|
+
|
|
+ if (toggle_button->inconsistent)
|
|
+ depressed = FALSE;
|
|
+ else if (button->in_button && button->button_down)
|
|
+ depressed = TRUE;
|
|
+ else
|
|
+ depressed = toggle_button->active;
|
|
+
|
|
+ if (button->in_button &&
|
|
+ (!button->button_down || toggle_button->draw_indicator))
|
|
+ new_state = GTK_STATE_PRELIGHT;
|
|
+ else
|
|
+ new_state = depressed ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL;
|
|
+
|
|
+ _gtk_button_set_depressed (button, depressed);
|
|
+ gtk_widget_set_state (GTK_WIDGET (toggle_button), new_state);
|
|
+}
|
|
+
|