1 /*
2 
3     This widget provides toggle switches
4 
5     (c) Fraser Stuart 2009
6 
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11 
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 #include "stdlib.h"
24 #include "math.h"
25 #include "string.h"
26 #include "widgets.h"
27 #include "switch-toggle.h"
28 #include "switch-toggle-img_off.xpm"
29 #include "switch-toggle-img_on.xpm"
30 
31 static void 	inv_switch_toggle_class_init(InvSwitchToggleClass *klass);
32 static void 	inv_switch_toggle_init(InvSwitchToggle *switch_toggle);
33 static void 	inv_switch_toggle_size_request(GtkWidget *widget, GtkRequisition *requisition);
34 static void 	inv_switch_toggle_size_allocate(GtkWidget *widget, GtkAllocation *allocation);
35 static void 	inv_switch_toggle_realize(GtkWidget *widget);
36 static gboolean inv_switch_toggle_expose(GtkWidget *widget,GdkEventExpose *event);
37 static void 	inv_switch_toggle_paint(GtkWidget *widget, gint mode);
38 static gboolean	inv_switch_toggle_button_press_event (GtkWidget *widget, GdkEventButton *event);
39 static gboolean inv_switch_toggle_button_release_event (GtkWidget *widget, GdkEventButton *event);
40 static void	inv_switch_toggle_destroy(GtkObject *object);
41 
42 
43 GtkType
inv_switch_toggle_get_type(void)44 inv_switch_toggle_get_type(void)
45 {
46 	static GType inv_switch_toggle_type = 0;
47 	char *name;
48 	int i;
49 
50 
51 	if (!inv_switch_toggle_type)
52 	{
53 		static const GTypeInfo type_info = {
54 			sizeof(InvSwitchToggleClass),
55 			NULL, /* base_init */
56 			NULL, /* base_finalize */
57 			(GClassInitFunc)inv_switch_toggle_class_init,
58 			NULL, /* class_finalize */
59 			NULL, /* class_data */
60 			sizeof(InvSwitchToggle),
61 			0,    /* n_preallocs */
62 			(GInstanceInitFunc)inv_switch_toggle_init
63 		};
64 		for (i = 0; ; i++) {
65 			name = g_strdup_printf("InvSwitchToggle-%p-%d",inv_switch_toggle_class_init, i);
66 			if (g_type_from_name(name)) {
67 				free(name);
68 				continue;
69 			}
70 			inv_switch_toggle_type = g_type_register_static(GTK_TYPE_WIDGET,name,&type_info,(GTypeFlags)0);
71 			free(name);
72 			break;
73 		}
74 	}
75 	return inv_switch_toggle_type;
76 }
77 
78 void
inv_switch_toggle_set_bypass(InvSwitchToggle * switch_toggle,gint num)79 inv_switch_toggle_set_bypass(InvSwitchToggle *switch_toggle, gint num)
80 {
81 	switch_toggle->bypass = num;
82 }
83 
84 void
inv_switch_toggle_toggle(InvSwitchToggle * switch_toggle)85 inv_switch_toggle_toggle(InvSwitchToggle *switch_toggle)
86 {
87 	if(switch_toggle->state == INV_SWITCH_TOGGLE_ON) {
88 		switch_toggle->state = INV_SWITCH_TOGGLE_OFF;
89 		switch_toggle->value = switch_toggle->off_value;
90 	} else {
91 		switch_toggle->state = INV_SWITCH_TOGGLE_ON;
92 		switch_toggle->value = switch_toggle->on_value;
93 	}
94 	if(GTK_WIDGET_REALIZED(switch_toggle))
95 		inv_switch_toggle_paint(GTK_WIDGET(switch_toggle),INV_SWITCH_TOGGLE_DRAW_DATA);
96 }
97 
98 float
inv_switch_toggle_get_value(InvSwitchToggle * switch_toggle)99 inv_switch_toggle_get_value(InvSwitchToggle *switch_toggle)
100 {
101 	return switch_toggle->value;
102 }
103 
104 void
inv_switch_toggle_set_state(InvSwitchToggle * switch_toggle,gint state)105 inv_switch_toggle_set_state(InvSwitchToggle *switch_toggle, gint state)
106 {
107 	if(switch_toggle->state != state) {
108 		switch_toggle->state = state;
109 		switch(state) {
110 			case INV_SWITCH_TOGGLE_ON:
111 				switch_toggle->value = switch_toggle->on_value;
112 				break;
113 			case INV_SWITCH_TOGGLE_OFF:
114 				switch_toggle->value = switch_toggle->off_value;
115 				break;
116 		}
117 		if(GTK_WIDGET_REALIZED(switch_toggle))
118 			inv_switch_toggle_paint(GTK_WIDGET(switch_toggle),INV_SWITCH_TOGGLE_DRAW_DATA);
119 	}
120 }
121 
inv_switch_toggle_set_value(InvSwitchToggle * switch_toggle,gint state,float value)122 void inv_switch_toggle_set_value(InvSwitchToggle *switch_toggle, gint state, float value)
123 {
124 	switch(state) {
125 		case INV_SWITCH_TOGGLE_ON:
126 			switch_toggle->on_value=value;
127 			break;
128 		case INV_SWITCH_TOGGLE_OFF:
129 			switch_toggle->off_value=value;
130 			break;
131 	}
132 }
133 
inv_switch_toggle_set_colour(InvSwitchToggle * switch_toggle,gint state,float R,float G,float B)134 void inv_switch_toggle_set_colour(InvSwitchToggle *switch_toggle, gint state, float R, float G, float B)
135 {
136 	switch(state) {
137 		case INV_SWITCH_TOGGLE_ON:
138 			switch_toggle->on.R=R;
139 			switch_toggle->on.G=G;
140 			switch_toggle->on.B=B;
141 			break;
142 		case INV_SWITCH_TOGGLE_OFF:
143 			switch_toggle->off.R=R;
144 			switch_toggle->off.G=G;
145 			switch_toggle->off.B=B;
146 			break;
147 	}
148 }
149 
inv_switch_toggle_set_text(InvSwitchToggle * switch_toggle,gint state,const char * text)150 void inv_switch_toggle_set_text(InvSwitchToggle *switch_toggle, gint state, const char *text)
151 {
152 	switch(state) {
153 		case INV_SWITCH_TOGGLE_ON:
154 			strncpy(switch_toggle->on_text,text,14);
155 			break;
156 		case INV_SWITCH_TOGGLE_OFF:
157 			strncpy(switch_toggle->off_text,text,14);
158 			break;
159 	}
160 }
161 
inv_switch_toggle_set_label(InvSwitchToggle * switch_toggle,const char * text)162 void inv_switch_toggle_set_label(InvSwitchToggle *switch_toggle, const char *text)
163 {
164 		strncpy(switch_toggle->label,text,14);
165 }
166 
inv_switch_toggle_set_tooltip(InvSwitchToggle * switch_toggle,gchar * tip)167 void inv_switch_toggle_set_tooltip(InvSwitchToggle *switch_toggle, gchar *tip)
168 {
169 	gtk_widget_set_tooltip_markup(GTK_WIDGET(switch_toggle),tip);
170 }
171 
172 
173 
inv_switch_toggle_new()174 GtkWidget * inv_switch_toggle_new()
175 {
176 	return GTK_WIDGET(gtk_type_new(inv_switch_toggle_get_type()));
177 }
178 
179 
180 static void
inv_switch_toggle_class_init(InvSwitchToggleClass * klass)181 inv_switch_toggle_class_init(InvSwitchToggleClass *klass)
182 {
183 	GtkWidgetClass *widget_class;
184 	GtkObjectClass *object_class;
185 
186 
187 	widget_class = (GtkWidgetClass *) klass;
188 	object_class = (GtkObjectClass *) klass;
189 
190 	widget_class->realize = inv_switch_toggle_realize;
191 	widget_class->size_request = inv_switch_toggle_size_request;
192 	widget_class->size_allocate = inv_switch_toggle_size_allocate;
193 	widget_class->expose_event = inv_switch_toggle_expose;
194 
195     	widget_class->button_press_event = inv_switch_toggle_button_press_event;
196     	widget_class->button_release_event = inv_switch_toggle_button_release_event;
197 
198 	object_class->destroy = inv_switch_toggle_destroy;
199 }
200 
201 
202 static void
inv_switch_toggle_init(InvSwitchToggle * switch_toggle)203 inv_switch_toggle_init(InvSwitchToggle *switch_toggle)
204 {
205 
206 	switch_toggle->bypass    = INV_PLUGIN_ACTIVE;
207 	switch_toggle->state     = INV_SWITCH_TOGGLE_OFF;
208 	switch_toggle->laststate = INV_SWITCH_TOGGLE_OFF;
209 	switch_toggle->value=0;
210 
211 	switch_toggle->on_value=1;
212 	switch_toggle->off_value=0;
213 
214 	switch_toggle->on.R =0.0;	switch_toggle->on.G =1.0;	switch_toggle->on.B =0.0;
215 	switch_toggle->off.R =1.0;	switch_toggle->off.G =0.0;	switch_toggle->off.B =0.0;
216 
217 	strcpy(switch_toggle->on_text,"");
218 	strcpy(switch_toggle->off_text,"");
219 	strcpy(switch_toggle->label,"");
220 
221      	switch_toggle->img_on=gdk_pixbuf_new_from_xpm_data((const char **)switch_toggle_img_on_xpm);
222      	switch_toggle->img_off=gdk_pixbuf_new_from_xpm_data((const char **)switch_toggle_img_off_xpm);
223 
224 	switch_toggle->font_size=0;
225 
226     	GTK_WIDGET_SET_FLAGS (GTK_WIDGET(switch_toggle), GTK_CAN_FOCUS);
227 }
228 
229 
230 static void
inv_switch_toggle_size_request(GtkWidget * widget,GtkRequisition * requisition)231 inv_switch_toggle_size_request(GtkWidget *widget,
232     GtkRequisition *requisition)
233 {
234 	g_return_if_fail(widget != NULL);
235 	g_return_if_fail(INV_IS_SWITCH_TOGGLE(widget));
236 	g_return_if_fail(requisition != NULL);
237 
238 	if(strlen(INV_SWITCH_TOGGLE(widget)->label)>0) {
239 		requisition->width = 76;
240 	} else {
241 		requisition->width = 64;
242 	}
243 
244 	requisition->height = 66;
245 }
246 
247 
248 static void
inv_switch_toggle_size_allocate(GtkWidget * widget,GtkAllocation * allocation)249 inv_switch_toggle_size_allocate(GtkWidget *widget,
250     GtkAllocation *allocation)
251 {
252 	g_return_if_fail(widget != NULL);
253 	g_return_if_fail(INV_IS_SWITCH_TOGGLE(widget));
254 	g_return_if_fail(allocation != NULL);
255 
256 	widget->allocation = *allocation;
257 
258 	if (GTK_WIDGET_REALIZED(widget)) {
259 		gdk_window_move_resize(
260 		   widget->window,
261 		   allocation->x, allocation->y,
262 		   allocation->width, allocation->height
263 		);
264 	}
265 }
266 
267 
268 static void
inv_switch_toggle_realize(GtkWidget * widget)269 inv_switch_toggle_realize(GtkWidget *widget)
270 {
271 	GdkWindowAttr attributes;
272 	guint attributes_mask;
273 
274 	g_return_if_fail(widget != NULL);
275 	g_return_if_fail(INV_IS_SWITCH_TOGGLE(widget));
276 
277 	GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
278 
279 	attributes.window_type = GDK_WINDOW_CHILD;
280 	attributes.x = widget->allocation.x;
281 	attributes.y = widget->allocation.y;
282 	if(strlen(INV_SWITCH_TOGGLE(widget)->label)>0) {
283 		attributes.width = 76;
284 	} else {
285 		attributes.width = 64;
286 	}
287 	attributes.height = 66;
288 
289 	attributes.wclass = GDK_INPUT_OUTPUT;
290 	attributes.event_mask = gtk_widget_get_events(widget) |
291 				GDK_EXPOSURE_MASK |
292 				GDK_BUTTON_PRESS_MASK |
293 				GDK_BUTTON_RELEASE_MASK;
294 
295 	attributes_mask = GDK_WA_X | GDK_WA_Y;
296 
297 	widget->window = gdk_window_new(
298 	  gtk_widget_get_parent_window (widget),
299 	  & attributes, attributes_mask
300 	);
301 
302 	gdk_window_set_user_data(widget->window, widget);
303 
304 	widget->style = gtk_style_attach(widget->style, widget->window);
305 	gtk_style_set_background(widget->style, widget->window, GTK_STATE_NORMAL);
306 }
307 
308 
309 static gboolean
inv_switch_toggle_expose(GtkWidget * widget,GdkEventExpose * event)310 inv_switch_toggle_expose(GtkWidget *widget, GdkEventExpose *event)
311 {
312 	g_return_val_if_fail(widget != NULL, FALSE);
313 	g_return_val_if_fail(INV_IS_SWITCH_TOGGLE(widget), FALSE);
314 	g_return_val_if_fail(event != NULL, FALSE);
315 
316 	inv_switch_toggle_paint(widget,INV_SWITCH_TOGGLE_DRAW_ALL);
317 
318 	return FALSE;
319 }
320 
321 
322 static void
inv_switch_toggle_paint(GtkWidget * widget,gint mode)323 inv_switch_toggle_paint(GtkWidget *widget, gint mode)
324 {
325 	gint 		bypass;
326 	gint 		state;
327 	gint 		laststate;
328 	struct colour	on,off;
329 	char		*on_text;
330 	char		*off_text;
331 	char		*label;
332 	GdkPixbuf 	*img_on;
333 	GdkPixbuf 	*img_off;
334 
335 	gint			i;
336 	float 			indent,topdent,max,grey;
337 	char 			character[2];
338 	cairo_t 		*cr;
339 	GtkStyle		*style;
340 	cairo_text_extents_t 	extents;
341 	cairo_pattern_t 	*pat;
342 
343 	style = gtk_widget_get_style(widget);
344 
345 	bypass = INV_SWITCH_TOGGLE(widget)->bypass;
346 	state = INV_SWITCH_TOGGLE(widget)->state;
347 	laststate = INV_SWITCH_TOGGLE(widget)->laststate;
348 
349 	if(bypass==INV_PLUGIN_BYPASS) {
350 		on.R = (INV_SWITCH_TOGGLE(widget)->on.R + INV_SWITCH_TOGGLE(widget)->on.G + INV_SWITCH_TOGGLE(widget)->on.B)/3;
351 		on.G = on.R;
352 		on.B = on.R;
353 		off.R = (INV_SWITCH_TOGGLE(widget)->off.R + INV_SWITCH_TOGGLE(widget)->off.G + INV_SWITCH_TOGGLE(widget)->off.B)/3;
354 		off.G = off.R;
355 		off.B = off.R;
356 	} else {
357 		on.R = INV_SWITCH_TOGGLE(widget)->on.R;
358 		on.G = INV_SWITCH_TOGGLE(widget)->on.G;
359 		on.B = INV_SWITCH_TOGGLE(widget)->on.B;
360 		off.R = INV_SWITCH_TOGGLE(widget)->off.R;
361 		off.G = INV_SWITCH_TOGGLE(widget)->off.G;
362 		off.B = INV_SWITCH_TOGGLE(widget)->off.B;
363 	}
364 	on_text = INV_SWITCH_TOGGLE(widget)->on_text;
365 	off_text = INV_SWITCH_TOGGLE(widget)->off_text;
366 	label = INV_SWITCH_TOGGLE(widget)->label;
367 	img_on = INV_SWITCH_TOGGLE(widget)->img_on;
368 	img_off = INV_SWITCH_TOGGLE(widget)->img_off;
369 
370 	cr = gdk_cairo_create(widget->window);
371 
372 	if(INV_SWITCH_TOGGLE(widget)->font_size==0) {
373 		INV_SWITCH_TOGGLE(widget)->font_size=inv_choose_font_size(cr,"sans-serif",CAIRO_FONT_SLANT_NORMAL,CAIRO_FONT_WEIGHT_NORMAL,7.1,7.1,"O");
374 	}
375 
376 
377 	indent = strlen(label)>0 ? 12.0 : 0.0;
378 
379 	if(mode==INV_SWITCH_TOGGLE_DRAW_ALL) {
380 
381 		gdk_cairo_set_source_color(cr,&style->bg[GTK_STATE_NORMAL]);
382 		cairo_paint(cr);
383 
384 		cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
385 		cairo_set_antialias (cr,CAIRO_ANTIALIAS_NONE);
386 		cairo_set_line_width(cr,1);
387 
388 		gdk_cairo_set_source_color(cr,&style->dark[GTK_STATE_NORMAL]);
389 		cairo_move_to(cr, indent, 13);
390 		cairo_line_to(cr, 63+indent, 13);
391 		cairo_line_to(cr, 63+indent, 0);
392 		cairo_move_to(cr, indent, 65);
393 		cairo_line_to(cr, 63+indent, 65);
394 		cairo_line_to(cr, 63+indent, 52);
395 		cairo_stroke(cr);
396 
397 		gdk_cairo_set_source_color(cr,&style->light[GTK_STATE_NORMAL]);
398 		cairo_move_to(cr, indent, 13);
399 		cairo_line_to(cr, indent, 0);
400 		cairo_line_to(cr, 63+indent, 0);
401 		cairo_move_to(cr, indent, 65);
402 		cairo_line_to(cr, indent, 52);
403 		cairo_line_to(cr, 63+indent, 52);
404 		cairo_stroke(cr);
405 
406 		cairo_set_antialias (cr,CAIRO_ANTIALIAS_DEFAULT);
407 		cairo_new_path(cr);
408 
409 		if(strlen(label)>0) {
410 			if(inv_choose_light_dark(&style->bg[GTK_STATE_NORMAL],&style->light[GTK_STATE_NORMAL],&style->dark[GTK_STATE_NORMAL])==1) {
411 				gdk_cairo_set_source_color(cr,&style->light[GTK_STATE_NORMAL]);
412 			} else {
413 				gdk_cairo_set_source_color(cr,&style->dark[GTK_STATE_NORMAL]);
414 			}
415 			cairo_set_antialias (cr,CAIRO_ANTIALIAS_NONE);
416 			cairo_set_line_width(cr,1);
417 			cairo_rectangle(cr, 0, 1, 10, 64);
418 			cairo_stroke(cr);
419 
420 			cairo_set_antialias (cr,CAIRO_ANTIALIAS_DEFAULT);
421 			cairo_select_font_face(cr,"sans-serif",CAIRO_FONT_SLANT_NORMAL,CAIRO_FONT_WEIGHT_NORMAL);
422 			gdk_cairo_set_source_color(cr,&style->fg[GTK_STATE_NORMAL]);
423 			cairo_set_font_size(cr,INV_SWITCH_TOGGLE(widget)->font_size);
424 			topdent=42.0-(8.0*(float)(strlen(label))/2);
425 			for(i=0; i<strlen(label); i++) {
426 				character[0]=label[i];
427 				character[1]='\0';
428 				cairo_text_extents (cr,character,&extents);
429 				cairo_move_to(cr,extents.width<=2? 4:2, topdent+((float)i*8.0));
430 				cairo_show_text(cr,character);
431 			}
432 		}
433 	}
434 
435 	cairo_select_font_face(cr,"sans-serif",CAIRO_FONT_SLANT_NORMAL,CAIRO_FONT_WEIGHT_NORMAL);
436 	cairo_set_font_size(cr,INV_SWITCH_TOGGLE(widget)->font_size);
437 
438 	if(inv_choose_light_dark(&style->bg[GTK_STATE_NORMAL],&style->light[GTK_STATE_NORMAL],&style->dark[GTK_STATE_NORMAL])==1) {
439 		gdk_cairo_set_source_color(cr,&style->light[GTK_STATE_NORMAL]);
440 	} else {
441 		gdk_cairo_set_source_color(cr,&style->dark[GTK_STATE_NORMAL]);
442 	}
443 
444 	switch(state) {
445 		case INV_SWITCH_TOGGLE_ON:
446 
447 			max = off.R > off.G ? off.R : off.G;
448 			max = off.B > max ? off.B : max;
449 			grey=max/3;
450 
451 			cairo_set_source_rgb(cr, grey/3, grey/3, grey/3);
452 			cairo_rectangle(cr, 1+indent, 1, 62, 13);
453 			cairo_fill(cr);
454 
455 			cairo_set_source_rgb(cr, grey, grey, grey);
456 			cairo_text_extents (cr,off_text,&extents);
457 			cairo_move_to(cr,31+indent-(extents.width/2), 11);
458 			cairo_show_text(cr,off_text);
459 
460 			pat = cairo_pattern_create_linear (indent, 0.0,  66.0+indent, 0.0);
461 			cairo_pattern_add_color_stop_rgba (pat, 0.0, on.R/6, on.G/6, on.B/6, 1);
462 			cairo_pattern_add_color_stop_rgba (pat, 0.3, on.R/3, on.G/3, on.B/3, 1);
463 			cairo_pattern_add_color_stop_rgba (pat, 0.5, on.R/2, on.G/2, on.B/2, 1);
464 			cairo_pattern_add_color_stop_rgba (pat, 0.7, on.R/3, on.G/3, on.B/3, 1);
465 			cairo_pattern_add_color_stop_rgba (pat, 1.0, on.R/6, on.G/6, on.B/6, 1);
466 			cairo_set_source (cr, pat);
467 			cairo_rectangle(cr, 1+indent, 53, 62, 13);
468 			cairo_fill(cr);
469 
470 			cairo_set_source_rgb(cr, on.R, on.G, on.B);
471 			cairo_text_extents (cr,on_text,&extents);
472 			cairo_move_to(cr,31+indent-(extents.width/2), 63);
473 			cairo_show_text(cr,on_text);
474 
475 			cairo_save(cr);
476 			cairo_arc(cr,32+indent,33.5,12,0,2*INV_PI);
477 			cairo_clip(cr);
478 
479 			gdk_cairo_set_source_pixbuf(cr,img_on, 32+indent-12.5, 33.5-12.5);
480 			cairo_paint(cr);
481 
482 			cairo_restore(cr);
483 
484 			break;
485 
486 		case INV_SWITCH_TOGGLE_OFF:
487 
488 			pat = cairo_pattern_create_linear (indent, 0.0,  66.0+indent, 0.0);
489 			cairo_pattern_add_color_stop_rgba (pat, 0.0, off.R/6, off.G/6, off.B/6, 1);
490 			cairo_pattern_add_color_stop_rgba (pat, 0.3, off.R/3, off.G/3, off.B/3, 1);
491 			cairo_pattern_add_color_stop_rgba (pat, 0.5, off.R/2, off.G/2, off.B/2, 1);
492 			cairo_pattern_add_color_stop_rgba (pat, 0.7, off.R/3, off.G/3, off.B/3, 1);
493 			cairo_pattern_add_color_stop_rgba (pat, 1.0, off.R/6, off.G/6, off.B/6, 1);
494 			cairo_set_source (cr, pat);
495 			cairo_rectangle(cr, 1+indent, 1, 62, 13);
496 			cairo_fill(cr);
497 
498 			cairo_set_source_rgb(cr, off.R, off.G, off.B);
499 			cairo_text_extents (cr,off_text,&extents);
500 			cairo_move_to(cr,31+indent-(extents.width/2), 11);
501 			cairo_show_text(cr,off_text);
502 
503 			max = on.R > on.G ? on.R : on.G;
504 			max = on.B > max ? on.B : max;
505 			grey=max/3;
506 
507 			cairo_set_source_rgb(cr, grey/3, grey/3, grey/3);
508 			cairo_rectangle(cr, 1+indent, 53, 62, 13);
509 			cairo_fill(cr);
510 
511 			cairo_set_source_rgb(cr, grey, grey, grey);
512 			cairo_text_extents (cr,on_text,&extents);
513 			cairo_move_to(cr,31+indent-(extents.width)/2, 63);
514 			cairo_show_text(cr,on_text);
515 
516 			cairo_save(cr);
517 			cairo_arc(cr,32+indent,33.5,12,0,2*INV_PI);
518 			cairo_clip(cr);
519 
520 			gdk_cairo_set_source_pixbuf(cr,img_off, 32+indent-12.5, 33.5-12.5);
521 			cairo_paint(cr);
522 
523 			cairo_restore(cr);
524 
525 			break;
526 	}
527 
528 	cairo_save(cr);
529 
530 	cairo_move_to(cr,32+indent,50.5);
531 	for(i=1;i<=6;i++) {
532 		cairo_line_to(cr,32+indent+17*sin(i*INV_PI/3),33.5+17*cos(i*INV_PI/3));
533 	}
534 	cairo_clip(cr);
535 
536 	pat = cairo_pattern_create_linear (indent, 0.0,  66.0+indent, 64.0);
537 	cairo_pattern_add_color_stop_rgba (pat, 0.0, 1.00, 1.00, 1.00, 1);
538 	cairo_pattern_add_color_stop_rgba (pat, 0.32, 0.91, 0.89, 0.83, 1);
539 	cairo_pattern_add_color_stop_rgba (pat, 0.5, 0.43, 0.32, 0.26, 1);
540 	cairo_pattern_add_color_stop_rgba (pat, 0.68, 0.10, 0.05, 0.04, 1);
541 	cairo_pattern_add_color_stop_rgba (pat, 1.0, 0.00, 0.00, 0.00, 1);
542 	cairo_set_source (cr, pat);
543 	cairo_set_line_width(cr,5);
544 	cairo_arc(cr,32+indent,33.5,14.5,0,2*INV_PI);
545 	cairo_stroke(cr);
546 
547 	cairo_restore(cr);
548 
549   	cairo_destroy(cr);
550 }
551 
552 static gboolean
inv_switch_toggle_button_press_event(GtkWidget * widget,GdkEventButton * event)553 inv_switch_toggle_button_press_event (GtkWidget *widget, GdkEventButton *event)
554 {
555 	g_assert(INV_IS_SWITCH_TOGGLE(widget));
556 	gtk_widget_set_state(widget,GTK_STATE_ACTIVE);
557     	gtk_widget_grab_focus(widget);
558 
559 	inv_switch_toggle_paint(widget,INV_SWITCH_TOGGLE_DRAW_ALL);
560 
561 	return TRUE;
562 }
563 
564 
565 static gboolean
inv_switch_toggle_button_release_event(GtkWidget * widget,GdkEventButton * event)566 inv_switch_toggle_button_release_event (GtkWidget *widget, GdkEventButton *event)
567 {
568 	g_assert(INV_IS_SWITCH_TOGGLE(widget));
569 	gtk_widget_set_state(widget,GTK_STATE_NORMAL);
570 
571 	inv_switch_toggle_toggle(INV_SWITCH_TOGGLE (widget)); //this will also paint the widget
572 
573 	return FALSE;  //let the signal in the gui run now
574 }
575 
576 static void
inv_switch_toggle_destroy(GtkObject * object)577 inv_switch_toggle_destroy(GtkObject *object)
578 {
579 	InvSwitchToggle *switch_toggle;
580 	InvSwitchToggleClass *klass;
581 
582 	g_return_if_fail(object != NULL);
583 	g_return_if_fail(INV_IS_SWITCH_TOGGLE(object));
584 
585 	switch_toggle = INV_SWITCH_TOGGLE(object);
586 
587 	klass = gtk_type_class(gtk_widget_get_type());
588 
589 	if (GTK_OBJECT_CLASS(klass)->destroy) {
590 		(* GTK_OBJECT_CLASS(klass)->destroy) (object);
591 	}
592 }
593 
594 
595 
596 
597