void update_cursor (WDialog * h) { GList *p = h->current; if (p != NULL && widget_get_state (WIDGET (h), WST_ACTIVE)) { Widget *w = WIDGET (p->data); if (!widget_get_state (w, WST_DISABLED) && widget_get_options (w, WOP_WANT_CURSOR)) send_message (w, NULL, MSG_CURSOR, 0, NULL); else do { p = dlg_get_widget_next_of (p); if (p == h->current) break; w = WIDGET (p->data); if (!widget_get_state (w, WST_DISABLED) && widget_get_options (w, WOP_WANT_CURSOR) && send_message (w, NULL, MSG_CURSOR, 0, NULL) == MSG_HANDLED) break; } while (TRUE); } }
void widget_replace (Widget * old_w, Widget * new_w) { WDialog *h = old_w->owner; gboolean should_focus = FALSE; GList *holder; if (h->widgets == NULL) return; if (h->current == NULL) h->current = h->widgets; /* locate widget position in the list */ if (old_w == h->current->data) holder = h->current; else holder = g_list_find (h->widgets, old_w); /* if old widget is focused, we should focus the new one... */ if (widget_get_state (old_w, WST_FOCUSED)) should_focus = TRUE; /* ...but if new widget isn't selectable, we cannot focus it */ if (!widget_get_options (new_w, WOP_SELECTABLE)) should_focus = FALSE; /* if new widget isn't selectable, select other widget before replace */ if (!should_focus) { GList *l; for (l = dlg_get_widget_next_of (holder); !widget_get_options (WIDGET (l->data), WOP_SELECTABLE) && !widget_get_state (WIDGET (l->data), WST_DISABLED); l = dlg_get_widget_next_of (l)) ; widget_select (WIDGET (l->data)); } /* replace widget */ new_w->owner = h; new_w->id = old_w->id; holder->data = new_w; send_message (old_w, NULL, MSG_DESTROY, 0, NULL); send_message (new_w, NULL, MSG_INIT, 0, NULL); if (should_focus) widget_select (new_w); else widget_redraw (new_w); }
void dlg_init (WDialog * h) { Widget *wh = WIDGET (h); if (top_dlg != NULL && widget_get_state (WIDGET (top_dlg->data), WST_MODAL)) widget_set_state (wh, WST_MODAL, TRUE); /* add dialog to the stack */ top_dlg = g_list_prepend (top_dlg, h); /* Initialize dialog manager and widgets */ if (widget_get_state (wh, WST_CONSTRUCT)) { if (!widget_get_state (wh, WST_MODAL)) dialog_switch_add (h); send_message (h, NULL, MSG_INIT, 0, NULL); dlg_broadcast_msg (h, MSG_INIT); dlg_read_history (h); } /* Select the first widget that takes focus */ while (h->current != NULL && !widget_get_options (WIDGET (h->current->data), WOP_SELECTABLE) && !widget_get_state (WIDGET (h->current->data), WST_DISABLED)) dlg_set_current_widget_next (h); widget_set_state (wh, WST_ACTIVE, TRUE); dlg_redraw (h); /* focus found widget */ if (h->current != NULL) widget_set_state (WIDGET (h->current->data), WST_FOCUSED, TRUE); h->ret_value = 0; }
void widget_select (Widget * w) { WDialog *h; if (!widget_get_options (w, WOP_SELECTABLE)) return; h = w->owner; if (h != NULL) { if (widget_get_options (w, WOP_TOP_SELECT)) { GList *l; l = dlg_find (h, w); widget_reorder (l, TRUE); } widget_focus (w); } }
static void dlg_key_event (WDialog * h, int d_key) { cb_ret_t handled; if (h->widgets == NULL) return; if (h->current == NULL) h->current = h->widgets; /* TAB used to cycle */ if (!widget_get_options (WIDGET (h), WOP_WANT_TAB)) { if (d_key == '\t') { dlg_select_next_widget (h); return; } else if ((d_key & ~(KEY_M_SHIFT | KEY_M_CTRL)) == '\t') { dlg_select_prev_widget (h); return; } } /* first can dlg_callback handle the key */ handled = send_message (h, NULL, MSG_KEY, d_key, NULL); /* next try the hotkey */ if (handled == MSG_NOT_HANDLED) handled = dlg_try_hotkey (h, d_key); if (handled == MSG_HANDLED) send_message (h, NULL, MSG_HOTKEY_HANDLED, 0, NULL); else /* not used - then try widget_callback */ handled = send_message (h->current->data, NULL, MSG_KEY, d_key, NULL); /* not used- try to use the unhandled case */ if (handled == MSG_NOT_HANDLED) handled = send_message (h, NULL, MSG_UNHANDLED_KEY, d_key, NULL); if (handled == MSG_NOT_HANDLED) handled = dlg_handle_key (h, d_key); (void) handled; send_message (h, NULL, MSG_POST_KEY, d_key, NULL); }
static void dlg_select_next_or_prev (WDialog * h, gboolean next) { if (h->widgets != NULL && h->current != NULL) { GList *l = h->current; Widget *w; do { l = dlg_get_next_or_prev_of (l, next); w = WIDGET (l->data); } while ((widget_get_state (w, WST_DISABLED) || !widget_get_options (w, WOP_SELECTABLE)) && l != h->current); widget_select (l->data); } }
static cb_ret_t dlg_try_hotkey (WDialog * h, int d_key) { GList *hot_cur; Widget *current; cb_ret_t handled; int c; if (h->widgets == NULL) return MSG_NOT_HANDLED; if (h->current == NULL) h->current = h->widgets; /* * Explanation: we don't send letter hotkeys to other widgets if * the currently selected widget is an input line */ current = WIDGET (h->current->data); if (widget_get_state (current, WST_DISABLED)) return MSG_NOT_HANDLED; if (widget_get_options (current, WOP_IS_INPUT)) { /* skip ascii control characters, anything else can valid character in * some encoding */ if (d_key >= 32 && d_key < 256) return MSG_NOT_HANDLED; } /* If it's an alt key, send the message */ c = d_key & ~ALT (0); if (d_key & ALT (0) && g_ascii_isalpha (c)) d_key = g_ascii_tolower (c); handled = MSG_NOT_HANDLED; if (widget_get_options (current, WOP_WANT_HOTKEY)) handled = send_message (current, NULL, MSG_HOTKEY, d_key, NULL); /* If not used, send hotkey to other widgets */ if (handled == MSG_HANDLED) return MSG_HANDLED; hot_cur = dlg_get_widget_next_of (h->current); /* send it to all widgets */ while (h->current != hot_cur && handled == MSG_NOT_HANDLED) { current = WIDGET (hot_cur->data); if (widget_get_options (current, WOP_WANT_HOTKEY) && !widget_get_state (current, WST_DISABLED)) handled = send_message (current, NULL, MSG_HOTKEY, d_key, NULL); if (handled == MSG_NOT_HANDLED) hot_cur = dlg_get_widget_next_of (hot_cur); } if (handled == MSG_HANDLED) widget_select (WIDGET (hot_cur->data)); return handled; }