diff options
| author | littleblack111 <littleblack11111@gmail.com> | 2025-06-12 21:41:41 +0800 |
|---|---|---|
| committer | littleblack111 <littleblack11111@gmail.com> | 2025-06-13 20:22:51 +0800 |
| commit | 6f7b994684032060f0a2d7af82f4f3572293b8d6 (patch) | |
| tree | 793d328cbcd6761365267550b55db45aee9b21fc /src/io/scroller.cpp | |
| parent | 6a51ab4525c59e9fe2bdbd92493019b0a98c6b94 (diff) | |
internal!: organized internal structure, using cmake now
Diffstat (limited to 'src/io/scroller.cpp')
| -rw-r--r-- | src/io/scroller.cpp | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/src/io/scroller.cpp b/src/io/scroller.cpp new file mode 100644 index 0000000..c595a39 --- /dev/null +++ b/src/io/scroller.cpp @@ -0,0 +1,85 @@ +#include "scroller.hpp" + +#include "../debug/log.hpp" +#include <algorithm> // for max, min +#include <ftxui/component/component_base.hpp> // for Component, ComponentBase +#include <ftxui/component/event.hpp> // for Event, Event::ArrowDown, Event::ArrowUp, Event::End, Event::Home, Event::PageDown, Event::PageUp +#include <memory> // for shared_ptr, allocator, __shared_ptr_access +#include <utility> // for move + +#include "ftxui/component/component.hpp" // for Make +#include "ftxui/component/mouse.hpp" // for Mouse, Mouse::WheelDown, Mouse::WheelUp +#include "ftxui/dom/deprecated.hpp" // for text +#include "ftxui/dom/elements.hpp" // for operator|, Element, size, vbox, EQUAL, HEIGHT, dbox, reflect, focus, inverted, nothing, select, vscroll_indicator, yflex, yframe +#include "ftxui/dom/node.hpp" // for Node +#include "ftxui/dom/requirement.hpp" // for Requirement +#include "ftxui/screen/box.hpp" // for Box + +namespace ftxui { // NOLINT + +class CScrollerBase : public ComponentBase { + public: + CScrollerBase(Component child) { Add(child); } + + private: + Element OnRender() final { // NOLINT + auto focused = Focused() ? focus : ftxui::select; + auto style = Focused() ? inverted : nothing; + + Element background = ComponentBase::Render(); + background->ComputeRequirement(); + size_ = background->requirement().min_y; + return dbox({ + std::move(background), + vbox({ + text(L"") | size(HEIGHT, EQUAL, selected_), + text(L"") | style | focused, + }), + }) | + vscroll_indicator | yframe | yflex | reflect(box_); + } + + bool OnEvent(Event event) final { // NOLINT + if (event.is_mouse() && box_.Contain(event.mouse().x, event.mouse().y)) + TakeFocus(); + + int selected_old = selected_; + if (event == Event::ArrowUp || event == Event::Character('k') || + (event.is_mouse() && event.mouse().button == Mouse::WheelUp)) + selected_--; + if ((event == Event::ArrowDown || event == Event::Character('j') || + (event.is_mouse() && event.mouse().button == Mouse::WheelDown))) + selected_++; + if (event == Event::PageDown) + selected_ += box_.y_max - box_.y_min; + if (event == Event::PageUp) + selected_ -= box_.y_max - box_.y_min; + if (event == Event::Home) + selected_ = 0; + if (event == Event::End) + selected_ = size_; + + if (event == Event::Custom && sticky_select) + selected_ = size_; + + selected_ = std::max(0, std::min(size_, selected_)); + sticky_select = selected_ >= size_ - 15; + return selected_old != selected_; + } + + bool Focusable() const final { return true; } // NOLINT + + bool sticky_select = true; + int selected_ = 0; + int size_ = 0; + Box box_; +}; + +Component Scroller(Component child) { // NOLINT + return Make<CScrollerBase>(std::move(child)); +} +} // namespace ftxui + +// Copyright 2021 Arthur Sonzogni. All rights reserved. +// Use of this source code is governed by the MIT license that can be found in +// the LICENSE file. |
