1
1

Reimplemented widget list in dialog using GList.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
Этот коммит содержится в:
Andrew Borodin 2010-04-05 20:59:21 +04:00
родитель 0e0f9c8ccd
Коммит 6efe7f2216
10 изменённых файлов: 208 добавлений и 164 удалений

Просмотреть файл

@ -222,7 +222,7 @@ static void update_mode (Dlg_head * h)
tty_setcolor (COLOR_NORMAL); tty_setcolor (COLOR_NORMAL);
dlg_move (h, BY + 2, 9); dlg_move (h, BY + 2, 9);
tty_printf ("%12o", get_mode ()); tty_printf ("%12o", get_mode ());
send_message (h->current, WIDGET_FOCUS, 0); send_message ((Widget *) h->current->data, WIDGET_FOCUS, 0);
} }
static cb_ret_t static cb_ret_t
@ -405,7 +405,7 @@ static cb_ret_t
advanced_chown_callback (Dlg_head *h, Widget *sender, advanced_chown_callback (Dlg_head *h, Widget *sender,
dlg_msg_t msg, int parm, void *data) dlg_msg_t msg, int parm, void *data)
{ {
int i = 0, f_pos = BUTTONS - h->current->dlg_id - single_set - 1; int i = 0, f_pos = BUTTONS - dlg_get_current_widget_id (h) - single_set - 1;
switch (msg) { switch (msg) {
case DLG_DRAW: case DLG_DRAW:
@ -467,8 +467,8 @@ advanced_chown_callback (Dlg_head *h, Widget *sender,
(x_toggle & (1 << parm)) ? '-' : '+'; (x_toggle & (1 << parm)) ? '-' : '+';
x_toggle ^= (1 << parm); x_toggle ^= (1 << parm);
update_mode (h); update_mode (h);
dlg_broadcast_msg (h, WIDGET_DRAW, 0); dlg_broadcast_msg (h, WIDGET_DRAW, FALSE);
send_message (h->current, WIDGET_FOCUS, 0); send_message ((Widget *) h->current->data, WIDGET_FOCUS, 0);
break; break;
case XCTRL ('x'): case XCTRL ('x'):
@ -484,8 +484,8 @@ advanced_chown_callback (Dlg_head *h, Widget *sender,
(x_toggle & (1 << parm)) ? '-' : '+'; (x_toggle & (1 << parm)) ? '-' : '+';
x_toggle ^= (1 << parm); x_toggle ^= (1 << parm);
update_mode (h); update_mode (h);
dlg_broadcast_msg (h, WIDGET_DRAW, 0); dlg_broadcast_msg (h, WIDGET_DRAW, FALSE);
send_message (h->current, WIDGET_FOCUS, 0); send_message ((Widget *) h->current->data, WIDGET_FOCUS, 0);
break; break;
case 'x': case 'x':

Просмотреть файл

@ -162,7 +162,7 @@ static cb_ret_t
chmod_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data) chmod_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data)
{ {
char buffer[BUF_TINY]; char buffer[BUF_TINY];
int id = h->current->dlg_id - BUTTONS + single_set * 2 - 1; int id = dlg_get_current_widget_id (h) - BUTTONS + single_set * 2 - 1;
switch (msg) switch (msg)
{ {

Просмотреть файл

@ -1035,7 +1035,7 @@ query_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *da
listbox_select_entry ((WListbox *) h->current, i); listbox_select_entry ((WListbox *) h->current, i);
end = str_get_prev_char (&(input->buffer[end])) - input->buffer; end = str_get_prev_char (&(input->buffer[end])) - input->buffer;
handle_char (input, parm); handle_char (input, parm);
send_message (h->current, WIDGET_DRAW, 0); send_message ((Widget *) h->current->data, WIDGET_DRAW, 0);
break; break;
} }
} }
@ -1127,7 +1127,7 @@ query_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *da
if (need_redraw == 2) if (need_redraw == 2)
{ {
insert_text (input, last_text, low); insert_text (input, last_text, low);
send_message (h->current, WIDGET_DRAW, 0); send_message ((Widget *) h->current->data, WIDGET_DRAW, 0);
} }
else if (need_redraw == 1) else if (need_redraw == 1)
{ {

Просмотреть файл

@ -60,7 +60,7 @@ Hook *idle_hook = NULL;
/* left click outside of dialog closes it */ /* left click outside of dialog closes it */
int mouse_close_dialog = 0; int mouse_close_dialog = 0;
static void dlg_broadcast_msg_to (Dlg_head * h, widget_msg_t message, int reverse, int flags); static void dlg_broadcast_msg_to (Dlg_head * h, widget_msg_t message, gboolean reverse, int flags);
/* draw box in window */ /* draw box in window */
void void
@ -142,9 +142,12 @@ dlg_set_position (Dlg_head * h, int y1, int x1, int y2, int x2)
h->cols = x2 - x1; h->cols = x2 - x1;
/* dialog is empty */ /* dialog is empty */
if (h->current == NULL) if (h->widgets == NULL)
return; return;
if (h->current == NULL)
h->current = h->widgets;
/* values by which controls should be moved */ /* values by which controls should be moved */
shift_x = h->x - ox; shift_x = h->x - ox;
shift_y = h->y - oy; shift_y = h->y - oy;
@ -153,9 +156,9 @@ dlg_set_position (Dlg_head * h, int y1, int x1, int y2, int x2)
if ((shift_x != 0) || (shift_y != 0) || (scale_x != 0) || (scale_y != 0)) if ((shift_x != 0) || (shift_y != 0) || (scale_x != 0) || (scale_y != 0))
{ {
Widget *c = h->current; GList *w;
do for (w = h->widgets; w != NULL; w = g_list_next (w))
{ {
/* there are, mainly, 2 generally possible /* there are, mainly, 2 generally possible
situations: situations:
@ -166,6 +169,7 @@ dlg_set_position (Dlg_head * h, int y1, int x1, int y2, int x2)
2. control sticks to two sides of 2. control sticks to two sides of
one direction - it should be sized */ one direction - it should be sized */
Widget *c = (Widget *) w->data;
int x = c->x; int x = c->x;
int y = c->y; int y = c->y;
int cols = c->cols; int cols = c->cols;
@ -192,10 +196,7 @@ dlg_set_position (Dlg_head * h, int y1, int x1, int y2, int x2)
y += shift_y + scale_y; y += shift_y + scale_y;
widget_set_size (c, y, x, lines, cols); widget_set_size (c, y, x, lines, cols);
c = c->next;
} }
while (h->current != c);
} }
} }
@ -237,7 +238,7 @@ default_dlg_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, vo
return MSG_NOT_HANDLED; return MSG_NOT_HANDLED;
case DLG_IDLE: case DLG_IDLE:
dlg_broadcast_msg_to (h, WIDGET_IDLE, 0, W_WANT_IDLE); dlg_broadcast_msg_to (h, WIDGET_IDLE, FALSE, W_WANT_IDLE);
return MSG_HANDLED; return MSG_HANDLED;
case DLG_RESIZE: case DLG_RESIZE:
@ -335,30 +336,21 @@ add_widget_autopos (Dlg_head * h, void *w, widget_pos_flags_t pos_flags)
Widget *widget = (Widget *) w; Widget *widget = (Widget *) w;
/* Don't accept 0 widgets */ /* Don't accept 0 widgets */
if (widget == NULL) if (w == NULL)
abort (); abort ();
widget->x += h->x; widget->x += h->x;
widget->y += h->y; widget->y += h->y;
widget->parent = h; widget->parent = h;
widget->dlg_id = h->count++;
widget->pos_flags = pos_flags; widget->pos_flags = pos_flags;
widget->dlg_id = g_list_length (h->widgets);
if (h->current) if ((h->flags & DLG_REVERSE) != 0)
{ h->widgets = g_list_prepend (h->widgets, widget);
widget->next = h->current;
widget->prev = h->current->prev;
h->current->prev->next = widget;
h->current->prev = widget;
}
else else
{ h->widgets = g_list_append (h->widgets, widget);
widget->prev = widget;
widget->next = widget;
}
if ((h->flags & DLG_REVERSE) || !h->current) h->current = h->widgets;
h->current = widget;
return widget->dlg_id; return widget->dlg_id;
} }
@ -398,34 +390,61 @@ do_refresh (void)
* to all widgets. * to all widgets.
*/ */
static void static void
dlg_broadcast_msg_to (Dlg_head * h, widget_msg_t message, int reverse, int flags) dlg_broadcast_msg_to (Dlg_head * h, widget_msg_t message, gboolean reverse, int flags)
{ {
Widget *p, *first, *wi; GList *p, *first;
if (!h->current) if (h->widgets == NULL)
return; return;
if (h->current == NULL)
h->current = h->widgets;
if (reverse) if (reverse)
first = p = h->current->prev; {
p = g_list_previous (h->current);
if (p == NULL)
p = g_list_last (h->widgets);
}
else else
first = p = h->current->next; {
p = g_list_next (h->current);
if (p == NULL)
p = h->widgets;
}
first = p;
do do
{ {
wi = p; Widget *w = (Widget *) p->data;
if (reverse) if (reverse)
p = p->prev; {
p = g_list_previous (p);
if (p == NULL)
p = g_list_last (h->widgets);
}
else else
p = p->next; {
if (flags == 0 || (flags & wi->options)) p = g_list_next (p);
send_message (wi, message, 0);
if (p == NULL)
p = h->widgets;
}
if ((flags == 0) || ((flags & w->options) != 0))
send_message (w, message, 0);
} }
while (first != p); while (first != p);
} }
/* broadcast a message to all the widgets in a dialog */ /* broadcast a message to all the widgets in a dialog */
void void
dlg_broadcast_msg (Dlg_head * h, widget_msg_t message, int reverse) dlg_broadcast_msg (Dlg_head * h, widget_msg_t message, gboolean reverse)
{ {
dlg_broadcast_msg_to (h, message, reverse, 0); dlg_broadcast_msg_to (h, message, reverse, 0);
} }
@ -433,9 +452,10 @@ dlg_broadcast_msg (Dlg_head * h, widget_msg_t message, int reverse)
int int
dlg_focus (Dlg_head * h) dlg_focus (Dlg_head * h)
{ {
if ((h->current != NULL) && (send_message (h->current, WIDGET_FOCUS, 0) == MSG_HANDLED)) if ((h->current != NULL)
&& (send_message ((Widget *) h->current->data, WIDGET_FOCUS, 0) == MSG_HANDLED))
{ {
h->callback (h, h->current, DLG_FOCUS, 0, NULL); h->callback (h, (Widget *) h->current->data, DLG_FOCUS, 0, NULL);
return 1; return 1;
} }
return 0; return 0;
@ -444,9 +464,10 @@ dlg_focus (Dlg_head * h)
static int static int
dlg_unfocus (Dlg_head * h) dlg_unfocus (Dlg_head * h)
{ {
if ((h->current != NULL) && (send_message (h->current, WIDGET_UNFOCUS, 0) == MSG_HANDLED)) if ((h->current != NULL)
&& (send_message ((Widget *) h->current->data, WIDGET_UNFOCUS, 0) == MSG_HANDLED))
{ {
h->callback (h, h->current, DLG_UNFOCUS, 0, NULL); h->callback (h, (Widget *) h->current->data, DLG_UNFOCUS, 0, NULL);
return 1; return 1;
} }
return 0; return 0;
@ -460,53 +481,39 @@ dlg_overlap (Widget * a, Widget * b)
|| (a->x >= b->x + b->cols) || (b->y >= a->y + a->lines) || (a->y >= b->y + b->lines)); || (a->x >= b->x + b->cols) || (b->y >= a->y + a->lines) || (a->y >= b->y + b->lines));
} }
static int
dlg_find_widget_callback (const void *a, const void *b)
{
const Widget *w = (const Widget *) a;
callback_fn f = (callback_fn) b;
return (w->callback == f) ? 0 : 1;
}
/* Find the widget with the given callback in the dialog h */ /* Find the widget with the given callback in the dialog h */
Widget * Widget *
find_widget_type (const Dlg_head * h, callback_fn callback) find_widget_type (const Dlg_head * h, callback_fn callback)
{ {
Widget *w = NULL; GList *w;
if ((h != NULL) && (h->current != NULL)) w = g_list_find_custom (h->widgets, callback, dlg_find_widget_callback);
{
int i;
Widget *item;
for (i = 0, item = h->current; i < h->count; i++, item = item->next) return (w == NULL) ? NULL : (Widget *) w->data;
{
if (item->callback == callback)
{
w = item;
break;
}
}
}
return w;
} }
/* Find the widget with the given dialog id in the dialog h and select it */ /* Find the widget with the given dialog id in the dialog h and select it */
void void
dlg_select_by_id (const Dlg_head * h, int id) dlg_select_by_id (const Dlg_head * h, unsigned int id)
{ {
Widget *w = h->current; if (h->widgets != NULL)
Widget *w_found = NULL;
if (h->current == NULL)
return;
do
{ {
if (w->dlg_id == id) Widget *w_found;
{
w_found = w;
break;
}
w = w->next;
}
while (w != h->current);
if (w_found != NULL) w_found = (Widget *) g_list_nth_data (h->widgets, id);
dlg_select_widget (w_found);
if (w_found != NULL)
dlg_select_widget (w_found);
}
} }
@ -523,14 +530,15 @@ typedef enum
* Otherwise go to the previous widget. * Otherwise go to the previous widget.
*/ */
static void static void
do_select_widget (Dlg_head * h, Widget * w, select_dir_t dir) do_select_widget (Dlg_head * h, GList * w, select_dir_t dir)
{ {
Widget *w0 = h->current; Widget *w0 = (Widget *) h->current->data;
if (!dlg_unfocus (h)) if (!dlg_unfocus (h))
return; return;
h->current = w; h->current = w;
do do
{ {
if (dlg_focus (h)) if (dlg_focus (h))
@ -539,23 +547,27 @@ do_select_widget (Dlg_head * h, Widget * w, select_dir_t dir)
switch (dir) switch (dir)
{ {
case SELECT_NEXT: case SELECT_NEXT:
h->current = h->current->next; h->current = g_list_next (h->current);
if (h->current == NULL)
h->current = h->widgets;
break; break;
case SELECT_PREV: case SELECT_PREV:
h->current = h->current->prev; h->current = g_list_previous (h->current);
if (h->current == NULL)
h->current = g_list_last (h->widgets);
break; break;
case SELECT_EXACT: case SELECT_EXACT:
h->current = w0; h->current = g_list_find (h->widgets, w0);
dlg_focus (h); dlg_focus (h);
return; return;
} }
} }
while (h->current != w); while (h->current != w);
if (dlg_overlap (w0, h->current)) if (dlg_overlap (w0, (Widget *) h->current->data))
{ {
send_message (h->current, WIDGET_DRAW, 0); send_message ((Widget *) h->current->data, WIDGET_DRAW, 0);
send_message (h->current, WIDGET_FOCUS, 0); send_message ((Widget *) h->current->data, WIDGET_FOCUS, 0);
} }
} }
@ -565,39 +577,67 @@ do_select_widget (Dlg_head * h, Widget * w, select_dir_t dir)
void void
dlg_select_widget (void *w) dlg_select_widget (void *w)
{ {
do_select_widget (((Widget *) w)->parent, w, SELECT_NEXT); const Widget *widget = (Widget *) w;
Dlg_head *h = widget->parent;
do_select_widget (h, g_list_find (h->widgets, widget), SELECT_NEXT);
} }
/* Try to select previous widget in the tab order */ /* Try to select previous widget in the tab order */
void void
dlg_one_up (Dlg_head * h) dlg_one_up (Dlg_head * h)
{ {
if (h->current) if (h->widgets != NULL)
do_select_widget (h, h->current->prev, SELECT_PREV); {
GList *prev;
prev = g_list_previous (h->current);
if (prev == NULL)
prev = g_list_last (h->widgets);
do_select_widget (h, prev, SELECT_PREV);
}
} }
/* Try to select next widget in the tab order */ /* Try to select next widget in the tab order */
void void
dlg_one_down (Dlg_head * h) dlg_one_down (Dlg_head * h)
{ {
if (h->current) if (h->widgets != NULL)
do_select_widget (h, h->current->next, SELECT_NEXT); {
GList *next;
next = g_list_next (h->current);
if (next == NULL)
next = h->widgets;
do_select_widget (h, next, SELECT_NEXT);
}
} }
void void
update_cursor (Dlg_head * h) update_cursor (Dlg_head * h)
{ {
Widget *p = h->current; GList *p = h->current;
if (p != NULL) if (p != NULL)
{ {
if (p->options & W_WANT_CURSOR) if (((Widget *) (p->data))->options & W_WANT_CURSOR)
send_message (p, WIDGET_CURSOR, 0); send_message ((Widget *) p->data, WIDGET_CURSOR, 0);
else else
while ((p = p->next) != h->current) do
if (p->options & W_WANT_CURSOR) {
if (send_message (p, WIDGET_CURSOR, 0) == MSG_HANDLED) p = g_list_next (p);
if (p == NULL)
p = h->widgets;
if (p == h->current)
break;
if (((Widget *) (p->data))->options & W_WANT_CURSOR)
if (send_message ((Widget *) p->data, WIDGET_CURSOR, 0) == MSG_HANDLED)
break; break;
}
while (TRUE);
} }
} }
@ -608,7 +648,7 @@ void
dlg_redraw (Dlg_head * h) dlg_redraw (Dlg_head * h)
{ {
h->callback (h, NULL, DLG_DRAW, 0, NULL); h->callback (h, NULL, DLG_DRAW, 0, NULL);
dlg_broadcast_msg (h, WIDGET_DRAW, 1); dlg_broadcast_msg (h, WIDGET_DRAW, TRUE);
update_cursor (h); update_cursor (h);
} }
@ -683,8 +723,8 @@ dlg_handle_key (Dlg_head * h, int d_key)
static int static int
dlg_mouse_event (Dlg_head * h, Gpm_Event * event) dlg_mouse_event (Dlg_head * h, Gpm_Event * event)
{ {
Widget *item; GList *item;
Widget *starting_widget = h->current; GList *starting_widget = h->current;
Gpm_Event new_event; Gpm_Event new_event;
int x = event->x; int x = event->x;
int y = event->y; int y = event->y;
@ -703,8 +743,10 @@ dlg_mouse_event (Dlg_head * h, Gpm_Event * event)
{ {
Widget *widget; Widget *widget;
widget = item; widget = (Widget *) item->data;
item = item->next; item = g_list_next (item);
if (item == NULL)
item = h->widgets;
if ((x > widget->x) && (x <= widget->x + widget->cols) if ((x > widget->x) && (x <= widget->x + widget->cols)
&& (y > widget->y) && (y <= widget->y + widget->lines)) && (y > widget->y) && (y <= widget->y + widget->lines))
@ -725,19 +767,22 @@ dlg_mouse_event (Dlg_head * h, Gpm_Event * event)
static cb_ret_t static cb_ret_t
dlg_try_hotkey (Dlg_head * h, int d_key) dlg_try_hotkey (Dlg_head * h, int d_key)
{ {
Widget *hot_cur; GList *hot_cur;
cb_ret_t handled; cb_ret_t handled;
int c; int c;
if (h->current == NULL) if (h->widgets == NULL)
return MSG_NOT_HANDLED; return MSG_NOT_HANDLED;
if (h->current == NULL)
h->current = h->widgets;
/* /*
* Explanation: we don't send letter hotkeys to other widgets if * Explanation: we don't send letter hotkeys to other widgets if
* the currently selected widget is an input line * the currently selected widget is an input line
*/ */
if (h->current->options & W_IS_INPUT) if (((Widget *) h->current->data)->options & W_IS_INPUT)
{ {
/* skip ascii control characters, anything else can valid character in /* skip ascii control characters, anything else can valid character in
* some encoding */ * some encoding */
@ -751,23 +796,29 @@ dlg_try_hotkey (Dlg_head * h, int d_key)
d_key = g_ascii_tolower (c); d_key = g_ascii_tolower (c);
handled = MSG_NOT_HANDLED; handled = MSG_NOT_HANDLED;
if (h->current->options & W_WANT_HOTKEY) if (((Widget *) h->current->data)->options & W_WANT_HOTKEY)
handled = send_message (h->current, WIDGET_HOTKEY, d_key); handled = send_message ((Widget *) h->current->data, WIDGET_HOTKEY, d_key);
/* If not used, send hotkey to other widgets */ /* If not used, send hotkey to other widgets */
if (handled == MSG_HANDLED) if (handled == MSG_HANDLED)
return MSG_HANDLED; return MSG_HANDLED;
hot_cur = h->current->next; hot_cur = g_list_next (h->current);
if (hot_cur == NULL)
hot_cur = h->widgets;
/* send it to all widgets */ /* send it to all widgets */
while (h->current != hot_cur && handled == MSG_NOT_HANDLED) while (h->current != hot_cur && handled == MSG_NOT_HANDLED)
{ {
if (hot_cur->options & W_WANT_HOTKEY) if (((Widget *) hot_cur->data)->options & W_WANT_HOTKEY)
handled = send_message (hot_cur, WIDGET_HOTKEY, d_key); handled = send_message ((Widget *) hot_cur->data, WIDGET_HOTKEY, d_key);
if (handled == MSG_NOT_HANDLED) if (handled == MSG_NOT_HANDLED)
hot_cur = hot_cur->next; {
hot_cur = g_list_next (hot_cur);
if (hot_cur == NULL)
hot_cur = h->widgets;
}
} }
if (handled == MSG_HANDLED) if (handled == MSG_HANDLED)
@ -781,9 +832,12 @@ dlg_key_event (Dlg_head * h, int d_key)
{ {
cb_ret_t handled; cb_ret_t handled;
if (h->current == NULL) if (h->widgets == NULL)
return; return;
if (h->current == NULL)
h->current = h->widgets;
/* TAB used to cycle */ /* TAB used to cycle */
if ((h->flags & DLG_WANT_TAB) == 0) if ((h->flags & DLG_WANT_TAB) == 0)
{ {
@ -810,7 +864,7 @@ dlg_key_event (Dlg_head * h, int d_key)
h->callback (h, NULL, DLG_HOTKEY_HANDLED, 0, NULL); h->callback (h, NULL, DLG_HOTKEY_HANDLED, 0, NULL);
else else
/* not used - then try widget_callback */ /* not used - then try widget_callback */
handled = send_message (h->current, WIDGET_KEY, d_key); handled = send_message ((Widget *) h->current->data, WIDGET_KEY, d_key);
/* not used- try to use the unhandled case */ /* not used- try to use the unhandled case */
if (handled == MSG_NOT_HANDLED) if (handled == MSG_NOT_HANDLED)
@ -826,19 +880,22 @@ dlg_key_event (Dlg_head * h, int d_key)
void void
init_dlg (Dlg_head * h) init_dlg (Dlg_head * h)
{ {
/* add dialog to the stack */ /* add dialog to the stack */
current_dlg = g_list_prepend (current_dlg, h); current_dlg = g_list_prepend (current_dlg, h);
/* Initialize dialog manager and widgets */ /* Initialize dialog manager and widgets */
h->callback (h, NULL, DLG_INIT, 0, NULL); h->callback (h, NULL, DLG_INIT, 0, NULL);
dlg_broadcast_msg (h, WIDGET_INIT, 0); dlg_broadcast_msg (h, WIDGET_INIT, FALSE);
dlg_redraw (h); dlg_redraw (h);
/* Select the first widget that takes focus */ /* Select the first widget that takes focus */
while (h->current != NULL && !dlg_focus (h)) while (h->current != NULL && !dlg_focus (h))
h->current = h->current->next; {
h->current = g_list_next (h->current);
if (h->current == NULL)
h->current = h->widgets;
}
h->ret_value = 0; h->ret_value = 0;
h->state = DLG_ACTIVE; h->state = DLG_ACTIVE;
@ -904,7 +961,7 @@ void
dlg_run_done (Dlg_head * h) dlg_run_done (Dlg_head * h)
{ {
if (h->current != NULL) if (h->current != NULL)
h->callback (h, h->current, DLG_END, 0, NULL); h->callback (h, (Widget *) h->current->data, DLG_END, 0, NULL);
current_dlg = g_list_remove (current_dlg, h); current_dlg = g_list_remove (current_dlg, h);
} }
@ -926,17 +983,9 @@ run_dlg (Dlg_head * h)
void void
destroy_dlg (Dlg_head * h) destroy_dlg (Dlg_head * h)
{ {
int i; dlg_broadcast_msg (h, WIDGET_DESTROY, FALSE);
Widget *c; g_list_foreach (h->widgets, (GFunc) g_free, NULL);
g_list_free (h->widgets);
dlg_broadcast_msg (h, WIDGET_DESTROY, 0);
c = h->current;
for (i = 0; i < h->count; i++)
{
c = c->next;
g_free (h->current);
h->current = c;
}
g_free (h->color); g_free (h->color);
g_free (h->title); g_free (h->title);
g_free (h); g_free (h);
@ -949,33 +998,24 @@ void
dlg_replace_widget (Widget * old_w, Widget * new_w) dlg_replace_widget (Widget * old_w, Widget * new_w)
{ {
Dlg_head *h = old_w->parent; Dlg_head *h = old_w->parent;
int should_focus = 0; gboolean should_focus = FALSE;
if (!h->current) if (h->widgets == NULL)
return; return;
if (old_w == h->current) if (h->current == NULL)
should_focus = 1; h->current = h->widgets;
if (old_w == h->current->data)
should_focus = TRUE;
new_w->parent = h; new_w->parent = h;
new_w->dlg_id = old_w->dlg_id; new_w->dlg_id = old_w->dlg_id;
if (old_w == old_w->next)
{
/* just one widget */
new_w->prev = new_w;
new_w->next = new_w;
}
else
{
new_w->prev = old_w->prev;
new_w->next = old_w->next;
old_w->prev->next = new_w;
old_w->next->prev = new_w;
}
if (should_focus) if (should_focus)
h->current = new_w; h->current->data = new_w;
else
g_list_find (h->widgets, old_w)->data = new_w;
send_message (old_w, WIDGET_DESTROY, 0); send_message (old_w, WIDGET_DESTROY, 0);
send_message (new_w, WIDGET_INIT, 0); send_message (new_w, WIDGET_INIT, 0);

Просмотреть файл

@ -145,8 +145,8 @@ struct Dlg_head
int mouse_status; /* For the autorepeat status of the mouse */ int mouse_status; /* For the autorepeat status of the mouse */
/* Internal variables */ /* Internal variables */
int count; /* Number of widgets */ GList *widgets; /* widgets list */
struct Widget *current; /* Curently active widget */ GList *current; /* Curently active widget */
void *data; /* Data can be passed to dialog */ void *data; /* Data can be passed to dialog */
dlg_cb_fn callback; dlg_cb_fn callback;
dlg_shortcut_str get_shortcut; /* Shortcut string */ dlg_shortcut_str get_shortcut; /* Shortcut string */
@ -189,9 +189,7 @@ struct Widget
int cols, lines; int cols, lines;
widget_options_t options; widget_options_t options;
widget_pos_flags_t pos_flags; /* repositioning flags */ widget_pos_flags_t pos_flags; /* repositioning flags */
int dlg_id; /* Number of the widget, starting with 0 */ unsigned int dlg_id; /* Number of the widget, starting with 0 */
struct Widget *next;
struct Widget *prev;
callback_fn callback; callback_fn callback;
mouse_h mouse; mouse_h mouse;
struct Dlg_head *parent; struct Dlg_head *parent;
@ -231,7 +229,7 @@ void destroy_dlg (Dlg_head * h);
void widget_set_size (Widget * widget, int y, int x, int lines, int cols); void widget_set_size (Widget * widget, int y, int x, int lines, int cols);
void dlg_broadcast_msg (Dlg_head * h, widget_msg_t message, int reverse); void dlg_broadcast_msg (Dlg_head * h, widget_msg_t message, gboolean reverse);
void init_widget (Widget * w, int y, int x, int lines, int cols, void init_widget (Widget * w, int y, int x, int lines, int cols,
callback_fn callback, mouse_h mouse_handler); callback_fn callback, mouse_h mouse_handler);
@ -253,7 +251,7 @@ extern Hook *idle_hook;
static inline cb_ret_t static inline cb_ret_t
send_message (Widget * w, widget_msg_t msg, int parm) send_message (Widget * w, widget_msg_t msg, int parm)
{ {
return (*(w->callback)) (w, msg, parm); return w->callback (w, msg, parm);
} }
/* Return 1 if the widget is active, 0 otherwise */ /* Return 1 if the widget is active, 0 otherwise */
@ -261,7 +259,13 @@ static inline int
dlg_widget_active (void *w) dlg_widget_active (void *w)
{ {
Widget *w1 = (Widget *) w; Widget *w1 = (Widget *) w;
return (w1->parent->current == w1); return ((Widget *) w1->parent->current->data == w1);
}
static inline unsigned int
dlg_get_current_widget_id (const Dlg_head * h)
{
return ((Widget *) h->current->data)->dlg_id;
} }
void dlg_replace_widget (Widget * old, Widget * new); void dlg_replace_widget (Widget * old, Widget * new);
@ -276,7 +280,7 @@ void dlg_one_up (Dlg_head * h);
void dlg_one_down (Dlg_head * h); void dlg_one_down (Dlg_head * h);
int dlg_focus (Dlg_head * h); int dlg_focus (Dlg_head * h);
Widget *find_widget_type (const Dlg_head * h, callback_fn callback); Widget *find_widget_type (const Dlg_head * h, callback_fn callback);
void dlg_select_by_id (const Dlg_head * h, int id); void dlg_select_by_id (const Dlg_head * h, unsigned int id);
/* Redraw all dialogs */ /* Redraw all dialogs */
void do_refresh (void); void do_refresh (void);

Просмотреть файл

@ -234,7 +234,7 @@ edit_drop_menu_cmd (WEdit * e, int which)
if (which >= 0) if (which >= 0)
menubar->selected = which; menubar->selected = which;
menubar->previous_widget = e->widget.parent->current->dlg_id; menubar->previous_widget = dlg_get_current_widget_id (e->widget.parent);
dlg_select_widget (menubar); dlg_select_widget (menubar);
} }
} }

Просмотреть файл

@ -135,7 +135,7 @@ static int learn_move (int right)
totalcols = (learn_total - 1) / ROWS + 1; totalcols = (learn_total - 1) / ROWS + 1;
for (i = 0; i < learn_total; i++) for (i = 0; i < learn_total; i++)
if (learnkeys [i].button == learn_dlg->current) { if (learnkeys [i].button == (Widget *) learn_dlg->current->data) {
if (right) { if (right) {
if (i < learn_total - ROWS) if (i < learn_total - ROWS)
i += ROWS; i += ROWS;

Просмотреть файл

@ -826,7 +826,7 @@ menu_last_selected_cmd (void)
{ {
the_menubar->is_active = TRUE; the_menubar->is_active = TRUE;
the_menubar->is_dropped = (drop_menus != 0); the_menubar->is_dropped = (drop_menus != 0);
the_menubar->previous_widget = midnight_dlg->current->dlg_id; the_menubar->previous_widget = dlg_get_current_widget_id (midnight_dlg);
dlg_select_widget (the_menubar); dlg_select_widget (the_menubar);
} }

Просмотреть файл

@ -608,7 +608,7 @@ menubar_event (Gpm_Event * event, void *data)
if (!menubar->is_dropped) if (!menubar->is_dropped)
{ {
menubar->previous_widget = menubar->widget.parent->current->dlg_id; menubar->previous_widget = dlg_get_current_widget_id (menubar->widget.parent);
menubar->is_active = TRUE; menubar->is_active = TRUE;
menubar->is_dropped = TRUE; menubar->is_dropped = TRUE;
was_active = FALSE; was_active = FALSE;

Просмотреть файл

@ -184,7 +184,7 @@ button_callback (Widget * w, widget_msg_t msg, int parm)
* when hotkeys are sent to all widgets before the key is * when hotkeys are sent to all widgets before the key is
* handled by the current widget. * handled by the current widget.
*/ */
if (parm == '\n' && h->current == &b->widget) if (parm == '\n' && (Widget *) h->current->data == &b->widget)
{ {
button_callback (w, WIDGET_KEY, ' '); button_callback (w, WIDGET_KEY, ' ');
return MSG_HANDLED; return MSG_HANDLED;