Merge branch '2919_visible'

* 2919_visible:
  WMenubar: remove unneeded action.
  (setup_panels): reduce the number of redraws.
  (setup_panels, setup_cmdline): use WST_VISIBLE to set up prompt and command line.
  (setup_panels): use WST_VISIBLE to set up hint bar.
  Buttonbar: use WST_VISIBLE state
  Menubar: use WST_VISIBLE state
  Add WST_VISIBLE widget state.
  Ticket #2919: implement WST_VISIBLE widget state.
This commit is contained in:
Andrew Borodin 2021-04-11 17:11:00 +03:00
commit 0aaf74777d
15 changed files with 136 additions and 74 deletions

View File

@ -173,7 +173,7 @@ buttonbar_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, voi
return MSG_NOT_HANDLED;
case MSG_DRAW:
if (bb->visible)
if (widget_get_state (w, WST_VISIBLE))
{
buttonbar_init_button_positions (bb);
widget_gotoyx (w, 0, 0);
@ -238,7 +238,7 @@ buttonbar_mouse_callback (Widget * w, mouse_msg_t msg, mouse_event_t * event)
/* --------------------------------------------------------------------------------------------- */
WButtonBar *
buttonbar_new (gboolean visible)
buttonbar_new (void)
{
WButtonBar *bb;
Widget *w;
@ -248,7 +248,6 @@ buttonbar_new (gboolean visible)
widget_init (w, LINES - 1, 0, 1, COLS, buttonbar_callback, buttonbar_mouse_callback);
w->pos_flags = WPOS_KEEP_HORZ | WPOS_KEEP_BOTTOM;
bb->visible = visible;
widget_want_hotkey (w, TRUE);
return bb;

View File

@ -22,7 +22,7 @@
typedef struct WButtonBar
{
Widget widget;
gboolean visible; /* Is it visible? */
struct
{
char *text;
@ -36,17 +36,11 @@ typedef struct WButtonBar
/*** declarations of public functions ************************************************************/
WButtonBar *buttonbar_new (gboolean visible);
WButtonBar *buttonbar_new (void);
void buttonbar_set_label (WButtonBar * bb, int idx, const char *text,
const global_keymap_t * keymap, Widget * receiver);
WButtonBar *find_buttonbar (const WDialog * h);
/*** inline functions ****************************************************************************/
static inline void
buttonbar_set_visible (WButtonBar * bb, gboolean visible)
{
bb->visible = visible;
}
#endif /* MC__WIDGET_BUTTONBAR_H */

View File

@ -514,8 +514,7 @@ dlg_init (WDialog * h)
}
/* Select the first widget that takes focus */
while (g->current != NULL && !widget_get_options (WIDGET (g->current->data), WOP_SELECTABLE)
&& !widget_get_state (WIDGET (g->current->data), WST_DISABLED))
while (g->current != NULL && !widget_is_focusable (g->current->data))
group_set_current_widget_next (g);
widget_set_state (wh, WST_ACTIVE, TRUE);

View File

@ -113,15 +113,12 @@ group_select_next_or_prev (WGroup * g, gboolean next)
if (g->widgets != NULL && g->current != NULL)
{
GList *l = g->current;
Widget *w;
do
{
l = group_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 != g->current);
while (!widget_is_focusable (l->data) && l != g->current);
widget_select (l->data);
}
@ -170,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);
}
@ -290,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);
@ -462,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
@ -655,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

@ -310,15 +310,20 @@ menubar_finish (WMenuBar * menubar)
{
Widget *w = WIDGET (menubar);
widget_set_state (w, WST_FOCUSED, FALSE);
menubar->is_dropped = FALSE;
w->lines = 1;
widget_want_hotkey (w, FALSE);
widget_set_options (w, WOP_SELECTABLE, FALSE);
/* Move the menubar to the bottom so that widgets displayed on top of
* an "invisible" menubar get the first chance to respond to mouse events. */
widget_set_bottom (w);
if (!mc_global.keybar_visible)
widget_hide (w);
else
{
/* Move the menubar to the bottom so that widgets displayed on top of
* an "invisible" menubar get the first chance to respond to mouse events. */
widget_set_bottom (w);
}
/* background must be bottom */
if (DIALOG (w->owner)->bg != NULL)
widget_set_bottom (WIDGET (DIALOG (w->owner)->bg));
@ -670,7 +675,7 @@ menubar_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void
return MSG_NOT_HANDLED;
case MSG_DRAW:
if (menubar->is_visible || menubar_refresh (menubar))
if (widget_get_state (w, WST_VISIBLE) || menubar_refresh (menubar))
menubar_draw (menubar);
return MSG_HANDLED;
@ -941,7 +946,7 @@ destroy_menu (menu_t * menu)
/* --------------------------------------------------------------------------------------------- */
WMenuBar *
menubar_new (GList * menu, gboolean visible)
menubar_new (GList * menu)
{
WMenuBar *menubar;
Widget *w;
@ -954,7 +959,6 @@ menubar_new (GList * menu, gboolean visible)
widget_set_options (w, WOP_SELECTABLE, FALSE);
w->options |= WOP_TOP_SELECT;
w->keymap = menu_map;
menubar->is_visible = visible;
menubar_set_menu (menubar, menu);
return menubar;
@ -1064,11 +1068,12 @@ menubar_activate (WMenuBar * menubar, gboolean dropped, int which)
{
Widget *w = WIDGET (menubar);
widget_show (w);
if (!widget_get_state (w, WST_FOCUSED))
{
widget_set_options (w, WOP_SELECTABLE, TRUE);
widget_set_state (w, WST_FOCUSED, TRUE); /* FIXME: unneeded? */
menubar->is_dropped = dropped;
if (which >= 0)
menubar->selected = (guint) which;

View File

@ -30,7 +30,6 @@ typedef struct WMenuBar
{
Widget widget;
gboolean is_visible; /* If the menubar is visible */
gboolean is_dropped; /* If the menubar has dropped */
GList *menu; /* The actual menus */
guint selected; /* Selected menu on the top bar */
@ -50,7 +49,7 @@ menu_t *create_menu (const char *name, GList * entries, const char *help_node);
void menu_set_name (menu_t * menu, const char *name);
void destroy_menu (menu_t * menu);
WMenuBar *menubar_new (GList * menu, gboolean visible);
WMenuBar *menubar_new (GList * menu);
void menubar_set_menu (WMenuBar * menubar, GList * menu);
void menubar_add_menu (WMenuBar * menubar, menu_t * menu);
void menubar_arrange (WMenuBar * menubar);
@ -61,10 +60,4 @@ void menubar_activate (WMenuBar * menubar, gboolean dropped, int which);
/*** inline functions ****************************************************************************/
static inline void
menubar_set_visible (WMenuBar * menubar, gboolean visible)
{
menubar->is_visible = visible;
}
#endif /* MC__WIDGET_MENU_H */

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,9 +575,7 @@ widget_replace (Widget * old_w, Widget * new_w)
{
GList *l;
for (l = group_get_widget_next_of (holder);
!widget_get_options (WIDGET (l->data), WOP_SELECTABLE)
&& !widget_get_state (WIDGET (l->data), WST_DISABLED);
for (l = group_get_widget_next_of (holder); widget_is_focusable (WIDGET (l->data));
l = group_get_widget_next_of (l))
;
@ -589,6 +596,15 @@ widget_replace (Widget * old_w, Widget * new_w)
widget_draw (new_w);
}
/* --------------------------------------------------------------------------------------------- */
gboolean
widget_is_focusable (const Widget * w)
{
return (widget_get_options (w, WOP_SELECTABLE) && widget_get_state (w, WST_VISIBLE) &&
!widget_get_state (w, WST_DISABLED));
}
/* --------------------------------------------------------------------------------------------- */
/**
* Select specified widget in it's owner.
@ -736,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;
@ -755,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;
@ -772,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,9 +211,11 @@ 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);
gboolean widget_is_focusable (const Widget * w);
void widget_select (Widget * w);
void widget_set_bottom (Widget * w);
@ -382,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 */

View File

@ -3459,7 +3459,7 @@ diff_view (const char *file1, const char *file2, const char *label1, const char
w->keymap = diff_map;
group_add_widget_autopos (g, w, WPOS_KEEP_ALL, NULL);
w = WIDGET (buttonbar_new (TRUE));
w = WIDGET (buttonbar_new ());
group_add_widget_autopos (g, w, w->pos_flags, NULL);
dview_dlg->get_title = dview_get_title;

View File

@ -1257,12 +1257,12 @@ edit_files (const GList * files)
(1, 0, wd->lines - 2, wd->cols, EDITOR_BACKGROUND, ' ', edit_dialog_bg_callback));
group_add_widget (g, edit_dlg->bg);
menubar = menubar_new (NULL, TRUE);
menubar = menubar_new (NULL);
w = WIDGET (menubar);
group_add_widget_autopos (g, w, w->pos_flags, NULL);
edit_init_menu (menubar);
w = WIDGET (buttonbar_new (TRUE));
w = WIDGET (buttonbar_new ());
group_add_widget_autopos (g, w, w->pos_flags, NULL);
for (file = files; file != NULL; file = g_list_next (file))

View File

@ -1082,7 +1082,7 @@ tree_box (const char *current_dir)
mytree = tree_new (2, 2, wd->lines - 6, wd->cols - 5, FALSE);
group_add_widget_autopos (g, mytree, WPOS_KEEP_ALL, NULL);
group_add_widget_autopos (g, hline_new (wd->lines - 4, 1, -1), WPOS_KEEP_BOTTOM, NULL);
bar = buttonbar_new (TRUE);
bar = buttonbar_new ();
group_add_widget (g, bar);
/* restore ButtonBar coordinates after add_widget() */
WIDGET (bar)->x = 0;

View File

@ -918,7 +918,7 @@ create_file_manager (void)
/* allow rebind tab */
widget_want_tab (w, TRUE);
the_menubar = menubar_new (NULL, menubar_visible);
the_menubar = menubar_new (NULL);
group_add_widget (g, the_menubar);
init_menu ();
@ -939,7 +939,7 @@ create_file_manager (void)
the_prompt->transparent = TRUE;
group_add_widget (g, the_prompt);
the_bar = buttonbar_new (mc_global.keybar_visible);
the_bar = buttonbar_new ();
group_add_widget (g, the_bar);
midnight_set_buttonbar (the_bar);
}
@ -1637,7 +1637,7 @@ update_menu (void)
menu_set_name (left_menu, panels_layout.horizontal_split ? _("&Above") : _("&Left"));
menu_set_name (right_menu, panels_layout.horizontal_split ? _("&Below") : _("&Right"));
menubar_arrange (the_menubar);
menubar_set_visible (the_menubar, menubar_visible);
widget_set_visibility (WIDGET (the_menubar), menubar_visible);
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -816,8 +816,15 @@ setup_panels (void)
* +--------+------------------------------------------------------+
*/
const Widget *mw = CONST_WIDGET (midnight_dlg);
Widget *mw = WIDGET (midnight_dlg);
int start_y;
gboolean active;
active = widget_get_state (mw, WST_ACTIVE);
/* lock the group to avoid many redraws */
if (active)
widget_set_state (mw, WST_SUSPENDED, TRUE);
/* iniitial height of panels */
height =
@ -841,7 +848,7 @@ setup_panels (void)
}
widget_set_size (WIDGET (the_menubar), mw->y, mw->x, 1, mw->cols);
menubar_set_visible (the_menubar, menubar_visible);
widget_set_visibility (WIDGET (the_menubar), menubar_visible);
check_split (&panels_layout);
start_y = mw->y + (menubar_visible ? 1 : 0);
@ -865,11 +872,8 @@ setup_panels (void)
panels[1].widget->cols);
}
if (mc_global.message_visible)
widget_set_size (WIDGET (the_hint), height + start_y, mw->x, 1, mw->cols);
else
/* make invisible */
widget_set_size (WIDGET (the_hint), 0, 0, 0, 0);
widget_set_size (WIDGET (the_hint), height + start_y, mw->x, 1, mw->cols);
widget_set_visibility (WIDGET (the_hint), mc_global.message_visible);
/* Output window */
if (mc_global.tty.console_flag != '\0' && output_lines != 0)
@ -891,15 +895,21 @@ setup_panels (void)
else
{
/* make invisible */
widget_set_size (WIDGET (cmdline), 0, 0, 0, 0);
widget_set_size (WIDGET (the_prompt), mw->lines, mw->cols, 0, 0);
widget_hide (WIDGET (cmdline));
widget_hide (WIDGET (the_prompt));
}
widget_set_size (WIDGET (the_bar), mw->lines - 1, mw->x, mc_global.keybar_visible ? 1 : 0,
mw->cols);
buttonbar_set_visible (the_bar, mc_global.keybar_visible);
widget_set_size (WIDGET (the_bar), mw->lines - 1, mw->x, 1, mw->cols);
widget_set_visibility (WIDGET (the_bar), mc_global.keybar_visible);
update_xterm_title_path ();
/* unlock */
if (active)
{
widget_set_state (mw, WST_ACTIVE, TRUE);
widget_draw (mw);
}
}
/* --------------------------------------------------------------------------------------------- */
@ -1001,6 +1011,9 @@ setup_cmdline (void)
widget_set_size (WIDGET (the_prompt), y, mw->x, 1, prompt_width);
label_set_text (the_prompt, mc_prompt);
widget_set_size (WIDGET (cmdline), y, mw->x + prompt_width, 1, mw->cols - prompt_width);
widget_show (WIDGET (the_prompt));
widget_show (WIDGET (cmdline));
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -1153,14 +1153,14 @@ help_interactive_display (const gchar * event_group_name, const gchar * event_na
history[history_ptr].link = selected_item;
}
help_bar = buttonbar_new (TRUE);
help_bar = buttonbar_new ();
WIDGET (help_bar)->y -= wh->y;
WIDGET (help_bar)->x -= wh->x;
md = mousedispatch_new (1, 1, help_lines, HELP_WINDOW_WIDTH - 2);
group_add_widget (g, md);
group_add_widget (g, help_bar);
group_add_widget (g, help_bar); /* FIXME */
buttonbar_set_label (help_bar, 1, Q_ ("ButtonBar|Help"), wh->keymap, NULL);
buttonbar_set_label (help_bar, 2, Q_ ("ButtonBar|Index"), wh->keymap, NULL);

View File

@ -250,7 +250,7 @@ mcview_viewer (const char *command, const vfs_path_t * file_vpath, int start_lin
lc_mcview = mcview_new (vw->y, vw->x, vw->lines - 1, vw->cols, FALSE);
group_add_widget_autopos (g, lc_mcview, WPOS_KEEP_ALL, NULL);
b = WIDGET (buttonbar_new (TRUE));
b = WIDGET (buttonbar_new ());
group_add_widget_autopos (g, b, b->pos_flags, NULL);
view_dlg->get_title = mcview_get_title;