mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2025-09-17 08:28:09 +08:00
Mouse support. Fix & verify Webassembly support.
There was some undefined behavior to be fixed in the terminal input parser. The behavior of flush seems to have change. The fix was to invert '\0' and std::flush.
This commit is contained in:
@@ -15,14 +15,15 @@ Element Input::Render() {
|
||||
// Placeholder.
|
||||
if (content.size() == 0) {
|
||||
if (is_focused)
|
||||
return text(placeholder) | focus | dim | inverted | main_decorator;
|
||||
return text(placeholder) | focus | dim | inverted | main_decorator |
|
||||
reflect(input_box_);
|
||||
else
|
||||
return text(placeholder) | dim | main_decorator;
|
||||
return text(placeholder) | dim | main_decorator | reflect(input_box_);
|
||||
}
|
||||
|
||||
// Not focused.
|
||||
if (!is_focused)
|
||||
return text(content) | main_decorator;
|
||||
return text(content) | main_decorator | reflect(input_box_);
|
||||
|
||||
std::wstring part_before_cursor = content.substr(0, cursor_position);
|
||||
std::wstring part_at_cursor = cursor_position < (int)content.size()
|
||||
@@ -37,13 +38,18 @@ Element Input::Render() {
|
||||
return
|
||||
hbox(
|
||||
text(part_before_cursor),
|
||||
text(part_at_cursor) | underlined | focused,
|
||||
text(part_at_cursor) | underlined | focused | reflect(cursor_box_),
|
||||
text(part_after_cursor)
|
||||
) | flex | inverted | frame | main_decorator;
|
||||
// clang-format off
|
||||
) | flex | inverted | frame | main_decorator | reflect(input_box_);
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
bool Input::OnEvent(Event event) {
|
||||
cursor_position = std::max(0, std::min<int>(content.size(), cursor_position));
|
||||
|
||||
if (event.is_mouse())
|
||||
return OnMouseEvent(event);
|
||||
|
||||
std::wstring c;
|
||||
|
||||
// Backspace.
|
||||
@@ -95,6 +101,26 @@ bool Input::OnEvent(Event event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Input::OnMouseEvent(Event event) {
|
||||
if (!input_box_.Contain(event.mouse().x, event.mouse().y))
|
||||
return false;
|
||||
|
||||
TakeFocus();
|
||||
|
||||
if (event.mouse().button == Mouse::Left &&
|
||||
event.mouse().motion == Mouse::Pressed) {
|
||||
int new_cursor_position =
|
||||
cursor_position + event.mouse().x - cursor_box_.x_min;
|
||||
new_cursor_position =
|
||||
std::max(0, std::min<int>(content.size(), new_cursor_position));
|
||||
if (cursor_position != new_cursor_position) {
|
||||
cursor_position = new_cursor_position;
|
||||
on_change();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace ftxui
|
||||
|
||||
// Copyright 2020 Arthur Sonzogni. All rights reserved.
|
||||
|
@@ -40,7 +40,7 @@ namespace {
|
||||
|
||||
void Flush() {
|
||||
// Emscripten doesn't implement flush. We interpret zero as flush.
|
||||
std::cout << std::flush << (char)0;
|
||||
std::cout << '\0' << std::flush;
|
||||
}
|
||||
|
||||
constexpr int timeout_milliseconds = 20;
|
||||
@@ -353,6 +353,8 @@ void ScreenInteractive::Loop(Component* component) {
|
||||
DECMode::kMouseSgrExtMode,
|
||||
});
|
||||
|
||||
flush();
|
||||
|
||||
auto event_listener =
|
||||
std::thread(&EventListener, &quit_, event_receiver_->MakeSender());
|
||||
|
||||
|
@@ -41,19 +41,23 @@ void TerminalInputParser::Send(TerminalInputParser::Output output) {
|
||||
|
||||
case CHARACTER:
|
||||
out_->Send(Event::Character(std::move(pending_)));
|
||||
pending_.clear();
|
||||
return;
|
||||
|
||||
case SPECIAL:
|
||||
out_->Send(Event::Special(std::move(pending_)));
|
||||
pending_.clear();
|
||||
return;
|
||||
|
||||
case MOUSE:
|
||||
out_->Send(Event::Mouse(std::move(pending_), output.mouse));
|
||||
pending_.clear();
|
||||
return;
|
||||
|
||||
case CURSOR_REPORTING:
|
||||
out_->Send(Event::CursorReporting(std::move(pending_), output.cursor.x,
|
||||
output.cursor.y));
|
||||
pending_.clear();
|
||||
return;
|
||||
}
|
||||
// NOT_REACHED().
|
||||
@@ -133,7 +137,7 @@ TerminalInputParser::Output TerminalInputParser::ParseDCS() {
|
||||
|
||||
TerminalInputParser::Output TerminalInputParser::ParseCSI() {
|
||||
bool altered = false;
|
||||
int argument;
|
||||
int argument = 0;
|
||||
std::vector<int> arguments;
|
||||
while (true) {
|
||||
if (!Eat())
|
||||
@@ -205,9 +209,8 @@ TerminalInputParser::Output TerminalInputParser::ParseMouse(
|
||||
output.mouse.button = Mouse::Button((arguments[0] & 3) + //
|
||||
((arguments[0] & 64) >> 4));
|
||||
output.mouse.motion = Mouse::Motion(pressed);
|
||||
output.mouse.shift = arguments[0] & 4;
|
||||
output.mouse.meta = arguments[0] & 8;
|
||||
output.mouse.control = arguments[0] & 16;
|
||||
output.mouse.shift = bool(arguments[0] & 4);
|
||||
output.mouse.meta = bool(arguments[0] & 8);
|
||||
output.mouse.x = arguments[1];
|
||||
output.mouse.y = arguments[2];
|
||||
return output;
|
||||
|
@@ -184,7 +184,7 @@ std::string Screen::ToString() {
|
||||
}
|
||||
|
||||
void Screen::Print() {
|
||||
std::cout << ToString() << std::flush << (char)0;
|
||||
std::cout << ToString() << '\0' << std::flush;
|
||||
}
|
||||
|
||||
/// @brief Access a character a given position.
|
||||
|
Reference in New Issue
Block a user