From eff21ee2ce1fdb4328d71d801352ec25f4e457ff Mon Sep 17 00:00:00 2001 From: littleblack111 Date: Wed, 2 Apr 2025 18:49:15 +0800 Subject: feat: ftxui (#17) * ready for merge rm sum random ocmments first and https://github.com/ArthurSonzogni/FTXUI/issues/1024 but still, ready for merge since we can't do anything on our end * style: clang-tidy * ci * ci * style: clang-tidy * fix * fix: scroll https://github.com/ArthurSonzogni/git-tui/blob/master/src/scroller.cpp * focus * update todo * style: clang-format * update todo * sticky scroll * update todxo * smol fix need event to update screen. so we just give event when IO updates * style: clang-format --------- Co-authored-by: github-actions[bot] --- src/scroller.cpp | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 src/scroller.cpp (limited to 'src/scroller.cpp') diff --git a/src/scroller.cpp b/src/scroller.cpp new file mode 100644 index 0000000..bf80770 --- /dev/null +++ b/src/scroller.cpp @@ -0,0 +1,85 @@ +#include "scroller.hpp" + +#include "log.hpp" +#include // for max, min +#include // for Component, ComponentBase +#include // for Event, Event::ArrowDown, Event::ArrowUp, Event::End, Event::Home, Event::PageDown, Event::PageUp +#include // for shared_ptr, allocator, __shared_ptr_access +#include // 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 { + +class ScrollerBase : public ComponentBase { + public: + ScrollerBase(Component child) { Add(child); } + + private: + Element OnRender() final { + 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 { + 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_; + return selected_old != selected_; + } + + bool Focusable() const final { return true; } + + bool sticky_select = true; + int selected_ = 0; + int size_ = 0; + Box box_; +}; + +Component Scroller(Component child) { + return Make(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. -- cgit v1.2.3