1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 #include "gtksignal.h"
22 #include "gtktogglebutton.h"
25 #define DEFAULT_LEFT_POS 4
26 #define DEFAULT_TOP_POS 4
27 #define DEFAULT_SPACING 7
41 static void gtk_toggle_button_class_init (GtkToggleButtonClass *klass);
42 static void gtk_toggle_button_init (GtkToggleButton *toggle_button);
43 static void gtk_toggle_button_draw_focus (GtkWidget *widget);
44 static void gtk_toggle_button_pressed (GtkButton *button);
45 static void gtk_toggle_button_released (GtkButton *button);
46 static void gtk_toggle_button_clicked (GtkButton *button);
47 static void gtk_toggle_button_enter (GtkButton *button);
48 static void gtk_toggle_button_leave (GtkButton *button);
49 static void gtk_toggle_button_set_arg (GtkObject *object,
52 static void gtk_toggle_button_get_arg (GtkObject *object,
57 static guint toggle_button_signals[LAST_SIGNAL] = { 0 };
61 gtk_toggle_button_get_type (void)
63 static GtkType toggle_button_type = 0;
65 if (!toggle_button_type)
67 GtkTypeInfo toggle_button_info =
70 sizeof (GtkToggleButton),
71 sizeof (GtkToggleButtonClass),
72 (GtkClassInitFunc) gtk_toggle_button_class_init,
73 (GtkObjectInitFunc) gtk_toggle_button_init,
74 /* reversed_1 */ NULL,
75 /* reversed_2 */ NULL,
76 (GtkClassInitFunc) NULL,
79 toggle_button_type = gtk_type_unique (gtk_button_get_type (), &toggle_button_info);
82 return toggle_button_type;
86 gtk_toggle_button_class_init (GtkToggleButtonClass *class)
88 GtkObjectClass *object_class;
89 GtkWidgetClass *widget_class;
90 GtkContainerClass *container_class;
91 GtkButtonClass *button_class;
93 object_class = (GtkObjectClass*) class;
94 widget_class = (GtkWidgetClass*) class;
95 container_class = (GtkContainerClass*) class;
96 button_class = (GtkButtonClass*) class;
98 gtk_object_add_arg_type ("GtkToggleButton::active", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ACTIVE);
99 gtk_object_add_arg_type ("GtkToggleButton::draw_indicator", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_DRAW_INDICATOR);
101 toggle_button_signals[TOGGLED] =
102 gtk_signal_new ("toggled",
105 GTK_SIGNAL_OFFSET (GtkToggleButtonClass, toggled),
106 gtk_signal_default_marshaller,
109 gtk_object_class_add_signals (object_class, toggle_button_signals, LAST_SIGNAL);
111 object_class->set_arg = gtk_toggle_button_set_arg;
112 object_class->get_arg = gtk_toggle_button_get_arg;
114 widget_class->draw_focus = gtk_toggle_button_draw_focus;
116 button_class->pressed = gtk_toggle_button_pressed;
117 button_class->released = gtk_toggle_button_released;
118 button_class->clicked = gtk_toggle_button_clicked;
119 button_class->enter = gtk_toggle_button_enter;
120 button_class->leave = gtk_toggle_button_leave;
122 class->toggled = NULL;
126 gtk_toggle_button_init (GtkToggleButton *toggle_button)
128 toggle_button->active = FALSE;
129 toggle_button->draw_indicator = FALSE;
134 gtk_toggle_button_new (void)
136 return GTK_WIDGET (gtk_type_new (gtk_toggle_button_get_type ()));
140 gtk_toggle_button_new_with_label (const gchar *label)
142 GtkWidget *toggle_button;
143 GtkWidget *label_widget;
145 toggle_button = gtk_toggle_button_new ();
146 label_widget = gtk_label_new (label);
147 gtk_misc_set_alignment (GTK_MISC (label_widget), 0.5, 0.5);
149 gtk_container_add (GTK_CONTAINER (toggle_button), label_widget);
150 gtk_widget_show (label_widget);
152 return toggle_button;
156 gtk_toggle_button_set_arg (GtkObject *object,
162 tb = GTK_TOGGLE_BUTTON (object);
167 gtk_toggle_button_set_state (tb, GTK_VALUE_BOOL (*arg));
169 case ARG_DRAW_INDICATOR:
170 gtk_toggle_button_set_mode (tb, GTK_VALUE_BOOL (*arg));
178 gtk_toggle_button_get_arg (GtkObject *object,
184 tb = GTK_TOGGLE_BUTTON (object);
189 GTK_VALUE_BOOL (*arg) = tb->active;
191 case ARG_DRAW_INDICATOR:
192 GTK_VALUE_BOOL (*arg) = tb->draw_indicator;
195 arg->type = GTK_TYPE_INVALID;
201 gtk_toggle_button_set_mode (GtkToggleButton *toggle_button,
204 g_return_if_fail (toggle_button != NULL);
205 g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button));
207 draw_indicator = draw_indicator ? TRUE : FALSE;
209 if (toggle_button->draw_indicator != draw_indicator)
211 toggle_button->draw_indicator = draw_indicator;
213 if (GTK_WIDGET_VISIBLE (toggle_button))
214 gtk_widget_queue_resize (GTK_WIDGET (toggle_button));
219 gtk_toggle_button_set_state (GtkToggleButton *toggle_button,
222 g_return_if_fail (toggle_button != NULL);
223 g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button));
225 if (toggle_button->active != (state != FALSE))
226 gtk_button_clicked (GTK_BUTTON (toggle_button));
230 gtk_toggle_button_toggled (GtkToggleButton *toggle_button)
232 gtk_signal_emit (GTK_OBJECT (toggle_button), toggle_button_signals[TOGGLED]);
237 gtk_toggle_button_draw_focus (GtkWidget *widget)
240 GtkToggleButton *toggle_button;
241 GtkShadowType shadow_type;
245 g_return_if_fail (widget != NULL);
246 g_return_if_fail (GTK_IS_TOGGLE_BUTTON (widget));
248 if (GTK_WIDGET_DRAWABLE (widget))
250 button = GTK_BUTTON (widget);
251 toggle_button = GTK_TOGGLE_BUTTON (widget);
255 width = widget->allocation.width - GTK_CONTAINER (widget)->border_width * 2;
256 height = widget->allocation.height - GTK_CONTAINER (widget)->border_width * 2;
258 if (GTK_WIDGET_CAN_DEFAULT (widget))
260 x += widget->style->klass->xthickness;
261 y += widget->style->klass->ythickness;
262 width -= 2 * x + DEFAULT_SPACING;
263 height -= 2 * y + DEFAULT_SPACING;
264 x += DEFAULT_LEFT_POS;
265 y += DEFAULT_TOP_POS;
268 if (GTK_WIDGET_HAS_FOCUS (widget))
277 if (GTK_WIDGET_STATE (toggle_button) == GTK_STATE_ACTIVE)
278 gdk_draw_rectangle (widget->window,
279 widget->style->bg_gc[GTK_WIDGET_STATE (widget)], FALSE,
280 x + 1, y + 1, width - 4, height - 4);
282 gdk_draw_rectangle (widget->window,
283 widget->style->bg_gc[GTK_WIDGET_STATE (widget)], FALSE,
284 x + 2, y + 2, width - 5, height - 5);
287 if (toggle_button->active)
288 shadow_type = GTK_SHADOW_IN;
290 shadow_type = GTK_SHADOW_OUT;
292 gtk_draw_shadow (widget->style, widget->window,
293 GTK_WIDGET_STATE (widget), shadow_type,
294 x, y, width, height);
296 if (GTK_WIDGET_HAS_FOCUS (widget))
303 gdk_draw_rectangle (widget->window,
304 widget->style->black_gc, FALSE,
305 x, y, width - 1, height - 1);
311 gtk_toggle_button_pressed (GtkButton *button)
313 GtkToggleButton *toggle_button;
314 GtkStateType new_state;
316 g_return_if_fail (button != NULL);
317 g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button));
319 toggle_button = GTK_TOGGLE_BUTTON (button);
321 button->button_down = TRUE;
323 if (toggle_button->active)
324 new_state = (button->in_button ? GTK_STATE_NORMAL : GTK_STATE_ACTIVE);
326 new_state = (button->in_button ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL);
328 if (GTK_WIDGET_STATE (button) != new_state)
330 gtk_widget_set_state (GTK_WIDGET (button), new_state);
331 gtk_widget_queue_draw (GTK_WIDGET (button));
336 gtk_toggle_button_released (GtkButton *button)
338 GtkToggleButton *toggle_button;
339 GtkStateType new_state;
341 g_return_if_fail (button != NULL);
342 g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button));
344 if (button->button_down)
346 toggle_button = GTK_TOGGLE_BUTTON (button);
348 button->button_down = FALSE;
350 if (button->in_button)
352 gtk_button_clicked (button);
356 if (toggle_button->active)
357 new_state = (button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_ACTIVE);
359 new_state = (button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL);
361 if (GTK_WIDGET_STATE (button) != new_state)
363 gtk_widget_set_state (GTK_WIDGET (button), new_state);
364 gtk_widget_queue_draw (GTK_WIDGET (button));
371 gtk_toggle_button_clicked (GtkButton *button)
373 GtkToggleButton *toggle_button;
374 GtkStateType new_state;
376 g_return_if_fail (button != NULL);
377 g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button));
379 toggle_button = GTK_TOGGLE_BUTTON (button);
380 toggle_button->active = !toggle_button->active;
382 gtk_toggle_button_toggled (toggle_button);
384 if (toggle_button->active)
385 new_state = (button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_ACTIVE);
387 new_state = (button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL);
389 if (GTK_WIDGET_STATE (button) != new_state)
390 gtk_widget_set_state (GTK_WIDGET (button), new_state);
391 gtk_widget_queue_draw (GTK_WIDGET (button));
395 gtk_toggle_button_enter (GtkButton *button)
397 GtkToggleButton *toggle_button;
398 GtkStateType new_state;
400 g_return_if_fail (button != NULL);
401 g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button));
403 toggle_button = GTK_TOGGLE_BUTTON (button);
405 if (toggle_button->active)
406 new_state = (button->button_down ? GTK_STATE_NORMAL : GTK_STATE_PRELIGHT);
408 new_state = (button->button_down ? GTK_STATE_ACTIVE : GTK_STATE_PRELIGHT);
410 if (GTK_WIDGET_STATE (button) != new_state)
412 gtk_widget_set_state (GTK_WIDGET (button), new_state);
413 gtk_widget_queue_draw (GTK_WIDGET (button));
418 gtk_toggle_button_leave (GtkButton *button)
420 GtkToggleButton *toggle_button;
421 GtkStateType new_state;
423 g_return_if_fail (button != NULL);
424 g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button));
426 toggle_button = GTK_TOGGLE_BUTTON (button);
428 new_state = (toggle_button->active ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL);
430 if (GTK_WIDGET_STATE (button) != new_state)
432 gtk_widget_set_state (GTK_WIDGET (button), new_state);
433 gtk_widget_queue_draw (GTK_WIDGET (button));