1 --- gtk+-2.6.4/gtk/gtkcheckbutton.c 2004-08-09 19:59:51.000000000 +0300
2 +++ gtk+-2.6.4/gtk/gtkcheckbutton.c 2005-04-06 16:19:36.317017336 +0300
7 -#define INDICATOR_SIZE 13
8 +#define INDICATOR_SIZE 24
9 #define INDICATOR_SPACING 2
11 +/* maJiK numbers for indicator */
12 +#define INDICATOR_SIDE_PADDING 5
13 +#define FOCUS_TOP_PADDING 7
14 +#define FOCUS_DOWN_PADDING 1
16 +/* spacing to take account of the 1 pixel
17 + transparency of the widgetfocus.png
19 +#define HILDON_SPACING 1
21 +#define TOGGLE_ON_CLICK "toggle-on-click"
23 -static void gtk_check_button_class_init (GtkCheckButtonClass *klass);
24 -static void gtk_check_button_init (GtkCheckButton *check_button);
25 -static void gtk_check_button_size_request (GtkWidget *widget,
26 - GtkRequisition *requisition);
27 -static void gtk_check_button_size_allocate (GtkWidget *widget,
28 - GtkAllocation *allocation);
29 -static gint gtk_check_button_expose (GtkWidget *widget,
30 - GdkEventExpose *event);
31 -static void gtk_check_button_paint (GtkWidget *widget,
32 - GdkRectangle *area);
33 -static void gtk_check_button_draw_indicator (GtkCheckButton *check_button,
34 - GdkRectangle *area);
35 -static void gtk_real_check_button_draw_indicator (GtkCheckButton *check_button,
36 - GdkRectangle *area);
37 +static void gtk_check_button_class_init (GtkCheckButtonClass *klass);
38 +static void gtk_check_button_init (GtkCheckButton *check_button);
39 +static void gtk_check_button_size_request (GtkWidget *widget,
40 + GtkRequisition *requisition);
41 +static void gtk_check_button_size_allocate (GtkWidget *widget,
42 + GtkAllocation *allocation);
43 +static gint gtk_check_button_expose (GtkWidget *widget,
44 + GdkEventExpose *event);
45 +static void gtk_check_button_paint (GtkWidget *widget,
46 + GdkRectangle *area);
47 +static void gtk_check_button_draw_indicator (GtkCheckButton *check_button,
48 + GdkRectangle *area);
49 +static void gtk_real_check_button_draw_indicator
50 + (GtkCheckButton *check_button,
51 + GdkRectangle *area);
53 -static GtkToggleButtonClass *parent_class = NULL;
54 +static void gtk_check_button_calc_indicator_size( GtkCheckButton *button,
55 + GdkRectangle *rect );
57 +static void gtk_check_button_clicked (GtkButton *button);
58 +static void gtk_check_button_update_state (GtkButton *button);
60 +static GtkToggleButtonClass *parent_class = NULL;
63 gtk_check_button_get_type (void)
65 gtk_check_button_class_init (GtkCheckButtonClass *class)
67 GtkWidgetClass *widget_class;
69 + GtkButtonClass *button_class;
71 widget_class = (GtkWidgetClass*) class;
72 + button_class = (GtkButtonClass*) class;
73 parent_class = g_type_class_peek_parent (class);
75 widget_class->size_request = gtk_check_button_size_request;
76 widget_class->size_allocate = gtk_check_button_size_allocate;
77 widget_class->expose_event = gtk_check_button_expose;
79 + button_class->clicked = gtk_check_button_clicked;
81 class->draw_indicator = gtk_real_check_button_draw_indicator;
83 gtk_widget_class_install_style_property (widget_class,
84 g_param_spec_int ("indicator_size",
85 - P_("Indicator Size"),
86 - P_("Size of check or radio indicator"),
91 + P_("Indicator Size"),
92 + P_("Size of check or radio indicator"),
97 gtk_widget_class_install_style_property (widget_class,
98 g_param_spec_int ("indicator_spacing",
99 - P_("Indicator Spacing"),
100 - P_("Spacing around check or radio indicator"),
104 - G_PARAM_READABLE));
105 + P_("Indicator Spacing"),
106 + P_("Spacing around check or radio indicator"),
110 + G_PARAM_READABLE));
116 gtk_check_button_new_with_mnemonic (const gchar *label)
118 - return g_object_new (GTK_TYPE_CHECK_BUTTON, "label", label, "use_underline", TRUE, NULL);
119 + return g_object_new (GTK_TYPE_CHECK_BUTTON, "label", label,
120 + "use_underline", TRUE, NULL);
124 @@ -163,39 +185,70 @@
126 if (GTK_WIDGET_DRAWABLE (widget))
129 - gint interior_focus;
133 + gint border_width = 0;
134 + gint interior_focus = 0;
135 + gint focus_width = 0;
136 + gint focus_pad = 0;
137 + gint indicator_size = 0;
138 + gint indicator_spacing = 0;
140 gtk_widget_style_get (widget,
141 "interior-focus", &interior_focus,
142 "focus-line-width", &focus_width,
143 "focus-padding", &focus_pad,
144 + "indicator-size", &indicator_size,
145 + "indicator-spacing", &indicator_spacing,
148 - gtk_check_button_draw_indicator (check_button, area);
150 border_width = GTK_CONTAINER (widget)->border_width;
152 + /* Hildon: change the focus so that it draws around the entire
153 + * widget - including both the indicator *and* the label
155 if (GTK_WIDGET_HAS_FOCUS (widget))
157 GtkWidget *child = GTK_BIN (widget)->child;
159 + int w = indicator_size + 2 * indicator_spacing +
160 + 2 * (focus_width + focus_pad);
161 + int h = indicator_size + 2 * indicator_spacing +
162 + 2 * (focus_width + focus_pad) + 2 * HILDON_SPACING
163 + - FOCUS_TOP_PADDING;
164 + int x = widget->allocation.x;
165 + int y = widget->allocation.y + (widget->allocation.height - h)/2
166 + + FOCUS_DOWN_PADDING;
168 + if (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL)
169 + x = widget->allocation.x + widget->allocation.width -
170 + (2 * HILDON_SPACING) - (indicator_size + 2) -
171 + (indicator_spacing + 2);
173 if (interior_focus && child && GTK_WIDGET_VISIBLE (child))
174 - gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget),
175 - NULL, widget, "checkbutton",
176 - child->allocation.x - focus_width - focus_pad,
177 - child->allocation.y - focus_width - focus_pad,
178 - child->allocation.width + 2 * (focus_width + focus_pad),
179 - child->allocation.height + 2 * (focus_width + focus_pad));
181 + if (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL)
183 + /* Move the "x" to the left, and enlarge the width,
184 + both accounting for the child
186 + x += - child->allocation.width - HILDON_SPACING -
187 + (widget->style->xthickness);
188 + w += child->allocation.width + HILDON_SPACING +
189 + (widget->style->xthickness);
191 + w = child->allocation.x + child->allocation.width +
192 + 2 * widget->style->xthickness - x;
195 + gtk_paint_focus (widget->style, widget->window,
196 + GTK_WIDGET_STATE (widget),
197 + NULL, widget, "checkbutton", x, y, w, h);
200 - gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget),
201 - NULL, widget, "checkbutton",
202 - border_width + widget->allocation.x,
203 - border_width + widget->allocation.y,
204 - widget->allocation.width - 2 * border_width,
205 - widget->allocation.height - 2 * border_width);
206 + gtk_paint_focus (widget->style, widget->window,
207 + GTK_WIDGET_STATE (widget),
208 + NULL, widget, "checkbutton", x, y, w, h);
210 + gtk_check_button_draw_indicator (check_button, area);
214 @@ -205,10 +258,10 @@
215 gint *indicator_spacing)
217 GtkWidget *widget = GTK_WIDGET (check_button);
221 gtk_widget_style_get (widget, "indicator_size", indicator_size, NULL);
224 if (indicator_spacing)
225 gtk_widget_style_get (widget, "indicator_spacing", indicator_spacing, NULL);
228 "focus-line-width", &focus_width,
229 "focus-padding", &focus_pad,
233 requisition->width = border_width * 2;
234 requisition->height = border_width * 2;
236 @@ -246,15 +299,19 @@
237 GtkRequisition child_requisition;
239 gtk_widget_size_request (child, &child_requisition);
241 - requisition->width += child_requisition.width + indicator_spacing;
243 + requisition->width += child_requisition.width +
244 + 2 * widget->style->xthickness;
245 requisition->height += child_requisition.height;
246 + requisition->width += 2 * widget->style->xthickness;
249 - requisition->width += (indicator_size + indicator_spacing * 2 + 2 * (focus_width + focus_pad));
250 + requisition->width += (indicator_size + indicator_spacing * 2 +
251 + 2 * (focus_width + focus_pad));
253 temp = indicator_size + indicator_spacing * 2;
254 - requisition->height = MAX (requisition->height, temp) + 2 * (focus_width + focus_pad);
255 + requisition->height = MAX (requisition->height, temp) +
256 + 2 * (focus_width + focus_pad);
259 (* GTK_WIDGET_CLASS (parent_class)->size_request) (widget, requisition);
260 @@ -280,45 +337,59 @@
264 - _gtk_check_button_get_props (check_button, &indicator_size, &indicator_spacing);
265 + _gtk_check_button_get_props (check_button,
266 + &indicator_size, &indicator_spacing);
267 gtk_widget_style_get (widget,
268 "focus-line-width", &focus_width,
269 "focus-padding", &focus_pad,
273 widget->allocation = *allocation;
274 if (GTK_WIDGET_REALIZED (widget))
275 gdk_window_move_resize (button->event_window,
276 allocation->x, allocation->y,
277 allocation->width, allocation->height);
279 - if (GTK_BIN (button)->child && GTK_WIDGET_VISIBLE (GTK_BIN (button)->child))
280 + if (GTK_BIN (button)->child &&
281 + GTK_WIDGET_VISIBLE (GTK_BIN (button)->child))
283 GtkRequisition child_requisition;
284 gint border_width = GTK_CONTAINER (widget)->border_width;
286 - gtk_widget_get_child_requisition (GTK_BIN (button)->child, &child_requisition);
288 + gtk_widget_get_child_requisition (GTK_BIN (button)->child,
289 + &child_requisition);
291 - child_allocation.width = MIN (child_requisition.width,
292 + child_allocation.width = MIN (
293 + child_requisition.width,
295 - ((border_width + focus_width + focus_pad) * 2
296 - + indicator_size + indicator_spacing * 3));
297 - child_allocation.width = MAX (child_allocation.width, 1);
298 + ((border_width + focus_width +
300 + - 2 * widget->style->xthickness +
302 + indicator_spacing * 2 ) );
304 + child_allocation.width = MAX (child_allocation.width, 1);
306 child_allocation.height = MIN (child_requisition.height,
307 - allocation->height - (border_width + focus_width + focus_pad) * 2);
308 + allocation->height -
309 + (border_width + focus_width +
311 child_allocation.height = MAX (child_allocation.height, 1);
313 - child_allocation.x = (border_width + indicator_size + indicator_spacing * 3 +
314 - widget->allocation.x + focus_width + focus_pad);
315 + child_allocation.x = (border_width + indicator_size +
316 + indicator_spacing * 2 +
317 + widget->style->xthickness +
318 + widget->allocation.x +
319 + focus_width + focus_pad);
320 child_allocation.y = widget->allocation.y +
321 - (allocation->height - child_allocation.height) / 2;
323 + (allocation->height - child_allocation.height) / 2;
325 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
326 - child_allocation.x = allocation->x + allocation->width
327 - - (child_allocation.x - allocation->x + child_allocation.width);
328 + child_allocation.x = allocation->x + allocation->width -
329 + (child_allocation.x - allocation->x + child_allocation.width);
331 - gtk_widget_size_allocate (GTK_BIN (button)->child, &child_allocation);
332 + gtk_widget_size_allocate (GTK_BIN (button)->child,
333 + &child_allocation);
337 @@ -375,45 +446,33 @@
343 GtkToggleButton *toggle_button;
344 GtkStateType state_type;
345 GtkShadowType shadow_type;
347 - gint indicator_size;
348 - gint indicator_spacing;
351 - gboolean interior_focus;
353 + GdkRectangle indicator = {0, 0, 0, 0};
355 if (GTK_WIDGET_DRAWABLE (check_button))
357 widget = GTK_WIDGET (check_button);
358 button = GTK_BUTTON (check_button);
359 toggle_button = GTK_TOGGLE_BUTTON (check_button);
361 - gtk_widget_style_get (widget, "interior_focus", &interior_focus,
362 - "focus-line-width", &focus_width,
363 - "focus-padding", &focus_pad, NULL);
365 - _gtk_check_button_get_props (check_button, &indicator_size, &indicator_spacing);
367 - x = widget->allocation.x + indicator_spacing + GTK_CONTAINER (widget)->border_width;
368 - y = widget->allocation.y + (widget->allocation.height - indicator_size) / 2;
370 - child = GTK_BIN (check_button)->child;
371 - if (!interior_focus || !(child && GTK_WIDGET_VISIBLE (child)))
372 - x += focus_width + focus_pad;
374 + gtk_check_button_calc_indicator_size( check_button, &indicator );
376 + /* move indicator to root coordinates */
377 + indicator.x += widget->allocation.x;
378 + indicator.y += widget->allocation.y;
380 if (toggle_button->inconsistent)
381 shadow_type = GTK_SHADOW_ETCHED_IN;
382 else if (toggle_button->active)
383 shadow_type = GTK_SHADOW_IN;
385 shadow_type = GTK_SHADOW_OUT;
387 - if (button->activate_timeout || (button->button_down && button->in_button))
389 + if (button->activate_timeout ||
390 + (button->button_down && button->in_button))
391 state_type = GTK_STATE_ACTIVE;
392 else if (button->in_button)
393 state_type = GTK_STATE_PRELIGHT;
394 @@ -422,32 +481,107 @@
396 state_type = GTK_STATE_NORMAL;
398 - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
399 - x = widget->allocation.x + widget->allocation.width - (indicator_size + x - widget->allocation.x);
400 + /* Hildon change. We want to draw active image always when we have
402 + if (GTK_WIDGET_HAS_FOCUS (widget))
403 + state_type = GTK_STATE_ACTIVE;
405 - if (GTK_WIDGET_STATE (toggle_button) == GTK_STATE_PRELIGHT)
406 + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
408 - GdkRectangle restrict_area;
409 - GdkRectangle new_area;
411 - restrict_area.x = widget->allocation.x + GTK_CONTAINER (widget)->border_width;
412 - restrict_area.y = widget->allocation.y + GTK_CONTAINER (widget)->border_width;
413 - restrict_area.width = widget->allocation.width - (2 * GTK_CONTAINER (widget)->border_width);
414 - restrict_area.height = widget->allocation.height - (2 * GTK_CONTAINER (widget)->border_width);
415 + indicator.x = widget->allocation.x + widget->allocation.width
416 + - (indicator.width + indicator.x - widget->allocation.x);
418 - if (gdk_rectangle_intersect (area, &restrict_area, &new_area))
420 - gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_PRELIGHT,
421 - GTK_SHADOW_ETCHED_OUT,
422 - area, widget, "checkbutton",
423 - new_area.x, new_area.y,
424 - new_area.width, new_area.height);
428 gtk_paint_check (widget->style, widget->window,
429 state_type, shadow_type,
430 area, widget, "checkbutton",
431 - x, y, indicator_size, indicator_size);
432 + indicator.x, indicator.y,
433 + indicator.width, indicator.height);
438 +/* calculates the size and position of the indicator
439 + * relative to the origin of the check button.
441 +static void gtk_check_button_calc_indicator_size( GtkCheckButton *button,
442 + GdkRectangle *rect )
444 + gint indicator_size;
445 + gint indicator_spacing;
448 + gboolean interior_focus;
450 + GtkWidget *widget = GTK_WIDGET(button);
453 + gtk_widget_style_get (widget, "interior_focus", &interior_focus,
454 + "focus-line-width", &focus_width,
455 + "focus-padding", &focus_pad,
456 + "indicator-size", &indicator_size,
457 + "indicator-spacing", &indicator_spacing,
462 + /* HILDON: We want the indicator to be positioned according to the spec.
464 + * NOTE: INDICATOR_SIDE_PADDING and INDICATOR_TOP_PADDING
465 + * are maJiKal numbers that make the indicator to be drawn
466 + * to correct coordinates, 1337 \o/
468 + rect->x = INDICATOR_SIDE_PADDING;
469 + rect->y = ( widget->allocation.height - indicator_size ) / 2;
471 + /* Hildon: we always add space for the focus */
472 + rect->x += focus_width + focus_pad;
474 + child = GTK_BIN (widget)->child;
475 + if (interior_focus && child && GTK_WIDGET_VISIBLE (child))
477 + rect->y += HILDON_SPACING;
480 + rect->width = indicator_size;
481 + rect->height = indicator_size;
485 +gtk_check_button_clicked (GtkButton *button)
487 + GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (button);
489 + toggle_button->active = !toggle_button->active;
490 + gtk_toggle_button_toggled (toggle_button);
492 + gtk_check_button_update_state (button);
494 + g_object_notify (G_OBJECT (toggle_button), "active");
498 +gtk_check_button_update_state (GtkButton *button)
500 + GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (button);
501 + gboolean depressed;
502 + GtkStateType new_state;
504 + if (toggle_button->inconsistent)
506 + else if (button->in_button && button->button_down)
509 + depressed = toggle_button->active;
511 + if (button->in_button &&
512 + (!button->button_down || toggle_button->draw_indicator))
513 + new_state = GTK_STATE_PRELIGHT;
515 + new_state = depressed ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL;
517 + _gtk_button_set_depressed (button, depressed);
518 + gtk_widget_set_state (GTK_WIDGET (toggle_button), new_state);