mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2025-09-16 08:04:21 +08:00
Add menu styles.
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
project(ftxui)
|
||||
|
||||
add_library(ftxui
|
||||
src/ftxui/component/component.cpp
|
||||
@@ -13,6 +12,7 @@ add_library(ftxui
|
||||
src/ftxui/dom/bold.cpp
|
||||
src/ftxui/dom/color.cpp
|
||||
src/ftxui/dom/composite_decorator.cpp
|
||||
src/ftxui/dom/dbox.cpp
|
||||
src/ftxui/dom/dim.cpp
|
||||
src/ftxui/dom/flex.cpp
|
||||
src/ftxui/dom/frame.cpp
|
||||
|
@@ -2,6 +2,7 @@
|
||||
#define FTXUI_COMPONENT_MENU
|
||||
|
||||
#include "ftxui/component/component.hpp"
|
||||
#include "ftxui/dom/elements.hpp"
|
||||
#include <functional>
|
||||
|
||||
namespace ftxui {
|
||||
@@ -16,6 +17,10 @@ class Menu : public Component {
|
||||
std::vector<std::wstring> entries = {};
|
||||
int selected = 0;
|
||||
|
||||
dom::Decorator active_style = dom::inverted;
|
||||
dom::Decorator selected_style = dom::bold;
|
||||
dom::Decorator normal_style = dom::nothing;
|
||||
|
||||
// State update callback.
|
||||
std::function<void()> on_change = [](){};
|
||||
std::function<void()> on_enter = [](){};
|
||||
|
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "ftxui/component/component.hpp"
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
namespace ftxui {
|
||||
namespace component {
|
||||
@@ -13,9 +14,8 @@ class Toggle : public Component {
|
||||
Toggle(Delegate*);
|
||||
|
||||
// State.
|
||||
bool activated = true;
|
||||
std::wstring on = L"On";
|
||||
std::wstring off = L"Off";
|
||||
size_t activated = 0;
|
||||
std::vector<std::wstring> options = {L"On", L"Off"};
|
||||
|
||||
// Callback.
|
||||
std::function<void()> on_change = [](){};
|
||||
|
@@ -1,6 +1,8 @@
|
||||
#ifndef FTXUI_DOM_ELEMENTS_HPP
|
||||
#define FTXUI_DOM_ELEMENTS_HPP
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "ftxui/color.hpp"
|
||||
#include "ftxui/dom/node.hpp"
|
||||
|
||||
@@ -8,12 +10,14 @@ namespace ftxui {
|
||||
namespace dom {
|
||||
|
||||
using Element = std::unique_ptr<Node>;
|
||||
using Decorator = std::function<Element(Element)>;
|
||||
using Child = std::unique_ptr<Node>;
|
||||
using Children = std::vector<Child>;
|
||||
|
||||
// --- Layout ----
|
||||
Element vbox(Children);
|
||||
Element hbox(Children);
|
||||
Element dbox(Children);
|
||||
Element flex();
|
||||
Element flex(Element);
|
||||
|
||||
@@ -32,6 +36,8 @@ Element underlined(Element);
|
||||
Element blink(Element);
|
||||
Element color(Color, Element);
|
||||
Element bgcolor(Color, Element);
|
||||
Decorator color(Color);
|
||||
Decorator bgcolor(Color);
|
||||
|
||||
// --- Util ---
|
||||
Element hcenter(Element);
|
||||
@@ -40,6 +46,7 @@ Element center(Element);
|
||||
|
||||
// --- Util ---
|
||||
Element nothing(Element element);
|
||||
Decorator compose(Decorator, Decorator);
|
||||
|
||||
template <class... Args>
|
||||
Children unpack(Args... args) {
|
||||
@@ -58,6 +65,11 @@ Element hbox(Args... children) {
|
||||
return hbox(unpack(std::forward<Args>(children)...));
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
Element dbox(Args... children) {
|
||||
return dbox(unpack(std::forward<Args>(children)...));
|
||||
}
|
||||
|
||||
}; // namespace dom
|
||||
}; // namespace ftxui
|
||||
|
||||
|
@@ -24,9 +24,6 @@ dom::Element Input::Render() {
|
||||
if (!is_focused)
|
||||
return flex(text(content));
|
||||
|
||||
std::wstring sub_content = content;
|
||||
size_t sub_cursor_position = cursor_position;
|
||||
|
||||
std::wstring part_before_cursor = content.substr(0,cursor_position);
|
||||
std::wstring part_at_cursor = cursor_position < (int)content.size()
|
||||
? content.substr(cursor_position, 1)
|
||||
|
@@ -14,12 +14,12 @@ dom::Element Menu::Render() {
|
||||
for (size_t i = 0; i < entries.size(); ++i) {
|
||||
if (size_t(selected) == i) {
|
||||
if (focused)
|
||||
elements.push_back(inverted(text(L"> " + entries[i])));
|
||||
elements.push_back(active_style(text(L"> " + entries[i])));
|
||||
else
|
||||
elements.push_back(bold(text(L"> " + entries[i])));
|
||||
elements.push_back(selected_style(text(L"> " + entries[i])));
|
||||
}
|
||||
else {
|
||||
elements.push_back(text(L" " + entries[i]));
|
||||
elements.push_back(normal_style(text(L" " + entries[i])));
|
||||
}
|
||||
}
|
||||
return vbox(std::move(elements));
|
||||
|
@@ -11,32 +11,33 @@ dom::Element Toggle::Render() {
|
||||
|
||||
Children children;
|
||||
children.push_back(text(L"["));
|
||||
if (activated) {
|
||||
children.push_back(highlight(text(on)));
|
||||
children.push_back(text(L"|"));
|
||||
children.push_back(dim(text(off)));
|
||||
} else {
|
||||
children.push_back(dim(text(on)));
|
||||
children.push_back(text(L"|"));
|
||||
children.push_back(highlight(text(off)));
|
||||
|
||||
for(size_t i = 0; i<options.size(); ++i) {
|
||||
// Separator.
|
||||
if (i != 0)
|
||||
children.push_back(text(L"|"));
|
||||
|
||||
// Entry.
|
||||
auto style = i == activated ? highlight : dim;
|
||||
children.push_back(style(text(options[i])));
|
||||
}
|
||||
children.push_back(text(L"]"));
|
||||
return hbox(std::move(children));
|
||||
}
|
||||
|
||||
bool Toggle::OnEvent(Event event) {
|
||||
if (activated) {
|
||||
if (event == Event::ArrowRight || event == Event::Character('l')) {
|
||||
activated = false;
|
||||
on_change();
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (event == Event::ArrowLeft || event == Event::Character('h')) {
|
||||
activated = true;
|
||||
on_change();
|
||||
return true;
|
||||
}
|
||||
if (activated > 0 &&
|
||||
(event == Event::ArrowLeft || event == Event::Character('h'))) {
|
||||
activated--;
|
||||
on_change();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (activated < options.size() - 1 &&
|
||||
(event == Event::ArrowRight || event == Event::Character('l'))) {
|
||||
activated++;
|
||||
on_change();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@@ -47,5 +47,17 @@ std::unique_ptr<Node> bgcolor(Color c, Child child) {
|
||||
return std::make_unique<BgColor>(unpack(std::move(child)), c);
|
||||
}
|
||||
|
||||
Decorator color(Color c) {
|
||||
return [c](Child child) {
|
||||
return color(c, std::move(child));
|
||||
};
|
||||
}
|
||||
|
||||
Decorator bgcolor(Color c) {
|
||||
return [c](Child child) {
|
||||
return bgcolor(c, std::move(child));
|
||||
};
|
||||
}
|
||||
|
||||
}; // namespace dom
|
||||
}; // namespace ftxui
|
||||
|
37
ftxui/src/ftxui/dom/dbox.cpp
Normal file
37
ftxui/src/ftxui/dom/dbox.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "ftxui/dom/node.hpp"
|
||||
#include "ftxui/dom/elements.hpp"
|
||||
|
||||
namespace ftxui {
|
||||
namespace dom {
|
||||
|
||||
class DBox : public Node {
|
||||
public:
|
||||
DBox(Children children) : Node(std::move(children)) {}
|
||||
~DBox() {}
|
||||
|
||||
void ComputeRequirement() override {
|
||||
requirement_.min.x = 0;
|
||||
requirement_.min.y = 0;
|
||||
requirement_.flex.x = 1;
|
||||
requirement_.flex.y = 0;
|
||||
for (auto& child : children) {
|
||||
child->ComputeRequirement();
|
||||
requirement_.min.x = std::max(requirement_.min.x, child->requirement().min.x);
|
||||
requirement_.min.y = std::max(requirement_.min.y, child->requirement().min.y);
|
||||
}
|
||||
}
|
||||
|
||||
void SetBox(Box box) override {
|
||||
Node::SetBox(box);
|
||||
|
||||
for (auto& child : children)
|
||||
child->SetBox(box);
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<Node> dbox(Children children) {
|
||||
return std::make_unique<DBox>(std::move(children));
|
||||
}
|
||||
|
||||
}; // namespace dom
|
||||
}; // namespace ftxui
|
@@ -7,5 +7,14 @@ Element nothing(Element element) {
|
||||
return std::move(element);
|
||||
}
|
||||
|
||||
Decorator compose(Decorator a, Decorator b) {
|
||||
return [
|
||||
a = std::move(a),
|
||||
b = std::move(b)
|
||||
](Element element) {
|
||||
return a(b(std::move(element)));
|
||||
};
|
||||
}
|
||||
|
||||
}; // namespace dom
|
||||
}; // namespace ftxui
|
||||
|
Reference in New Issue
Block a user