mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2024-11-22 18:59:59 +08:00
Checkbox button debounce (#774)
This fixes: https://github.com/ArthurSonzogni/FTXUI/issues/773 Dragging the mouse with the left button pressed now avoids activating multiple checkboxes. Add support for detecting mouse press transition. Added: ```cpp // The previous mouse event. Mouse Mouse::previous; // Return whether the mouse transitionned from: // released to pressed => IsPressed() // pressed to pressed => IsHeld() // pressed to released => IsReleased() bool Mouse::IsPressed(Button button) const; bool Mouse::IsHeld(Button button) const; bool Mouse::IsReleased(Button button) const; ``` A couple of components are now activated when the mouse is pressed, as opposed to released. Co-authored-by: ArthurSonzogni <sonzogniarthur@gmail.com>
This commit is contained in:
parent
e8589dd533
commit
c31aecf2ed
20
CHANGELOG.md
20
CHANGELOG.md
@ -7,6 +7,26 @@ current (development)
|
||||
### Component
|
||||
- Feature: Add support for `Input`'s insert mode. Add `InputOption::insert`
|
||||
option. Added by @mingsheng13.
|
||||
- Feature/Bugfix/Breaking change: `Mouse transition`:
|
||||
This fixes: https://github.com/ArthurSonzogni/FTXUI/issues/773
|
||||
Dragging the mouse with the left button pressed now avoids activating multiple
|
||||
checkboxes.
|
||||
|
||||
Add support for detecting mouse press transition. Added:
|
||||
```cpp
|
||||
// The previous mouse event.
|
||||
Mouse Mouse::previous;
|
||||
|
||||
// Return whether the mouse transitionned from:
|
||||
// released to pressed => IsPressed()
|
||||
// pressed to pressed => IsHeld()
|
||||
// pressed to released => IsReleased()
|
||||
bool Mouse::IsPressed(Button button) const;
|
||||
bool Mouse::IsHeld(Button button) const;
|
||||
bool Mouse::IsReleased(Button button) const;
|
||||
```
|
||||
A couple of components are now activated when the mouse is pressed,
|
||||
as opposed to released.
|
||||
- Bugfix: `Input` `onchange` was not called on backspace or delete key.
|
||||
Fixed by @chrysante in chrysante in PR #776.
|
||||
|
||||
|
@ -123,6 +123,7 @@ add_library(component
|
||||
src/ftxui/component/maybe.cpp
|
||||
src/ftxui/component/menu.cpp
|
||||
src/ftxui/component/modal.cpp
|
||||
src/ftxui/component/mouse.cpp
|
||||
src/ftxui/component/radiobox.cpp
|
||||
src/ftxui/component/radiobox.cpp
|
||||
src/ftxui/component/renderer.cpp
|
||||
|
@ -23,6 +23,11 @@ struct Mouse {
|
||||
Pressed = 1,
|
||||
};
|
||||
|
||||
// Utility function to check the variations of the mouse state.
|
||||
bool IsPressed(Button btn = Left) const; // Released => Pressed.
|
||||
bool IsHeld(Button btn = Left) const; // Pressed => Pressed.
|
||||
bool IsReleased(Button btn = Left) const; // Pressed => Released.
|
||||
|
||||
// Button
|
||||
Button button = Button::None;
|
||||
|
||||
@ -37,6 +42,9 @@ struct Mouse {
|
||||
// Coordinates:
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
// Previous mouse event, if any.
|
||||
Mouse* previous = nullptr;
|
||||
};
|
||||
|
||||
} // namespace ftxui
|
||||
|
@ -112,6 +112,7 @@ class ScreenInteractive : public Screen {
|
||||
|
||||
bool frame_valid_ = false;
|
||||
|
||||
Mouse latest_mouse_event_;
|
||||
friend class Loop;
|
||||
|
||||
public:
|
||||
|
@ -124,8 +124,7 @@ class ButtonBase : public ComponentBase, public ButtonOption {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.mouse().button == Mouse::Left &&
|
||||
event.mouse().motion == Mouse::Pressed) {
|
||||
if (event.mouse().IsPressed()) {
|
||||
TakeFocus();
|
||||
OnClick();
|
||||
return true;
|
||||
|
@ -69,8 +69,7 @@ class CheckboxBase : public ComponentBase, public CheckboxOption {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.mouse().button == Mouse::Left &&
|
||||
event.mouse().motion == Mouse::Pressed) {
|
||||
if (event.mouse().IsPressed()) {
|
||||
*checked = !*checked;
|
||||
on_change();
|
||||
return true;
|
||||
|
@ -466,8 +466,7 @@ class InputBase : public ComponentBase, public InputOption {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.mouse().button != Mouse::Left ||
|
||||
event.mouse().motion != Mouse::Pressed) {
|
||||
if (!event.mouse().IsPressed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -318,8 +318,7 @@ class MenuBase : public ComponentBase, public MenuOption {
|
||||
|
||||
TakeFocus();
|
||||
focused_entry() = i;
|
||||
if (event.mouse().button == Mouse::Left &&
|
||||
event.mouse().motion == Mouse::Released) {
|
||||
if (event.mouse().IsPressed()) {
|
||||
if (selected() != i) {
|
||||
selected() = i;
|
||||
selected_previous_ = selected();
|
||||
@ -683,8 +682,7 @@ Component MenuEntry(MenuEntryOption option) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.mouse().button == Mouse::Left &&
|
||||
event.mouse().motion == Mouse::Released) {
|
||||
if (event.mouse().IsPressed()) {
|
||||
TakeFocus();
|
||||
return true;
|
||||
}
|
||||
|
36
src/ftxui/component/mouse.cpp
Normal file
36
src/ftxui/component/mouse.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright 2023 Arthur Sonzogni. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license that can be found in
|
||||
// the LICENSE file.
|
||||
|
||||
#include "ftxui/component/mouse.hpp"
|
||||
|
||||
namespace ftxui {
|
||||
|
||||
namespace {
|
||||
bool IsDown(const Mouse* mouse, Mouse::Button btn) {
|
||||
return mouse->button == btn && mouse->motion == Mouse::Pressed;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
/// Return whether the mouse transitionned from released to pressed.
|
||||
/// This is useful to detect a click.
|
||||
/// @arg btn The button to check.
|
||||
bool Mouse::IsPressed(Button btn) const {
|
||||
return IsDown(this, btn) && (!previous || !IsDown(previous, btn));
|
||||
}
|
||||
|
||||
/// Return whether the mouse is currently held.
|
||||
/// This is useful to detect a drag.
|
||||
/// @arg btn The button to check.
|
||||
bool Mouse::IsHeld(Button btn) const {
|
||||
return IsDown(this, btn) && previous && IsDown(previous, btn);
|
||||
}
|
||||
|
||||
/// Return whether the mouse transitionned from pressed to released.
|
||||
/// This is useful to detect a click.
|
||||
/// @arg btn The button to check.
|
||||
bool Mouse::IsReleased(Button btn) const {
|
||||
return !IsDown(this, btn) && (previous && IsDown(previous, btn));
|
||||
}
|
||||
|
||||
} // namespace ftxui
|
@ -123,8 +123,7 @@ class RadioboxBase : public ComponentBase, public RadioboxOption {
|
||||
|
||||
TakeFocus();
|
||||
focused_entry() = i;
|
||||
if (event.mouse().button == Mouse::Left &&
|
||||
event.mouse().motion == Mouse::Released) {
|
||||
if (event.mouse().IsPressed()) {
|
||||
if (selected() != i) {
|
||||
selected() = i;
|
||||
on_change();
|
||||
|
@ -42,8 +42,7 @@ class ResizableSplitBase : public ComponentBase {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (event.mouse().button == Mouse::Left &&
|
||||
event.mouse().motion == Mouse::Pressed &&
|
||||
if (event.mouse().IsPressed() &&
|
||||
separator_box_.Contain(event.mouse().x, event.mouse().y) &&
|
||||
!captured_mouse_) {
|
||||
captured_mouse_ = CaptureMouse(event);
|
||||
|
@ -689,11 +689,17 @@ void ScreenInteractive::HandleTask(Component component, Task& task) {
|
||||
if (arg.is_mouse()) {
|
||||
arg.mouse().x -= cursor_x_;
|
||||
arg.mouse().y -= cursor_y_;
|
||||
arg.mouse().previous = &latest_mouse_event_;
|
||||
}
|
||||
|
||||
arg.screen_ = this;
|
||||
component->OnEvent(arg);
|
||||
frame_valid_ = false;
|
||||
|
||||
if (arg.is_mouse()) {
|
||||
latest_mouse_event_ = arg.mouse();
|
||||
latest_mouse_event_.previous = nullptr;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -174,8 +174,7 @@ class SliderBase : public ComponentBase {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (event.mouse().button != Mouse::Left ||
|
||||
event.mouse().motion != Mouse::Pressed) {
|
||||
if (!event.mouse().IsPressed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -225,8 +225,7 @@ class WindowImpl : public ComponentBase, public WindowOptions {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (event.mouse().button != Mouse::Left ||
|
||||
event.mouse().motion != Mouse::Pressed) {
|
||||
if (!event.mouse().IsPressed()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user