diff --git a/CHANGELOG.md b/CHANGELOG.md index 94a86ff..2d1e557 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ current (development) ### Component: - Feature: Add the `Modal` component. - Feature: `Slider` supports taking references for all its arguments. +- Improvement: The `Menu` keeps the focus when an entry is selected with the + mouse. ### Screen - Feature: add `Box::Union(a,b) -> Box` diff --git a/src/ftxui/component/menu.cpp b/src/ftxui/component/menu.cpp index 0727c32..df9d211 100644 --- a/src/ftxui/component/menu.cpp +++ b/src/ftxui/component/menu.cpp @@ -83,8 +83,13 @@ class MenuBase : public ComponentBase { } void Clamp() { + if (*selected_ != selected_previous_) { + SelectedTakeFocus(); + } boxes_.resize(size()); *selected_ = util::clamp(*selected_, 0, size() - 1); + selected_previous_ = util::clamp(selected_previous_, 0, size() - 1); + selected_focus_ = util::clamp(selected_focus_, 0, size() - 1); focused_entry() = util::clamp(focused_entry(), 0, size() - 1); } @@ -115,9 +120,6 @@ class MenuBase : public ComponentBase { bool is_focused = (focused_entry() == i) && is_menu_focused; bool is_selected = (*selected_ == i); - auto focus_management = !is_selected ? nothing - : is_menu_focused ? focus - : nothing; EntryState state = { entries_[i], false, @@ -125,6 +127,9 @@ class MenuBase : public ComponentBase { is_focused, }; + auto focus_management = + is_menu_focused && (selected_focus_ == i) ? focus : nothing; + Element element = (option_->entries.transform ? option_->entries.transform : DefaultOptionTransform) // @@ -166,6 +171,11 @@ class MenuBase : public ComponentBase { } } + void SelectedTakeFocus() { + selected_previous_ = *selected_; + selected_focus_ = *selected_; + } + void OnUp() { switch (option_->direction) { case MenuOption::Direction::Up: @@ -270,6 +280,7 @@ class MenuBase : public ComponentBase { if (*selected_ != old_selected) { focused_entry() = *selected_; + SelectedTakeFocus(); OnChange(); return true; } @@ -307,6 +318,7 @@ class MenuBase : public ComponentBase { event.mouse().motion == Mouse::Released) { if (*selected_ != i) { *selected_ = i; + selected_previous_ = *selected_; OnChange(); } return true; @@ -331,6 +343,7 @@ class MenuBase : public ComponentBase { *selected_ = util::clamp(*selected_, 0, size() - 1); if (*selected_ != old_selected) { + SelectedTakeFocus(); OnChange(); } return true; @@ -449,7 +462,9 @@ class MenuBase : public ComponentBase { protected: ConstStringListRef entries_; - int* selected_ = nullptr; + int* selected_; + int selected_previous_ = *selected_; + int selected_focus_= *selected_; Ref option_; std::vector boxes_; diff --git a/src/ftxui/component/slider.cpp b/src/ftxui/component/slider.cpp index 20aa5e9..de07e2c 100644 --- a/src/ftxui/component/slider.cpp +++ b/src/ftxui/component/slider.cpp @@ -23,10 +23,10 @@ class SliderBase : public ComponentBase { ConstRef max, ConstRef increment) : label_(std::move(label)), - value_(std::move(value)), - min_(std::move(min)), - max_(std::move(max)), - increment_(std::move(increment)) {} + value_(value), + min_(min), + max_(max), + increment_(increment) {} Element Render() override { auto gauge_color = @@ -81,8 +81,9 @@ class SliderBase : public ComponentBase { } if (captured_mouse_) { - value_() = min_() + (event.mouse().x - gauge_box_.x_min) * (max_() - min_()) / - (gauge_box_.x_max - gauge_box_.x_min); + value_() = min_() + (event.mouse().x - gauge_box_.x_min) * + (max_() - min_()) / + (gauge_box_.x_max - gauge_box_.x_min); value_() = std::max(min_(), std::min(max_(), value_())); return true; } @@ -129,24 +130,21 @@ Component Slider(ConstStringRef label, ConstRef min, ConstRef max, ConstRef increment) { - return Make>(std::move(label), std::move(value), std::move(min), - std::move(max), std::move(increment)); + return Make>(std::move(label), value, min, max, increment); } Component Slider(ConstStringRef label, Ref value, ConstRef min, ConstRef max, ConstRef increment) { - return Make>(std::move(label), std::move(value), std::move(min), - std::move(max), std::move(increment)); + return Make>(std::move(label), value, min, max, increment); } Component Slider(ConstStringRef label, Ref value, ConstRef min, ConstRef max, ConstRef increment) { - return Make>(std::move(label), std::move(value), std::move(min), - std::move(max), std::move(increment)); + return Make>(std::move(label), value, min, max, increment); } } // namespace ftxui