Slight refactor in ncurses_ui, group info and menu data in structs

This commit is contained in:
Maxime Coste 2016-02-27 17:22:31 +00:00
parent a25e46f1eb
commit f0edf40543
2 changed files with 65 additions and 60 deletions

View File

@ -443,11 +443,11 @@ void NCursesUI::check_resize(bool force)
if (menu) if (menu)
{ {
auto items = std::move(m_items); auto items = std::move(m_menu.items);
menu_show(items, m_menu_anchor, m_menu_fg, m_menu_bg, m_menu_style); menu_show(items, m_menu.anchor, m_menu.fg, m_menu.bg, m_menu.style);
} }
if (info) if (info)
info_show(m_info_title, m_info_content, m_info_anchor, m_info_face, m_info_style); info_show(m_info.title, m_info.content, m_info.anchor, m_info.face, m_info.style);
} }
else else
kak_assert(false); kak_assert(false);
@ -580,34 +580,34 @@ void NCursesUI::draw_menu()
if (not m_menu) if (not m_menu)
return; return;
const auto menu_bg = get_color_pair(m_menu_bg); const auto menu_bg = get_color_pair(m_menu.bg);
wattron(m_menu.win, COLOR_PAIR(menu_bg)); wattron(m_menu.win, COLOR_PAIR(menu_bg));
wbkgdset(m_menu.win, COLOR_PAIR(menu_bg)); wbkgdset(m_menu.win, COLOR_PAIR(menu_bg));
const int item_count = (int)m_items.size(); const int item_count = (int)m_menu.items.size();
const LineCount menu_lines = div_round_up(item_count, m_menu_columns); const LineCount menu_lines = div_round_up(item_count, m_menu.columns);
const LineCount& win_height = m_menu.size.line; const LineCount& win_height = m_menu.size.line;
kak_assert(win_height <= menu_lines); kak_assert(win_height <= menu_lines);
const CharCount column_width = (m_menu.size.column - 1) / m_menu_columns; const CharCount column_width = (m_menu.size.column - 1) / m_menu.columns;
const LineCount mark_height = min(div_round_up(sq(win_height), menu_lines), const LineCount mark_height = min(div_round_up(sq(win_height), menu_lines),
win_height); win_height);
const LineCount mark_line = (win_height - mark_height) * m_menu_top_line / const LineCount mark_line = (win_height - mark_height) * m_menu.top_line /
max(1_line, menu_lines - win_height); max(1_line, menu_lines - win_height);
for (auto line = 0_line; line < win_height; ++line) for (auto line = 0_line; line < win_height; ++line)
{ {
wmove(m_menu.win, (int)line, 0); wmove(m_menu.win, (int)line, 0);
for (int col = 0; col < m_menu_columns; ++col) for (int col = 0; col < m_menu.columns; ++col)
{ {
const int item_idx = (int)(m_menu_top_line + line) * m_menu_columns const int item_idx = (int)(m_menu.top_line + line) * m_menu.columns
+ col; + col;
if (item_idx >= item_count) if (item_idx >= item_count)
break; break;
const DisplayLine& item = m_items[item_idx]; const DisplayLine& item = m_menu.items[item_idx];
draw_line(m_menu.win, item, 0, column_width, draw_line(m_menu.win, item, 0, column_width,
item_idx == m_selected_item ? m_menu_fg : m_menu_bg); item_idx == m_menu.selected_item ? m_menu.fg : m_menu.bg);
const CharCount pad = column_width - item.length(); const CharCount pad = column_width - item.length();
add_str(m_menu.win, String{' ' COMMA pad}); add_str(m_menu.win, String{' ' COMMA pad});
} }
@ -627,10 +627,10 @@ void NCursesUI::menu_show(ConstArrayView<DisplayLine> items,
{ {
menu_hide(); menu_hide();
m_menu_fg = fg; m_menu.fg = fg;
m_menu_bg = bg; m_menu.bg = bg;
m_menu_style = style; m_menu.style = style;
m_menu_anchor = anchor; m_menu.anchor = anchor;
if (style == MenuStyle::Prompt) if (style == MenuStyle::Prompt)
anchor = CharCoord{m_status_on_top ? 0_line : m_dimensions.line, 0}; anchor = CharCoord{m_status_on_top ? 0_line : m_dimensions.line, 0};
@ -643,33 +643,33 @@ void NCursesUI::menu_show(ConstArrayView<DisplayLine> items,
return; return;
const int item_count = items.size(); const int item_count = items.size();
m_items.clear(); // make sure it is empty m_menu.items.clear(); // make sure it is empty
m_items.reserve(item_count); m_menu.items.reserve(item_count);
CharCount longest = 1; CharCount longest = 1;
for (auto& item : items) for (auto& item : items)
longest = max(longest, item.length()); longest = max(longest, item.length());
const bool is_prompt = style == MenuStyle::Prompt; const bool is_prompt = style == MenuStyle::Prompt;
m_menu_columns = is_prompt ? max((int)((maxsize.column-1) / (longest+1)), 1) : 1; m_menu.columns = is_prompt ? max((int)((maxsize.column-1) / (longest+1)), 1) : 1;
CharCount maxlen = maxsize.column-1; CharCount maxlen = maxsize.column-1;
if (m_menu_columns > 1 and item_count > 1) if (m_menu.columns > 1 and item_count > 1)
maxlen = maxlen / m_menu_columns - 1; maxlen = maxlen / m_menu.columns - 1;
for (auto& item : items) for (auto& item : items)
{ {
m_items.push_back(item); m_menu.items.push_back(item);
m_items.back().trim(0, maxlen, false); m_menu.items.back().trim(0, maxlen, false);
kak_assert(m_items.back().length() <= maxlen); kak_assert(m_menu.items.back().length() <= maxlen);
} }
int height = min(10, div_round_up(item_count, m_menu_columns)); int height = min(10, div_round_up(item_count, m_menu.columns));
int line = (int)anchor.line + 1; int line = (int)anchor.line + 1;
if (line + height >= (int)maxsize.line) if (line + height >= (int)maxsize.line)
line = (int)anchor.line - height; line = (int)anchor.line - height;
m_selected_item = item_count; m_menu.selected_item = item_count;
m_menu_top_line = 0; m_menu.top_line = 0;
auto width = is_prompt ? maxsize.column : min(longest+1, maxsize.column); auto width = is_prompt ? maxsize.column : min(longest+1, maxsize.column);
m_menu.create({line, anchor.column}, {height, width}); m_menu.create({line, anchor.column}, {height, width});
@ -678,23 +678,23 @@ void NCursesUI::menu_show(ConstArrayView<DisplayLine> items,
void NCursesUI::menu_select(int selected) void NCursesUI::menu_select(int selected)
{ {
const int item_count = m_items.size(); const int item_count = m_menu.items.size();
const LineCount menu_lines = div_round_up(item_count, m_menu_columns); const LineCount menu_lines = div_round_up(item_count, m_menu.columns);
if (selected < 0 or selected >= item_count) if (selected < 0 or selected >= item_count)
{ {
m_selected_item = -1; m_menu.selected_item = -1;
m_menu_top_line = 0; m_menu.top_line = 0;
} }
else else
{ {
m_selected_item = selected; m_menu.selected_item = selected;
const LineCount selected_line = m_selected_item / m_menu_columns; const LineCount selected_line = m_menu.selected_item / m_menu.columns;
const LineCount win_height = m_menu.size.line; const LineCount win_height = m_menu.size.line;
kak_assert(menu_lines >= win_height); kak_assert(menu_lines >= win_height);
if (selected_line < m_menu_top_line) if (selected_line < m_menu.top_line)
m_menu_top_line = selected_line; m_menu.top_line = selected_line;
if (selected_line >= m_menu_top_line + win_height) if (selected_line >= m_menu.top_line + win_height)
m_menu_top_line = min(selected_line, menu_lines - win_height); m_menu.top_line = min(selected_line, menu_lines - win_height);
} }
draw_menu(); draw_menu();
} }
@ -703,7 +703,7 @@ void NCursesUI::menu_hide()
{ {
if (not m_menu) if (not m_menu)
return; return;
m_items.clear(); m_menu.items.clear();
mark_dirty(m_menu); mark_dirty(m_menu);
m_menu.destroy(); m_menu.destroy();
m_dirty = true; m_dirty = true;
@ -833,16 +833,16 @@ void NCursesUI::info_show(StringView title, StringView content,
{ {
info_hide(); info_hide();
m_info_title = title.str(); m_info.title = title.str();
m_info_content = content.str(); m_info.content = content.str();
m_info_anchor = anchor; m_info.anchor = anchor;
m_info_face = face; m_info.face = face;
m_info_style = style; m_info.style = style;
String info_box; String info_box;
if (style == InfoStyle::Prompt) if (style == InfoStyle::Prompt)
{ {
info_box = make_info_box(m_info_title, m_info_content, info_box = make_info_box(m_info.title, m_info.content,
m_dimensions.column, m_assistant); m_dimensions.column, m_assistant);
anchor = CharCoord{m_status_on_top ? 0 : m_dimensions.line, anchor = CharCoord{m_status_on_top ? 0 : m_dimensions.line,
m_dimensions.column-1}; m_dimensions.column-1};
@ -859,7 +859,7 @@ void NCursesUI::info_show(StringView title, StringView content,
if (max_width < 4) if (max_width < 4)
return; return;
for (auto& line : wrap_lines(m_info_content, max_width)) for (auto& line : wrap_lines(m_info.content, max_width))
info_box += line + "\n"; info_box += line + "\n";
} }

View File

@ -91,23 +91,28 @@ private:
void mark_dirty(const Window& win); void mark_dirty(const Window& win);
Window m_menu; struct Menu : Window
Vector<DisplayLine> m_items; {
Face m_menu_fg; Vector<DisplayLine> items;
Face m_menu_bg; Face fg;
CharCoord m_menu_anchor; Face bg;
MenuStyle m_menu_style; CharCoord anchor;
int m_selected_item = 0; MenuStyle style;
int m_menu_columns = 1; int selected_item = 0;
LineCount m_menu_top_line = 0; int columns = 1;
LineCount top_line = 0;
} m_menu;
void draw_menu(); void draw_menu();
Window m_info; struct Info : Window
String m_info_title; {
String m_info_content; String title;
Face m_info_face; String content;
CharCoord m_info_anchor; Face face;
InfoStyle m_info_style; CharCoord anchor;
InfoStyle style;
} m_info;
FDWatcher m_stdin_watcher; FDWatcher m_stdin_watcher;
InputCallback m_input_callback; InputCallback m_input_callback;