parent
98c0cdedb1
commit
e6b98744c6
|
@ -1031,6 +1031,38 @@ static DisplayCoord compute_pos(DisplayCoord anchor, DisplayCoord size,
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DisplayLineList wrap_lines(const DisplayLineList& lines, ColumnCount max_width)
|
||||||
|
{
|
||||||
|
DisplayLineList result;
|
||||||
|
for (auto line : lines)
|
||||||
|
{
|
||||||
|
ColumnCount column = 0;
|
||||||
|
for (auto it = line.begin(); it != line.end(); )
|
||||||
|
{
|
||||||
|
auto length = it->length();
|
||||||
|
column += length;
|
||||||
|
if (column > max_width)
|
||||||
|
{
|
||||||
|
auto content = it->content().substr(0, length - (column - max_width));
|
||||||
|
auto pos = find_if(content | reverse(), [](char c) { return not is_word(c); });
|
||||||
|
if (pos != content.rend())
|
||||||
|
content = {content.begin(), pos.base()};
|
||||||
|
|
||||||
|
if (not content.empty())
|
||||||
|
it = ++line.split(it, content.column_length());
|
||||||
|
result.push_back(AtomList(std::make_move_iterator(line.begin()),
|
||||||
|
std::make_move_iterator(it)));
|
||||||
|
it = line.erase(line.begin(), it);
|
||||||
|
column = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
result.push_back(std::move(line));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void NCursesUI::info_show(const DisplayLine& title, const DisplayLineList& content,
|
void NCursesUI::info_show(const DisplayLine& title, const DisplayLineList& content,
|
||||||
DisplayCoord anchor, Face face, InfoStyle style)
|
DisplayCoord anchor, Face face, InfoStyle style)
|
||||||
{
|
{
|
||||||
|
@ -1042,6 +1074,9 @@ void NCursesUI::info_show(const DisplayLine& title, const DisplayLineList& conte
|
||||||
m_info.face = face;
|
m_info.face = face;
|
||||||
m_info.style = style;
|
m_info.style = style;
|
||||||
|
|
||||||
|
const bool framed = style == InfoStyle::Prompt or style == InfoStyle::Modal;
|
||||||
|
const bool assisted = style == InfoStyle::Prompt and m_assistant.size() != 0;
|
||||||
|
|
||||||
DisplayCoord max_size = m_dimensions;
|
DisplayCoord max_size = m_dimensions;
|
||||||
if (style == InfoStyle::MenuDoc)
|
if (style == InfoStyle::MenuDoc)
|
||||||
max_size.column = std::max(m_dimensions.column - (m_menu.pos.column + m_menu.size.column),
|
max_size.column = std::max(m_dimensions.column - (m_menu.pos.column + m_menu.size.column),
|
||||||
|
@ -1049,21 +1084,32 @@ void NCursesUI::info_show(const DisplayLine& title, const DisplayLineList& conte
|
||||||
else if (style != InfoStyle::Modal)
|
else if (style != InfoStyle::Modal)
|
||||||
max_size.line -= m_menu.size.line;
|
max_size.line -= m_menu.size.line;
|
||||||
|
|
||||||
const bool framed = style == InfoStyle::Prompt or style == InfoStyle::Modal;
|
const auto max_content_width = max_size.column - (framed ? 4 : 2) - (assisted ? m_assistant[0].column_length() : 0);
|
||||||
const bool assisted = style == InfoStyle::Prompt and m_assistant.size() != 0;
|
if (max_content_width <= 0)
|
||||||
DisplayCoord size{(int)content.size(), accumulate(content, 0_col, [](ColumnCount c, const DisplayLine& l) {
|
return;
|
||||||
return std::max(c, l.length());
|
|
||||||
})};
|
auto compute_size = [](const DisplayLineList& lines) -> DisplayCoord {
|
||||||
size.column = std::max(size.column, title.length() + (framed ? 2 : 0));
|
return {(int)lines.size(), accumulate(lines, 0_col, [](ColumnCount c, const DisplayLine& l) { return std::max(c, l.length()); })};
|
||||||
|
};
|
||||||
|
|
||||||
|
DisplayCoord content_size = compute_size(content);
|
||||||
|
const bool wrap = content_size.column > max_content_width;
|
||||||
|
DisplayLineList wrapped_content;
|
||||||
|
if (wrap)
|
||||||
|
{
|
||||||
|
wrapped_content = wrap_lines(content, max_content_width);
|
||||||
|
content_size = compute_size(wrapped_content);
|
||||||
|
}
|
||||||
|
const auto& lines = wrap ? wrapped_content : content;
|
||||||
|
|
||||||
|
DisplayCoord size{content_size.line, std::max(content_size.column, title.length() + (framed ? 2 : 0))};
|
||||||
if (framed)
|
if (framed)
|
||||||
size += {2, 4};
|
size += {2, 4};
|
||||||
if (assisted)
|
if (assisted)
|
||||||
size = {std::max(LineCount{(int)m_assistant.size()-1}, size.line), size.column + m_assistant[0].column_length()};
|
size = {std::max(LineCount{(int)m_assistant.size()-1}, size.line), size.column + m_assistant[0].column_length()};
|
||||||
|
|
||||||
size = {std::min(max_size.line, size.line), std::min(max_size.column, size.column)};
|
size = {std::min(max_size.line, size.line), std::min(max_size.column, size.column)};
|
||||||
|
|
||||||
const auto content_width = size.column - (framed ? 4 : 2) - (assisted ? m_assistant[0].column_length() : 0);
|
if ((framed and size.line < 3) or size.line <= 0)
|
||||||
if (content_width <= 0 or (framed and size.line < 3) or size.line <= 0)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const Rect rect = {content_line_offset(), m_dimensions};
|
const Rect rect = {content_line_offset(), m_dimensions};
|
||||||
|
@ -1117,30 +1163,30 @@ void NCursesUI::info_show(const DisplayLine& title, const DisplayLineList& conte
|
||||||
draw_atoms(assistant_line.str());
|
draw_atoms(assistant_line.str());
|
||||||
}
|
}
|
||||||
if (not framed)
|
if (not framed)
|
||||||
draw_atoms(content[(int)line]);
|
draw_atoms(lines[(int)line]);
|
||||||
else if (line == 0)
|
else if (line == 0)
|
||||||
{
|
{
|
||||||
if (title.atoms().empty() or content_width < 2)
|
if (title.atoms().empty() or content_size.column < 2)
|
||||||
draw_atoms("╭─" + String{dash, content_width} + "─╮");
|
draw_atoms("╭─" + String{dash, content_size.column} + "─╮");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto trimmed_title = title;
|
auto trimmed_title = title;
|
||||||
trimmed_title.trim(0, content_width - 2);
|
trimmed_title.trim(0, content_size.column - 2);
|
||||||
auto dash_count = content_width - trimmed_title.length() - 2;
|
auto dash_count = content_size.column - trimmed_title.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};
|
||||||
draw_atoms("╭─" + left + "┤", trimmed_title, "├" + right +"─╮");
|
draw_atoms("╭─" + left + "┤", trimmed_title, "├" + right +"─╮");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (line < size.line - 1 and line <= content.size())
|
else if (line < size.line - 1 and line <= lines.size())
|
||||||
{
|
{
|
||||||
auto info_line = content[(int)line - 1];
|
auto info_line = lines[(int)line - 1];
|
||||||
const bool trimmed = info_line.trim(0, content_width);
|
const bool trimmed = info_line.trim(0, content_size.column);
|
||||||
const ColumnCount padding = content_width - info_line.length();
|
const ColumnCount padding = content_size.column - info_line.length();
|
||||||
draw_atoms("│ ", info_line, String{' ', padding} + (trimmed ? "…│" : " │"));
|
draw_atoms("│ ", info_line, String{' ', padding} + (trimmed ? "…│" : " │"));
|
||||||
}
|
}
|
||||||
else if (line == std::min<LineCount>((int)content.size() + 1, size.line - 1))
|
else if (line == std::min<LineCount>((int)lines.size() + 1, size.line - 1))
|
||||||
draw_atoms("╰─" + String(line > content.size() ? dash : dotted_dash, content_width) + "─╯");
|
draw_atoms("╰─" + String(line > lines.size() ? dash : dotted_dash, content_size.column) + "─╯");
|
||||||
}
|
}
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user