comparison 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
comparison
equal deleted inserted replaced
13854:a4c30c1d9de8 13855:5b288502a382
1 #include <string.h>
2 #include "gntentry.h"
3
4 enum
5 {
6 SIGS = 1,
7 };
8
9 static GntWidgetClass *parent_class = NULL;
10 static guint signals[SIGS] = { 0 };
11
12 static void
13 gnt_entry_draw(GntWidget *widget)
14 {
15 GntEntry *entry = GNT_ENTRY(widget);
16 int stop;
17
18 wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_TEXT_NORMAL));
19 mvwprintw(widget->window, 0, 0, entry->scroll);
20
21 stop = entry->end - entry->scroll;
22 if (stop < widget->priv.width)
23 mvwhline(widget->window, 0, stop, ENTRY_CHAR, widget->priv.width - stop);
24
25 wrefresh(widget->window);
26
27 DEBUG;
28 }
29
30 static void
31 gnt_entry_size_request(GntWidget *widget)
32 {
33 GntEntry *entry = GNT_ENTRY(widget);
34 widget->priv.height = 1;
35 widget->priv.width = 20;
36 }
37
38 static void
39 gnt_entry_map(GntWidget *widget)
40 {
41 if (widget->priv.width == 0 || widget->priv.height == 0)
42 gnt_widget_size_request(widget);
43 DEBUG;
44 }
45
46 static gboolean
47 gnt_entry_key_pressed(GntWidget *widget, const char *text)
48 {
49 GntEntry *entry = GNT_ENTRY(widget);
50
51 if (text[0] == 27)
52 {
53 if (strcmp(text + 1, GNT_KEY_DEL) == 0 && entry->cursor < entry->end)
54 {
55 memmove(entry->cursor, entry->cursor + 1, entry->end - entry->cursor + 1);
56 entry->end--;
57 gnt_entry_draw(widget);
58 }
59 else if (strcmp(text + 1, GNT_KEY_LEFT) == 0 && entry->cursor > entry->start)
60 {
61 entry->cursor--;
62 if (entry->cursor < entry->scroll)
63 entry->scroll--;
64 gnt_entry_draw(widget);
65 }
66 else if (strcmp(text + 1, GNT_KEY_RIGHT) == 0 && entry->cursor < entry->end)
67 {
68 entry->cursor++;
69 if (entry->cursor - entry->scroll > widget->priv.width)
70 entry->scroll++;
71 gnt_entry_draw(widget);
72 }
73 /* XXX: handle other keys, like home/end, and ctrl+ goodness */
74 }
75 else
76 {
77 if (!iscntrl(text[0]))
78 {
79 int i;
80
81 for (i = 0; text[i]; i++)
82 {
83 /* Valid input? */
84 if (ispunct(text[i]) && (entry->flag & GNT_ENTRY_FLAG_NO_PUNCT))
85 continue;
86 if (isspace(text[i]) && (entry->flag & GNT_ENTRY_FLAG_NO_SPACE))
87 continue;
88 if (isalpha(text[i]) && !(entry->flag & GNT_ENTRY_FLAG_ALPHA))
89 continue;
90 if (isdigit(text[i]) && !(entry->flag & GNT_ENTRY_FLAG_INT))
91 continue;
92
93 /* Reached the max? */
94 if (entry->max && entry->end - entry->start >= entry->max)
95 continue;
96
97 if (entry->end - entry->start >= entry->buffer)
98 {
99 char *tmp = g_strdup_printf(entry->start);
100 gnt_entry_set_text(entry, tmp);
101 g_free(tmp);
102 }
103
104 *(entry->cursor) = text[i];
105 entry->cursor++;
106
107 entry->end++;
108 if (entry->cursor - entry->scroll > widget->priv.width)
109 entry->scroll++;
110 }
111 gnt_entry_draw(widget);
112 }
113 else
114 {
115 /* Backspace is here */
116 if (strcmp(text, GNT_KEY_BACKSPACE) == 0 && entry->cursor > entry->start)
117 {
118 entry->cursor--;
119 memmove(entry->cursor, entry->cursor + 1, entry->end - entry->cursor);
120 entry->end--;
121
122 if (entry->scroll > entry->start)
123 entry->scroll--;
124
125 gnt_entry_draw(widget);
126 }
127 }
128 }
129
130 return FALSE;
131 }
132
133 static void
134 gnt_entry_destroy(GntWidget *widget)
135 {
136 GntEntry *entry = GNT_ENTRY(widget);
137 g_free(entry->start);
138 }
139
140 static void
141 gnt_entry_class_init(GntWidgetClass *klass)
142 {
143 GObjectClass *obj_class = G_OBJECT_CLASS(klass);
144
145 parent_class = GNT_WIDGET_CLASS(klass);
146 parent_class->destroy = gnt_entry_destroy;
147 parent_class->draw = gnt_entry_draw;
148 parent_class->map = gnt_entry_map;
149 parent_class->size_request = gnt_entry_size_request;
150 parent_class->key_pressed = gnt_entry_key_pressed;
151
152 DEBUG;
153 }
154
155 static void
156 gnt_entry_init(GTypeInstance *instance, gpointer class)
157 {
158 GntEntry *entry = GNT_ENTRY(instance);
159
160 entry->flag = GNT_ENTRY_FLAG_ALL;
161 entry->max = 0;
162
163 GNT_WIDGET_SET_FLAGS(GNT_WIDGET(entry),
164 GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW | GNT_WIDGET_CAN_TAKE_FOCUS);
165
166 DEBUG;
167 }
168
169 /******************************************************************************
170 * GntEntry API
171 *****************************************************************************/
172 GType
173 gnt_entry_get_gtype(void)
174 {
175 static GType type = 0;
176
177 if(type == 0)
178 {
179 static const GTypeInfo info = {
180 sizeof(GntEntryClass),
181 NULL, /* base_init */
182 NULL, /* base_finalize */
183 (GClassInitFunc)gnt_entry_class_init,
184 NULL, /* class_finalize */
185 NULL, /* class_data */
186 sizeof(GntEntry),
187 0, /* n_preallocs */
188 gnt_entry_init, /* instance_init */
189 };
190
191 type = g_type_register_static(GNT_TYPE_WIDGET,
192 "GntEntry",
193 &info, 0);
194 }
195
196 return type;
197 }
198
199 GntWidget *gnt_entry_new(const char *text)
200 {
201 GntWidget *widget = g_object_new(GNT_TYPE_ENTRY, NULL);
202 GntEntry *entry = GNT_ENTRY(widget);
203
204 gnt_entry_set_text(entry, text);
205
206 return widget;
207 }
208
209 void gnt_entry_set_text(GntEntry *entry, const char *text)
210 {
211 int len;
212 int scroll, cursor;
213
214 g_free(entry->start);
215
216 if (text && text[0])
217 {
218 len = g_utf8_strlen(text, -1);
219 entry->buffer = len * 2;
220 }
221 else
222 {
223 entry->buffer = 128;
224 len = 0;
225 }
226
227 scroll = entry->scroll - entry->start;
228 cursor = entry->end - entry->cursor;
229
230 entry->start = g_new0(char, entry->buffer);
231 if (text)
232 snprintf(entry->start, len + 1, "%s", text);
233 entry->end = entry->start + len;
234
235 entry->scroll = entry->start + scroll;
236 entry->cursor = entry->end - cursor;
237
238 /* XXX: redraw if necessary? */
239 }
240
241 void gnt_entry_set_max(GntEntry *entry, int max)
242 {
243 entry->max = max;
244 }
245
246 void gnt_entry_set_flag(GntEntry *entry, GntEntryFlag flag)
247 {
248 entry->flag = flag;
249 /* XXX: Check the existing string to make sure the flags are respected? */
250 }
251