mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 12:32:40 +03:00
Allow add and remove widgets in runtime.
Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
parent
33d25a0c8f
commit
6ad4b2466b
@ -178,23 +178,22 @@ dlg_read_history (Dlg_head * h)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
static gboolean
|
||||
dlg_unfocus (Dlg_head * h)
|
||||
{
|
||||
/* ... but can unfocus disabled widget */
|
||||
|
||||
if ((h->current != NULL) && (h->state == DLG_ACTIVE))
|
||||
/* we can unfocus disabled widget */
|
||||
if ((h->current != NULL) && (h->state == DLG_CONSTRUCT || h->state == DLG_ACTIVE))
|
||||
{
|
||||
Widget *current = (Widget *) h->current->data;
|
||||
|
||||
if (send_message (current, WIDGET_UNFOCUS, 0) == MSG_HANDLED)
|
||||
{
|
||||
h->callback (h, current, DLG_UNFOCUS, 0, NULL);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -759,6 +758,7 @@ create_dlg (gboolean modal, int y1, int x1, int lines, int cols,
|
||||
Dlg_head *new_d;
|
||||
|
||||
new_d = g_new0 (Dlg_head, 1);
|
||||
new_d->state = DLG_CONSTRUCT;
|
||||
new_d->modal = modal;
|
||||
if (colors != NULL)
|
||||
memmove (new_d->color, colors, sizeof (dlg_colors_t));
|
||||
@ -832,12 +832,11 @@ set_idle_proc (Dlg_head * d, int enable)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Insert widget to dialog before current widget. For dialogs populated
|
||||
* from the bottom, make the widget current. Return widget number.
|
||||
* Insert widget to dialog before requested widget. Make the widget current. Return widget ID.
|
||||
*/
|
||||
|
||||
int
|
||||
add_widget_autopos (Dlg_head * h, void *w, widget_pos_flags_t pos_flags)
|
||||
unsigned long
|
||||
add_widget_autopos (Dlg_head * h, void *w, widget_pos_flags_t pos_flags, const void *before)
|
||||
{
|
||||
Widget *widget = (Widget *) w;
|
||||
|
||||
@ -852,11 +851,59 @@ add_widget_autopos (Dlg_head * h, void *w, widget_pos_flags_t pos_flags)
|
||||
widget->id = h->widget_id++;
|
||||
|
||||
if ((h->flags & DLG_REVERSE) != 0)
|
||||
h->widgets = g_list_prepend (h->widgets, widget);
|
||||
else
|
||||
h->widgets = g_list_append (h->widgets, widget);
|
||||
{
|
||||
if (h->widgets == NULL || before == NULL)
|
||||
{
|
||||
h->widgets = g_list_prepend (h->widgets, widget);
|
||||
h->current = h->widgets;
|
||||
}
|
||||
else
|
||||
{
|
||||
GList *b;
|
||||
|
||||
h->current = h->widgets;
|
||||
b = g_list_find (h->widgets, before);
|
||||
|
||||
/* don't accept widget not from dialog. This shouldn't happen */
|
||||
if (b == NULL)
|
||||
abort ();
|
||||
|
||||
h->widgets = g_list_insert_before (h->widgets, b, widget);
|
||||
h->current = g_list_previous (b);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (h->widgets == NULL || before == NULL)
|
||||
{
|
||||
h->widgets = g_list_append (h->widgets, widget);
|
||||
h->current = g_list_last (h->widgets);
|
||||
}
|
||||
else
|
||||
{
|
||||
GList *b;
|
||||
|
||||
b = g_list_find (h->widgets, before);
|
||||
|
||||
/* don't accept widget not from dialog. This shouldn't happen */
|
||||
if (b == NULL)
|
||||
abort ();
|
||||
|
||||
b = g_list_next (b);
|
||||
h->widgets = g_list_insert_before (h->widgets, b, widget);
|
||||
if (b != NULL)
|
||||
h->current = g_list_previous (b);
|
||||
else
|
||||
h->current = g_list_last (h->widgets);
|
||||
}
|
||||
}
|
||||
|
||||
/* widget has been added in runtime */
|
||||
if (h->state == DLG_ACTIVE)
|
||||
{
|
||||
send_message (widget, WIDGET_INIT, 0);
|
||||
send_message (widget, WIDGET_DRAW, 0);
|
||||
send_message (widget, WIDGET_FOCUS, 0);
|
||||
}
|
||||
|
||||
return widget->id;
|
||||
}
|
||||
@ -864,10 +911,53 @@ add_widget_autopos (Dlg_head * h, void *w, widget_pos_flags_t pos_flags)
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/** wrapper to simply add lefttop positioned controls */
|
||||
|
||||
int
|
||||
unsigned long
|
||||
add_widget (Dlg_head * h, void *w)
|
||||
{
|
||||
return add_widget_autopos (h, w, WPOS_KEEP_LEFT | WPOS_KEEP_TOP);
|
||||
return add_widget_autopos (h, w, WPOS_KEEP_LEFT | WPOS_KEEP_TOP,
|
||||
h->current != NULL ? h->current->data : NULL);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
unsigned long
|
||||
add_widget_before (Dlg_head * h, void *w, void *before)
|
||||
{
|
||||
return add_widget_autopos (h, w, WPOS_KEEP_LEFT | WPOS_KEEP_TOP, before);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/** delete widget from dialog */
|
||||
void
|
||||
del_widget (void *w)
|
||||
{
|
||||
Dlg_head *h = ((Widget *) w)->owner;
|
||||
GList *d;
|
||||
|
||||
/* Don't accept NULL widget. This shouldn't happen */
|
||||
if (w == NULL)
|
||||
abort ();
|
||||
|
||||
d = g_list_find (h->widgets, w);
|
||||
if (d == h->current)
|
||||
{
|
||||
if ((h->flags & DLG_REVERSE) != 0)
|
||||
h->current = dlg_widget_prev (h, d);
|
||||
else
|
||||
h->current = dlg_widget_next (h, d);
|
||||
}
|
||||
|
||||
h->widgets = g_list_remove_link (h->widgets, d);
|
||||
send_message (d->data, WIDGET_DESTROY, 0);
|
||||
g_list_free_1 (d);
|
||||
|
||||
/* widget has been deleted in runtime */
|
||||
if (h->state == DLG_ACTIVE)
|
||||
{
|
||||
dlg_redraw (h);
|
||||
dlg_focus (h);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -906,12 +996,11 @@ dlg_broadcast_msg (Dlg_head * h, widget_msg_t msg, gboolean reverse)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
int
|
||||
gboolean
|
||||
dlg_focus (Dlg_head * h)
|
||||
{
|
||||
/* cannot focus disabled widget ... */
|
||||
|
||||
if ((h->current != NULL) && (h->state == DLG_ACTIVE))
|
||||
/* cannot focus disabled widget */
|
||||
if ((h->current != NULL) && (h->state == DLG_CONSTRUCT || h->state == DLG_ACTIVE))
|
||||
{
|
||||
Widget *current = (Widget *) h->current->data;
|
||||
|
||||
@ -919,11 +1008,11 @@ dlg_focus (Dlg_head * h)
|
||||
&& (send_message (current, WIDGET_FOCUS, 0) == MSG_HANDLED))
|
||||
{
|
||||
h->callback (h, current, DLG_FOCUS, 0, NULL);
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -1085,7 +1174,7 @@ init_dlg (Dlg_head * h)
|
||||
top_dlg = g_list_prepend (top_dlg, h);
|
||||
|
||||
/* Initialize dialog manager and widgets */
|
||||
if (h->state == DLG_ACTIVE)
|
||||
if (h->state == DLG_CONSTRUCT)
|
||||
{
|
||||
if (!h->modal)
|
||||
dialog_switch_add (h);
|
||||
@ -1095,14 +1184,13 @@ init_dlg (Dlg_head * h)
|
||||
dlg_read_history (h);
|
||||
}
|
||||
|
||||
h->state = DLG_ACTIVE;
|
||||
|
||||
dlg_redraw (h);
|
||||
|
||||
/* Select the first widget that takes focus */
|
||||
while (h->current != NULL && !dlg_focus (h))
|
||||
h->current = dlg_widget_next (h, h->current);
|
||||
|
||||
h->state = DLG_ACTIVE;
|
||||
dlg_redraw (h);
|
||||
|
||||
h->ret_value = 0;
|
||||
}
|
||||
|
||||
@ -1265,7 +1353,8 @@ dlg_replace_widget (Widget * old_w, Widget * new_w)
|
||||
if (should_focus)
|
||||
dlg_select_widget (new_w);
|
||||
|
||||
send_message (new_w, WIDGET_DRAW, 0);
|
||||
if (new_w->owner->state == DLG_ACTIVE)
|
||||
send_message (new_w, WIDGET_DRAW, 0);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -62,9 +62,10 @@ typedef enum
|
||||
/* Dialog state */
|
||||
typedef enum
|
||||
{
|
||||
DLG_ACTIVE = 0, /* Dialog is visible and active */
|
||||
DLG_SUSPENDED = 1, /* Dialog is suspended */
|
||||
DLG_CLOSED = 2 /* Dialog is closed */
|
||||
DLG_CONSTRUCT = 0, /* DIalog has been constructed but bot run yet */
|
||||
DLG_ACTIVE = 1, /* Dialog is visible and active */
|
||||
DLG_SUSPENDED = 2, /* Dialog is suspended */
|
||||
DLG_CLOSED = 3 /* Dialog is closed */
|
||||
} dlg_state_t;
|
||||
|
||||
/* Dialog color constants */
|
||||
@ -159,8 +160,11 @@ Dlg_head *create_dlg (gboolean modal, int y1, int x1, int lines, int cols,
|
||||
|
||||
void dlg_set_default_colors (void);
|
||||
|
||||
int add_widget_autopos (Dlg_head * dest, void *w, widget_pos_flags_t pos_flags);
|
||||
int add_widget (Dlg_head * dest, void *w);
|
||||
unsigned long add_widget_autopos (Dlg_head * dest, void *w, widget_pos_flags_t pos_flags,
|
||||
const void *before);
|
||||
unsigned long add_widget (Dlg_head * dest, void *w);
|
||||
unsigned long add_widget_before (Dlg_head * h, void *w, void *before);
|
||||
void del_widget (void *w);
|
||||
|
||||
/* sets size of dialog, leaving positioning to automatic mehtods
|
||||
according to dialog flags */
|
||||
@ -200,7 +204,7 @@ void dlg_stop (Dlg_head * h);
|
||||
void dlg_select_widget (void *widget);
|
||||
void dlg_one_up (Dlg_head * h);
|
||||
void dlg_one_down (Dlg_head * h);
|
||||
int dlg_focus (Dlg_head * h);
|
||||
gboolean dlg_focus (Dlg_head * h);
|
||||
Widget *find_widget_type (const Dlg_head * h, callback_fn callback);
|
||||
Widget *dlg_find_by_id (const Dlg_head * h, unsigned long id);
|
||||
void dlg_select_by_id (const Dlg_head * h, unsigned long id);
|
||||
|
@ -328,7 +328,7 @@ history_show (GList ** history, Widget * widget)
|
||||
|
||||
/* this call makes list stick to all sides of dialog, effectively make
|
||||
it be resized with dialog */
|
||||
add_widget_autopos (query_dlg, query_list, WPOS_KEEP_ALL);
|
||||
add_widget_autopos (query_dlg, query_list, WPOS_KEEP_ALL, NULL);
|
||||
|
||||
/* to avoid diplicating of (calculating sizes in two places)
|
||||
code, call dlg_hist_callback function here, to set dialog and
|
||||
|
@ -788,7 +788,8 @@ init_hotlist (int list_type)
|
||||
hotlist_but[i].ret_cmd,
|
||||
hotlist_but[i].flags,
|
||||
hotlist_but[i].text,
|
||||
hotlist_button_callback), hotlist_but[i].pos_flags);
|
||||
hotlist_button_callback), hotlist_but[i].pos_flags,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* We add the labels.
|
||||
@ -796,7 +797,7 @@ init_hotlist (int list_type)
|
||||
* pname_group will hold name of current group
|
||||
*/
|
||||
pname = label_new (UY - 11 + LINES, UX + 2, "");
|
||||
add_widget_autopos (hotlist_dlg, pname, WPOS_KEEP_BOTTOM | WPOS_KEEP_LEFT);
|
||||
add_widget_autopos (hotlist_dlg, pname, WPOS_KEEP_BOTTOM | WPOS_KEEP_LEFT, NULL);
|
||||
if (!hotlist_state.moving)
|
||||
{
|
||||
char label_text[BUF_TINY];
|
||||
@ -804,7 +805,7 @@ init_hotlist (int list_type)
|
||||
g_snprintf (label_text, sizeof (label_text), " %s ", _("Directory path"));
|
||||
add_widget_autopos (hotlist_dlg,
|
||||
label_new (UY - 12 + LINES, UX + 2,
|
||||
label_text), WPOS_KEEP_BOTTOM | WPOS_KEEP_LEFT);
|
||||
label_text), WPOS_KEEP_BOTTOM | WPOS_KEEP_LEFT, NULL);
|
||||
|
||||
/* This one holds the displayed pathname */
|
||||
pname_group = label_new (UY, UX + 2, _("Directory label"));
|
||||
@ -824,7 +825,7 @@ init_hotlist (int list_type)
|
||||
#endif /* !ENABLE_VFS */
|
||||
fill_listbox ();
|
||||
|
||||
add_widget_autopos (hotlist_dlg, l_hotlist, WPOS_KEEP_ALL);
|
||||
add_widget_autopos (hotlist_dlg, l_hotlist, WPOS_KEEP_ALL, NULL);
|
||||
/* add listbox to the dialogs */
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user