5 * Copyright (C) 2002-2005 Monty
7 * Postfish 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, or (at your option)
12 * Postfish 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.
17 * You should have received a copy of the GNU General Public License
18 * along with Postfish; see the file COPYING. If not, write to the
19 * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "windowbutton.h"
26 static GtkCheckButtonClass
*parent_class
= NULL
;
28 static void draw_triangle (GtkStyle
*style
,
30 GtkStateType state_type
,
31 GtkShadowType shadow_type
,
36 GdkGC
*gc
=style
->bg_gc
[state_type
];
37 GdkGC
*light_gc
=style
->light_gc
[state_type
];
38 GdkGC
*dark_gc
=style
->dark_gc
[state_type
];
39 GdkGC
*black_gc
=style
->black_gc
;
42 /* fill the main triangle */
44 gdk_draw_line(window
,gc
,x
+i
,y
+((i
)>>1),x
+i
,y
+size
-1-((i
)>>1));
49 case GTK_SHADOW_ETCHED_IN
:
51 if(y
+size
-1-(i
>>1) > y
+(i
>>1)+1){
52 gdk_draw_point(window
,dark_gc
,x
+i
,y
+size
-1-(i
>>1)-1);
53 gdk_draw_point(window
,light_gc
,x
+i
,y
+(i
>>1)+1);
55 gdk_draw_point(window
,light_gc
,x
+i
,y
+size
-1-(i
>>1));
56 gdk_draw_point(window
,dark_gc
,x
+i
,y
+(i
>>1));
58 gdk_draw_line(window
,dark_gc
,x
,y
,x
,y
+size
-1);
59 gdk_draw_line(window
,light_gc
,x
+1,y
+1,x
+1,y
+size
-2);
64 if(y
+size
-1-(i
>>1) > y
+(i
>>1)+1)
65 gdk_draw_point(window
,black_gc
,x
+i
,y
+(i
>>1)+1);
66 gdk_draw_point(window
,light_gc
,x
+i
,y
+size
-1-(i
>>1));
67 gdk_draw_point(window
,dark_gc
,x
+i
,y
+(i
>>1));
69 gdk_draw_line(window
,dark_gc
,x
,y
,x
,y
+size
-1);
70 gdk_draw_line(window
,black_gc
,x
+1,y
+1,x
+1,y
+size
-2);
76 if(y
+size
-1-(i
>>1)-1 > y
+(i
>>1))
77 gdk_draw_point(window
,dark_gc
,x
+i
,y
+size
-1-(i
>>1)-1);
78 gdk_draw_point(window
,light_gc
,x
+i
,y
+(i
>>1));
79 gdk_draw_point(window
,black_gc
,x
+i
,y
+size
-1-(i
>>1));
81 gdk_draw_line(window
,light_gc
,x
,y
,x
,y
+size
-2);
85 case GTK_SHADOW_ETCHED_OUT
:
86 /* unimplemented, unused */
92 static void windowbutton_get_props (GtkCheckButton
*check_button
,
94 gint
*indicator_spacing
){
95 GtkWidget
*widget
= GTK_WIDGET (check_button
);
98 gtk_widget_style_get (widget
, "indicator_size", indicator_size
, NULL
);
100 if (indicator_spacing
)
101 gtk_widget_style_get (widget
, "indicator_spacing", indicator_spacing
, NULL
);
104 static void windowbutton_draw_indicator (GtkCheckButton
*check_button
,
109 GtkToggleButton
*toggle_button
;
110 GtkStateType state_type
;
111 GtkShadowType shadow_type
;
114 gint indicator_spacing
;
117 gboolean interior_focus
;
119 if (GTK_WIDGET_DRAWABLE (check_button
)){
121 widget
= GTK_WIDGET (check_button
);
122 button
= GTK_BUTTON (check_button
);
123 toggle_button
= GTK_TOGGLE_BUTTON (check_button
);
125 gtk_widget_style_get (widget
, "interior_focus", &interior_focus
,
126 "focus-line-width", &focus_width
,
127 "focus-padding", &focus_pad
, NULL
);
129 windowbutton_get_props (check_button
, &indicator_size
,
132 x
= widget
->allocation
.x
+
133 indicator_spacing
+ GTK_CONTAINER (widget
)->border_width
;
134 y
= widget
->allocation
.y
+
135 (widget
->allocation
.height
- indicator_size
) / 2;
137 child
= GTK_BIN (check_button
)->child
;
138 if (!interior_focus
|| !(child
&& GTK_WIDGET_VISIBLE (child
)))
139 x
+= focus_width
+ focus_pad
;
141 if (toggle_button
->inconsistent
)
142 shadow_type
= GTK_SHADOW_ETCHED_IN
;
143 else if (toggle_button
->active
)
144 shadow_type
= GTK_SHADOW_IN
;
146 shadow_type
= GTK_SHADOW_OUT
;
148 if (button
->activate_timeout
|| (toggle_button
->active
))
149 state_type
= GTK_STATE_ACTIVE
;
150 else if (button
->in_button
)
151 state_type
= GTK_STATE_PRELIGHT
;
152 else if (!GTK_WIDGET_IS_SENSITIVE (widget
)){
153 state_type
= GTK_STATE_INSENSITIVE
;
154 shadow_type
= GTK_SHADOW_ETCHED_IN
;
156 state_type
= GTK_STATE_NORMAL
;
158 if (gtk_widget_get_direction (widget
) == GTK_TEXT_DIR_RTL
)
159 x
= widget
->allocation
.x
+ widget
->allocation
.width
-
160 (indicator_size
+ x
- widget
->allocation
.x
);
162 draw_triangle (widget
->style
, widget
->window
,
163 state_type
, shadow_type
,
164 x
, y
, indicator_size
);
169 static void windowbutton_class_init (WindowbuttonClass
*class){
170 GtkCheckButtonClass
*cb_class
= (GtkCheckButtonClass
*) class;
171 parent_class
= g_type_class_peek_parent (class);
172 cb_class
->draw_indicator
= windowbutton_draw_indicator
;
175 static void windowbutton_init (Windowbutton
*r
){
178 GType
windowbutton_get_type (void){
179 static GType m_type
= 0;
181 static const GTypeInfo m_info
={
182 sizeof (WindowbuttonClass
),
183 NULL
, /* base_init */
184 NULL
, /* base_finalize */
185 (GClassInitFunc
) windowbutton_class_init
,
186 NULL
, /* class_finalize */
187 NULL
, /* class_data */
188 sizeof (Windowbutton
),
190 (GInstanceInitFunc
) windowbutton_init
,
194 m_type
= g_type_register_static (GTK_TYPE_CHECK_BUTTON
, "Windowbutton", &m_info
, 0);
200 GtkWidget
* windowbutton_new (char *markup
){
201 return g_object_new (windowbutton_get_type (),
203 "use_underline", TRUE
, NULL
);