comparison console/libgnt/gntentry.c @ 14793:8a0cfee11af8

[gaim-migrate @ 17558] Introduce actions. You can specify the bindings for the actions. Right now, only the tree and the entry widget have them. The manual includes the details. I believe Ethan had suggested something like this a while back. It made sense, so here it is. committer: Tailor Script <tailor@pidgin.im>
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Sat, 21 Oct 2006 21:08:24 +0000
parents 61416f315d1c
children 02b70dc43044
comparison
equal deleted inserted replaced
14792:242f948ee707 14793:8a0cfee11af8
155 { 155 {
156 gnt_entry_draw(widget); 156 gnt_entry_draw(widget);
157 gnt_widget_queue_update(widget); 157 gnt_widget_queue_update(widget);
158 } 158 }
159 159
160 static void 160 static gboolean
161 move_back(GntEntry *entry) 161 move_back(GntWidget *widget, GList *null)
162 { 162 {
163 GntEntry *entry = GNT_ENTRY(widget);
163 if (entry->cursor <= entry->start) 164 if (entry->cursor <= entry->start)
164 return; 165 return FALSE;
165 entry->cursor = g_utf8_find_prev_char(entry->start, entry->cursor); 166 entry->cursor = g_utf8_find_prev_char(entry->start, entry->cursor);
166 if (entry->cursor < entry->scroll) 167 if (entry->cursor < entry->scroll)
167 entry->scroll = entry->cursor; 168 entry->scroll = entry->cursor;
168 entry_redraw(GNT_WIDGET(entry)); 169 entry_redraw(GNT_WIDGET(entry));
169 } 170 return TRUE;
170 171 }
171 static void 172
172 move_forward(GntEntry *entry) 173 static gboolean
173 { 174 move_forward(GntWidget *widget, GList *list)
175 {
176 GntEntry *entry = GNT_ENTRY(widget);
174 if (entry->cursor >= entry->end) 177 if (entry->cursor >= entry->end)
175 return; 178 return FALSE;
176 entry->cursor = g_utf8_find_next_char(entry->cursor, NULL); 179 entry->cursor = g_utf8_find_next_char(entry->cursor, NULL);
177 while (gnt_util_onscreen_width(entry->scroll, entry->cursor) >= GNT_WIDGET(entry)->priv.width) 180 while (gnt_util_onscreen_width(entry->scroll, entry->cursor) >= GNT_WIDGET(entry)->priv.width)
178 entry->scroll = g_utf8_find_next_char(entry->scroll, NULL); 181 entry->scroll = g_utf8_find_next_char(entry->scroll, NULL);
179 entry_redraw(GNT_WIDGET(entry)); 182 entry_redraw(GNT_WIDGET(entry));
180 } 183 return TRUE;
181 184 }
182 static void 185
183 backspace(GntEntry *entry) 186 static gboolean
187 backspace(GntWidget *widget, GList *null)
184 { 188 {
185 int len; 189 int len;
190 GntEntry *entry = GNT_ENTRY(widget);
186 191
187 if (entry->cursor <= entry->start) 192 if (entry->cursor <= entry->start)
188 return; 193 return TRUE;
189 194
190 len = entry->cursor - g_utf8_find_prev_char(entry->start, entry->cursor); 195 len = entry->cursor - g_utf8_find_prev_char(entry->start, entry->cursor);
191 entry->cursor -= len; 196 entry->cursor -= len;
192 memmove(entry->cursor, entry->cursor + len, entry->end - entry->cursor); 197 memmove(entry->cursor, entry->cursor + len, entry->end - entry->cursor);
193 entry->end -= len; 198 entry->end -= len;
196 entry->scroll = g_utf8_find_prev_char(entry->start, entry->scroll); 201 entry->scroll = g_utf8_find_prev_char(entry->start, entry->scroll);
197 202
198 entry_redraw(GNT_WIDGET(entry)); 203 entry_redraw(GNT_WIDGET(entry));
199 if (entry->ddown) 204 if (entry->ddown)
200 show_suggest_dropdown(entry); 205 show_suggest_dropdown(entry);
201 } 206 return TRUE;
202 207 }
203 static void 208
204 delkey(GntEntry *entry) 209 static gboolean
210 delkey(GntWidget *widget, GList *null)
205 { 211 {
206 int len; 212 int len;
213 GntEntry *entry = GNT_ENTRY(widget);
207 214
208 if (entry->cursor >= entry->end) 215 if (entry->cursor >= entry->end)
209 return; 216 return FALSE;
210 217
211 len = g_utf8_find_next_char(entry->cursor, NULL) - entry->cursor; 218 len = g_utf8_find_next_char(entry->cursor, NULL) - entry->cursor;
212 memmove(entry->cursor, entry->cursor + len, entry->end - entry->cursor - len + 1); 219 memmove(entry->cursor, entry->cursor + len, entry->end - entry->cursor - len + 1);
213 entry->end -= len; 220 entry->end -= len;
214 entry_redraw(GNT_WIDGET(entry)); 221 entry_redraw(GNT_WIDGET(entry));
215 222
216 if (entry->ddown) 223 if (entry->ddown)
217 show_suggest_dropdown(entry); 224 show_suggest_dropdown(entry);
218 } 225 return TRUE;
219 226 }
220 static void 227
221 move_start(GntEntry *entry) 228 static gboolean
222 { 229 move_start(GntWidget *widget, GList *null)
230 {
231 GntEntry *entry = GNT_ENTRY(widget);
223 entry->scroll = entry->cursor = entry->start; 232 entry->scroll = entry->cursor = entry->start;
224 entry_redraw(GNT_WIDGET(entry)); 233 entry_redraw(GNT_WIDGET(entry));
225 } 234 return TRUE;
226 235 }
227 static void 236
228 move_end(GntEntry *entry) 237 static gboolean
229 { 238 move_end(GntWidget *widget, GList *null)
239 {
240 GntEntry *entry = GNT_ENTRY(widget);
230 entry->cursor = entry->end; 241 entry->cursor = entry->end;
231 /* This should be better than this */ 242 /* This should be better than this */
232 while (gnt_util_onscreen_width(entry->scroll, entry->cursor) >= GNT_WIDGET(entry)->priv.width) 243 while (gnt_util_onscreen_width(entry->scroll, entry->cursor) >= GNT_WIDGET(entry)->priv.width)
233 entry->scroll = g_utf8_find_next_char(entry->scroll, NULL); 244 entry->scroll = g_utf8_find_next_char(entry->scroll, NULL);
234 entry_redraw(GNT_WIDGET(entry)); 245 entry_redraw(GNT_WIDGET(entry));
246 return TRUE;
247 }
248
249 static gboolean
250 history_prev(GntWidget *widget, GList *null)
251 {
252 GntEntry *entry = GNT_ENTRY(widget);
253 if (entry->histlength && entry->history->prev)
254 {
255 entry->history = entry->history->prev;
256 gnt_entry_set_text(entry, entry->history->data);
257 destroy_suggest(entry);
258
259 return TRUE;
260 }
261 return FALSE;
262 }
263
264 static gboolean
265 history_next(GntWidget *widget, GList *null)
266 {
267 GntEntry *entry = GNT_ENTRY(widget);
268 if (entry->histlength && entry->history->next)
269 {
270 if (entry->history->prev == NULL)
271 {
272 /* Save the current contents */
273 char *text = g_strdup(gnt_entry_get_text(entry));
274 g_free(entry->history->data);
275 entry->history->data = text;
276 }
277
278 entry->history = entry->history->next;
279 gnt_entry_set_text(entry, entry->history->data);
280 destroy_suggest(entry);
281
282 return TRUE;
283 }
284 return FALSE;
285 }
286
287 static gboolean
288 suggest_show(GntWidget *widget, GList *null)
289 {
290 return show_suggest_dropdown(GNT_ENTRY(widget));
291 }
292
293 static gboolean
294 suggest_next(GntWidget *widget, GList *null)
295 {
296 GntEntry *entry = GNT_ENTRY(widget);
297 if (entry->ddown) {
298 gnt_widget_perform_action_named(entry->ddown, "move-down", NULL);
299 return TRUE;
300 }
301 return FALSE;
302 }
303
304 static gboolean
305 suggest_prev(GntWidget *widget, GList *null)
306 {
307 GntEntry *entry = GNT_ENTRY(widget);
308 if (entry->ddown) {
309 gnt_widget_perform_action_named(entry->ddown, "move-up", NULL);
310 return TRUE;
311 }
312 return FALSE;
313 }
314
315 static gboolean
316 del_to_home(GntWidget *widget, GList *null)
317 {
318 GntEntry *entry = GNT_ENTRY(widget);
319 memmove(entry->start, entry->cursor, entry->end - entry->cursor);
320 entry->end -= (entry->cursor - entry->start);
321 entry->cursor = entry->scroll = entry->start;
322 memset(entry->end, '\0', entry->buffer - (entry->end - entry->start));
323 entry_redraw(widget);
324 return TRUE;
325 }
326
327 static gboolean
328 del_to_end(GntWidget *widget, GList *null)
329 {
330 GntEntry *entry = GNT_ENTRY(widget);
331 entry->end = entry->cursor;
332 memset(entry->end, '\0', entry->buffer - (entry->end - entry->start));
333 entry_redraw(widget);
334 return TRUE;
235 } 335 }
236 336
237 static gboolean 337 static gboolean
238 gnt_entry_key_pressed(GntWidget *widget, const char *text) 338 gnt_entry_key_pressed(GntWidget *widget, const char *text)
239 { 339 {
240 GntEntry *entry = GNT_ENTRY(widget); 340 GntEntry *entry = GNT_ENTRY(widget);
241 341
242 if (text[0] == 27) 342 if (text[0] == 27)
243 { 343 {
244 if (strcmp(text + 1, GNT_KEY_DEL) == 0 && entry->cursor < entry->end) 344 if (text[1] == 0)
245 {
246 delkey(entry);
247 return TRUE;
248 }
249 else if (strcmp(text + 1, GNT_KEY_LEFT) == 0)
250 {
251 move_back(entry);
252 return TRUE;
253 }
254 else if (strcmp(text + 1, GNT_KEY_RIGHT) == 0)
255 {
256 move_forward(entry);
257 return TRUE;
258 }
259 else if (strcmp(text + 1, GNT_KEY_HOME) == 0)
260 {
261 move_start(entry);
262 return TRUE;
263 }
264 else if (strcmp(text + 1, GNT_KEY_END) == 0)
265 {
266 move_end(entry);
267 return TRUE;
268 }
269 else if (strcmp(text + 1, GNT_KEY_CTRL_DOWN) == 0 && entry->histlength)
270 {
271 if (entry->history->prev)
272 {
273 entry->history = entry->history->prev;
274 gnt_entry_set_text(entry, entry->history->data);
275 destroy_suggest(entry);
276
277 return TRUE;
278 }
279 }
280 else if (strcmp(text + 1, GNT_KEY_UP) == 0 ||
281 strcmp(text + 1, GNT_KEY_DOWN) == 0)
282 {
283 if (entry->ddown)
284 {
285 gnt_widget_key_pressed(entry->ddown, text);
286 return TRUE;
287 }
288 }
289 else if (strcmp(text + 1, GNT_KEY_CTRL_UP) == 0 && entry->histlength)
290 {
291 if (entry->history->next)
292 {
293 if (entry->history->prev == NULL)
294 {
295 /* Save the current contents */
296 char *text = g_strdup(gnt_entry_get_text(entry));
297 g_free(entry->history->data);
298 entry->history->data = text;
299 }
300
301 entry->history = entry->history->next;
302 gnt_entry_set_text(entry, entry->history->data);
303 destroy_suggest(entry);
304
305 return TRUE;
306 }
307 }
308 else if (text[1] == 0)
309 { 345 {
310 destroy_suggest(entry); 346 destroy_suggest(entry);
347 return TRUE;
311 } 348 }
312 349
313 return FALSE; 350 return FALSE;
314 } 351 }
315 else 352 else
398 show_suggest_dropdown(entry); 435 show_suggest_dropdown(entry);
399 } 436 }
400 entry_redraw(widget); 437 entry_redraw(widget);
401 return TRUE; 438 return TRUE;
402 } 439 }
403 else
404 {
405 if (strcmp(text, GNT_KEY_BACKSPACE) == 0 && entry->cursor > entry->start)
406 {
407 backspace(entry);
408 return TRUE;
409 }
410 else if (strcmp(text, GNT_KEY_CTRL_A) == 0)
411 {
412 move_start(entry);
413 return TRUE;
414 }
415 else if (strcmp(text, GNT_KEY_CTRL_B) == 0)
416 {
417 move_back(entry);
418 return TRUE;
419 }
420 else if (strcmp(text, GNT_KEY_CTRL_D) == 0)
421 {
422 delkey(entry);
423 return TRUE;
424 }
425 else if (strcmp(text, GNT_KEY_CTRL_E) == 0)
426 {
427 move_end(entry);
428 return TRUE;
429 }
430 else if (strcmp(text, GNT_KEY_CTRL_F) == 0)
431 {
432 move_forward(entry);
433 return TRUE;
434 }
435 else if (strcmp(text, GNT_KEY_CTRL_H) == 0)
436 {
437 backspace(entry);
438 return TRUE;
439 }
440 else if (strcmp(text, GNT_KEY_CTRL_K) == 0)
441 {
442 entry->end = entry->cursor;
443 memset(entry->end, '\0', entry->buffer - (entry->end - entry->start));
444 entry_redraw(widget);
445 return TRUE;
446 }
447 else if (strcmp(text, GNT_KEY_CTRL_U) == 0)
448 {
449 memmove(entry->start, entry->cursor, entry->end - entry->cursor);
450 entry->end -= (entry->cursor - entry->start);
451 entry->cursor = entry->scroll = entry->start;
452 memset(entry->end, '\0', entry->buffer - (entry->end - entry->start));
453 entry_redraw(widget);
454 return TRUE;
455 }
456 }
457 } 440 }
458 441
459 return FALSE; 442 return FALSE;
460 } 443 }
461 444
500 parent_class->draw = gnt_entry_draw; 483 parent_class->draw = gnt_entry_draw;
501 parent_class->map = gnt_entry_map; 484 parent_class->map = gnt_entry_map;
502 parent_class->size_request = gnt_entry_size_request; 485 parent_class->size_request = gnt_entry_size_request;
503 parent_class->key_pressed = gnt_entry_key_pressed; 486 parent_class->key_pressed = gnt_entry_key_pressed;
504 parent_class->lost_focus = gnt_entry_lost_focus; 487 parent_class->lost_focus = gnt_entry_lost_focus;
488
489 parent_class->actions = g_hash_table_duplicate(parent_class->actions, g_str_hash,
490 g_str_equal, g_free, (GDestroyNotify)gnt_widget_action_free);
491 parent_class->bindings = g_hash_table_duplicate(parent_class->bindings, g_str_hash,
492 g_str_equal, g_free, (GDestroyNotify)gnt_widget_action_param_free);
493
494 gnt_widget_class_register_action(parent_class, "cursor-home", move_start,
495 GNT_KEY_CTRL_A, NULL);
496 gnt_widget_register_binding(parent_class, "cursor-home", "\033" GNT_KEY_HOME, NULL);
497 gnt_widget_class_register_action(parent_class, "cursor-end", move_end,
498 GNT_KEY_CTRL_E, NULL);
499 gnt_widget_register_binding(parent_class, "cursor-end", "\033" GNT_KEY_END, NULL);
500 gnt_widget_class_register_action(parent_class, "delete-prev", backspace,
501 GNT_KEY_BACKSPACE, NULL);
502 gnt_widget_class_register_action(parent_class, "delete-next", delkey,
503 "\033" GNT_KEY_DEL, NULL);
504 gnt_widget_register_binding(parent_class, "delete-next", GNT_KEY_CTRL_D, NULL);
505 gnt_widget_class_register_action(parent_class, "delete-start", del_to_home,
506 GNT_KEY_CTRL_U, NULL);
507 gnt_widget_class_register_action(parent_class, "delete-end", del_to_end,
508 GNT_KEY_CTRL_K, NULL);
509 #if 0
510 gnt_widget_class_register_action(parent_class, "delete-prev-word", del_prev_word,
511 NULL, 1, NULL);
512 gnt_widget_class_register_action(parent_class, "delete-next-word", del_next_word,
513 NULL, 1, NULL);
514 #endif
515 gnt_widget_class_register_action(parent_class, "cursor-prev", move_back,
516 "\033" GNT_KEY_LEFT, NULL);
517 gnt_widget_class_register_action(parent_class, "cursor-next", move_forward,
518 "\033" GNT_KEY_RIGHT, NULL);
519 gnt_widget_class_register_action(parent_class, "suggest-show", suggest_show,
520 "\t", NULL);
521 gnt_widget_class_register_action(parent_class, "suggest-next", suggest_next,
522 "\033" GNT_KEY_DOWN, NULL);
523 gnt_widget_class_register_action(parent_class, "suggest-prev", suggest_prev,
524 "\033" GNT_KEY_UP, NULL);
525 gnt_widget_class_register_action(parent_class, "history-prev", history_prev,
526 "\033" GNT_KEY_CTRL_UP, NULL);
527 gnt_widget_class_register_action(parent_class, "history-next", history_next,
528 "\033" GNT_KEY_CTRL_DOWN, NULL);
529
530 gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), klass);
505 531
506 GNTDEBUG; 532 GNTDEBUG;
507 } 533 }
508 534
509 static void 535 static void