From 240350db958dd20f5676ee2e3228eda783d03675 Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Mon, 13 Jun 2016 10:16:45 +0300 Subject: [PATCH] Refactoring of widget drawing to avoid multiple widget redraw. Send MSG_DRAW message immediately after MSG_FOCUS/MSG_UNFOCUS. Thus, the MSG_DRAW message handler is the only place where widget should be drawn. Widget should not draw itself in other message handlers. Signed-off-by: Andrew Borodin --- lib/widget/button.c | 2 -- lib/widget/check.c | 17 ++++++++++------- lib/widget/dialog.c | 4 ---- lib/widget/input.c | 2 -- lib/widget/listbox.c | 2 -- lib/widget/radio.c | 25 ++++++++++++++----------- lib/widget/widget-common.c | 5 +++-- src/editor/editwidget.c | 10 +++------- src/filemanager/panel.c | 3 --- src/filemanager/tree.c | 29 ++++++++++++++++------------- src/viewer/actions_cmd.c | 1 + 11 files changed, 47 insertions(+), 53 deletions(-) diff --git a/lib/widget/button.c b/lib/widget/button.c index 45e954acf..bace34888 100644 --- a/lib/widget/button.c +++ b/lib/widget/button.c @@ -117,8 +117,6 @@ button_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void * widget_move (w, 0, b->hotpos + off); return MSG_HANDLED; - case MSG_UNFOCUS: - case MSG_FOCUS: case MSG_DRAW: { gboolean focused; diff --git a/lib/widget/check.c b/lib/widget/check.c index e04fb5608..bb0a36493 100644 --- a/lib/widget/check.c +++ b/lib/widget/check.c @@ -83,14 +83,17 @@ check_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *d widget_move (w, 0, 1); return MSG_HANDLED; - case MSG_FOCUS: - case MSG_UNFOCUS: case MSG_DRAW: - widget_selectcolor (w, msg == MSG_FOCUS, FALSE); - widget_move (w, 0, 0); - tty_print_string ((c->state & C_BOOL) ? "[x] " : "[ ] "); - hotkey_draw (w, c->text, msg == MSG_FOCUS); - return MSG_HANDLED; + { + gboolean focused; + + focused = widget_get_state (w, WST_FOCUSED); + widget_selectcolor (w, focused, FALSE); + widget_move (w, 0, 0); + tty_print_string ((c->state & C_BOOL) ? "[x] " : "[ ] "); + hotkey_draw (w, c->text, focused); + return MSG_HANDLED; + } case MSG_DESTROY: release_hotkey (c->text); diff --git a/lib/widget/dialog.c b/lib/widget/dialog.c index 8cc26e333..a2c255663 100644 --- a/lib/widget/dialog.c +++ b/lib/widget/dialog.c @@ -277,10 +277,7 @@ do_select_widget (WDialog * h, GList * w, select_dir_t dir) dlg_reorder_widgets (h->current, TRUE); if (widget_overlapped (w0, WIDGET (h->current->data))) - { - send_message (h->current->data, NULL, MSG_DRAW, 0, NULL); widget_set_state (WIDGET (h->current->data), WST_FOCUSED, TRUE); - } } /* --------------------------------------------------------------------------------------------- */ @@ -966,7 +963,6 @@ add_widget_autopos (WDialog * h, void *w, widget_pos_flags_t pos_flags, const vo if (widget_get_state (wh, WST_ACTIVE)) { send_message (widget, NULL, MSG_INIT, 0, NULL); - send_message (widget, NULL, MSG_DRAW, 0, NULL); widget_set_state (widget, WST_FOCUSED, TRUE); } diff --git a/lib/widget/input.c b/lib/widget/input.c index 47ba6b865..e0e9fcc44 100644 --- a/lib/widget/input.c +++ b/lib/widget/input.c @@ -1079,8 +1079,6 @@ input_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *d return input_execute_cmd (in, parm); case MSG_RESIZE: - case MSG_FOCUS: - case MSG_UNFOCUS: case MSG_DRAW: input_update (in, FALSE); return MSG_HANDLED; diff --git a/lib/widget/listbox.c b/lib/widget/listbox.c index a47cf78c3..3c1e27d37 100644 --- a/lib/widget/listbox.c +++ b/lib/widget/listbox.c @@ -482,8 +482,6 @@ listbox_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void widget_move (l, l->cursor_y, 0); return MSG_HANDLED; - case MSG_FOCUS: - case MSG_UNFOCUS: case MSG_DRAW: listbox_draw (l, widget_get_state (w, WST_FOCUSED)); return MSG_HANDLED; diff --git a/lib/widget/radio.c b/lib/widget/radio.c index 7a49f830c..23558fc17 100644 --- a/lib/widget/radio.c +++ b/lib/widget/radio.c @@ -108,24 +108,27 @@ radio_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *d } case MSG_CURSOR: - widget_move (r, r->pos, 1); widget_set_state (w, WST_FOCUSED, TRUE); + widget_move (r, r->pos, 1); return MSG_HANDLED; - case MSG_UNFOCUS: - case MSG_FOCUS: case MSG_DRAW: - for (i = 0; i < r->count; i++) { - const gboolean focused = (i == r->pos && msg == MSG_FOCUS); + gboolean focused; - widget_selectcolor (w, focused, FALSE); - widget_move (r, i, 0); - tty_draw_hline (w->y + i, w->x, ' ', w->cols); - tty_print_string ((r->sel == i) ? "(*) " : "( ) "); - hotkey_draw (w, r->texts[i], focused); + focused = widget_get_state (w, WST_FOCUSED); + + for (i = 0; i < r->count; i++) + { + widget_selectcolor (w, i == r->pos && focused, FALSE); + widget_move (w, i, 0); + tty_draw_hline (w->y + i, w->x, ' ', w->cols); + tty_print_string ((r->sel == i) ? "(*) " : "( ) "); + hotkey_draw (w, r->texts[i], i == r->pos && focused); + } + + return MSG_HANDLED; } - return MSG_HANDLED; case MSG_DESTROY: for (i = 0; i < r->count; i++) diff --git a/lib/widget/widget-common.c b/lib/widget/widget-common.c index b965c5e2e..6fe525142 100644 --- a/lib/widget/widget-common.c +++ b/lib/widget/widget-common.c @@ -245,7 +245,7 @@ widget_set_state (Widget * w, widget_state_t state, gboolean enable) { case WST_DISABLED: ret = send_message (w, NULL, enable ? MSG_DISABLE : MSG_ENABLE, 0, NULL); - if (ret == MSG_HANDLED) + if (ret == MSG_HANDLED && widget_get_state (WIDGET (w->owner), WST_ACTIVE)) ret = send_message (w, NULL, MSG_DRAW, 0, NULL); break; @@ -255,8 +255,9 @@ widget_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) + if (ret == MSG_HANDLED && widget_get_state (WIDGET (w->owner), WST_ACTIVE)) { + send_message (w, NULL, MSG_DRAW, 0, NULL); /* Notify owner that focus was moved from one widget to another */ send_message (w->owner, w, MSG_NOTIFY, (int) msg, NULL); } diff --git a/src/editor/editwidget.c b/src/editor/editwidget.c index 03c3701b1..478983de2 100644 --- a/src/editor/editwidget.c +++ b/src/editor/editwidget.c @@ -936,18 +936,13 @@ edit_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *da { case MSG_FOCUS: edit_set_buttonbar (e, find_buttonbar (w->owner)); - /* fall through */ + return MSG_HANDLED; case MSG_DRAW: e->force |= REDRAW_COMPLETELY; edit_update_screen (e); return MSG_HANDLED; - case MSG_UNFOCUS: - /* redraw frame and status */ - edit_status (e, FALSE); - return MSG_HANDLED; - case MSG_KEY: { int cmd, ch; @@ -1296,7 +1291,7 @@ edit_update_screen (WEdit * e) edit_scroll_screen_over_cursor (e); edit_update_curs_col (e); - edit_status (e, (void *) e == h->current->data); + edit_status (e, widget_get_state (WIDGET (e), WST_FOCUSED)); /* pop all events for this window for internal handling */ if (!is_idle ()) @@ -1359,6 +1354,7 @@ edit_add_window (WDialog * h, int y, int x, int lines, int cols, const vfs_path_ w->mouse_callback = edit_mouse_callback; add_widget (h, w); + edit_set_buttonbar (edit, find_buttonbar (h)); dlg_redraw (h); return TRUE; diff --git a/src/filemanager/panel.c b/src/filemanager/panel.c index 66fbf3615..e7c210bfe 100644 --- a/src/filemanager/panel.c +++ b/src/filemanager/panel.c @@ -3683,9 +3683,7 @@ panel_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *d update_xterm_title_path (); select_item (panel); - show_dir (panel); paint_dir (panel); - panel->dirty = 0; bb = find_buttonbar (w->owner); midnight_set_buttonbar (bb); @@ -3696,7 +3694,6 @@ panel_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *d /* Janne: look at this for the multiple panel options */ stop_search (panel); panel->active = 0; - show_dir (panel); unselect_item (panel); return MSG_HANDLED; diff --git a/src/filemanager/tree.c b/src/filemanager/tree.c index 8218db4bb..568f298a7 100644 --- a/src/filemanager/tree.c +++ b/src/filemanager/tree.c @@ -973,10 +973,15 @@ tree_start_search (WTree * tree) static void tree_toggle_navig (WTree * tree) { + WButtonBar *b; + tree_navigation_flag = !tree_navigation_flag; - buttonbar_set_label (find_buttonbar (WIDGET (tree)->owner), 4, - tree_navigation_flag ? Q_ ("ButtonBar|Static") - : Q_ ("ButtonBar|Dynamc"), tree_map, WIDGET (tree)); + + b = find_buttonbar (WIDGET (tree)->owner); + buttonbar_set_label (b, 4, + tree_navigation_flag ? Q_ ("ButtonBar|Static") : Q_ ("ButtonBar|Dynamc"), + tree_map, WIDGET (tree)); + widget_redraw (WIDGET (b)); } /* --------------------------------------------------------------------------------------------- */ @@ -1145,16 +1150,22 @@ tree_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *da { WTree *tree = (WTree *) w; WDialog *h = w->owner; - WButtonBar *b = find_buttonbar (h); + WButtonBar *b; switch (msg) { case MSG_DRAW: tree_frame (h, tree); show_tree (tree); + if (widget_get_state (w, WST_FOCUSED)) + { + b = find_buttonbar (h); + widget_redraw (WIDGET (b)); + } return MSG_HANDLED; case MSG_FOCUS: + b = find_buttonbar (h); buttonbar_set_label (b, 1, Q_ ("ButtonBar|Help"), tree_map, w); buttonbar_set_label (b, 2, Q_ ("ButtonBar|Rescan"), tree_map, w); buttonbar_set_label (b, 3, Q_ ("ButtonBar|Forget"), tree_map, w); @@ -1166,22 +1177,14 @@ tree_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *da /* FIXME: mkdir is currently defunct */ buttonbar_set_label (b, 7, Q_ ("ButtonBar|Mkdir"), tree_map, w); #else - buttonbar_clear_label (b, 7, WIDGET (tree)); + buttonbar_clear_label (b, 7, w); #endif buttonbar_set_label (b, 8, Q_ ("ButtonBar|Rmdir"), tree_map, w); - widget_redraw (WIDGET (b)); - /* FIXME: Should find a better way of only displaying the - currently selected item */ - show_tree (tree); return MSG_HANDLED; - /* FIXME: Should find a better way of changing the color of the - selected item */ - case MSG_UNFOCUS: tree->searching = 0; - show_tree (tree); return MSG_HANDLED; case MSG_KEY: diff --git a/src/viewer/actions_cmd.c b/src/viewer/actions_cmd.c index 3c7f0c469..bf9d40079 100644 --- a/src/viewer/actions_cmd.c +++ b/src/viewer/actions_cmd.c @@ -684,6 +684,7 @@ mcview_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void * case MSG_FOCUS: view->dpy_bbar_dirty = TRUE; + /* TODO: get rid of draw here before MSG_DRAW */ mcview_update (view); return MSG_HANDLED;