Support multiple kind of cursor shapes. (#505)

https://github.com/ArthurSonzogni/FTXUI/issues/424
This commit is contained in:
Arthur Sonzogni (slow/sick)
2022-11-11 14:09:53 +01:00
committed by GitHub
parent 9babfea36b
commit 1689802349
8 changed files with 156 additions and 32 deletions

View File

@@ -96,24 +96,23 @@ class InputBase : public ComponentBase {
// placeholder.
if (size == 0) {
bool hovered = hovered_;
Decorator decorator = dim | main_decorator;
auto element = text(*placeholder_) | dim | main_decorator | reflect(box_);
if (is_focused) {
decorator = decorator | focus;
element |= focus;
}
if (hovered || is_focused) {
decorator = decorator | inverted;
if (hovered_|| is_focused) {
element |= inverted;
}
return text(*placeholder_) | decorator | reflect(box_);
return element;
}
// Not focused.
if (!is_focused) {
auto element = text(content) | main_decorator | reflect(box_);
if (hovered_) {
return text(content) | main_decorator | inverted | reflect(box_);
} else {
return text(content) | main_decorator | reflect(box_);
}
element |= inverted;
}
return element;
}
int index_before_cursor = GlyphPosition(content, cursor_position());
@@ -125,10 +124,10 @@ class InputBase : public ComponentBase {
index_after_cursor - index_before_cursor);
}
std::string part_after_cursor = content.substr(index_after_cursor);
auto focused = (is_focused || hovered_) ? focus : select;
auto focused = (is_focused || hovered_) ? focusCursorBarBlinking : select;
return hbox({
text(part_before_cursor),
text(part_at_cursor) | focused | inverted | reflect(cursor_box_),
text(part_at_cursor) | focused | reflect(cursor_box_),
text(part_after_cursor),
}) |
flex | frame | bold | main_decorator | reflect(box_);

View File

@@ -512,8 +512,13 @@ void ScreenInteractive::Install() {
});
}
on_exit_functions.push([=] {
std::cout << "\033[?25h"; // Enable cursor.
std::cout << "\033[?1 q"; // Cursor block blinking.
});
disable({
DECMode::kCursor,
//DECMode::kCursor,
DECMode::kLineWrap,
});
@@ -685,16 +690,26 @@ void ScreenInteractive::Draw(Component component) {
set_cursor_position = "";
reset_cursor_position = "";
int dx = dimx_ - 1 - cursor_.x;
int dy = dimy_ - 1 - cursor_.y;
{
int dx = dimx_ - 1 - cursor_.x;
int dy = dimy_ - 1 - cursor_.y;
if (dx != 0) {
set_cursor_position += "\x1B[" + std::to_string(dx) + "D";
reset_cursor_position += "\x1B[" + std::to_string(dx) + "C";
}
if (dy != 0) {
set_cursor_position += "\x1B[" + std::to_string(dy) + "A";
reset_cursor_position += "\x1B[" + std::to_string(dy) + "B";
if (dy != 0) {
set_cursor_position += "\x1B[" + std::to_string(dy) + "A";
reset_cursor_position += "\x1B[" + std::to_string(dy) + "B";
}
if (dx != 0) {
set_cursor_position += "\x1B[" + std::to_string(dx) + "D";
reset_cursor_position += "\x1B[" + std::to_string(dx) + "C";
}
if (cursor_.shape == Cursor::Hidden) {
set_cursor_position += "\033[?25l";
} else {
set_cursor_position += "\033[?25h";
set_cursor_position += "\033[" + std::to_string(int(cursor_.shape)) + " q";
}
}
std::cout << ToString() << set_cursor_position;

View File

@@ -71,7 +71,11 @@ class Focus : public Select {
// https://github.com/microsoft/terminal/issues/1203
// https://github.com/microsoft/terminal/issues/3093
#if !defined(FTXUI_MICROSOFT_TERMINAL_FALLBACK)
screen.SetCursor(Screen::Cursor{box_.x_min, box_.y_min});
screen.SetCursor(Screen::Cursor{
box_.x_min,
box_.y_min,
Screen::Cursor::Shape::Hidden,
});
#endif
}
};
@@ -147,6 +151,48 @@ Element yframe(Element child) {
return std::make_shared<Frame>(unpack(std::move(child)), false, true);
}
class FocusCursor : public Focus {
public:
FocusCursor(Elements children, Screen::Cursor::Shape shape)
: Focus(std::move(children)), shape_(shape) {}
private:
void Render(Screen& screen) override {
Select::Render(screen);
screen.SetCursor(Screen::Cursor{
box_.x_min,
box_.y_min,
shape_,
});
}
Screen::Cursor::Shape shape_;
};
Element focusCursorBlock(Element child) {
return std::make_shared<FocusCursor>(unpack(std::move(child)),
Screen::Cursor::Block);
}
Element focusCursorBlockBlinking(Element child) {
return std::make_shared<FocusCursor>(unpack(std::move(child)),
Screen::Cursor::BlockBlinking);
}
Element focusCursorBar(Element child) {
return std::make_shared<FocusCursor>(unpack(std::move(child)),
Screen::Cursor::Bar);
}
Element focusCursorBarBlinking(Element child) {
return std::make_shared<FocusCursor>(unpack(std::move(child)),
Screen::Cursor::BarBlinking);
}
Element focusCursorUnderline(Element child) {
return std::make_shared<FocusCursor>(unpack(std::move(child)),
Screen::Cursor::Underline);
}
Element focusCursorUnderlineBlinking(Element child) {
return std::make_shared<FocusCursor>(unpack(std::move(child)),
Screen::Cursor::UnderlineBlinking);
}
} // namespace ftxui
// Copyright 2020 Arthur Sonzogni. All rights reserved.