This source file includes following definitions.
- dlg_default_get_colors
- refresh_cmd
- dlg_help
- dlg_execute_cmd
- dlg_handle_key
- dlg_key_event
- dlg_handle_mouse_event
- frontend_dlg_run
- dlg_default_destroy
- dlg_default_callback
- dlg_default_mouse_callback
- dlg_create
- dlg_set_default_colors
- dlg_close
- dlg_init
- dlg_process_event
- dlg_run_done
- dlg_run
- dlg_get_title
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 #include <config.h>
28
29 #include <stdlib.h>
30
31 #include "lib/global.h"
32
33 #include "lib/tty/tty.h"
34 #include "lib/skin.h"
35 #include "lib/tty/key.h"
36 #include "lib/strutil.h"
37 #include "lib/event.h"
38 #include "lib/util.h"
39
40 #include "lib/widget.h"
41 #include "lib/widget/mouse.h"
42
43
44
45
46 dlg_colors_t dialog_colors;
47 dlg_colors_t alarm_colors;
48 dlg_colors_t listbox_colors;
49 dlg_colors_t help_colors;
50
51
52 hook_t *idle_hook = NULL;
53
54
55 gboolean mouse_close_dialog = FALSE;
56
57 const global_keymap_t *dialog_map = NULL;
58
59
60
61
62
63
64
65
66
67
68
69
70
71 static const int *
72 dlg_default_get_colors (const Widget *w)
73 {
74 return CONST_DIALOG (w)->colors;
75 }
76
77
78
79 static void
80 refresh_cmd (void)
81 {
82 #ifdef HAVE_SLANG
83 tty_touch_screen ();
84 mc_refresh ();
85 #else
86
87 tty_clear_screen ();
88 repaint_screen ();
89 #endif
90 }
91
92
93
94 static void
95 dlg_help (const WDialog *h)
96 {
97 ev_help_t event_data = { NULL, h->help_ctx };
98
99 mc_event_raise (MCEVENT_GROUP_CORE, "help", &event_data);
100 }
101
102
103
104 static cb_ret_t
105 dlg_execute_cmd (WDialog *h, long command)
106 {
107 WGroup *g = GROUP (h);
108 cb_ret_t ret = MSG_HANDLED;
109
110 if (send_message (h, NULL, MSG_ACTION, command, NULL) == MSG_HANDLED)
111 return MSG_HANDLED;
112
113 switch (command)
114 {
115 case CK_Ok:
116 h->ret_value = B_ENTER;
117 dlg_close (h);
118 break;
119 case CK_Cancel:
120 h->ret_value = B_CANCEL;
121 dlg_close (h);
122 break;
123
124 case CK_Up:
125 case CK_Left:
126 group_select_prev_widget (g);
127 break;
128 case CK_Down:
129 case CK_Right:
130 group_select_next_widget (g);
131 break;
132
133 case CK_Help:
134 dlg_help (h);
135 break;
136
137 case CK_Suspend:
138 mc_event_raise (MCEVENT_GROUP_CORE, "suspend", NULL);
139 refresh_cmd ();
140 break;
141 case CK_Refresh:
142 refresh_cmd ();
143 break;
144
145 case CK_ScreenList:
146 if (!widget_get_state (WIDGET (h), WST_MODAL))
147 dialog_switch_list ();
148 else
149 ret = MSG_NOT_HANDLED;
150 break;
151 case CK_ScreenNext:
152 if (!widget_get_state (WIDGET (h), WST_MODAL))
153 dialog_switch_next ();
154 else
155 ret = MSG_NOT_HANDLED;
156 break;
157 case CK_ScreenPrev:
158 if (!widget_get_state (WIDGET (h), WST_MODAL))
159 dialog_switch_prev ();
160 else
161 ret = MSG_NOT_HANDLED;
162 break;
163
164 default:
165 ret = MSG_NOT_HANDLED;
166 }
167
168 return ret;
169 }
170
171
172
173 static cb_ret_t
174 dlg_handle_key (WDialog *h, int d_key)
175 {
176 long command;
177
178 command = widget_lookup_key (WIDGET (h), d_key);
179 if (command == CK_IgnoreKey)
180 command = keybind_lookup_keymap_command (dialog_map, d_key);
181 if (command != CK_IgnoreKey)
182 return dlg_execute_cmd (h, command);
183
184 return MSG_NOT_HANDLED;
185 }
186
187
188
189 static void
190 dlg_key_event (WDialog *h, int d_key)
191 {
192 Widget *w = WIDGET (h);
193 WGroup *g = GROUP (h);
194 cb_ret_t handled;
195
196 if (g->widgets == NULL)
197 return;
198
199 if (g->current == NULL)
200 g->current = g->widgets;
201
202
203 if (!widget_get_options (w, WOP_WANT_TAB))
204 {
205 if (d_key == '\t')
206 {
207 group_select_next_widget (g);
208 return;
209 }
210 else if ((d_key & ~(KEY_M_SHIFT | KEY_M_CTRL)) == '\t')
211 {
212 group_select_prev_widget (g);
213 return;
214 }
215 }
216
217
218 handled = send_message (h, NULL, MSG_KEY, d_key, NULL);
219
220 if (handled == MSG_NOT_HANDLED)
221 handled = group_default_callback (w, NULL, MSG_KEY, d_key, NULL);
222
223 if (handled == MSG_NOT_HANDLED)
224 handled = dlg_handle_key (h, d_key);
225
226 (void) handled;
227 send_message (h, NULL, MSG_POST_KEY, d_key, NULL);
228 }
229
230
231
232 static int
233 dlg_handle_mouse_event (Widget *w, Gpm_Event *event)
234 {
235 if (w->mouse_callback != NULL)
236 {
237 int mou;
238
239 mou = mouse_handle_event (w, event);
240 if (mou != MOU_UNHANDLED)
241 return mou;
242 }
243
244 return group_handle_mouse_event (w, event);
245 }
246
247
248
249 static void
250 frontend_dlg_run (WDialog *h)
251 {
252 Widget *wh = WIDGET (h);
253 Gpm_Event event;
254
255 event.x = -1;
256
257
258 if (!widget_get_state (wh, WST_MODAL) && mc_global.midnight_shutdown)
259 {
260 send_message (h, NULL, MSG_VALIDATE, 0, NULL);
261 return;
262 }
263
264 while (widget_get_state (wh, WST_ACTIVE))
265 {
266 int d_key;
267
268 if (tty_got_winch ())
269 dialog_change_screen_size ();
270
271 if (is_idle ())
272 {
273 if (idle_hook)
274 execute_hooks (idle_hook);
275
276 while (widget_get_state (wh, WST_IDLE) && is_idle ())
277 send_message (wh, NULL, MSG_IDLE, 0, NULL);
278
279
280 if (!widget_get_state (wh, WST_ACTIVE))
281 break;
282 }
283
284 widget_update_cursor (wh);
285
286
287 tty_got_interrupt ();
288 d_key = tty_get_event (&event, GROUP (h)->mouse_status == MOU_REPEAT, TRUE);
289
290 dlg_process_event (h, d_key, &event);
291
292 if (widget_get_state (wh, WST_CLOSED))
293 send_message (h, NULL, MSG_VALIDATE, 0, NULL);
294 }
295 }
296
297
298
299 static void
300 dlg_default_destroy (Widget *w)
301 {
302 WDialog *h = DIALOG (w);
303
304
305 history_save (h, NULL);
306 group_default_callback (w, NULL, MSG_DESTROY, 0, NULL);
307 send_message (w, NULL, MSG_DESTROY, 0, NULL);
308 mc_event_group_del (h->event_group);
309 g_free (h->event_group);
310 g_free (h);
311
312 do_refresh ();
313 }
314
315
316
317
318
319
320 cb_ret_t
321 dlg_default_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
322 {
323 switch (msg)
324 {
325 case MSG_INIT:
326
327 return MSG_HANDLED;
328
329 case MSG_IDLE:
330
331 widget_idle (w, FALSE);
332 return MSG_HANDLED;
333
334 case MSG_DESTROY:
335
336 return MSG_HANDLED;
337
338 default:
339 return group_default_callback (w, sender, msg, parm, data);
340 }
341 }
342
343
344
345 void
346 dlg_default_mouse_callback (Widget *w, mouse_msg_t msg, mouse_event_t *event)
347 {
348 switch (msg)
349 {
350 case MSG_MOUSE_CLICK:
351 if (event->y < 0 || event->y >= w->rect.lines || event->x < 0 || event->x >= w->rect.cols)
352 {
353 DIALOG (w)->ret_value = B_CANCEL;
354 dlg_close (DIALOG (w));
355 }
356 break;
357
358 default:
359
360 event->result.abort = TRUE;
361 break;
362 }
363 }
364
365
366
367 WDialog *
368 dlg_create (gboolean modal, int y1, int x1, int lines, int cols, widget_pos_flags_t pos_flags,
369 gboolean compact, const int *colors, widget_cb_fn callback,
370 widget_mouse_cb_fn mouse_callback, const char *help_ctx, const char *title)
371 {
372 WRect r = { y1, x1, lines, cols };
373 WDialog *new_d;
374 Widget *w;
375 WGroup *g;
376
377 new_d = g_new0 (WDialog, 1);
378 w = WIDGET (new_d);
379 g = GROUP (new_d);
380 widget_adjust_position (pos_flags, &r);
381 group_init (g, &r, callback != NULL ? callback : dlg_default_callback,
382 mouse_callback != NULL ? mouse_callback : dlg_default_mouse_callback);
383
384 w->pos_flags = pos_flags;
385 w->options |= WOP_SELECTABLE | WOP_TOP_SELECT;
386 w->state |= WST_FOCUSED;
387
388 w->owner = g;
389
390 w->keymap = dialog_map;
391
392 w->mouse_handler = dlg_handle_mouse_event;
393 w->mouse.forced_capture = mouse_close_dialog && (w->pos_flags & WPOS_FULLSCREEN) == 0;
394
395 w->destroy = dlg_default_destroy;
396 w->get_colors = dlg_default_get_colors;
397
398 new_d->colors = colors;
399 new_d->help_ctx = help_ctx;
400 new_d->compact = compact;
401 new_d->data.p = NULL;
402
403 if (modal)
404 {
405 w->state |= WST_MODAL;
406
407 new_d->bg =
408 WIDGET (frame_new (0, 0, w->rect.lines, w->rect.cols, title, FALSE, new_d->compact));
409 group_add_widget (g, new_d->bg);
410 frame_set_title (FRAME (new_d->bg), title);
411 }
412
413
414 new_d->event_group = g_strdup_printf ("%s_%p", MCEVENT_GROUP_DIALOG, (void *) new_d);
415
416 return new_d;
417 }
418
419
420
421 void
422 dlg_set_default_colors (void)
423 {
424 dialog_colors[DLG_COLOR_NORMAL] = DIALOG_NORMAL_COLOR;
425 dialog_colors[DLG_COLOR_FOCUS] = DIALOG_FOCUS_COLOR;
426 dialog_colors[DLG_COLOR_HOT_NORMAL] = DIALOG_HOT_NORMAL_COLOR;
427 dialog_colors[DLG_COLOR_HOT_FOCUS] = DIALOG_HOT_FOCUS_COLOR;
428 dialog_colors[DLG_COLOR_SELECTED_NORMAL] = DIALOG_SELECTED_NORMAL_COLOR;
429 dialog_colors[DLG_COLOR_SELECTED_FOCUS] = DIALOG_SELECTED_FOCUS_COLOR;
430 dialog_colors[DLG_COLOR_TITLE] = DIALOG_TITLE_COLOR;
431 dialog_colors[DLG_COLOR_FRAME] = DIALOG_FRAME_COLOR;
432
433 alarm_colors[DLG_COLOR_NORMAL] = ERROR_NORMAL_COLOR;
434 alarm_colors[DLG_COLOR_FOCUS] = ERROR_FOCUS_COLOR;
435 alarm_colors[DLG_COLOR_HOT_NORMAL] = ERROR_HOT_NORMAL_COLOR;
436 alarm_colors[DLG_COLOR_HOT_FOCUS] = ERROR_HOT_FOCUS_COLOR;
437 alarm_colors[DLG_COLOR_SELECTED_NORMAL] = ERROR_HOT_FOCUS_COLOR;
438 alarm_colors[DLG_COLOR_SELECTED_FOCUS] = ERROR_FOCUS_COLOR;
439 alarm_colors[DLG_COLOR_TITLE] = ERROR_TITLE_COLOR;
440 alarm_colors[DLG_COLOR_FRAME] = ERROR_FRAME_COLOR;
441
442 listbox_colors[DLG_COLOR_NORMAL] = PMENU_ENTRY_COLOR;
443 listbox_colors[DLG_COLOR_FOCUS] = PMENU_SELECTED_COLOR;
444 listbox_colors[DLG_COLOR_HOT_NORMAL] = PMENU_ENTRY_COLOR;
445 listbox_colors[DLG_COLOR_HOT_FOCUS] = PMENU_SELECTED_COLOR;
446 listbox_colors[DLG_COLOR_SELECTED_NORMAL] = PMENU_SELECTED_COLOR;
447 listbox_colors[DLG_COLOR_SELECTED_FOCUS] = PMENU_SELECTED_COLOR;
448 listbox_colors[DLG_COLOR_TITLE] = PMENU_TITLE_COLOR;
449 listbox_colors[DLG_COLOR_FRAME] = PMENU_FRAME_COLOR;
450
451 help_colors[DLG_COLOR_NORMAL] = HELP_NORMAL_COLOR;
452 help_colors[DLG_COLOR_FOCUS] = 0;
453 help_colors[DLG_COLOR_HOT_NORMAL] = HELP_BOLD_COLOR;
454 help_colors[DLG_COLOR_HOT_FOCUS] = 0;
455 help_colors[DLG_COLOR_SELECTED_NORMAL] = 0;
456 help_colors[DLG_COLOR_SELECTED_FOCUS] = 0;
457 help_colors[DLG_COLOR_TITLE] = HELP_TITLE_COLOR;
458 help_colors[DLG_COLOR_FRAME] = HELP_FRAME_COLOR;
459 }
460
461
462
463 void
464 dlg_close (WDialog *h)
465 {
466 widget_set_state (WIDGET (h), WST_CLOSED, TRUE);
467 }
468
469
470
471
472 void
473 dlg_init (WDialog *h)
474 {
475 WGroup *g = GROUP (h);
476 Widget *wh = WIDGET (h);
477
478 if (top_dlg != NULL && widget_get_state (WIDGET (top_dlg->data), WST_MODAL))
479 widget_set_state (wh, WST_MODAL, TRUE);
480
481
482 top_dlg = g_list_prepend (top_dlg, h);
483
484
485 if (widget_get_state (wh, WST_CONSTRUCT))
486 {
487 if (!widget_get_state (wh, WST_MODAL))
488 dialog_switch_add (h);
489
490 send_message (h, NULL, MSG_INIT, 0, NULL);
491 group_default_callback (wh, NULL, MSG_INIT, 0, NULL);
492 history_load (h, NULL);
493 }
494
495
496 while (g->current != NULL && !widget_is_focusable (g->current->data))
497 group_set_current_widget_next (g);
498
499 widget_set_state (wh, WST_ACTIVE, TRUE);
500 widget_draw (wh);
501
502 h->ret_value = 0;
503 }
504
505
506
507 void
508 dlg_process_event (WDialog *h, int key, Gpm_Event *event)
509 {
510 switch (key)
511 {
512 case EV_NONE:
513 if (tty_got_interrupt ())
514 dlg_execute_cmd (h, CK_Cancel);
515 break;
516
517 case EV_MOUSE:
518 {
519 Widget *w = WIDGET (h);
520
521 GROUP (h)->mouse_status = w->mouse_handler (w, event);
522 break;
523 }
524
525 default:
526 dlg_key_event (h, key);
527 break;
528 }
529 }
530
531
532
533
534 void
535 dlg_run_done (WDialog *h)
536 {
537 top_dlg = g_list_remove (top_dlg, h);
538
539 if (widget_get_state (WIDGET (h), WST_CLOSED))
540 {
541 send_message (h, GROUP (h)->current == NULL ? NULL : WIDGET (GROUP (h)->current->data),
542 MSG_END, 0, NULL);
543 if (!widget_get_state (WIDGET (h), WST_MODAL))
544 dialog_switch_remove (h);
545 }
546 }
547
548
549
550
551
552
553
554
555
556 int
557 dlg_run (WDialog *h)
558 {
559 dlg_init (h);
560 frontend_dlg_run (h);
561 dlg_run_done (h);
562 return h->ret_value;
563 }
564
565
566
567 char *
568 dlg_get_title (const WDialog *h, const ssize_t width)
569 {
570 char *t;
571
572 if (h == NULL)
573 abort ();
574
575 if (h->get_title != NULL)
576 t = h->get_title (h, width);
577 else
578 t = g_strdup ("");
579
580 return t;
581 }
582
583