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