From 9f610a01109f25c0e767144d3baf01aa2e4ac504 Mon Sep 17 00:00:00 2001 From: Arthur Sonzogni Date: Sun, 3 Apr 2022 15:04:33 +0200 Subject: [PATCH] Make the focused button to take the focus inside frame. (#371) This resolves: https://github.com/ArthurSonzogni/FTXUI/issues/370 --- CHANGELOG.md | 1 + examples/component/CMakeLists.txt | 1 + examples/component/button_in_frame.cpp | 48 ++++++++++++++++++++++++++ src/ftxui/component/button.cpp | 16 +++++---- 4 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 examples/component/button_in_frame.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index c5abf7f..613a437 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ current (development) - `Menu` can now be used in the 4 directions, using `MenuOption.direction`. - `Menu` can display an animated underline, using `MenuOption.underline.enabled`. +- `Button` is now taking the focus in frame. - **breaking** All the options are now using a transform function. - **breaking** The `Toggle` component is now implemented using `Menu`. - **bugfix** Container::Tab implements `Focusable()`. diff --git a/examples/component/CMakeLists.txt b/examples/component/CMakeLists.txt index 4c135df..f030781 100644 --- a/examples/component/CMakeLists.txt +++ b/examples/component/CMakeLists.txt @@ -2,6 +2,7 @@ set(DIRECTORY_LIB component) example(button) example(button_animated) +example(button_in_frame) example(button_style) example(canvas_animated) example(checkbox) diff --git a/examples/component/button_in_frame.cpp b/examples/component/button_in_frame.cpp new file mode 100644 index 0000000..23a0d94 --- /dev/null +++ b/examples/component/button_in_frame.cpp @@ -0,0 +1,48 @@ +#include // for array +#include // for shared_ptr, __shared_ptr_access +#include // for operator+, to_string + +#include "ftxui/component/captured_mouse.hpp" // for ftxui +#include "ftxui/component/component.hpp" // for Checkbox, Renderer, Vertical +#include "ftxui/component/component_base.hpp" // for ComponentBase +#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive +#include "ftxui/dom/elements.hpp" // for operator|, Element, size, border, frame, vscroll_indicator, HEIGHT, LESS_THAN + +using namespace ftxui; + +int main(int argc, const char* argv[]) { + int counter = 0; + auto on_click = [&] { counter++; }; + + auto button_style = ButtonOption::Animated(Color::Default, Color::GrayDark, + Color::Default, Color::White); + + auto container = Container::Vertical({}); + for (int i = 0; i < 30; ++i) { + auto button = + Button("Button " + std::to_string(i), on_click, &button_style); + container->Add(button); + } + + auto renderer = Renderer(container, [&] { + return vbox({ + hbox({ + text("Counter:"), + text(std::to_string(counter)), + }), + separator(), + container->Render() | vscroll_indicator | frame | + size(HEIGHT, LESS_THAN, 20), + }) | + border; + }); + + auto screen = ScreenInteractive::FitComponent(); + screen.Loop(renderer); + + return 0; +} + +// Copyright 2022 Arthur Sonzogni. All rights reserved. +// Use of this source code is governed by the MIT license that can be found in +// the LICENSE file. diff --git a/src/ftxui/component/button.cpp b/src/ftxui/component/button.cpp index b827f2d..30ebfec 100644 --- a/src/ftxui/component/button.cpp +++ b/src/ftxui/component/button.cpp @@ -69,22 +69,27 @@ Component Button(ConstStringRef label, // Component implementation: Element Render() override { - float target = Focused() ? 1.F : 0.F; // NOLINT + const bool active = Active(); + const bool focused = Focused(); + const bool focused_or_hover = focused || mouse_hover_; + + float target = focused_or_hover ? 1.F : 0.F; // NOLINT if (target != animator_background_.to()) { SetAnimationTarget(target); } + auto focus_management = focused ? focus : active ? select : nothing; EntryState state = { *label_, false, - Active(), - Focused(), + active, + focused_or_hover, }; auto element = (option_->transform ? option_->transform : DefaultTransform) // (state); - return element | AnimatedColorStyle() | reflect(box_); + return element | AnimatedColorStyle() | focus_management | reflect(box_); } Decorator AnimatedColorStyle() { @@ -151,10 +156,9 @@ Component Button(ConstStringRef label, return false; } - TakeFocus(); - if (event.mouse().button == Mouse::Left && event.mouse().motion == Mouse::Pressed) { + TakeFocus(); OnClick(); return true; }