Mercurial > pidgin.yaz
diff console/libgnt/gntentry.c @ 13855:5b288502a382
[gaim-migrate @ 16314]
New widget GntEntry. It's mostly functional.
Some minor improvements to the box-packing code.
Minor improvements to the skeleton code for gnt, and completely change the name from my initial choice of GN (Glib and Ncurses) to GNT (Gaim Ncurses Toolkit).
committer: Tailor Script <tailor@pidgin.im>
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Fri, 23 Jun 2006 06:24:25 +0000 |
parents | |
children | c1e3f7c75c3f |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/console/libgnt/gntentry.c Fri Jun 23 06:24:25 2006 +0000 @@ -0,0 +1,251 @@ +#include <string.h> +#include "gntentry.h" + +enum +{ + SIGS = 1, +}; + +static GntWidgetClass *parent_class = NULL; +static guint signals[SIGS] = { 0 }; + +static void +gnt_entry_draw(GntWidget *widget) +{ + GntEntry *entry = GNT_ENTRY(widget); + int stop; + + wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_TEXT_NORMAL)); + mvwprintw(widget->window, 0, 0, entry->scroll); + + stop = entry->end - entry->scroll; + if (stop < widget->priv.width) + mvwhline(widget->window, 0, stop, ENTRY_CHAR, widget->priv.width - stop); + + wrefresh(widget->window); + + DEBUG; +} + +static void +gnt_entry_size_request(GntWidget *widget) +{ + GntEntry *entry = GNT_ENTRY(widget); + widget->priv.height = 1; + widget->priv.width = 20; +} + +static void +gnt_entry_map(GntWidget *widget) +{ + if (widget->priv.width == 0 || widget->priv.height == 0) + gnt_widget_size_request(widget); + DEBUG; +} + +static gboolean +gnt_entry_key_pressed(GntWidget *widget, const char *text) +{ + GntEntry *entry = GNT_ENTRY(widget); + + if (text[0] == 27) + { + if (strcmp(text + 1, GNT_KEY_DEL) == 0 && entry->cursor < entry->end) + { + memmove(entry->cursor, entry->cursor + 1, entry->end - entry->cursor + 1); + entry->end--; + gnt_entry_draw(widget); + } + else if (strcmp(text + 1, GNT_KEY_LEFT) == 0 && entry->cursor > entry->start) + { + entry->cursor--; + if (entry->cursor < entry->scroll) + entry->scroll--; + gnt_entry_draw(widget); + } + else if (strcmp(text + 1, GNT_KEY_RIGHT) == 0 && entry->cursor < entry->end) + { + entry->cursor++; + if (entry->cursor - entry->scroll > widget->priv.width) + entry->scroll++; + gnt_entry_draw(widget); + } + /* XXX: handle other keys, like home/end, and ctrl+ goodness */ + } + else + { + if (!iscntrl(text[0])) + { + int i; + + for (i = 0; text[i]; i++) + { + /* Valid input? */ + if (ispunct(text[i]) && (entry->flag & GNT_ENTRY_FLAG_NO_PUNCT)) + continue; + if (isspace(text[i]) && (entry->flag & GNT_ENTRY_FLAG_NO_SPACE)) + continue; + if (isalpha(text[i]) && !(entry->flag & GNT_ENTRY_FLAG_ALPHA)) + continue; + if (isdigit(text[i]) && !(entry->flag & GNT_ENTRY_FLAG_INT)) + continue; + + /* Reached the max? */ + if (entry->max && entry->end - entry->start >= entry->max) + continue; + + if (entry->end - entry->start >= entry->buffer) + { + char *tmp = g_strdup_printf(entry->start); + gnt_entry_set_text(entry, tmp); + g_free(tmp); + } + + *(entry->cursor) = text[i]; + entry->cursor++; + + entry->end++; + if (entry->cursor - entry->scroll > widget->priv.width) + entry->scroll++; + } + gnt_entry_draw(widget); + } + else + { + /* Backspace is here */ + if (strcmp(text, GNT_KEY_BACKSPACE) == 0 && entry->cursor > entry->start) + { + entry->cursor--; + memmove(entry->cursor, entry->cursor + 1, entry->end - entry->cursor); + entry->end--; + + if (entry->scroll > entry->start) + entry->scroll--; + + gnt_entry_draw(widget); + } + } + } + + return FALSE; +} + +static void +gnt_entry_destroy(GntWidget *widget) +{ + GntEntry *entry = GNT_ENTRY(widget); + g_free(entry->start); +} + +static void +gnt_entry_class_init(GntWidgetClass *klass) +{ + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + + parent_class = GNT_WIDGET_CLASS(klass); + parent_class->destroy = gnt_entry_destroy; + parent_class->draw = gnt_entry_draw; + parent_class->map = gnt_entry_map; + parent_class->size_request = gnt_entry_size_request; + parent_class->key_pressed = gnt_entry_key_pressed; + + DEBUG; +} + +static void +gnt_entry_init(GTypeInstance *instance, gpointer class) +{ + GntEntry *entry = GNT_ENTRY(instance); + + entry->flag = GNT_ENTRY_FLAG_ALL; + entry->max = 0; + + GNT_WIDGET_SET_FLAGS(GNT_WIDGET(entry), + GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW | GNT_WIDGET_CAN_TAKE_FOCUS); + + DEBUG; +} + +/****************************************************************************** + * GntEntry API + *****************************************************************************/ +GType +gnt_entry_get_gtype(void) +{ + static GType type = 0; + + if(type == 0) + { + static const GTypeInfo info = { + sizeof(GntEntryClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)gnt_entry_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(GntEntry), + 0, /* n_preallocs */ + gnt_entry_init, /* instance_init */ + }; + + type = g_type_register_static(GNT_TYPE_WIDGET, + "GntEntry", + &info, 0); + } + + return type; +} + +GntWidget *gnt_entry_new(const char *text) +{ + GntWidget *widget = g_object_new(GNT_TYPE_ENTRY, NULL); + GntEntry *entry = GNT_ENTRY(widget); + + gnt_entry_set_text(entry, text); + + return widget; +} + +void gnt_entry_set_text(GntEntry *entry, const char *text) +{ + int len; + int scroll, cursor; + + g_free(entry->start); + + if (text && text[0]) + { + len = g_utf8_strlen(text, -1); + entry->buffer = len * 2; + } + else + { + entry->buffer = 128; + len = 0; + } + + scroll = entry->scroll - entry->start; + cursor = entry->end - entry->cursor; + + entry->start = g_new0(char, entry->buffer); + if (text) + snprintf(entry->start, len + 1, "%s", text); + entry->end = entry->start + len; + + entry->scroll = entry->start + scroll; + entry->cursor = entry->end - cursor; + + /* XXX: redraw if necessary? */ +} + +void gnt_entry_set_max(GntEntry *entry, int max) +{ + entry->max = max; +} + +void gnt_entry_set_flag(GntEntry *entry, GntEntryFlag flag) +{ + entry->flag = flag; + /* XXX: Check the existing string to make sure the flags are respected? */ +} +