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:
- 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`

View File

@ -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<MenuOption> option_;
std::vector<Box> boxes_;

View File

@ -23,10 +23,10 @@ class SliderBase : public ComponentBase {
ConstRef<T> max,
ConstRef<T> 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,7 +81,8 @@ class SliderBase : public ComponentBase {
}
if (captured_mouse_) {
value_() = min_() + (event.mouse().x - gauge_box_.x_min) * (max_() - 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<int> min,
ConstRef<int> max,
ConstRef<int> increment) {
return Make<SliderBase<int>>(std::move(label), std::move(value), std::move(min),
std::move(max), std::move(increment));
return Make<SliderBase<int>>(std::move(label), value, min, max, increment);
}
Component Slider(ConstStringRef label,
Ref<float> value,
ConstRef<float> min,
ConstRef<float> max,
ConstRef<float> increment) {
return Make<SliderBase<float>>(std::move(label), std::move(value), std::move(min),
std::move(max), std::move(increment));
return Make<SliderBase<float>>(std::move(label), value, min, max, increment);
}
Component Slider(ConstStringRef label,
Ref<long> value,
ConstRef<long> min,
ConstRef<long> max,
ConstRef<long> increment) {
return Make<SliderBase<long>>(std::move(label), std::move(value), std::move(min),
std::move(max), std::move(increment));
return Make<SliderBase<long>>(std::move(label), value, min, max, increment);
}
} // namespace ftxui