Remove the concept of cursor in TerminalUI::Window
This commit is contained in:
parent
65fbabcb86
commit
8e1b79b1b7
|
@ -136,15 +136,11 @@ void TerminalUI::Window::blit(Window& target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TerminalUI::Window::move_cursor(DisplayCoord coord)
|
void TerminalUI::Window::draw(DisplayCoord pos,
|
||||||
{
|
ConstArrayView<DisplayAtom> atoms,
|
||||||
cursor = {std::min(size.line-1, coord.line), std::min(size.column-1, coord.column)};
|
|
||||||
}
|
|
||||||
|
|
||||||
void TerminalUI::Window::draw(ConstArrayView<DisplayAtom> atoms,
|
|
||||||
const Face& default_face)
|
const Face& default_face)
|
||||||
{
|
{
|
||||||
lines[(size_t)cursor.line].resize(cursor.column);
|
lines[(size_t)pos.line].resize(pos.column);
|
||||||
for (const DisplayAtom& atom : atoms)
|
for (const DisplayAtom& atom : atoms)
|
||||||
{
|
{
|
||||||
StringView content = atom.content();
|
StringView content = atom.content();
|
||||||
|
@ -154,16 +150,16 @@ void TerminalUI::Window::draw(ConstArrayView<DisplayAtom> atoms,
|
||||||
auto face = merge_faces(default_face, atom.face);
|
auto face = merge_faces(default_face, atom.face);
|
||||||
if (content.back() == '\n')
|
if (content.back() == '\n')
|
||||||
{
|
{
|
||||||
lines[(int)cursor.line].append(content.substr(0, content.length()-1).str(), face);
|
lines[(int)pos.line].append(content.substr(0, content.length()-1).str(), face);
|
||||||
lines[(int)cursor.line].append(" ", face);
|
lines[(int)pos.line].append(" ", face);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
lines[(int)cursor.line].append(content.str(), face);
|
lines[(int)pos.line].append(content.str(), face);
|
||||||
cursor.column += content.column_length();
|
pos.column += content.column_length();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cursor.column < size.column)
|
if (pos.column < size.column)
|
||||||
lines[(int)cursor.line].append(String(' ', size.column - cursor.column), default_face);
|
lines[(int)pos.line].append(String(' ', size.column - pos.column), default_face);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TerminalUI::Screen::output(bool force)
|
void TerminalUI::Screen::output(bool force)
|
||||||
|
@ -421,20 +417,14 @@ void TerminalUI::draw(const DisplayBuffer& display_buffer,
|
||||||
const LineCount line_offset = content_line_offset();
|
const LineCount line_offset = content_line_offset();
|
||||||
LineCount line_index = line_offset;
|
LineCount line_index = line_offset;
|
||||||
for (const DisplayLine& line : display_buffer.lines())
|
for (const DisplayLine& line : display_buffer.lines())
|
||||||
{
|
m_window.draw(line_index++, line.atoms(), default_face);
|
||||||
m_window.move_cursor(line_index++);
|
|
||||||
m_window.draw(line.atoms(), default_face);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto face = merge_faces(default_face, padding_face);
|
auto face = merge_faces(default_face, padding_face);
|
||||||
|
|
||||||
|
DisplayAtom padding{String{m_padding_char, m_padding_fill ? dim.column : 1}};
|
||||||
|
|
||||||
while (line_index < dim.line + line_offset)
|
while (line_index < dim.line + line_offset)
|
||||||
{
|
m_window.draw(line_index++, padding, face);
|
||||||
m_window.move_cursor(line_index++);
|
|
||||||
m_window.draw(m_padding_char, face);
|
|
||||||
const auto padding_len = m_padding_char.length();
|
|
||||||
for (auto col = padding_len; m_padding_fill and col < dim.column; col += padding_len)
|
|
||||||
m_window.draw(m_padding_char, face);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
|
@ -444,9 +434,7 @@ void TerminalUI::draw_status(const DisplayLine& status_line,
|
||||||
const Face& default_face)
|
const Face& default_face)
|
||||||
{
|
{
|
||||||
const LineCount status_line_pos = m_status_on_top ? 0 : m_dimensions.line;
|
const LineCount status_line_pos = m_status_on_top ? 0 : m_dimensions.line;
|
||||||
m_window.move_cursor(status_line_pos);
|
m_window.draw(status_line_pos, status_line.atoms(), default_face);
|
||||||
|
|
||||||
m_window.draw(status_line.atoms(), default_face);
|
|
||||||
|
|
||||||
const auto mode_len = mode_line.length();
|
const auto mode_len = mode_line.length();
|
||||||
m_status_len = status_line.length();
|
m_status_len = status_line.length();
|
||||||
|
@ -454,8 +442,7 @@ void TerminalUI::draw_status(const DisplayLine& status_line,
|
||||||
if (mode_len < remaining)
|
if (mode_len < remaining)
|
||||||
{
|
{
|
||||||
ColumnCount col = m_dimensions.column - mode_len;
|
ColumnCount col = m_dimensions.column - mode_len;
|
||||||
m_window.move_cursor({status_line_pos, col});
|
m_window.draw({status_line_pos, col}, mode_line.atoms(), default_face);
|
||||||
m_window.draw(mode_line.atoms(), default_face);
|
|
||||||
}
|
}
|
||||||
else if (remaining > 2)
|
else if (remaining > 2)
|
||||||
{
|
{
|
||||||
|
@ -465,8 +452,7 @@ void TerminalUI::draw_status(const DisplayLine& status_line,
|
||||||
kak_assert(trimmed_mode_line.length() == remaining - 1);
|
kak_assert(trimmed_mode_line.length() == remaining - 1);
|
||||||
|
|
||||||
ColumnCount col = m_dimensions.column - remaining + 1;
|
ColumnCount col = m_dimensions.column - remaining + 1;
|
||||||
m_window.move_cursor({status_line_pos, col});
|
m_window.draw({status_line_pos, col}, trimmed_mode_line.atoms(), default_face);
|
||||||
m_window.draw(trimmed_mode_line.atoms(), default_face);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_set_title)
|
if (m_set_title)
|
||||||
|
@ -833,8 +819,7 @@ void TerminalUI::draw_menu()
|
||||||
kak_assert(m_menu.size.line == 1);
|
kak_assert(m_menu.size.line == 1);
|
||||||
ColumnCount pos = 0;
|
ColumnCount pos = 0;
|
||||||
|
|
||||||
m_menu.move_cursor({0, 0});
|
m_menu.draw({0, 0}, DisplayAtom(m_menu.first_item > 0 ? "< " : " "), m_menu.bg);
|
||||||
m_menu.draw(DisplayAtom(m_menu.first_item > 0 ? "< " : " "), m_menu.bg);
|
|
||||||
|
|
||||||
int i = m_menu.first_item;
|
int i = m_menu.first_item;
|
||||||
for (; i < item_count and pos < win_width; ++i)
|
for (; i < item_count and pos < win_width; ++i)
|
||||||
|
@ -842,19 +827,15 @@ void TerminalUI::draw_menu()
|
||||||
const DisplayLine& item = m_menu.items[i];
|
const DisplayLine& item = m_menu.items[i];
|
||||||
const ColumnCount item_width = item.length();
|
const ColumnCount item_width = item.length();
|
||||||
auto& face = i == m_menu.selected_item ? m_menu.fg : m_menu.bg;
|
auto& face = i == m_menu.selected_item ? m_menu.fg : m_menu.bg;
|
||||||
m_menu.draw(item.atoms(), face);
|
m_menu.draw({0, pos+2}, item.atoms(), face);
|
||||||
if (pos + item_width < win_width)
|
if (pos + item_width < win_width)
|
||||||
m_menu.draw(DisplayAtom(" "), m_menu.bg);
|
m_menu.draw({0, pos + item_width + 2}, DisplayAtom(" "), m_menu.bg);
|
||||||
else
|
else
|
||||||
{
|
m_menu.draw({0, win_width+2}, DisplayAtom("…"), m_menu.bg);
|
||||||
m_menu.move_cursor({0, win_width+2});
|
|
||||||
m_menu.draw(DisplayAtom("…"), m_menu.bg);
|
|
||||||
}
|
|
||||||
pos += item_width + 1;
|
pos += item_width + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_menu.move_cursor({0, win_width+3});
|
m_menu.draw({0, win_width+3}, DisplayAtom(i == item_count ? " " : ">"), m_menu.bg);
|
||||||
m_menu.draw(DisplayAtom(i == item_count ? " " : ">"), m_menu.bg);
|
|
||||||
|
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
return;
|
return;
|
||||||
|
@ -878,15 +859,13 @@ void TerminalUI::draw_menu()
|
||||||
{
|
{
|
||||||
for (int col = 0; col < m_menu.columns; ++col)
|
for (int col = 0; col < m_menu.columns; ++col)
|
||||||
{
|
{
|
||||||
m_menu.move_cursor({line, col * column_width});
|
|
||||||
int item_idx = (first_col + col) * (int)m_menu.size.line + (int)line;
|
int item_idx = (first_col + col) * (int)m_menu.size.line + (int)line;
|
||||||
auto& face = item_idx < item_count and item_idx == m_menu.selected_item ? m_menu.fg : m_menu.bg;
|
auto& face = item_idx < item_count and item_idx == m_menu.selected_item ? m_menu.fg : m_menu.bg;
|
||||||
auto atoms = item_idx < item_count ? m_menu.items[item_idx].atoms() : ConstArrayView<DisplayAtom>{};
|
auto atoms = item_idx < item_count ? m_menu.items[item_idx].atoms() : ConstArrayView<DisplayAtom>{};
|
||||||
m_menu.draw(atoms, face);
|
m_menu.draw({line, col * column_width}, atoms, face);
|
||||||
}
|
}
|
||||||
const bool is_mark = line >= mark_line and line < mark_line + mark_height;
|
const bool is_mark = line >= mark_line and line < mark_line + mark_height;
|
||||||
m_menu.move_cursor({line, m_menu.size.column - 1});
|
m_menu.draw({line, m_menu.size.column - 1}, DisplayAtom(is_mark ? "█" : "░"), m_menu.bg);
|
||||||
m_menu.draw(DisplayAtom(is_mark ? "█" : "░"), m_menu.bg);
|
|
||||||
}
|
}
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
|
@ -1180,19 +1159,24 @@ void TerminalUI::info_show(const DisplayLine& title, const DisplayLineList& cont
|
||||||
}
|
}
|
||||||
|
|
||||||
m_info.create(anchor, size);
|
m_info.create(anchor, size);
|
||||||
auto draw_atoms = [&](auto&&... args) {
|
for (auto line = 0_line; line < size.line; ++line)
|
||||||
|
{
|
||||||
|
auto draw_atoms = [&, this, pos=DisplayCoord{line}](auto&&... args) mutable {
|
||||||
auto draw = overload(
|
auto draw = overload(
|
||||||
[&](String str) { m_info.draw(DisplayAtom{std::move(str)}, face); },
|
[&](String str) {
|
||||||
[&](const DisplayLine& atoms) { m_info.draw(atoms.atoms(), face); });
|
auto len = str.column_length();
|
||||||
|
m_info.draw(pos, DisplayAtom{std::move(str)}, face);
|
||||||
|
pos.column += len;
|
||||||
|
},
|
||||||
|
[&](const DisplayLine& atoms) {
|
||||||
|
m_info.draw(pos, atoms.atoms(), face);
|
||||||
|
pos.column += atoms.length();
|
||||||
|
});
|
||||||
(draw(args), ...);
|
(draw(args), ...);
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto line = 0_line; line < size.line; ++line)
|
|
||||||
{
|
|
||||||
constexpr Codepoint dash{L'─'};
|
constexpr Codepoint dash{L'─'};
|
||||||
constexpr Codepoint dotted_dash{L'┄'};
|
constexpr Codepoint dotted_dash{L'┄'};
|
||||||
m_info.move_cursor(line);
|
|
||||||
if (assisted)
|
if (assisted)
|
||||||
{
|
{
|
||||||
const auto assistant_top_margin = (size.line - m_assistant.size()+1) / 2;
|
const auto assistant_top_margin = (size.line - m_assistant.size()+1) / 2;
|
||||||
|
@ -1369,19 +1353,19 @@ void TerminalUI::set_ui_options(const Options& options)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto it = options.find("ncurses_padding_char"_sv);
|
auto it = options.find("terminal_padding_char"_sv);
|
||||||
if (it == options.end())
|
if (it == options.end())
|
||||||
// Defaults to tilde.
|
// Defaults to tilde.
|
||||||
m_padding_char = DisplayAtom("~");
|
m_padding_char = '~';
|
||||||
else if (it->value.column_length() < 1)
|
else if (it->value.column_length() < 1)
|
||||||
// Do not allow empty string, use space instead.
|
// Do not allow empty string, use space instead.
|
||||||
m_padding_char = DisplayAtom(" ");
|
m_padding_char = ' ';
|
||||||
else
|
else
|
||||||
m_padding_char = DisplayAtom(it->value);
|
m_padding_char = it->value[0_char];
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto it = options.find("ncurses_padding_fill"_sv);
|
auto it = options.find("terminal_padding_fill"_sv);
|
||||||
m_padding_fill = it != options.end() and
|
m_padding_fill = it != options.end() and
|
||||||
(it->value == "yes" or it->value == "true");
|
(it->value == "yes" or it->value == "true");
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,14 +78,12 @@ private:
|
||||||
void create(const DisplayCoord& pos, const DisplayCoord& size);
|
void create(const DisplayCoord& pos, const DisplayCoord& size);
|
||||||
void destroy();
|
void destroy();
|
||||||
void blit(Window& target);
|
void blit(Window& target);
|
||||||
void move_cursor(DisplayCoord coord);
|
void draw(DisplayCoord pos, ConstArrayView<DisplayAtom> atoms, const Face& default_face);
|
||||||
void draw(ConstArrayView<DisplayAtom> atoms, const Face& default_face);
|
|
||||||
|
|
||||||
explicit operator bool() const { return not lines.empty(); }
|
explicit operator bool() const { return not lines.empty(); }
|
||||||
|
|
||||||
struct Line;
|
struct Line;
|
||||||
Vector<Line> lines;
|
Vector<Line> lines;
|
||||||
DisplayCoord cursor;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Screen : Window
|
struct Screen : Window
|
||||||
|
@ -152,7 +150,7 @@ private:
|
||||||
|
|
||||||
bool m_set_title = true;
|
bool m_set_title = true;
|
||||||
|
|
||||||
DisplayAtom m_padding_char = DisplayAtom("~");
|
Codepoint m_padding_char = '~';
|
||||||
bool m_padding_fill = false;
|
bool m_padding_fill = false;
|
||||||
|
|
||||||
bool m_dirty = false;
|
bool m_dirty = false;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user