mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2025-09-18 17:18:08 +08:00
Support multiple kind of cursor shapes. (#505)
https://github.com/ArthurSonzogni/FTXUI/issues/424
This commit is contained in:

committed by
GitHub

parent
9babfea36b
commit
1689802349
@@ -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_);
|
||||
|
@@ -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;
|
||||
|
@@ -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.
|
||||
|
Reference in New Issue
Block a user