#include <string.h>
#include <ctype.h>
#include <gtk/gtk.h>
#include "ergtklog.h"
#include "erGtkEntry.h"
#include "erGtkEntryFilter.h"
Go to the source code of this file.
Enumerations | |
enum | { SIGNAL_CHANGED_STABLE = 0, SIGNAL_SCREEN_REFRESH, LAST_SIGNAL } |
Functions | |
static void | ergtk_entry_grab_focus (GtkWidget *widget) |
static void | ergtk_entry_notify (GObject *object, GParamSpec *pspec) |
static gboolean | ergtk_entry_focus_in (GtkWidget *widget, GdkEventFocus *event) |
static gboolean | ergtk_entry_focus_out (GtkWidget *widget, GdkEventFocus *event) |
static gboolean | ergtk_entry_focus (GtkWidget *widget, GtkDirectionType arg1) |
static gboolean | ergtk_entry_button_release (GtkWidget *widget, GdkEventButton *event) |
static void | ergtk_entry_move_cursor (GtkEntry *widget, GtkMovementStep arg1, gint arg2, gboolean arg3) |
static void | ergtk_entry_changed (GtkEditable *widget) |
static void | ergtk_entry_real_set_text (erGtkEntry *er_entry, const gchar *text) |
static void | ergtk_entry_class_init (erGtkEntryClass *klass) |
static void | ergtk_entry_editable_init (GtkEditableClass *iface) |
static void | ergtk_entry_init (erGtkEntry *input_entry) |
static gboolean | ergtk_entry_delayed_changed_or_movecursor (gpointer user_data) |
GtkWidget * | ergtk_entry_new () |
void | ergtk_entry_set_ipv4_filter (erGtkEntry *er_entry) |
void | ergtk_entry_set_integer_filter (erGtkEntry *er_entry) |
gboolean | ergtk_entry_check_field (erGtkEntry *er_entry) |
GType | ergtk_entry_get_type (void) |
void | ergtk_entry_set_text (erGtkEntry *er_entry, const gchar *text) |
Variables | |
static GtkEntryClass * | g_parent_class = NULL |
static gint | g_signals [LAST_SIGNAL] |
Emits signal "changed-stable" shortly after the latest change of the entry text. Emits signal "screen-refresh" when a screen refresh is needed for the entry object.
Copyright (C) 2007 iRex Technologies B.V. All rights reserved.
Definition in file erGtkEntry.c.
anonymous enum |
Definition at line 49 of file erGtkEntry.c.
00050 { 00051 SIGNAL_CHANGED_STABLE = 0, // changed + additional delay to wait for next signal 00052 SIGNAL_SCREEN_REFRESH, // request screen refresh 00053 LAST_SIGNAL 00054 };
static gboolean ergtk_entry_button_release | ( | GtkWidget * | widget, | |
GdkEventButton * | event | |||
) | [static] |
Definition at line 460 of file erGtkEntry.c.
00461 { 00462 g_return_val_if_fail(ERGTK_IS_ENTRY(widget), FALSE); 00463 00464 gboolean rc = FALSE; 00465 erGtkEntry* er_entry = (erGtkEntry*)widget; 00466 00467 // chain to parent class 00468 if (g_parent_class->parent_class.button_release_event) 00469 { 00470 rc = g_parent_class->parent_class.button_release_event(widget, event); 00471 } 00472 00473 g_signal_emit(er_entry, g_signals[SIGNAL_SCREEN_REFRESH], 0, GTK_WIDGET(er_entry), NULL); 00474 return rc; 00475 }
static void ergtk_entry_changed | ( | GtkEditable * | widget | ) | [static] |
Definition at line 403 of file erGtkEntry.c.
00404 { 00405 g_return_if_fail(ERGTK_IS_ENTRY(editable)); 00406 00407 erGtkEntry* er_entry = (erGtkEntry*)editable; 00408 GtkEntry* entry = (GtkEntry*)editable; 00409 GtkWidget* widget = (GtkWidget*)editable; 00410 00411 // for protected object, show content when empty 00412 if ( er_entry->visible == FALSE 00413 && gtk_widget_is_focus(widget) ) 00414 { 00415 const gchar* text = gtk_entry_get_text(entry); 00416 if (text[0] == '\0') 00417 { 00418 gtk_entry_set_visibility(entry, TRUE); 00419 } 00420 } 00421 00422 if (er_entry->changed_pending) 00423 { 00424 // changed event from ..set_text() -> ignore 00425 er_entry->changed_pending = FALSE; 00426 } 00427 else 00428 { 00429 // (re)start timer that will do the display update 00430 if (er_entry->timeout_id > 0) 00431 { 00432 g_source_remove(er_entry->timeout_id); 00433 } 00434 er_entry->timeout_id = g_timeout_add(300, ergtk_entry_delayed_changed_or_movecursor, er_entry); 00435 er_entry->changed_occurred = TRUE; 00436 } 00437 }
gboolean ergtk_entry_check_field | ( | erGtkEntry * | er_entry | ) |
Definition at line 103 of file erGtkEntry.c.
00104 { 00105 GtkEntry *entry; 00106 const gchar *text; 00107 gint i, len, ret; 00108 gboolean valid = FALSE; 00109 00110 g_return_val_if_fail(ERGTK_IS_ENTRY(er_entry), FALSE); 00111 00112 entry = GTK_ENTRY(er_entry); 00113 text = gtk_entry_get_text(entry); 00114 if (text && (text[0] != '\0')) 00115 { 00116 switch (er_entry->filter) 00117 { 00118 case ipAddress_e: 00119 ret = ipv4_filter_check_address(text); 00120 if (ret == ipv4Complete_e) 00121 { 00122 valid = TRUE; 00123 } 00124 break; 00125 00126 case integer_e: 00127 valid = TRUE; 00128 len = strlen(text); 00129 for (i = 0; i < len; i++) 00130 { 00131 if (!isdigit(text[i])) 00132 { 00133 valid = FALSE; 00134 break; 00135 } 00136 } 00137 break; 00138 case string_e: 00139 default: 00140 valid = TRUE; 00141 break; 00142 } 00143 } 00144 00145 LOGPRINTF("return %d", valid); 00146 return valid; 00147 }
static void ergtk_entry_class_init | ( | erGtkEntryClass * | klass | ) | [static] |
Definition at line 182 of file erGtkEntry.c.
00183 { 00184 LOGPRINTF("entry"); 00185 00186 GObjectClass* object_class = (GObjectClass* )klass; 00187 GtkWidgetClass* widget_class = (GtkWidgetClass*)klass; 00188 GtkEntryClass* entry_class = (GtkEntryClass* )klass; 00189 00190 // remember parent class struct, needed for chaining up to parent class 00191 g_parent_class = g_type_class_peek_parent(klass); 00192 00193 // overload some virtual methods 00194 object_class->notify = ergtk_entry_notify; 00195 // 00196 widget_class->button_release_event = ergtk_entry_button_release; 00197 widget_class->focus_in_event = ergtk_entry_focus_in; 00198 widget_class->focus_out_event = ergtk_entry_focus_out; 00199 widget_class->focus = ergtk_entry_focus; 00200 widget_class->grab_focus = ergtk_entry_grab_focus; 00201 // 00202 entry_class->move_cursor = ergtk_entry_move_cursor; 00203 // 00204 klass->set_text = ergtk_entry_real_set_text; 00205 00206 // event to notify entry text has changed 00207 g_signals[SIGNAL_CHANGED_STABLE] = g_signal_new( "changed-stable", 00208 G_OBJECT_CLASS_TYPE(object_class), 00209 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, 00210 G_STRUCT_OFFSET(erGtkEntryClass, changed_stable), // class closure 00211 NULL, // accumulator 00212 NULL, // accu data 00213 gtk_marshal_VOID__VOID, 00214 G_TYPE_NONE, // return type 00215 0, // #params 00216 0 ); // param types 00217 // event to notify screen refresh is needed 00218 g_signals[SIGNAL_SCREEN_REFRESH] = g_signal_new( "screen-refresh", 00219 G_OBJECT_CLASS_TYPE(object_class), 00220 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE, 00221 G_STRUCT_OFFSET(erGtkEntryClass, screen_refresh), // class closure 00222 NULL, // accumulator 00223 NULL, // accu data 00224 gtk_marshal_VOID__VOID, 00225 G_TYPE_NONE, // return type 00226 0, // #params 00227 0 ); // param types 00228 }
static gboolean ergtk_entry_delayed_changed_or_movecursor | ( | gpointer | user_data | ) | [static] |
Definition at line 477 of file erGtkEntry.c.
00478 { 00479 g_assert(ERGTK_IS_ENTRY(user_data)); 00480 00481 erGtkEntry* er_entry = (erGtkEntry*)user_data; 00482 00483 // inform clients 00484 if (er_entry->movecursor_occurred) 00485 { 00486 er_entry->movecursor_occurred = FALSE; 00487 g_signal_emit(er_entry, g_signals[SIGNAL_SCREEN_REFRESH], 0, GTK_WIDGET(er_entry), NULL); 00488 } 00489 if (er_entry->changed_occurred) 00490 { 00491 er_entry->changed_occurred = FALSE; 00492 g_signal_emit(er_entry, g_signals[SIGNAL_CHANGED_STABLE], 0, GTK_WIDGET(er_entry), NULL); 00493 g_signal_emit(er_entry, g_signals[SIGNAL_SCREEN_REFRESH], 0, GTK_WIDGET(er_entry), NULL); 00494 } 00495 00496 er_entry->timeout_id = 0; 00497 return FALSE; // FALSE = don't call again 00498 }
static void ergtk_entry_editable_init | ( | GtkEditableClass * | iface | ) | [static] |
Definition at line 231 of file erGtkEntry.c.
00232 { 00233 iface->changed = ergtk_entry_changed; 00234 }
static gboolean ergtk_entry_focus | ( | GtkWidget * | widget, | |
GtkDirectionType | arg1 | |||
) | [static] |
Definition at line 374 of file erGtkEntry.c.
00375 { 00376 g_return_val_if_fail(ERGTK_IS_ENTRY(widget), FALSE); 00377 00378 gboolean rc = FALSE; 00379 erGtkEntry* er_entry = (erGtkEntry*)widget; 00380 00381 // chain to parent class 00382 if (g_parent_class->parent_class.focus) 00383 { 00384 rc = g_parent_class->parent_class.focus(widget, arg1); 00385 } 00386 00387 g_signal_emit(er_entry, g_signals[SIGNAL_SCREEN_REFRESH], 0, GTK_WIDGET(er_entry), NULL); 00388 return rc; 00389 }
static gboolean ergtk_entry_focus_in | ( | GtkWidget * | widget, | |
GdkEventFocus * | event | |||
) | [static] |
Definition at line 320 of file erGtkEntry.c.
00321 { 00322 g_return_val_if_fail(ERGTK_IS_ENTRY(widget), FALSE); 00323 00324 gboolean rc = FALSE; 00325 GtkEntry* entry = (GtkEntry*)widget; 00326 erGtkEntry* er_entry = (erGtkEntry*)widget; 00327 00328 // chain to parent class 00329 if (g_parent_class->parent_class.focus_in_event) 00330 { 00331 rc = g_parent_class->parent_class.focus_in_event(widget, event); 00332 } 00333 00334 // if protected, show content when empty 00335 er_entry->visible = gtk_entry_get_visibility(entry); 00336 if (er_entry->visible == FALSE) 00337 { 00338 const gchar* text = gtk_entry_get_text(entry); 00339 if (text[0] == '\0') 00340 { 00341 gtk_entry_set_visibility(entry, TRUE); 00342 } 00343 } 00344 00345 return rc; 00346 }
static gboolean ergtk_entry_focus_out | ( | GtkWidget * | widget, | |
GdkEventFocus * | event | |||
) | [static] |
Definition at line 348 of file erGtkEntry.c.
00349 { 00350 g_return_val_if_fail(ERGTK_IS_ENTRY(widget), FALSE); 00351 00352 gboolean rc = FALSE; 00353 GtkEntry* entry = GTK_ENTRY(widget); 00354 erGtkEntry* er_entry = ERGTK_ENTRY(widget); 00355 00356 // chain to parent class 00357 if (g_parent_class->parent_class.focus_out_event) 00358 { 00359 rc = g_parent_class->parent_class.focus_out_event(widget, event); 00360 } 00361 00362 // de-select characters 00363 gtk_editable_select_region(GTK_EDITABLE(entry), -1, -1); 00364 00365 // if protected, hide content 00366 if (er_entry->visible == FALSE) 00367 { 00368 gtk_entry_set_visibility(entry, FALSE); 00369 } 00370 00371 return rc; 00372 }
GType ergtk_entry_get_type | ( | void | ) |
get type of erGtkEntry widget
Definition at line 149 of file erGtkEntry.c.
00150 { 00151 static GType class_type = 0; 00152 00153 if (class_type == 0) 00154 { 00155 static const GTypeInfo class_info = 00156 { 00157 sizeof(erGtkEntryClass), 00158 NULL, /* base_init */ 00159 NULL, /* base_finalize */ 00160 (GClassInitFunc) ergtk_entry_class_init, 00161 NULL, /* class_finalize */ 00162 NULL, /* class_data */ 00163 sizeof(erGtkEntry), 00164 0, /* n_preallocs */ 00165 (GInstanceInitFunc) ergtk_entry_init, 00166 }; 00167 class_type = g_type_register_static(GTK_TYPE_ENTRY, "erGtkEntry", &class_info, 0); 00168 00169 static const GInterfaceInfo editable_info = 00170 { 00171 (GInterfaceInitFunc)ergtk_entry_editable_init, /* interface_init */ 00172 NULL, /* interface_finalize */ 00173 NULL /* interface_data */ 00174 }; 00175 g_type_add_interface_static(class_type, GTK_TYPE_EDITABLE, &editable_info); 00176 } 00177 00178 return class_type; 00179 }
static void ergtk_entry_grab_focus | ( | GtkWidget * | widget | ) | [static] |
Definition at line 391 of file erGtkEntry.c.
00392 { 00393 g_return_if_fail(ERGTK_IS_ENTRY(widget)); 00394 00395 // chain to parent class 00396 if ( gtk_widget_is_focus(widget) == FALSE 00397 && g_parent_class->parent_class.grab_focus ) 00398 { 00399 g_parent_class->parent_class.grab_focus(widget); 00400 } 00401 }
static void ergtk_entry_init | ( | erGtkEntry * | input_entry | ) | [static] |
Definition at line 237 of file erGtkEntry.c.
00238 { 00239 g_return_if_fail(ERGTK_IS_ENTRY(er_entry)); 00240 00241 GtkEntry* entry = (GtkEntry*) er_entry; 00242 GtkWidget* widget = (GtkWidget*)er_entry; 00243 00244 // E-ink display requires a non-blinking cursur 00245 g_object_set(gtk_widget_get_settings(widget), "gtk-cursor-blink", FALSE, NULL); 00246 00247 // set default size and attributes 00248 gtk_entry_set_editable(entry, TRUE); 00249 gtk_widget_set_size_request(widget, ERGTK_ENTRY_DEFAULT_WIDTH, ERGTK_ENTRY_DEFAULT_HEIGHT); 00250 gtk_entry_set_visibility(entry, TRUE); 00251 00252 // instance-private data 00253 er_entry->timeout_id = 0; 00254 er_entry->changed_pending = FALSE; 00255 er_entry->changed_occurred = FALSE; 00256 er_entry->movecursor_occurred = FALSE; 00257 er_entry->visible = TRUE; 00258 er_entry->filter = string_e; 00259 }
static void ergtk_entry_move_cursor | ( | GtkEntry * | widget, | |
GtkMovementStep | arg1, | |||
gint | arg2, | |||
gboolean | arg3 | |||
) | [static] |
Definition at line 439 of file erGtkEntry.c.
00440 { 00441 g_return_if_fail(ERGTK_IS_ENTRY(widget)); 00442 00443 erGtkEntry* er_entry = (erGtkEntry*)widget; 00444 00445 // chain to parent class 00446 if (g_parent_class->move_cursor) 00447 { 00448 g_parent_class->move_cursor(widget, arg1, arg2, arg3); 00449 } 00450 00451 // (re)start timer that triggers ..-stable signal 00452 if (er_entry->timeout_id > 0) 00453 { 00454 g_source_remove(er_entry->timeout_id); 00455 } 00456 er_entry->timeout_id = g_timeout_add(300, ergtk_entry_delayed_changed_or_movecursor, er_entry); 00457 er_entry->movecursor_occurred = TRUE; 00458 }
GtkWidget* ergtk_entry_new | ( | ) |
creates a new erGtkEntry widget
- |
Definition at line 80 of file erGtkEntry.c.
00081 { 00082 erGtkEntry* item = (erGtkEntry*) g_object_new(ERGTK_ENTRY_TYPE, NULL); 00083 00084 return GTK_WIDGET(item); 00085 }
static void ergtk_entry_notify | ( | GObject * | object, | |
GParamSpec * | pspec | |||
) | [static] |
Definition at line 297 of file erGtkEntry.c.
00298 { 00299 g_return_if_fail(ERGTK_IS_ENTRY(object)); 00300 00301 GtkWidget* widget = (GtkWidget*)object; 00302 00303 // chain to parent class 00304 GObjectClass* parent_object_class = G_OBJECT_CLASS(g_parent_class); 00305 if (parent_object_class->notify) 00306 { 00307 parent_object_class->notify(object, pspec); 00308 } 00309 00310 gboolean b; 00311 const gchar* name = pspec->name; 00312 00313 if (strcmp(name, "editable") == 0) 00314 { 00315 g_object_get(object, name, &b, NULL); 00316 gtk_widget_set_sensitive(widget, b); 00317 } 00318 }
static void ergtk_entry_real_set_text | ( | erGtkEntry * | er_entry, | |
const gchar * | text | |||
) | [static] |
Definition at line 276 of file erGtkEntry.c.
00277 { 00278 g_return_if_fail(ERGTK_IS_ENTRY(er_entry)); 00279 g_return_if_fail(text != NULL); 00280 00281 GtkEntry* entry = (GtkEntry*)er_entry; 00282 00283 if (strcmp(text, gtk_entry_get_text(entry)) != 0) 00284 { 00285 // remember we expect a "changed" signal 00286 // Note: set changed_pending before calling parent class method, 00287 // so we are sure that ergtk_entry_changed() callback reads it correctly. 00288 er_entry->changed_pending = TRUE; 00289 00290 // chain to parent class 00291 gtk_entry_set_text(entry, text); 00292 } 00293 }
void ergtk_entry_set_integer_filter | ( | erGtkEntry * | er_entry | ) |
Definition at line 95 of file erGtkEntry.c.
00096 { 00097 g_return_if_fail(ERGTK_IS_ENTRY(er_entry)); 00098 00099 er_entry->filter = integer_e; 00100 integer_filter_init(GTK_ENTRY(er_entry)); 00101 }
void ergtk_entry_set_ipv4_filter | ( | erGtkEntry * | er_entry | ) |
Definition at line 87 of file erGtkEntry.c.
00088 { 00089 g_return_if_fail(ERGTK_IS_ENTRY(er_entry)); 00090 00091 er_entry->filter = ipAddress_e; 00092 ipv4_filter_init(GTK_ENTRY(er_entry)); 00093 }
void ergtk_entry_set_text | ( | erGtkEntry * | er_entry, | |
const gchar * | text | |||
) |
set the user input text
er_entry | the erGtkEntry widget | |
text | the user input text |
Definition at line 263 of file erGtkEntry.c.
00264 { 00265 g_return_if_fail(ERGTK_IS_ENTRY(er_entry)); 00266 00267 erGtkEntryClass* klass = ERGTK_ENTRY_GET_CLASS(er_entry); 00268 00269 // chain to real method, which may be overloaded 00270 if (klass->set_text) 00271 { 00272 klass->set_text(er_entry, text); 00273 } 00274 }
GtkEntryClass* g_parent_class = NULL [static] |
Definition at line 46 of file erGtkEntry.c.
gint g_signals[LAST_SIGNAL] [static] |
Definition at line 55 of file erGtkEntry.c.