Change ncurses_ui info box generation logic to use a Vector<String>
We were generating a string, then splitting it into lines, there is no need for that, we can directly generate a vector of lines and simplify the code.
This commit is contained in:
parent
e97f23f2be
commit
76d3425bf9
|
@ -4,6 +4,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
@ -347,6 +348,12 @@ void unordered_erase(Container&& vec, U&& value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Container, typename Init, typename BinOp>
|
||||||
|
Init accumulate(Container&& c, Init&& init, BinOp&& op)
|
||||||
|
{
|
||||||
|
return std::accumulate(begin(c), end(c), init, op);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // containers_hh_INCLUDED
|
#endif // containers_hh_INCLUDED
|
||||||
|
|
|
@ -791,32 +791,6 @@ void NCursesUI::menu_hide()
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DisplayCoord compute_needed_size(StringView str)
|
|
||||||
{
|
|
||||||
DisplayCoord res{1,0};
|
|
||||||
ColumnCount line_len = 0;
|
|
||||||
for (auto it = str.begin(), end = str.end();
|
|
||||||
it != end; it = utf8::next(it, end))
|
|
||||||
{
|
|
||||||
if (*it == '\n')
|
|
||||||
{
|
|
||||||
// ignore last '\n', no need to show an empty line
|
|
||||||
if (it+1 == end)
|
|
||||||
break;
|
|
||||||
|
|
||||||
res.column = max(res.column, line_len);
|
|
||||||
line_len = 0;
|
|
||||||
++res.line;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
++line_len;
|
|
||||||
res.column = max(res.column, line_len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static DisplayCoord compute_pos(DisplayCoord anchor, DisplayCoord size,
|
static DisplayCoord compute_pos(DisplayCoord anchor, DisplayCoord size,
|
||||||
NCursesUI::Rect rect, NCursesUI::Rect to_avoid,
|
NCursesUI::Rect rect, NCursesUI::Rect to_avoid,
|
||||||
bool prefer_above)
|
bool prefer_above)
|
||||||
|
@ -858,14 +832,14 @@ static DisplayCoord compute_pos(DisplayCoord anchor, DisplayCoord size,
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
String make_info_box(StringView title, StringView message, ColumnCount max_width,
|
Vector<String> make_info_box(StringView title, StringView message, ColumnCount max_width,
|
||||||
ConstArrayView<StringView> assistant)
|
ConstArrayView<StringView> assistant)
|
||||||
{
|
{
|
||||||
DisplayCoord assistant_size;
|
DisplayCoord assistant_size;
|
||||||
if (not assistant.empty())
|
if (not assistant.empty())
|
||||||
assistant_size = { (int)assistant.size(), assistant[0].column_length() };
|
assistant_size = { (int)assistant.size(), assistant[0].column_length() };
|
||||||
|
|
||||||
String result;
|
Vector<String> result;
|
||||||
|
|
||||||
const ColumnCount max_bubble_width = max_width - assistant_size.column - 6;
|
const ColumnCount max_bubble_width = max_width - assistant_size.column - 6;
|
||||||
if (max_bubble_width < 4)
|
if (max_bubble_width < 4)
|
||||||
|
@ -882,36 +856,37 @@ String make_info_box(StringView title, StringView message, ColumnCount max_width
|
||||||
const auto assistant_top_margin = (line_count - assistant_size.line+1) / 2;
|
const auto assistant_top_margin = (line_count - assistant_size.line+1) / 2;
|
||||||
for (LineCount i = 0; i < line_count; ++i)
|
for (LineCount i = 0; i < line_count; ++i)
|
||||||
{
|
{
|
||||||
|
String line;
|
||||||
constexpr Codepoint dash{L'─'};
|
constexpr Codepoint dash{L'─'};
|
||||||
if (not assistant.empty())
|
if (not assistant.empty())
|
||||||
{
|
{
|
||||||
if (i >= assistant_top_margin)
|
if (i >= assistant_top_margin)
|
||||||
result += assistant[(int)min(i - assistant_top_margin, assistant_size.line-1)];
|
line += assistant[(int)min(i - assistant_top_margin, assistant_size.line-1)];
|
||||||
else
|
else
|
||||||
result += assistant[(int)assistant_size.line-1];
|
line += assistant[(int)assistant_size.line-1];
|
||||||
}
|
}
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
{
|
{
|
||||||
if (title.empty())
|
if (title.empty())
|
||||||
result += "╭─" + String{dash, bubble_width} + "─╮";
|
line += "╭─" + String{dash, bubble_width} + "─╮";
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto dash_count = bubble_width - title.column_length() - 2;
|
auto dash_count = bubble_width - title.column_length() - 2;
|
||||||
String left{dash, dash_count / 2};
|
String left{dash, dash_count / 2};
|
||||||
String right{dash, dash_count - dash_count / 2};
|
String right{dash, dash_count - dash_count / 2};
|
||||||
result += "╭─" + left + "┤" + title +"├" + right +"─╮";
|
line += "╭─" + left + "┤" + title +"├" + right +"─╮";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (i < lines.size() + 1)
|
else if (i < lines.size() + 1)
|
||||||
{
|
{
|
||||||
auto& line = lines[(int)i - 1];
|
auto& info_line = lines[(int)i - 1];
|
||||||
const ColumnCount padding = bubble_width - line.column_length();
|
const ColumnCount padding = bubble_width - info_line.column_length();
|
||||||
result += "│ " + line + String{' ', padding} + " │";
|
line += "│ " + info_line + String{' ', padding} + " │";
|
||||||
}
|
}
|
||||||
else if (i == lines.size() + 1)
|
else if (i == lines.size() + 1)
|
||||||
result += "╰─" + String(dash, bubble_width) + "─╯";
|
line += "╰─" + String(dash, bubble_width) + "─╯";
|
||||||
|
|
||||||
result += "\n";
|
result.push_back(std::move(line));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -927,7 +902,7 @@ void NCursesUI::info_show(StringView title, StringView content,
|
||||||
m_info.face = face;
|
m_info.face = face;
|
||||||
m_info.style = style;
|
m_info.style = style;
|
||||||
|
|
||||||
String info_box;
|
Vector<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,
|
||||||
|
@ -951,11 +926,14 @@ void NCursesUI::info_show(StringView title, StringView content,
|
||||||
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.push_back(line.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayCoord size = compute_needed_size(info_box), pos;
|
const DisplayCoord size{(int)info_box.size(),
|
||||||
|
accumulate(info_box | transform(std::mem_fn(&String::column_length)), 0_col,
|
||||||
|
[](ColumnCount lhs, ColumnCount rhs){ return lhs < rhs ? rhs : lhs; })};
|
||||||
const Rect rect = {m_status_on_top ? 1_line : 0_line, m_dimensions};
|
const Rect rect = {m_status_on_top ? 1_line : 0_line, m_dimensions};
|
||||||
|
DisplayCoord pos;
|
||||||
if (style == InfoStyle::MenuDoc and m_menu)
|
if (style == InfoStyle::MenuDoc and m_menu)
|
||||||
pos = m_menu.pos + DisplayCoord{0_line, m_menu.size.column};
|
pos = m_menu.pos + DisplayCoord{0_line, m_menu.size.column};
|
||||||
else if (style == InfoStyle::Modal)
|
else if (style == InfoStyle::Modal)
|
||||||
|
@ -973,16 +951,10 @@ void NCursesUI::info_show(StringView title, StringView content,
|
||||||
m_info.create(pos, size);
|
m_info.create(pos, size);
|
||||||
|
|
||||||
wbkgd(m_info.win, COLOR_PAIR(get_color_pair(face)));
|
wbkgd(m_info.win, COLOR_PAIR(get_color_pair(face)));
|
||||||
int line = 0;
|
for (size_t line = 0; line < info_box.size(); ++line)
|
||||||
auto it = info_box.begin(), end = info_box.end();
|
|
||||||
while (true)
|
|
||||||
{
|
{
|
||||||
wmove(m_info.win, line++, 0);
|
wmove(m_info.win, line, 0);
|
||||||
auto eol = std::find_if(it, end, [](char c) { return c == '\n'; });
|
add_str(m_info.win, info_box[line]);
|
||||||
add_str(m_info.win, {it, eol});
|
|
||||||
if (eol == end)
|
|
||||||
break;
|
|
||||||
it = eol + 1;
|
|
||||||
}
|
}
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user