From: <sa...@us...> - 2006-06-23 06:24:36
|
Revision: 16314 Author: sadrul Date: 2006-06-22 23:24:25 -0700 (Thu, 22 Jun 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16314&view=rev Log Message: ----------- 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). Modified Paths: -------------- trunk/console/libgnt/Makefile trunk/console/libgnt/gnt-skel.c trunk/console/libgnt/gnt-skel.h trunk/console/libgnt/gntbox.c trunk/console/libgnt/gntcolors.c trunk/console/libgnt/gntkeys.h trunk/console/libgnt/gnttree.c trunk/console/libgnt/gntwidget.c trunk/console/libgnt/test.c Added Paths: ----------- trunk/console/libgnt/gntentry.c trunk/console/libgnt/gntentry.h Modified: trunk/console/libgnt/Makefile =================================================================== --- trunk/console/libgnt/Makefile 2006-06-23 00:57:30 UTC (rev 16313) +++ trunk/console/libgnt/Makefile 2006-06-23 06:24:25 UTC (rev 16314) @@ -6,6 +6,7 @@ gntbox.h \ gntbutton.h \ gntcolors.h \ + gntentry.h \ gntlabel.h \ gnttree.h \ gntutils.h \ @@ -16,6 +17,7 @@ gntbox.c \ gntbutton.c \ gntcolors.c \ + gntentry.c \ gntlabel.c \ gnttree.c \ gntutils.c \ @@ -26,6 +28,7 @@ gntbox.o \ gntbutton.o \ gntcolors.o \ + gntentry.o \ gntlabel.o \ gnttree.o \ gntutils.o \ @@ -34,11 +37,13 @@ all: libgnt test: $(OBJECTS) +key: $(OBJECTS) gntwidget.o: gntwidget.c $(HEADERS) gntbox.o: gntbox.c $(HEADERS) gntbutton.o: gntbutton.c $(HEADERS) gntcolors.o: gntcolors.c $(HEADERS) +gntentry.o: gntentry.c $(HEADERS) gntlabel.o: gntlabel.c $(HEADERS) gnttree.o: gnttree.c $(HEADERS) gntutils.o: gntutils.c $(HEADERS) Modified: trunk/console/libgnt/gnt-skel.c =================================================================== --- trunk/console/libgnt/gnt-skel.c 2006-06-23 00:57:30 UTC (rev 16313) +++ trunk/console/libgnt/gnt-skel.c 2006-06-23 06:24:25 UTC (rev 16314) @@ -1,4 +1,4 @@ -#include "gn-skel.h" +#include "gnt-skel.h" enum { @@ -34,11 +34,17 @@ } static void +gnt_skel_destroy(GntWidget *widget) +{ +} + +static void gnt_skel_class_init(GntWidgetClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS(klass); parent_class = GNT_WIDGET_CLASS(klass); + parent_class->destroy = gnt_skel_destroy; parent_class->draw = gnt_skel_draw; parent_class->map = gnt_skel_map; parent_class->size_request = gnt_skel_size_request; Modified: trunk/console/libgnt/gnt-skel.h =================================================================== --- trunk/console/libgnt/gnt-skel.h 2006-06-23 00:57:30 UTC (rev 16313) +++ trunk/console/libgnt/gnt-skel.h 2006-06-23 06:24:25 UTC (rev 16314) @@ -1,10 +1,10 @@ #ifndef GNT_SKEL_H #define GNT_SKEL_H -#include "gnwidget.h" -#include "gn.h" -#include "gncolors.h" -#include "gnkeys.h" +#include "gntwidget.h" +#include "gnt.h" +#include "gntcolors.h" +#include "gntkeys.h" #define GNT_TYPE_SKEL (gnt_skel_get_gtype()) #define GNT_SKEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_SKEL, GntSkel)) Modified: trunk/console/libgnt/gntbox.c =================================================================== --- trunk/console/libgnt/gntbox.c 2006-06-23 00:57:30 UTC (rev 16313) +++ trunk/console/libgnt/gntbox.c 2006-06-23 06:24:25 UTC (rev 16314) @@ -53,15 +53,13 @@ w = h = 0; max = -1; - curx = widget->priv.x + 1; - cury = widget->priv.y + 1; + curx = widget->priv.x; + cury = widget->priv.y; if (!(GNT_WIDGET_FLAGS(widget) & GNT_WIDGET_NO_BORDER)) { has_border = TRUE; - curx += box->pad; - cury += box->pad; - if (!box->vertical) - curx++; + curx += 1; + cury += 1; } for (iter = box->list; iter; iter = iter->next) @@ -84,7 +82,7 @@ if (has_border) { - curx += 2; + curx += 1; cury += 1; max += 2; } @@ -146,16 +144,44 @@ DEBUG; } +/* Ensures that the current widget can take focus */ +static void +ensure_active(GntBox *box) +{ + int investigated = 0; + int total; + + if (box->active == NULL) + box->active = box->list; + + total = g_list_length(box->list); + + while (box->active && !GNT_WIDGET_IS_FLAG_SET(box->active->data, GNT_WIDGET_CAN_TAKE_FOCUS)) + { + box->active = box->active->next; + investigated++; + } + + /* Rotate if necessary */ + if (!box->active && investigated < total) + { + box->active = box->list; + while (investigated < total && !GNT_WIDGET_IS_FLAG_SET(box->active->data, GNT_WIDGET_CAN_TAKE_FOCUS)) + { + box->active = box->active->next; + investigated++; + } + } +} + static gboolean gnt_box_key_pressed(GntWidget *widget, const char *text) { GntBox *box = GNT_BOX(widget); - /*if (box->list == NULL)*/ - /*return FALSE;*/ - + ensure_active(box); if (box->active == NULL) - box->active = box->list; + return FALSE; if (gnt_widget_key_pressed(box->active->data, text)) return TRUE; Modified: trunk/console/libgnt/gntcolors.c =================================================================== --- trunk/console/libgnt/gntcolors.c 2006-06-23 00:57:30 UTC (rev 16313) +++ trunk/console/libgnt/gntcolors.c 2006-06-23 06:24:25 UTC (rev 16314) @@ -19,6 +19,7 @@ init_pair(GNT_COLOR_HIGHLIGHT, GNT_COLOR_BLUE, GNT_COLOR_GRAY); init_pair(GNT_COLOR_SHADOW, GNT_COLOR_BLACK, GNT_COLOR_DARK_GRAY); init_pair(GNT_COLOR_TITLE, GNT_COLOR_WHITE, GNT_COLOR_DARK_GRAY); + init_pair(GNT_COLOR_TEXT_NORMAL, GNT_COLOR_BLACK, GNT_COLOR_GRAY); } else { @@ -26,6 +27,7 @@ init_pair(GNT_COLOR_HIGHLIGHT, COLOR_CYAN, COLOR_BLACK); init_pair(GNT_COLOR_SHADOW, COLOR_BLACK, COLOR_BLACK); init_pair(GNT_COLOR_TITLE, COLOR_WHITE, COLOR_BLACK); + init_pair(GNT_COLOR_TEXT_NORMAL, COLOR_BLACK, COLOR_WHITE); } } Added: trunk/console/libgnt/gntentry.c =================================================================== --- trunk/console/libgnt/gntentry.c (rev 0) +++ trunk/console/libgnt/gntentry.c 2006-06-23 06:24:25 UTC (rev 16314) @@ -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? */ +} + Property changes on: trunk/console/libgnt/gntentry.c ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: trunk/console/libgnt/gntentry.h =================================================================== --- trunk/console/libgnt/gntentry.h (rev 0) +++ trunk/console/libgnt/gntentry.h 2006-06-23 06:24:25 UTC (rev 16314) @@ -0,0 +1,78 @@ +#ifndef GNT_ENTRY_H +#define GNT_ENTRY_H + +#include "gntwidget.h" +#include "gnt.h" +#include "gntcolors.h" +#include "gntkeys.h" + +#define GNT_TYPE_ENTRY (gnt_entry_get_gtype()) +#define GNT_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_ENTRY, GntEntry)) +#define GNT_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_ENTRY, GntEntryClass)) +#define GNT_IS_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_ENTRY)) +#define GNT_IS_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_ENTRY)) +#define GNT_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_ENTRY, GntEntryClass)) + +#define GNT_ENTRY_FLAGS(obj) (GNT_ENTRY(obj)->priv.flags) +#define GNT_ENTRY_SET_FLAGS(obj, flags) (GNT_ENTRY_FLAGS(obj) |= flags) +#define GNT_ENTRY_UNSET_FLAGS(obj, flags) (GNT_ENTRY_FLAGS(obj) &= ~(flags)) + +#define ENTRY_CHAR '_' /* The character to use to fill in the blank places */ + +typedef struct _GnEntry GntEntry; +typedef struct _GnEntryPriv GntEntryPriv; +typedef struct _GnEntryClass GntEntryClass; + +typedef enum +{ + GNT_ENTRY_FLAG_ALPHA = 1 << 0, /* Only alpha */ + GNT_ENTRY_FLAG_INT = 1 << 1, /* Only integer */ + GNT_ENTRY_FLAG_NO_SPACE = 1 << 2, /* No blank space is allowed */ + GNT_ENTRY_FLAG_NO_PUNCT = 1 << 3, /* No punctuations */ + GNT_ENTRY_FLAG_MASK = 1 << 4, /* Mask the inputs */ +} GntEntryFlag; + +#define GNT_ENTRY_FLAG_ALL (GNT_ENTRY_FLAG_ALPHA | GNT_ENTRY_FLAG_INT) + +struct _GnEntry +{ + GntWidget parent; + + GntEntryFlag flag; + + char *start; + char *end; + char *scroll; /* Current scrolling position */ + char *cursor; /* Cursor location */ + /* 0 <= cursor - scroll < widget-width */ + + size_t buffer; /* Size of the buffer */ + + int max; /* 0 means infinite */ +}; + +struct _GnEntryClass +{ + GntWidgetClass parent; + + void (*gnt_reserved1)(void); + void (*gnt_reserved2)(void); + void (*gnt_reserved3)(void); + void (*gnt_reserved4)(void); +}; + +G_BEGIN_DECLS + +GType gnt_entry_get_gtype(void); + +GntWidget *gnt_entry_new(const char *text); + +void gnt_entry_set_max(GntEntry *entry, int max); + +void gnt_entry_set_text(GntEntry *entry, const char *text); + +void gnt_entry_set_flag(GntEntry *entry, GntEntryFlag flag); + +G_END_DECLS + +#endif /* GNT_ENTRY_H */ Property changes on: trunk/console/libgnt/gntentry.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Modified: trunk/console/libgnt/gntkeys.h =================================================================== --- trunk/console/libgnt/gntkeys.h 2006-06-23 00:57:30 UTC (rev 16313) +++ trunk/console/libgnt/gntkeys.h 2006-06-23 06:24:25 UTC (rev 16314) @@ -1,14 +1,17 @@ #ifndef GNT_KEYS_H #define GNT_KEYS_H -#define GNT_KEY_POPUP "[29~" +#define GNT_KEY_POPUP "[29~" /* Arrow keys */ -#define GNT_KEY_LEFT "[D" -#define GNT_KEY_RIGHT "[C" -#define GNT_KEY_UP "[A" -#define GNT_KEY_DOWN "[B" +#define GNT_KEY_LEFT "[D" +#define GNT_KEY_RIGHT "[C" +#define GNT_KEY_UP "[A" +#define GNT_KEY_DOWN "[B" -#define GNT_KEY_ENTER "\r" +#define GNT_KEY_ENTER "\r" +#define GNT_KEY_BACKSPACE "\177" +#define GNT_KEY_DEL "[3~" + #endif Modified: trunk/console/libgnt/gnttree.c =================================================================== --- trunk/console/libgnt/gnttree.c 2006-06-23 00:57:30 UTC (rev 16313) +++ trunk/console/libgnt/gnttree.c 2006-06-23 06:24:25 UTC (rev 16314) @@ -46,11 +46,11 @@ if ((wr = snprintf(str, widget->priv.width, "%s", row->text)) >= widget->priv.width) { /* XXX: ellipsize */ - str[widget->priv.width - 1] = 0; + str[widget->priv.width - 1 - pos] = 0; } else { - while (wr < widget->priv.width - 1) + while (wr < widget->priv.width - 1 - pos) str[wr++] = ' '; str[wr] = 0; } @@ -67,8 +67,8 @@ while (start < tree->bottom) { - wmove(widget->window, start - tree->top + pos, pos); - wclrtoeol(widget->window); + mvwhline(widget->window, start - tree->top + pos, pos, ' ', + widget->priv.width - pos * 2); start++; } Modified: trunk/console/libgnt/gntwidget.c =================================================================== --- trunk/console/libgnt/gntwidget.c 2006-06-23 00:57:30 UTC (rev 16313) +++ trunk/console/libgnt/gntwidget.c 2006-06-23 06:24:25 UTC (rev 16314) @@ -286,6 +286,8 @@ gnt_widget_key_pressed(GntWidget *widget, const char *keys) { gboolean ret; + if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_CAN_TAKE_FOCUS)) + return FALSE; g_signal_emit(widget, signals[SIG_KEY_PRESSED], 0, keys, &ret); return ret; } Modified: trunk/console/libgnt/test.c =================================================================== --- trunk/console/libgnt/test.c 2006-06-23 00:57:30 UTC (rev 16313) +++ trunk/console/libgnt/test.c 2006-06-23 06:24:25 UTC (rev 16314) @@ -90,8 +90,10 @@ gnt_box_add_widget(GNT_BOX(vbox), widget2); gnt_box_add_widget(GNT_BOX(hbox), label); - gnt_box_add_widget(GNT_BOX(hbox), vbox); + /*gnt_box_add_widget(GNT_BOX(hbox), vbox);*/ + gnt_box_add_widget(GNT_BOX(hbox), gnt_entry_new("a")); + tree = gnt_tree_new(); gnt_box_add_widget(GNT_BOX(hbox), tree); @@ -106,11 +108,11 @@ /*gnt_widget_set_take_focus(vbox, TRUE);*/ /*gnt_widget_set_take_focus(hbox, TRUE);*/ - gnt_widget_set_position(hbox, 10, 10); + /*gnt_widget_set_position(hbox, 10, 10);*/ gnt_widget_show(hbox); - g_signal_connect(hbox, "key_pressed", G_CALLBACK(key_pressed), widget); + /*g_signal_connect(hbox, "key_pressed", G_CALLBACK(key_pressed), widget);*/ g_signal_connect(widget, "activate", G_CALLBACK(button1), hbox); g_signal_connect(widget2, "activate", G_CALLBACK(button2), hbox); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |