Add WST_VISIBLE widget state.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
Andrew Borodin 2019-08-11 15:15:14 +03:00
parent 4598667b4d
commit 7196a15d81
3 changed files with 73 additions and 19 deletions

View File

@ -167,7 +167,9 @@ group_send_broadcast_msg_custom (WGroup * g, widget_msg_t msg, gboolean reverse,
p = group_get_next_or_prev_of (p, !reverse);
if (options == WOP_DEFAULT || (options & w->options) != 0)
send_message (w, NULL, msg, 0, NULL);
/* special case: don't draw invisible widgets */
if (msg != MSG_DRAW || widget_get_state (w, WST_VISIBLE))
send_message (w, NULL, msg, 0, NULL);
}
while (first != p);
}
@ -287,8 +289,11 @@ group_update_cursor (WGroup * g)
{
Widget *w = WIDGET (p->data);
if (widget_get_options (w, WOP_WANT_CURSOR) && !widget_get_state (w, WST_DISABLED)
&& widget_update_cursor (WIDGET (p->data)))
/* Don't use widget_is_selectable() here.
If WOP_SELECTABLE option is not set, widget can handle mouse events.
For example, commandl line in file manager */
if (widget_get_options (w, WOP_WANT_CURSOR) && widget_get_state (w, WST_VISIBLE)
&& !widget_get_state (w, WST_DISABLED) && widget_update_cursor (WIDGET (p->data)))
return MSG_HANDLED;
p = group_get_widget_next_of (p);
@ -459,7 +464,7 @@ group_handle_hotkey (WGroup * g, int key)
w = WIDGET (g->current->data);
if (widget_get_state (w, WST_DISABLED))
if (!widget_get_state (w, WST_VISIBLE) || widget_get_state (w, WST_DISABLED))
return MSG_NOT_HANDLED;
/* Explanation: we don't send letter hotkeys to other widgets
@ -652,7 +657,10 @@ group_handle_mouse_event (Widget * w, Gpm_Event * event)
{
Widget *wp = WIDGET (p->data);
if (!widget_get_state (wp, WST_DISABLED))
/* Don't use widget_is_selectable() here.
If WOP_SELECTABLE option is not set, widget can handle mouse events.
For example, commandl line in file manager */
if (widget_get_state (w, WST_VISIBLE) && !widget_get_state (wp, WST_DISABLED))
{
/* put global cursor position to the widget */
int ret;

View File

@ -98,7 +98,7 @@ widget_default_resize (Widget * w, const WRect * r)
static void
widget_do_focus (Widget * w, gboolean enable)
{
if (w != NULL && widget_get_state (WIDGET (w->owner), WST_FOCUSED))
if (w != NULL && widget_get_state (WIDGET (w->owner), WST_VISIBLE | WST_FOCUSED))
widget_set_state (w, WST_FOCUSED, enable);
}
@ -332,7 +332,7 @@ widget_init (Widget * w, int y, int x, int lines, int cols,
w->mouse.last_buttons_down = 0;
w->options = WOP_DEFAULT;
w->state = WST_CONSTRUCT;
w->state = WST_CONSTRUCT | WST_VISIBLE;
w->find = widget_default_find;
w->find_by_type = widget_default_find_by_type;
@ -478,6 +478,15 @@ widget_erase (Widget * w)
tty_fill_region (w->y, w->x, w->lines, w->cols, ' ');
}
/* --------------------------------------------------------------------------------------------- */
void
widget_set_visibility (Widget * w, gboolean make_visible)
{
if (widget_get_state (w, WST_VISIBLE) != make_visible)
widget_set_state (w, WST_VISIBLE, make_visible);
}
/* --------------------------------------------------------------------------------------------- */
/**
* Check whether widget is active or not.
@ -516,7 +525,7 @@ widget_draw (Widget * w)
{
cb_ret_t ret = MSG_NOT_HANDLED;
if (w != NULL)
if (w != NULL && widget_get_state (w, WST_VISIBLE))
{
WGroup *g = w->owner;
@ -566,8 +575,7 @@ widget_replace (Widget * old_w, Widget * new_w)
{
GList *l;
for (l = group_get_widget_next_of (holder);
widget_is_focusable (WIDGET (l->data);
for (l = group_get_widget_next_of (holder); widget_is_focusable (WIDGET (l->data));
l = group_get_widget_next_of (l))
;
@ -593,7 +601,8 @@ widget_replace (Widget * old_w, Widget * new_w)
gboolean
widget_is_focusable (const Widget * w)
{
return (widget_get_options (w, WOP_SELECTABLE) && !widget_get_state (w, WST_DISABLED));
return (widget_get_options (w, WOP_SELECTABLE) && widget_get_state (w, WST_VISIBLE) &&
!widget_get_state (w, WST_DISABLED));
}
/* --------------------------------------------------------------------------------------------- */
@ -743,6 +752,7 @@ cb_ret_t
widget_default_set_state (Widget * w, widget_state_t state, gboolean enable)
{
gboolean ret = MSG_HANDLED;
Widget *owner = WIDGET (GROUP (w->owner));
if (enable)
w->state |= state;
@ -762,14 +772,32 @@ widget_default_set_state (Widget * w, widget_state_t state, gboolean enable)
w->state &= ~(WST_CONSTRUCT | WST_ACTIVE | WST_SUSPENDED);
}
if (w->owner == NULL)
if (owner == NULL)
return MSG_NOT_HANDLED;
switch (state)
{
case WST_VISIBLE:
if (widget_get_state (owner, WST_ACTIVE))
{
/* redraw owner to show/hide widget */
widget_draw (owner);
if (!enable)
{
/* try select another widget if current one got hidden */
if (w == GROUP (owner)->current->data)
group_select_next_widget (GROUP (owner));
widget_update_cursor (owner); /* FIXME: unneeded? */
}
}
break;
case WST_DISABLED:
ret = send_message (w, NULL, enable ? MSG_DISABLE : MSG_ENABLE, 0, NULL);
if (ret == MSG_HANDLED && widget_get_state (WIDGET (w->owner), WST_ACTIVE))
if (ret == MSG_HANDLED && widget_get_state (owner, WST_ACTIVE))
ret = widget_draw (w);
break;
@ -779,11 +807,11 @@ widget_default_set_state (Widget * w, widget_state_t state, gboolean enable)
msg = enable ? MSG_FOCUS : MSG_UNFOCUS;
ret = send_message (w, NULL, msg, 0, NULL);
if (ret == MSG_HANDLED && widget_get_state (WIDGET (w->owner), WST_ACTIVE))
if (ret == MSG_HANDLED && widget_get_state (owner, WST_ACTIVE))
{
widget_draw (w);
/* Notify owner that focus was moved from one widget to another */
send_message (w->owner, w, MSG_CHANGED_FOCUS, 0, NULL);
send_message (owner, w, MSG_CHANGED_FOCUS, 0, NULL);
}
}
break;

View File

@ -80,10 +80,11 @@ typedef enum
typedef enum
{
WST_DEFAULT = (0 << 0),
WST_DISABLED = (1 << 0), /* Widget cannot be selected */
WST_IDLE = (1 << 1),
WST_MODAL = (1 << 2), /* Widget (dialog) is modal */
WST_FOCUSED = (1 << 3),
WST_VISIBLE = (1 << 0), /* Widget is visible */
WST_DISABLED = (1 << 1), /* Widget cannot be selected */
WST_IDLE = (1 << 2),
WST_MODAL = (1 << 3), /* Widget (dialog) is modal */
WST_FOCUSED = (1 << 4),
WST_CONSTRUCT = (1 << 15), /* Widget has been constructed but not run yet */
WST_ACTIVE = (1 << 16), /* Dialog is visible and active */
@ -210,6 +211,7 @@ void widget_set_size (Widget * w, int y, int x, int lines, int cols);
void widget_selectcolor (Widget * w, gboolean focused, gboolean hotkey);
cb_ret_t widget_draw (Widget * w);
void widget_erase (Widget * w);
void widget_set_visibility (Widget * w, gboolean make_visible);
gboolean widget_is_active (const void *w);
gboolean widget_overlapped (const Widget * a, const Widget * b);
void widget_replace (Widget * old, Widget * new);
@ -383,4 +385,20 @@ widget_set_size_rect (Widget * w, const WRect * r)
/* --------------------------------------------------------------------------------------------- */
static inline void
widget_show (Widget * w)
{
widget_set_visibility (w, TRUE);
}
/* --------------------------------------------------------------------------------------------- */
static inline void
widget_hide (Widget * w)
{
widget_set_visibility (w, FALSE);
}
/* --------------------------------------------------------------------------------------------- */
#endif /* MC__WIDGET_INTERNAL_H */