00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00028
00029 #include <string.h>
00030 #include <gtk/gtk.h>
00031
00032
00033
00034
00035 #include "ergtklog.h"
00036 #include "erGtkToggleButton.h"
00037
00038
00039
00040 static GtkToggleButtonClass* g_parent_class = NULL;
00041
00042
00043
00044 static const struct
00045 {
00046 guint width;
00047 guint height;
00048 const gchar* style;
00049 } g_style_tbl[]
00050 = {
00051 { 130, 27, "erGtkToggleButton_130_27" },
00052 { 150, 27, "erGtkToggleButton_150_27" },
00053 { 200, 27, "erGtkToggleButton_200_27" },
00054 { 310, 27, "erGtkToggleButton_310_27" },
00055 { 640, 44, "erGtkToggleButton_640_44" },
00056 { 0, 0, "" }
00057 };
00058 #define DEFAULT_STYLE_INDEX 0
00059 #define STYLE_PREFIX "erGtkToggleButton"
00060 #define STYLE_PREFIX_LEN strlen(STYLE_PREFIX)
00061
00062
00063
00064
00065 static void ergtk_toggle_button_notify(GObject* object, GParamSpec* pspec);
00066 static gboolean ergtk_toggle_button_expose_event(GtkWidget* widget, GdkEventExpose* event);
00067 static void ergtk_toggle_button_toggled(GtkToggleButton* toggleButton);
00068
00069
00070
00071
00072 static void ergtk_toggle_button_class_init(erGtkToggleButtonClass* klass);
00073 static void ergtk_toggle_button_init(erGtkToggleButton* input_entry);
00074 static void fix_label_colour(erGtkToggleButton* toggleButton);
00075
00076
00077 GtkWidget* ergtk_toggle_button_new()
00078 {
00079 erGtkToggleButton* item = (erGtkToggleButton*) g_object_new(ERGTK_TOGGLE_BUTTON_TYPE, NULL);
00080
00081 GtkWidget* widget = (GtkWidget*)item;
00082 GTK_WIDGET_UNSET_FLAGS(widget, GTK_CAN_FOCUS);
00083
00084 return widget;
00085 }
00086
00087 GtkWidget* ergtk_toggle_button_new_with_label(const gchar *label)
00088 {
00089 erGtkToggleButton* item = (erGtkToggleButton*) g_object_new(ERGTK_TOGGLE_BUTTON_TYPE, "label", label, NULL);
00090
00091 GtkWidget* widget = (GtkWidget*)item;
00092 GTK_WIDGET_UNSET_FLAGS(widget, GTK_CAN_FOCUS);
00093
00094 return widget;
00095 }
00096
00097 GType ergtk_toggle_button_get_type(void)
00098 {
00099 static GType class_type = 0;
00100
00101 if (class_type == 0)
00102 {
00103 static const GTypeInfo class_info =
00104 {
00105 sizeof(erGtkToggleButtonClass),
00106 NULL,
00107 NULL,
00108 (GClassInitFunc) ergtk_toggle_button_class_init,
00109 NULL,
00110 NULL,
00111 sizeof(erGtkToggleButton),
00112 0,
00113 (GInstanceInitFunc) ergtk_toggle_button_init,
00114 };
00115 class_type = g_type_register_static(GTK_TYPE_TOGGLE_BUTTON, "erGtkToggleButton", &class_info, 0);
00116 }
00117
00118 return class_type;
00119 }
00120
00121
00122 static void ergtk_toggle_button_class_init(erGtkToggleButtonClass* klass)
00123 {
00124 LOGPRINTF("entry");
00125
00126 GObjectClass* object_class = (GObjectClass* )klass;
00127 GtkWidgetClass* widget_class = (GtkWidgetClass* )klass;
00128 GtkToggleButtonClass* toggleButton_class = (GtkToggleButtonClass*)klass;
00129
00130
00131 g_parent_class = g_type_class_peek_parent(klass);
00132
00133
00134 object_class->notify = ergtk_toggle_button_notify;
00135
00136 widget_class->expose_event = ergtk_toggle_button_expose_event;
00137
00138 toggleButton_class->toggled = ergtk_toggle_button_toggled;
00139 }
00140
00141
00142 static void ergtk_toggle_button_init(erGtkToggleButton* item)
00143 {
00144 LOGPRINTF("entry");
00145 g_return_if_fail(ERGTK_IS_TOGGLE_BUTTON(item));
00146
00147 GtkWidget* widget = (GtkWidget*)item;
00148
00149
00150 gtk_widget_set_size_request( widget,
00151 g_style_tbl[DEFAULT_STYLE_INDEX].width,
00152 g_style_tbl[DEFAULT_STYLE_INDEX].height );
00153 }
00154
00155
00156
00157
00158
00159
00160 static void ergtk_toggle_button_notify(GObject* object, GParamSpec* pspec)
00161 {
00162 g_return_if_fail(ERGTK_IS_TOGGLE_BUTTON(object));
00163
00164 int i;
00165 gint width;
00166 const gchar* name = pspec->name;
00167 GtkWidget* widget = (GtkWidget*)object;
00168 const gchar* widget_name;
00169
00170
00171 GObjectClass* parent_object_class = G_OBJECT_CLASS(g_parent_class);
00172 if (parent_object_class->notify)
00173 {
00174 parent_object_class->notify(object, pspec);
00175 }
00176
00177 if (strcmp(name, "width-request") == 0)
00178 {
00179
00180 g_object_get(object, name, &width, NULL);
00181 widget_name = gtk_widget_get_name(widget);
00182 if ( strcmp(widget_name, "erGtkToggleButton") == 0
00183 || strncmp(widget_name, STYLE_PREFIX, STYLE_PREFIX_LEN) == 0 )
00184 {
00185 i = 0;
00186 while (width > g_style_tbl[i].width && g_style_tbl[i+1].width != 0)
00187 {
00188 i++;
00189 }
00190 gtk_widget_set_name(widget, g_style_tbl[i].style);
00191 }
00192 }
00193 }
00194
00195 static gboolean ergtk_toggle_button_expose_event(GtkWidget* widget, GdkEventExpose* event)
00196 {
00197 g_return_val_if_fail(ERGTK_IS_TOGGLE_BUTTON(widget), FALSE);
00198
00199
00200 GtkWidgetClass* parent_widget_class = GTK_WIDGET_CLASS(g_parent_class);
00201 if (parent_widget_class->expose_event)
00202 {
00203 parent_widget_class->expose_event(widget, event);
00204 }
00205
00206 fix_label_colour(ERGTK_TOGGLE_BUTTON(widget));
00207
00208 return FALSE;
00209 }
00210
00211 static void ergtk_toggle_button_toggled(GtkToggleButton* toggleButton)
00212 {
00213 g_return_if_fail(ERGTK_IS_TOGGLE_BUTTON(toggleButton));
00214
00215
00216 if (g_parent_class->toggled)
00217 {
00218 g_parent_class->toggled(toggleButton);
00219 }
00220
00221 fix_label_colour(ERGTK_TOGGLE_BUTTON(toggleButton));
00222 }
00223
00224 static void fix_label_colour(erGtkToggleButton* erToggleButton)
00225 {
00226
00227
00228
00229
00230 gboolean active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(erToggleButton));
00231 GtkWidget* label = gtk_bin_get_child(GTK_BIN(erToggleButton));
00232 GtkStyle* style = gtk_widget_get_style(label);
00233 GtkStateType betterstate;
00234 if (active)
00235 {
00236 betterstate = GTK_STATE_ACTIVE;
00237 }
00238 else
00239 {
00240 betterstate = GTK_STATE_NORMAL;
00241 }
00242
00243
00244
00245 if (memcmp( &(style->fg[GTK_STATE_PRELIGHT]), &(style->fg[betterstate]), sizeof(style->fg[0])) != 0)
00246 {
00247 gtk_widget_modify_fg(label, GTK_STATE_PRELIGHT, &(style->fg[betterstate]));
00248 }
00249 }
00250