Input shouldn't take focus. (#253)

This fixes:
https://github.com/ArthurSonzogni/FTXUI/issues/252
This commit is contained in:
Arthur Sonzogni 2021-11-07 12:01:17 +01:00 committed by GitHub
parent aa6b78b8ad
commit 8652280c85
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 47 additions and 40 deletions

View File

@ -4,6 +4,9 @@ Changelog
unreleased (development) unreleased (development)
------------------------ ------------------------
# Component:
- Bugfix: Input shouldn't take focus when hovered by the mouse.
0.11.1 0.11.1
------ ------

View File

@ -1,25 +1,21 @@
#include "ftxui/component/captured_mouse.hpp" // for ftxui #include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive
#include "ftxui/component/component.hpp" // for Checkbox, Vertical #include "ftxui/dom/elements.hpp"
#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive #include "ftxui/component/component.hpp"
using namespace ftxui;
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
bool build_examples_state = false; using namespace ftxui;
bool build_tests_state = false;
bool use_webassembly_state = true;
auto component = Container::Vertical({ Component input_list = Container::Vertical({});
Checkbox("Build examples", &build_examples_state), std::vector<std::string> items(100, "");
Checkbox("Build tests", &build_tests_state), for (int i = 0; i < items.size(); ++i) {
Checkbox("Use WebAssembly", &use_webassembly_state), input_list->Add(Input(&(items[i]), "placeholder " + std::to_string(i)));
}
auto renderer = Renderer(input_list, [&] {
return input_list->Render() | vscroll_indicator | frame | border |
size(HEIGHT, LESS_THAN, 10);
}); });
auto screen = ScreenInteractive::TerminalOutput(); auto screen = ScreenInteractive::TerminalOutput();
screen.Loop(component); screen.Loop(renderer);
return 0;
} }
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.

View File

@ -50,16 +50,22 @@ class WideInputBase : public ComponentBase {
// placeholder. // placeholder.
if (content.size() == 0) { if (content.size() == 0) {
bool hovered = hovered_;
Decorator decorator = dim | main_decorator;
if (is_focused) if (is_focused)
return text(*placeholder_) | focus | dim | inverted | main_decorator | decorator = decorator | focus | bold;
reflect(box_); if (hovered || is_focused)
else decorator = decorator | inverted;
return text(*placeholder_) | dim | main_decorator | reflect(box_); return text(*placeholder_) | decorator | reflect(box_);
} }
// Not focused. // Not focused.
if (!is_focused) if (!is_focused) {
return text(content) | main_decorator | reflect(box_); if (hovered_)
return text(content) | main_decorator | inverted | reflect(box_);
else
return text(content) | main_decorator | reflect(box_);
}
std::wstring part_before_cursor = content.substr(0, cursor_position()); std::wstring part_before_cursor = content.substr(0, cursor_position());
std::wstring part_at_cursor = cursor_position() < (int)content.size() std::wstring part_at_cursor = cursor_position() < (int)content.size()
@ -68,15 +74,14 @@ class WideInputBase : public ComponentBase {
std::wstring part_after_cursor = cursor_position() < (int)content.size() - 1 std::wstring part_after_cursor = cursor_position() < (int)content.size() - 1
? content.substr(cursor_position() + 1) ? content.substr(cursor_position() + 1)
: L""; : L"";
auto focused = is_focused ? focus : select; auto focused = (is_focused || hovered_) ? focus : select;
// clang-format off // clang-format off
return return
hbox( hbox(
text(part_before_cursor), text(part_before_cursor),
text(part_at_cursor) | underlined | focused | reflect(cursor_box_), text(part_at_cursor) | underlined | focused | reflect(cursor_box_),
text(part_after_cursor) text(part_after_cursor)
) | flex | inverted | frame | main_decorator | reflect(box_); ) | flex | inverted | frame | bold |main_decorator | reflect(box_);
// clang-format on // clang-format on
} }
@ -151,29 +156,31 @@ class WideInputBase : public ComponentBase {
private: private:
bool OnMouseEvent(Event event) { bool OnMouseEvent(Event event) {
if (!CaptureMouse(event)) hovered_ =
box_.Contain(event.mouse().x, event.mouse().y) && CaptureMouse(event);
if (!hovered_)
return false; return false;
if (!box_.Contain(event.mouse().x, event.mouse().y))
if (event.mouse().button != Mouse::Left ||
event.mouse().motion != Mouse::Pressed) {
return false; return false;
}
TakeFocus(); TakeFocus();
int new_cursor_position =
if (event.mouse().button == Mouse::Left && cursor_position() + event.mouse().x - cursor_box_.x_min;
event.mouse().motion == Mouse::Pressed) { new_cursor_position =
int new_cursor_position = std::max(0, std::min<int>(content_->size(), new_cursor_position));
cursor_position() + event.mouse().x - cursor_box_.x_min; if (cursor_position() != new_cursor_position) {
new_cursor_position = cursor_position() = new_cursor_position;
std::max(0, std::min<int>(content_->size(), new_cursor_position)); option_->on_change();
if (cursor_position() != new_cursor_position) {
cursor_position() = new_cursor_position;
option_->on_change();
}
} }
return true; return true;
} }
bool Focusable() const final { return true; } bool Focusable() const final { return true; }
bool hovered_ = false;
WideStringRef content_; WideStringRef content_;
ConstStringRef placeholder_; ConstStringRef placeholder_;

View File

@ -23,6 +23,7 @@ class Blink : public NodeDecorator {
} }
}; };
/// @brief The text drawn alternates in between visible and hidden. /// @brief The text drawn alternates in between visible and hidden.
/// @ingroup dom /// @ingroup dom
Element blink(Element child) { Element blink(Element child) {