Menu: keep the previously focused element with mouse. (#462)

This resolves:
https://github.com/ArthurSonzogni/FTXUI/issues/453
This commit is contained in:
Arthur Sonzogni 2022-08-21 17:23:13 +02:00 committed by GitHub
parent 251306a4bb
commit 3ec765e1f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 16 deletions

View File

@ -15,6 +15,8 @@ current (development)
### Component: ### Component:
- Feature: Add the `Modal` component. - Feature: Add the `Modal` component.
- Feature: `Slider` supports taking references for all its arguments. - Feature: `Slider` supports taking references for all its arguments.
- Improvement: The `Menu` keeps the focus when an entry is selected with the
mouse.
### Screen ### Screen
- Feature: add `Box::Union(a,b) -> Box` - Feature: add `Box::Union(a,b) -> Box`

View File

@ -83,8 +83,13 @@ class MenuBase : public ComponentBase {
} }
void Clamp() { void Clamp() {
if (*selected_ != selected_previous_) {
SelectedTakeFocus();
}
boxes_.resize(size()); boxes_.resize(size());
*selected_ = util::clamp(*selected_, 0, size() - 1); *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); 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_focused = (focused_entry() == i) && is_menu_focused;
bool is_selected = (*selected_ == i); bool is_selected = (*selected_ == i);
auto focus_management = !is_selected ? nothing
: is_menu_focused ? focus
: nothing;
EntryState state = { EntryState state = {
entries_[i], entries_[i],
false, false,
@ -125,6 +127,9 @@ class MenuBase : public ComponentBase {
is_focused, is_focused,
}; };
auto focus_management =
is_menu_focused && (selected_focus_ == i) ? focus : nothing;
Element element = Element element =
(option_->entries.transform ? option_->entries.transform (option_->entries.transform ? option_->entries.transform
: DefaultOptionTransform) // : DefaultOptionTransform) //
@ -166,6 +171,11 @@ class MenuBase : public ComponentBase {
} }
} }
void SelectedTakeFocus() {
selected_previous_ = *selected_;
selected_focus_ = *selected_;
}
void OnUp() { void OnUp() {
switch (option_->direction) { switch (option_->direction) {
case MenuOption::Direction::Up: case MenuOption::Direction::Up:
@ -270,6 +280,7 @@ class MenuBase : public ComponentBase {
if (*selected_ != old_selected) { if (*selected_ != old_selected) {
focused_entry() = *selected_; focused_entry() = *selected_;
SelectedTakeFocus();
OnChange(); OnChange();
return true; return true;
} }
@ -307,6 +318,7 @@ class MenuBase : public ComponentBase {
event.mouse().motion == Mouse::Released) { event.mouse().motion == Mouse::Released) {
if (*selected_ != i) { if (*selected_ != i) {
*selected_ = i; *selected_ = i;
selected_previous_ = *selected_;
OnChange(); OnChange();
} }
return true; return true;
@ -331,6 +343,7 @@ class MenuBase : public ComponentBase {
*selected_ = util::clamp(*selected_, 0, size() - 1); *selected_ = util::clamp(*selected_, 0, size() - 1);
if (*selected_ != old_selected) { if (*selected_ != old_selected) {
SelectedTakeFocus();
OnChange(); OnChange();
} }
return true; return true;
@ -449,7 +462,9 @@ class MenuBase : public ComponentBase {
protected: protected:
ConstStringListRef entries_; ConstStringListRef entries_;
int* selected_ = nullptr; int* selected_;
int selected_previous_ = *selected_;
int selected_focus_= *selected_;
Ref<MenuOption> option_; Ref<MenuOption> option_;
std::vector<Box> boxes_; std::vector<Box> boxes_;

View File

@ -23,10 +23,10 @@ class SliderBase : public ComponentBase {
ConstRef<T> max, ConstRef<T> max,
ConstRef<T> increment) ConstRef<T> increment)
: label_(std::move(label)), : label_(std::move(label)),
value_(std::move(value)), value_(value),
min_(std::move(min)), min_(min),
max_(std::move(max)), max_(max),
increment_(std::move(increment)) {} increment_(increment) {}
Element Render() override { Element Render() override {
auto gauge_color = auto gauge_color =
@ -81,8 +81,9 @@ class SliderBase : public ComponentBase {
} }
if (captured_mouse_) { if (captured_mouse_) {
value_() = min_() + (event.mouse().x - gauge_box_.x_min) * (max_() - min_()) / value_() = min_() + (event.mouse().x - gauge_box_.x_min) *
(gauge_box_.x_max - gauge_box_.x_min); (max_() - min_()) /
(gauge_box_.x_max - gauge_box_.x_min);
value_() = std::max(min_(), std::min(max_(), value_())); value_() = std::max(min_(), std::min(max_(), value_()));
return true; return true;
} }
@ -129,24 +130,21 @@ Component Slider(ConstStringRef label,
ConstRef<int> min, ConstRef<int> min,
ConstRef<int> max, ConstRef<int> max,
ConstRef<int> increment) { ConstRef<int> increment) {
return Make<SliderBase<int>>(std::move(label), std::move(value), std::move(min), return Make<SliderBase<int>>(std::move(label), value, min, max, increment);
std::move(max), std::move(increment));
} }
Component Slider(ConstStringRef label, Component Slider(ConstStringRef label,
Ref<float> value, Ref<float> value,
ConstRef<float> min, ConstRef<float> min,
ConstRef<float> max, ConstRef<float> max,
ConstRef<float> increment) { ConstRef<float> increment) {
return Make<SliderBase<float>>(std::move(label), std::move(value), std::move(min), return Make<SliderBase<float>>(std::move(label), value, min, max, increment);
std::move(max), std::move(increment));
} }
Component Slider(ConstStringRef label, Component Slider(ConstStringRef label,
Ref<long> value, Ref<long> value,
ConstRef<long> min, ConstRef<long> min,
ConstRef<long> max, ConstRef<long> max,
ConstRef<long> increment) { ConstRef<long> increment) {
return Make<SliderBase<long>>(std::move(label), std::move(value), std::move(min), return Make<SliderBase<long>>(std::move(label), value, min, max, increment);
std::move(max), std::move(increment));
} }
} // namespace ftxui } // namespace ftxui