mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2024-11-22 18:59:59 +08:00
Add "frame" : scrollable area.
This commit is contained in:
parent
cb4df0b56f
commit
fddcbdea65
@ -14,11 +14,11 @@ A C++ library for making text based user interface.
|
|||||||
~~~cpp
|
~~~cpp
|
||||||
vbox(
|
vbox(
|
||||||
hbox(
|
hbox(
|
||||||
text(L"left") | frame,
|
text(L"left") | border,
|
||||||
text(L"middle") | frame | flex,
|
text(L"middle") | border | flex,
|
||||||
text(L"right") | frame
|
text(L"right") | border
|
||||||
),
|
),
|
||||||
gauge(0.5) | frame
|
gauge(0.5) | border
|
||||||
)
|
)
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
|
@ -5,12 +5,14 @@ function(example name)
|
|||||||
endfunction(example)
|
endfunction(example)
|
||||||
|
|
||||||
example(checkbox)
|
example(checkbox)
|
||||||
|
example(checkbox_in_frame)
|
||||||
example(gallery)
|
example(gallery)
|
||||||
example(input)
|
example(input)
|
||||||
example(menu)
|
example(menu)
|
||||||
example(menu2)
|
example(menu2)
|
||||||
example(menu_style)
|
example(menu_style)
|
||||||
example(radiobox)
|
example(radiobox)
|
||||||
|
example(radiobox_in_frame)
|
||||||
example(tab_horizontal)
|
example(tab_horizontal)
|
||||||
example(tab_vertical)
|
example(tab_vertical)
|
||||||
example(toggle)
|
example(toggle)
|
||||||
|
@ -22,19 +22,10 @@ class MyComponent : public Component {
|
|||||||
box_3_.label = L"Use WebAssembly";
|
box_3_.label = L"Use WebAssembly";
|
||||||
box_3_.state = true;
|
box_3_.state = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Element Render() {
|
|
||||||
return
|
|
||||||
window(text(L" Checkbox "),
|
|
||||||
hbox(
|
|
||||||
container_.Render()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, const char *argv[]) {
|
int main(int argc, const char *argv[]) {
|
||||||
auto screen = ScreenInteractive::FixedSize(30,5);
|
auto screen = ScreenInteractive::TerminalOutput();
|
||||||
MyComponent component;
|
MyComponent component;
|
||||||
screen.Loop(&component);
|
screen.Loop(&component);
|
||||||
return 0;
|
return 0;
|
||||||
|
42
examples/component/checkbox_in_frame.cpp
Normal file
42
examples/component/checkbox_in_frame.cpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#include "ftxui/component/checkbox.hpp"
|
||||||
|
#include "ftxui/component/container.hpp"
|
||||||
|
#include "ftxui/component/input.hpp"
|
||||||
|
#include "ftxui/component/menu.hpp"
|
||||||
|
#include "ftxui/component/checkbox.hpp"
|
||||||
|
#include "ftxui/component/screen_interactive.hpp"
|
||||||
|
#include "ftxui/component/toggle.hpp"
|
||||||
|
#include "ftxui/screen/string.hpp"
|
||||||
|
|
||||||
|
using namespace ftxui;
|
||||||
|
|
||||||
|
class MyComponent : public Component {
|
||||||
|
public:
|
||||||
|
MyComponent() {
|
||||||
|
Add(&container);
|
||||||
|
checkbox.resize(30);
|
||||||
|
for(int i = 0; i<checkbox.size(); ++i) {
|
||||||
|
checkbox[i].label = (L"CheckBox " + to_wstring(i));
|
||||||
|
container.Add(&checkbox[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Element Render() override {
|
||||||
|
Elements content;
|
||||||
|
for(auto& it : checkbox) {
|
||||||
|
content.push_back(it.Render());
|
||||||
|
}
|
||||||
|
return vbox(std::move(content)) | frame | size(20, 10) | border;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<CheckBox> checkbox;
|
||||||
|
Container container = Container::Vertical();
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, const char* argv[]) {
|
||||||
|
auto screen = ScreenInteractive::FitComponent();
|
||||||
|
MyComponent component;
|
||||||
|
screen.Loop(&component);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -69,7 +69,7 @@ class MyComponent : public Component {
|
|||||||
Render(L"radiobox", radiobox),
|
Render(L"radiobox", radiobox),
|
||||||
separator(),
|
separator(),
|
||||||
Render(L"input", input)
|
Render(L"input", input)
|
||||||
) | frame;
|
) | border | frame | size(10,10) | border;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ class MyComponent : public Component {
|
|||||||
|
|
||||||
Element Render() override {
|
Element Render() override {
|
||||||
return
|
return
|
||||||
frame(
|
border(
|
||||||
vbox(
|
vbox(
|
||||||
hbox(text(L" input_1 : "), input_1.Render()),
|
hbox(text(L" input_1 : "), input_1.Render()),
|
||||||
hbox(text(L" input_2 : "), input_2.Render()),
|
hbox(text(L" input_2 : "), input_2.Render()),
|
||||||
|
@ -34,7 +34,7 @@ class MyComponent : public Component {
|
|||||||
Element Render() override {
|
Element Render() override {
|
||||||
int sum = left_menu.selected * 10 + right_menu.selected;
|
int sum = left_menu.selected * 10 + right_menu.selected;
|
||||||
return
|
return
|
||||||
frame(
|
border(
|
||||||
vbox(
|
vbox(
|
||||||
// -------- Top panel --------------
|
// -------- Top panel --------------
|
||||||
hbox(
|
hbox(
|
||||||
|
@ -26,21 +26,21 @@ class MyComponent : public Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
menu_2.selected_style = color(Color::Blue);
|
menu_2.selected_style = color(Color::Blue);
|
||||||
menu_2.active_style = bold | color(Color::Blue);
|
menu_2.focused_style = bold | color(Color::Blue);
|
||||||
|
|
||||||
menu_3.selected_style = color(Color::Blue);
|
menu_3.selected_style = color(Color::Blue);
|
||||||
menu_3.active_style = bgcolor(Color::Blue);
|
menu_3.focused_style = bgcolor(Color::Blue);
|
||||||
|
|
||||||
menu_4.selected_style = bgcolor(Color::Blue);
|
menu_4.selected_style = bgcolor(Color::Blue);
|
||||||
menu_4.active_style = bgcolor(Color::BlueLight);
|
menu_4.focused_style = bgcolor(Color::BlueLight);
|
||||||
|
|
||||||
menu_5.normal_style = bgcolor(Color::Blue);
|
menu_5.normal_style = bgcolor(Color::Blue);
|
||||||
menu_5.selected_style = bgcolor(Color::Yellow);
|
menu_5.selected_style = bgcolor(Color::Yellow);
|
||||||
menu_5.active_style = bgcolor(Color::Red);
|
menu_5.focused_style = bgcolor(Color::Red);
|
||||||
|
|
||||||
menu_6.normal_style = dim | color(Color::Blue);
|
menu_6.normal_style = dim | color(Color::Blue);
|
||||||
menu_6.selected_style = color(Color::Blue);
|
menu_6.selected_style = color(Color::Blue);
|
||||||
menu_6.active_style = bold | color(Color::Blue);
|
menu_6.focused_style = bold | color(Color::Blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::function<void()> on_enter = [](){};
|
std::function<void()> on_enter = [](){};
|
||||||
@ -62,7 +62,7 @@ class MyComponent : public Component {
|
|||||||
menu_4.Render() | flex, separator(),
|
menu_4.Render() | flex, separator(),
|
||||||
menu_5.Render() | flex, separator(),
|
menu_5.Render() | flex, separator(),
|
||||||
menu_6.Render() | flex
|
menu_6.Render() | flex
|
||||||
) | frame;
|
) | border;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
34
examples/component/radiobox_in_frame.cpp
Normal file
34
examples/component/radiobox_in_frame.cpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#include "ftxui/component/checkbox.hpp"
|
||||||
|
#include "ftxui/component/container.hpp"
|
||||||
|
#include "ftxui/component/input.hpp"
|
||||||
|
#include "ftxui/component/menu.hpp"
|
||||||
|
#include "ftxui/component/radiobox.hpp"
|
||||||
|
#include "ftxui/component/screen_interactive.hpp"
|
||||||
|
#include "ftxui/component/toggle.hpp"
|
||||||
|
#include "ftxui/screen/string.hpp"
|
||||||
|
|
||||||
|
using namespace ftxui;
|
||||||
|
|
||||||
|
class MyComponent : public Component {
|
||||||
|
RadioBox radiobox;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MyComponent() {
|
||||||
|
for(int i = 0; i<30; ++i) {
|
||||||
|
radiobox.entries.push_back(L"RadioBox " + to_wstring(i));
|
||||||
|
}
|
||||||
|
Add(&radiobox);
|
||||||
|
}
|
||||||
|
|
||||||
|
Element Render() override {
|
||||||
|
return radiobox.Render() | frame | size(20,10) | border;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, const char* argv[]) {
|
||||||
|
auto screen = ScreenInteractive::FitComponent();
|
||||||
|
MyComponent component;
|
||||||
|
screen.Loop(&component);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -50,7 +50,7 @@ class MyComponent : public Component {
|
|||||||
toggle_.Render(),
|
toggle_.Render(),
|
||||||
separator(),
|
separator(),
|
||||||
tab_container_.Render()
|
tab_container_.Render()
|
||||||
) | frame;
|
) | border;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -4,7 +4,7 @@ function(example name)
|
|||||||
endfunction(example)
|
endfunction(example)
|
||||||
|
|
||||||
example(dbox)
|
example(dbox)
|
||||||
example(frame)
|
example(border)
|
||||||
example(gauge)
|
example(gauge)
|
||||||
example(package_manager)
|
example(package_manager)
|
||||||
example(separator)
|
example(separator)
|
||||||
|
@ -15,13 +15,11 @@ int main(int argc, const char *argv[])
|
|||||||
text(L"Line 1"),
|
text(L"Line 1"),
|
||||||
text(L"Line 2"),
|
text(L"Line 2"),
|
||||||
text(L"Line 3"),
|
text(L"Line 3"),
|
||||||
frame(
|
vbox(
|
||||||
vbox(
|
text(L"Line 4"),
|
||||||
text(L"Line 4"),
|
text(L"Line 5"),
|
||||||
text(L"Line 5"),
|
text(L"Line 6")
|
||||||
text(L"Line 6")
|
) | border,
|
||||||
)
|
|
||||||
),
|
|
||||||
hbox(
|
hbox(
|
||||||
window(text(L"frame 2"),
|
window(text(L"frame 2"),
|
||||||
vbox(
|
vbox(
|
@ -7,20 +7,14 @@ int main(int argc, const char *argv[])
|
|||||||
using namespace ftxui;
|
using namespace ftxui;
|
||||||
auto document =
|
auto document =
|
||||||
dbox(
|
dbox(
|
||||||
frame(
|
vbox(
|
||||||
vbox(
|
text(L"line_1"),
|
||||||
text(L"line_1"),
|
text(L"line_2"),
|
||||||
text(L"line_2"),
|
text(L"line_3"),
|
||||||
text(L"line_3"),
|
text(L"line_4"),
|
||||||
text(L"line_4"),
|
text(L"line_5")
|
||||||
text(L"line_5")
|
) | border,
|
||||||
)
|
text(L"overlay") | border | center
|
||||||
),
|
|
||||||
center(
|
|
||||||
frame(
|
|
||||||
text(L"overlay")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
auto screen = Screen::TerminalOutput(document);
|
auto screen = Screen::TerminalOutput(document);
|
||||||
Render(screen, document.get());
|
Render(screen, document.get());
|
||||||
|
@ -24,7 +24,7 @@ int main(int argc, const char *argv[])
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
auto document = hbox(vbox(std::move(entries)) | frame, filler());
|
auto document = hbox(vbox(std::move(entries)) | border, filler());
|
||||||
auto screen = Screen::TerminalOutput(document);
|
auto screen = Screen::TerminalOutput(document);
|
||||||
Render(screen, document.get());
|
Render(screen, document.get());
|
||||||
std::cout << reset_position << screen.ToString() << std::flush;
|
std::cout << reset_position << screen.ToString() << std::flush;
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
cmake_minimum_required(VERSION 3.0)
|
cmake_minimum_required(VERSION 3.0)
|
||||||
|
|
||||||
add_library(screen
|
add_library(screen
|
||||||
|
src/ftxui/screen/box.cpp
|
||||||
src/ftxui/screen/screen.cpp
|
src/ftxui/screen/screen.cpp
|
||||||
src/ftxui/screen/terminal.cpp
|
|
||||||
src/ftxui/screen/string.cpp
|
src/ftxui/screen/string.cpp
|
||||||
|
src/ftxui/screen/terminal.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(dom
|
add_library(dom
|
||||||
src/ftxui/dom/blink.cpp
|
src/ftxui/dom/blink.cpp
|
||||||
src/ftxui/dom/bold.cpp
|
src/ftxui/dom/bold.cpp
|
||||||
|
src/ftxui/dom/border.cpp
|
||||||
src/ftxui/dom/color.cpp
|
src/ftxui/dom/color.cpp
|
||||||
src/ftxui/dom/composite_decorator.cpp
|
src/ftxui/dom/composite_decorator.cpp
|
||||||
src/ftxui/dom/dbox.cpp
|
src/ftxui/dom/dbox.cpp
|
||||||
|
@ -13,7 +13,7 @@ class Container : public Component {
|
|||||||
public:
|
public:
|
||||||
static Container Vertical();
|
static Container Vertical();
|
||||||
static Container Horizontal();
|
static Container Horizontal();
|
||||||
static Container Tab(size_t* selector);
|
static Container Tab(int* selector);
|
||||||
|
|
||||||
~Container() override = default;
|
~Container() override = default;
|
||||||
|
|
||||||
@ -36,8 +36,8 @@ class Container : public Component {
|
|||||||
Element TabRender();
|
Element TabRender();
|
||||||
RenderHandler render_handler_;
|
RenderHandler render_handler_;
|
||||||
|
|
||||||
size_t selected_ = 0;
|
int selected_ = 0;
|
||||||
size_t* selector_ = &selected_;
|
int* selector_ = &selected_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ftxui
|
} // namespace ftxui
|
||||||
|
@ -15,9 +15,9 @@ class Menu : public Component {
|
|||||||
|
|
||||||
// State.
|
// State.
|
||||||
std::vector<std::wstring> entries = {};
|
std::vector<std::wstring> entries = {};
|
||||||
size_t selected = 0;
|
int selected = 0;
|
||||||
|
|
||||||
Decorator active_style = inverted;
|
Decorator focused_style = inverted;
|
||||||
Decorator selected_style = bold;
|
Decorator selected_style = bold;
|
||||||
Decorator normal_style = nothing;
|
Decorator normal_style = nothing;
|
||||||
|
|
||||||
|
@ -13,9 +13,13 @@ class Toggle : public Component {
|
|||||||
~Toggle() override = default;
|
~Toggle() override = default;
|
||||||
|
|
||||||
// State.
|
// State.
|
||||||
size_t selected = 0;
|
int selected = 0;
|
||||||
std::vector<std::wstring> entries = {L"On", L"Off"};
|
std::vector<std::wstring> entries = {L"On", L"Off"};
|
||||||
|
|
||||||
|
Decorator focused_style = inverted;
|
||||||
|
Decorator selected_style = bold;
|
||||||
|
Decorator normal_style = dim;
|
||||||
|
|
||||||
// Callback.
|
// Callback.
|
||||||
std::function<void()> on_change = [](){};
|
std::function<void()> on_change = [](){};
|
||||||
|
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
#ifndef FTXUI_DOM_BOX_HPP
|
|
||||||
#define FTXUI_DOM_BOX_HPP
|
|
||||||
|
|
||||||
namespace ftxui {
|
|
||||||
|
|
||||||
struct Box {
|
|
||||||
int left;
|
|
||||||
int right;
|
|
||||||
int top;
|
|
||||||
int bottom;
|
|
||||||
};
|
|
||||||
|
|
||||||
}; // namespace ftxui
|
|
||||||
|
|
||||||
#endif /* end of include guard: FTXUI_DOM_BOX_HPP */
|
|
@ -12,21 +12,11 @@ using Element = std::unique_ptr<Node>;
|
|||||||
using Elements = std::vector<Element>;
|
using Elements = std::vector<Element>;
|
||||||
using Decorator = std::function<Element(Element)>;
|
using Decorator = std::function<Element(Element)>;
|
||||||
|
|
||||||
// --- Layout ----
|
// --- Widget ---
|
||||||
Element vbox(Elements);
|
|
||||||
Element hbox(Elements);
|
|
||||||
Element dbox(Elements);
|
|
||||||
|
|
||||||
// -- Flexibility --
|
|
||||||
Element filler();
|
|
||||||
Element flex(Element);
|
|
||||||
Decorator size(size_t width, size_t height);
|
|
||||||
|
|
||||||
// --- Widget --
|
|
||||||
Element text(std::wstring text);
|
Element text(std::wstring text);
|
||||||
Element separator();
|
Element separator();
|
||||||
Element gauge(float ratio);
|
Element gauge(float ratio);
|
||||||
Element frame(Element);
|
Element border(Element);
|
||||||
Element window(Element title, Element content);
|
Element window(Element title, Element content);
|
||||||
Element spinner(int charset_index, size_t image_index);
|
Element spinner(int charset_index, size_t image_index);
|
||||||
|
|
||||||
@ -36,19 +26,37 @@ Element dim(Element);
|
|||||||
Element inverted(Element);
|
Element inverted(Element);
|
||||||
Element underlined(Element);
|
Element underlined(Element);
|
||||||
Element blink(Element);
|
Element blink(Element);
|
||||||
|
|
||||||
Decorator color(Color);
|
Decorator color(Color);
|
||||||
Decorator bgcolor(Color);
|
Decorator bgcolor(Color);
|
||||||
Element color(Color, Element);
|
Element color(Color, Element);
|
||||||
Element bgcolor(Color, Element);
|
Element bgcolor(Color, Element);
|
||||||
|
|
||||||
// --- Util ---
|
// --- Layout ---
|
||||||
|
// Horizontal, Vertical or stacked set of elements.
|
||||||
|
Element vbox(Elements);
|
||||||
|
Element hbox(Elements);
|
||||||
|
Element dbox(Elements);
|
||||||
|
|
||||||
|
// -- Flexibility ---
|
||||||
|
// Define how to share the remaining space when not all of it is used inside a
|
||||||
|
// container.
|
||||||
|
Element filler();
|
||||||
|
Element flex(Element);
|
||||||
|
Decorator size(size_t width, size_t height);
|
||||||
|
|
||||||
|
// --- Frame ---
|
||||||
|
// A frame is a scrollable area. The internal area is potentially larger than
|
||||||
|
// the external one. The internal area is scrolled in order to make visible the
|
||||||
|
// focused element.
|
||||||
|
Element frame(Element);
|
||||||
|
Element focus(Element);
|
||||||
|
Element select(Element);
|
||||||
|
|
||||||
|
// --- Util --------------------------------------------------------------------
|
||||||
Element hcenter(Element);
|
Element hcenter(Element);
|
||||||
Element vcenter(Element);
|
Element vcenter(Element);
|
||||||
Element center(Element);
|
Element center(Element);
|
||||||
Element align_right(Element);
|
Element align_right(Element);
|
||||||
|
|
||||||
// --- Util ---
|
|
||||||
Element nothing(Element element);
|
Element nothing(Element element);
|
||||||
|
|
||||||
// Pipe elements into decorator togethers.
|
// Pipe elements into decorator togethers.
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "ftxui/dom/box.hpp"
|
|
||||||
#include "ftxui/dom/requirement.hpp"
|
#include "ftxui/dom/requirement.hpp"
|
||||||
|
#include "ftxui/screen/box.hpp"
|
||||||
#include "ftxui/screen/screen.hpp"
|
#include "ftxui/screen/screen.hpp"
|
||||||
|
|
||||||
namespace ftxui {
|
namespace ftxui {
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#ifndef FTXUI_DOM_REQUIREMENT_HPP
|
#ifndef FTXUI_DOM_REQUIREMENT_HPP
|
||||||
#define FTXUI_DOM_REQUIREMENT_HPP
|
#define FTXUI_DOM_REQUIREMENT_HPP
|
||||||
|
|
||||||
|
#include "ftxui/screen/box.hpp"
|
||||||
|
|
||||||
namespace ftxui {
|
namespace ftxui {
|
||||||
|
|
||||||
struct Requirement {
|
struct Requirement {
|
||||||
@ -9,6 +11,14 @@ struct Requirement {
|
|||||||
|
|
||||||
// How much flexibility is given to the component.
|
// How much flexibility is given to the component.
|
||||||
struct { int x = 0; int y = 0; } flex;
|
struct { int x = 0; int y = 0; } flex;
|
||||||
|
|
||||||
|
// Frame.
|
||||||
|
enum Selection {
|
||||||
|
NORMAL = 0,
|
||||||
|
SELECTED = 1,
|
||||||
|
FOCUSED = 2,
|
||||||
|
} selection = NORMAL;
|
||||||
|
Box selected_box;
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace ftxui
|
}; // namespace ftxui
|
||||||
|
17
ftxui/include/ftxui/screen/box.hpp
Normal file
17
ftxui/include/ftxui/screen/box.hpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef FTXUI_SCREEN_BOX_HPP
|
||||||
|
#define FTXUI_SCREEN_BOX_HPP
|
||||||
|
|
||||||
|
namespace ftxui {
|
||||||
|
|
||||||
|
struct Box {
|
||||||
|
int x_min;
|
||||||
|
int x_max;
|
||||||
|
int y_min;
|
||||||
|
int y_max;
|
||||||
|
|
||||||
|
static Box Intersection(Box a, Box b);
|
||||||
|
};
|
||||||
|
|
||||||
|
}; // namespace ftxui
|
||||||
|
|
||||||
|
#endif /* end of include guard: FTXUI_SCREEN_BOX_HPP */
|
@ -6,6 +6,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "ftxui/screen/color.hpp"
|
#include "ftxui/screen/color.hpp"
|
||||||
|
#include "ftxui/screen/box.hpp"
|
||||||
|
|
||||||
namespace ftxui {
|
namespace ftxui {
|
||||||
class Node;
|
class Node;
|
||||||
@ -51,6 +52,7 @@ class Screen {
|
|||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
void ApplyShader();
|
void ApplyShader();
|
||||||
|
Box stencil;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
size_t dimx_;
|
size_t dimx_;
|
||||||
|
22
ftxui/include/ftxui/util/autoreset.hpp
Normal file
22
ftxui/include/ftxui/util/autoreset.hpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef FTXUI_UTIL_AUTORESET_HPP
|
||||||
|
#define FTXUI_UTIL_AUTORESET_HPP
|
||||||
|
|
||||||
|
namespace ftxui {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class AutoReset {
|
||||||
|
public:
|
||||||
|
AutoReset(T* variable, T new_value)
|
||||||
|
: variable_(variable),
|
||||||
|
previous_value_(std::move(*variable)) {
|
||||||
|
*variable_ = std::move(new_value);
|
||||||
|
}
|
||||||
|
~AutoReset() { *variable_ = std::move(previous_value_); }
|
||||||
|
private:
|
||||||
|
T* variable_;
|
||||||
|
T previous_value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ftxui
|
||||||
|
|
||||||
|
#endif /* end of include guard: FTXUI_UTIL_AUTORESET_HPP */
|
@ -4,8 +4,11 @@
|
|||||||
namespace ftxui {
|
namespace ftxui {
|
||||||
|
|
||||||
Element CheckBox::Render() {
|
Element CheckBox::Render() {
|
||||||
auto style = Focused() ? focused_style : unfocused_style;
|
bool is_focused = Focused();
|
||||||
return hbox(text(state ? checked : unchecked), text(label) | style);
|
auto style = is_focused ? focused_style : unfocused_style;
|
||||||
|
auto focus_management = is_focused ? focus : state ? select : nothing;
|
||||||
|
return hbox(text(state ? checked : unchecked),
|
||||||
|
text(label) | style | focus_management);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckBox::OnEvent(Event event) {
|
bool CheckBox::OnEvent(Event event) {
|
||||||
|
@ -19,7 +19,7 @@ Container Container::Vertical() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
Container Container::Tab(size_t* selector) {
|
Container Container::Tab(int* selector) {
|
||||||
Container container;
|
Container container;
|
||||||
container.event_handler_ = &Container::TabEvent;
|
container.event_handler_ = &Container::TabEvent;
|
||||||
container.render_handler_ = &Container::TabRender;
|
container.render_handler_ = &Container::TabRender;
|
||||||
@ -53,7 +53,7 @@ bool Container::VerticalEvent(Event event) {
|
|||||||
|
|
||||||
// Left pressed ?
|
// Left pressed ?
|
||||||
if (event == Event::ArrowDown || event == Event::Character('j')) {
|
if (event == Event::ArrowDown || event == Event::Character('j')) {
|
||||||
if (selected_ != children_.size() - 1) {
|
if (selected_ != int(children_.size()) - 1) {
|
||||||
selected_++;
|
selected_++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ bool Container::HorizontalEvent(Event event) {
|
|||||||
|
|
||||||
// Left pressed ?
|
// Left pressed ?
|
||||||
if (event == Event::ArrowRight || event == Event::Character('l')) {
|
if (event == Event::ArrowRight || event == Event::Character('l')) {
|
||||||
if (selected_ != children_.size() - 1) {
|
if (selected_ != int(children_.size()) - 1) {
|
||||||
selected_++;
|
selected_++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -26,12 +26,15 @@ Element Input::Render() {
|
|||||||
std::wstring part_after_cursor = cursor_position < (int)content.size() - 1
|
std::wstring part_after_cursor = cursor_position < (int)content.size() - 1
|
||||||
? content.substr(cursor_position + 1)
|
? content.substr(cursor_position + 1)
|
||||||
: L"";
|
: L"";
|
||||||
|
auto focused =
|
||||||
|
is_focused ? focus : select;
|
||||||
|
|
||||||
return
|
return
|
||||||
hbox(
|
hbox(
|
||||||
text(part_before_cursor),
|
text(part_before_cursor),
|
||||||
text(part_at_cursor) | underlined,
|
text(part_at_cursor) | underlined | focused,
|
||||||
text(part_after_cursor)
|
text(part_after_cursor)
|
||||||
) | flex | inverted;
|
) | flex | inverted | frame;
|
||||||
}
|
}
|
||||||
bool Input::OnEvent(Event event) {
|
bool Input::OnEvent(Event event) {
|
||||||
std::wstring c;
|
std::wstring c;
|
||||||
|
@ -6,17 +6,14 @@ namespace ftxui {
|
|||||||
|
|
||||||
Element Menu::Render() {
|
Element Menu::Render() {
|
||||||
std::vector<Element> elements;
|
std::vector<Element> elements;
|
||||||
bool focused = Focused();
|
bool is_focused = Focused();
|
||||||
for (size_t i = 0; i < entries.size(); ++i) {
|
for (size_t i = 0; i < entries.size(); ++i) {
|
||||||
if (selected == i) {
|
auto style = (selected != int(i))
|
||||||
if (focused)
|
? normal_style
|
||||||
elements.push_back(active_style(text(L"> " + entries[i])));
|
: is_focused ? focused_style : selected_style;
|
||||||
else
|
auto focused = (selected != int(i)) ? nothing : is_focused ? focus : select;
|
||||||
elements.push_back(selected_style(text(L"> " + entries[i])));
|
auto icon = (selected != int(i)) ? L" " : L"> ";
|
||||||
}
|
elements.push_back(text(icon + entries[i]) | style | focused);
|
||||||
else {
|
|
||||||
elements.push_back(normal_style(text(L" " + entries[i])));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return vbox(std::move(elements));
|
return vbox(std::move(elements));
|
||||||
}
|
}
|
||||||
@ -25,12 +22,12 @@ bool Menu::OnEvent(Event event) {
|
|||||||
if (!Focused())
|
if (!Focused())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
size_t new_selected = selected;
|
int new_selected = selected;
|
||||||
if (event == Event::ArrowUp || event == Event::Character('k'))
|
if (event == Event::ArrowUp || event == Event::Character('k'))
|
||||||
new_selected--;
|
new_selected--;
|
||||||
if (event == Event::ArrowDown || event == Event::Character('j'))
|
if (event == Event::ArrowDown || event == Event::Character('j'))
|
||||||
new_selected++;
|
new_selected++;
|
||||||
new_selected = std::max(size_t(0), std::min(entries.size()-size_t(1), new_selected));
|
new_selected = std::max(0, std::min(int(entries.size()) - 1, new_selected));
|
||||||
|
|
||||||
if (selected != new_selected) {
|
if (selected != new_selected) {
|
||||||
selected = new_selected;
|
selected = new_selected;
|
||||||
|
@ -9,8 +9,12 @@ Element RadioBox::Render() {
|
|||||||
for (size_t i = 0; i < entries.size(); ++i) {
|
for (size_t i = 0; i < entries.size(); ++i) {
|
||||||
auto style =
|
auto style =
|
||||||
(focused == int(i) && is_focused) ? focused_style : unfocused_style;
|
(focused == int(i) && is_focused) ? focused_style : unfocused_style;
|
||||||
|
auto focus_management =
|
||||||
|
(focused != int(i)) ? nothing : is_focused ? focus : select;
|
||||||
|
|
||||||
const std::wstring& symbol = selected == int(i) ? checked : unchecked;
|
const std::wstring& symbol = selected == int(i) ? checked : unchecked;
|
||||||
elements.push_back(hbox(text(symbol), text(entries[i]) | style));
|
elements.push_back(hbox(text(symbol), text(entries[i]) | style) |
|
||||||
|
focus_management);
|
||||||
}
|
}
|
||||||
return vbox(std::move(elements));
|
return vbox(std::move(elements));
|
||||||
}
|
}
|
||||||
@ -30,7 +34,7 @@ bool RadioBox::OnEvent(Event event) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event == Event::Character(' ')) {
|
if (event == Event::Character(' ') || event==Event::Return) {
|
||||||
selected = focused;
|
selected = focused;
|
||||||
on_change();
|
on_change();
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
namespace ftxui {
|
namespace ftxui {
|
||||||
|
|
||||||
Element Toggle::Render() {
|
Element Toggle::Render() {
|
||||||
auto highlight = Focused() ? inverted : bold;
|
bool is_focused = Focused();
|
||||||
|
|
||||||
Elements children;
|
Elements children;
|
||||||
for(size_t i = 0; i<entries.size(); ++i) {
|
for(size_t i = 0; i<entries.size(); ++i) {
|
||||||
@ -12,8 +12,11 @@ Element Toggle::Render() {
|
|||||||
children.push_back(separator());
|
children.push_back(separator());
|
||||||
|
|
||||||
// Entry.
|
// Entry.
|
||||||
auto style = i == selected ? highlight : dim;
|
auto style = (selected != int(i))
|
||||||
children.push_back(style(text(entries[i])));
|
? normal_style
|
||||||
|
: is_focused ? focused_style : selected_style;
|
||||||
|
auto focused = (selected != int(i)) ? nothing : is_focused ? focus : select;
|
||||||
|
children.push_back(text(entries[i]) | style | focused);
|
||||||
}
|
}
|
||||||
return hbox(std::move(children));
|
return hbox(std::move(children));
|
||||||
}
|
}
|
||||||
@ -26,7 +29,7 @@ bool Toggle::OnEvent(Event event) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected < entries.size() - 1 &&
|
if (selected < int(entries.size()) - 1 &&
|
||||||
(event == Event::ArrowRight || event == Event::Character('l'))) {
|
(event == Event::ArrowRight || event == Event::Character('l'))) {
|
||||||
selected++;
|
selected++;
|
||||||
on_change();
|
on_change();
|
||||||
|
@ -10,8 +10,8 @@ class Blink : public NodeDecorator {
|
|||||||
|
|
||||||
void Render(Screen& screen) override {
|
void Render(Screen& screen) override {
|
||||||
Node::Render(screen);
|
Node::Render(screen);
|
||||||
for (int y = box_.top; y <= box_.bottom; ++y) {
|
for (int y = box_.y_min; y <= box_.y_max; ++y) {
|
||||||
for (int x = box_.left; x <= box_.right; ++x) {
|
for (int x = box_.x_min; x <= box_.x_max; ++x) {
|
||||||
screen.PixelAt(x, y).blink = true;
|
screen.PixelAt(x, y).blink = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,8 @@ class Bold : public NodeDecorator {
|
|||||||
~Bold() override {}
|
~Bold() override {}
|
||||||
|
|
||||||
void Render(Screen& screen) override {
|
void Render(Screen& screen) override {
|
||||||
for (int y = box_.top; y <= box_.bottom; ++y) {
|
for (int y = box_.y_min; y <= box_.y_max; ++y) {
|
||||||
for (int x = box_.left; x <= box_.right; ++x) {
|
for (int x = box_.x_min; x <= box_.x_max; ++x) {
|
||||||
screen.PixelAt(x,y).bold = true;
|
screen.PixelAt(x,y).bold = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
88
ftxui/src/ftxui/dom/border.cpp
Normal file
88
ftxui/src/ftxui/dom/border.cpp
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#include "ftxui/dom/node.hpp"
|
||||||
|
#include "ftxui/dom/elements.hpp"
|
||||||
|
|
||||||
|
namespace ftxui {
|
||||||
|
|
||||||
|
using namespace ftxui;
|
||||||
|
|
||||||
|
static wchar_t charset[] = L"┌┐└┘─│┬┴┤├";
|
||||||
|
|
||||||
|
class Border : public Node {
|
||||||
|
public:
|
||||||
|
Border(Elements children) : Node(std::move(children)) {}
|
||||||
|
~Border() override {}
|
||||||
|
|
||||||
|
void ComputeRequirement() override {
|
||||||
|
Node::ComputeRequirement();
|
||||||
|
requirement_ = children[0]->requirement();
|
||||||
|
requirement_.min.x += 2;
|
||||||
|
requirement_.min.y += 2;
|
||||||
|
if (children.size() == 2) {
|
||||||
|
requirement_.min.x =
|
||||||
|
std::max(requirement_.min.x, children[1]->requirement().min.x + 2);
|
||||||
|
}
|
||||||
|
requirement_.selected_box.x_min++;
|
||||||
|
requirement_.selected_box.x_max++;
|
||||||
|
requirement_.selected_box.y_min++;
|
||||||
|
requirement_.selected_box.y_max++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetBox(Box box) override {
|
||||||
|
Node::SetBox(box);
|
||||||
|
if (children.size() == 2) {
|
||||||
|
Box title_box;
|
||||||
|
title_box.x_min = box.x_min + 1;
|
||||||
|
title_box.x_max = box.x_max - 1;
|
||||||
|
title_box.y_min = box.y_min;
|
||||||
|
title_box.y_max = box.y_min;
|
||||||
|
children[1]->SetBox(title_box);
|
||||||
|
}
|
||||||
|
box.x_min++;
|
||||||
|
box.x_max--;
|
||||||
|
box.y_min++;
|
||||||
|
box.y_max--;
|
||||||
|
children[0]->SetBox(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Render(Screen& screen) override {
|
||||||
|
// Draw content.
|
||||||
|
children[0]->Render(screen);
|
||||||
|
|
||||||
|
// Draw the border.
|
||||||
|
if (box_.x_min >= box_.x_max || box_.y_min >= box_.y_max)
|
||||||
|
return;
|
||||||
|
|
||||||
|
screen.at(box_.x_min, box_.y_min) = charset[0];
|
||||||
|
screen.at(box_.x_max, box_.y_min) = charset[1];
|
||||||
|
screen.at(box_.x_min, box_.y_max) = charset[2];
|
||||||
|
screen.at(box_.x_max, box_.y_max) = charset[3];
|
||||||
|
for(float x = box_.x_min + 1; x<box_.x_max; ++x) {
|
||||||
|
screen.at(x, box_.y_min) = charset[4];
|
||||||
|
screen.at(x, box_.y_max) = charset[4];
|
||||||
|
}
|
||||||
|
for(float y = box_.y_min + 1; y<box_.y_max; ++y) {
|
||||||
|
screen.at(box_.x_min, y) = charset[5];
|
||||||
|
screen.at(box_.x_max,y) = charset[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw title.
|
||||||
|
if (children.size() == 2)
|
||||||
|
children[1]->Render(screen);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<Node> border(Element child) {
|
||||||
|
return std::make_unique<Border>(unpack(std::move(child)));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Node> window(Element title, Element content) {
|
||||||
|
return std::make_unique<Border>(unpack(std::move(content), std::move(title)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Decorator boxed() {
|
||||||
|
return [](Element child) {
|
||||||
|
return border(std::move(child));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // namespace ftxui
|
@ -9,8 +9,8 @@ class BgColor : public NodeDecorator {
|
|||||||
: NodeDecorator(std::move(children)), color_(color) {}
|
: NodeDecorator(std::move(children)), color_(color) {}
|
||||||
|
|
||||||
void Render(Screen& screen) override {
|
void Render(Screen& screen) override {
|
||||||
for (int y = box_.top; y <= box_.bottom; ++y) {
|
for (int y = box_.y_min; y <= box_.y_max; ++y) {
|
||||||
for (int x = box_.left; x <= box_.right; ++x) {
|
for (int x = box_.x_min; x <= box_.x_max; ++x) {
|
||||||
screen.PixelAt(x, y).background_color = color_;
|
screen.PixelAt(x, y).background_color = color_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -27,8 +27,8 @@ class FgColor : public NodeDecorator {
|
|||||||
~FgColor() override {}
|
~FgColor() override {}
|
||||||
|
|
||||||
void Render(Screen& screen) override {
|
void Render(Screen& screen) override {
|
||||||
for (int y = box_.top; y <= box_.bottom; ++y) {
|
for (int y = box_.y_min; y <= box_.y_max; ++y) {
|
||||||
for (int x = box_.left; x <= box_.right; ++x) {
|
for (int x = box_.x_min; x <= box_.x_max; ++x) {
|
||||||
screen.PixelAt(x, y).foreground_color = color_;
|
screen.PixelAt(x, y).foreground_color = color_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,11 @@ class DBox : public Node {
|
|||||||
child->ComputeRequirement();
|
child->ComputeRequirement();
|
||||||
requirement_.min.x = std::max(requirement_.min.x, child->requirement().min.x);
|
requirement_.min.x = std::max(requirement_.min.x, child->requirement().min.x);
|
||||||
requirement_.min.y = std::max(requirement_.min.y, child->requirement().min.y);
|
requirement_.min.y = std::max(requirement_.min.y, child->requirement().min.y);
|
||||||
|
|
||||||
|
if (requirement_.selection < child->requirement().selection) {
|
||||||
|
requirement_.selection = child->requirement().selection;
|
||||||
|
requirement_.selected_box = child->requirement().selected_box;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@ class Dim : public NodeDecorator {
|
|||||||
|
|
||||||
void Render(Screen& screen) override {
|
void Render(Screen& screen) override {
|
||||||
Node::Render(screen);
|
Node::Render(screen);
|
||||||
for (int y = box_.top; y <= box_.bottom; ++y) {
|
for (int y = box_.y_min; y <= box_.y_max; ++y) {
|
||||||
for (int x = box_.left; x <= box_.right; ++x) {
|
for (int x = box_.x_min; x <= box_.x_max; ++x) {
|
||||||
screen.PixelAt(x,y).dim = true;
|
screen.PixelAt(x,y).dim = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,69 +1,116 @@
|
|||||||
#include "ftxui/dom/node.hpp"
|
|
||||||
#include "ftxui/dom/elements.hpp"
|
#include "ftxui/dom/elements.hpp"
|
||||||
|
#include "ftxui/dom/node.hpp"
|
||||||
|
#include "ftxui/util/autoreset.hpp"
|
||||||
|
|
||||||
namespace ftxui {
|
namespace ftxui {
|
||||||
|
|
||||||
using namespace ftxui;
|
using namespace ftxui;
|
||||||
|
|
||||||
static wchar_t charset[] = L"┌┐└┘─│┬┴┤├";
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
class Frame : public Node {
|
class Select : public Node {
|
||||||
public:
|
public:
|
||||||
Frame(Elements children) : Node(std::move(children)) {}
|
Select(std::vector<std::unique_ptr<Node>> children)
|
||||||
~Frame() override {}
|
: Node(std::move(children)) {}
|
||||||
|
|
||||||
|
void ComputeRequirement() override {
|
||||||
|
Node::ComputeRequirement();
|
||||||
|
requirement_ = children[0]->requirement();
|
||||||
|
auto& selected_box = requirement_.selected_box;
|
||||||
|
selected_box.x_min = 0;
|
||||||
|
selected_box.y_min = 0;
|
||||||
|
selected_box.x_max = requirement_.min.x;
|
||||||
|
selected_box.y_max = requirement_.min.y;
|
||||||
|
requirement_.selection = Requirement::SELECTED;
|
||||||
|
};
|
||||||
|
|
||||||
|
void SetBox(Box box) override {
|
||||||
|
box_ = box;
|
||||||
|
children[0]->SetBox(box);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<Node> select(Element child) {
|
||||||
|
return std::make_unique<Select>(unpack(std::move(child)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class Focus : public Select {
|
||||||
|
public:
|
||||||
|
Focus(std::vector<std::unique_ptr<Node>> children)
|
||||||
|
: Select(std::move(children)) {}
|
||||||
|
|
||||||
|
void ComputeRequirement() override {
|
||||||
|
Select::ComputeRequirement();
|
||||||
|
requirement_.selection = Requirement::FOCUSED;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<Node> focus(Element child) {
|
||||||
|
return std::make_unique<Focus>(unpack(std::move(child)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class Frame : public Node {
|
||||||
|
public:
|
||||||
|
Frame(std::vector<std::unique_ptr<Node>> children)
|
||||||
|
: Node(std::move(children)) {}
|
||||||
|
|
||||||
void ComputeRequirement() override {
|
void ComputeRequirement() override {
|
||||||
Node::ComputeRequirement();
|
Node::ComputeRequirement();
|
||||||
requirement_ = children[0]->requirement();
|
requirement_ = children[0]->requirement();
|
||||||
requirement_.min.x += 2;
|
|
||||||
requirement_.min.y += 2;
|
|
||||||
if (children.size() == 2) {
|
|
||||||
requirement_.min.x =
|
|
||||||
std::max(requirement_.min.x, children[1]->requirement().min.x + 2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetBox(Box box) override {
|
void SetBox(Box box) override {
|
||||||
Node::SetBox(box);
|
Node::SetBox(box);
|
||||||
if (children.size() == 2) {
|
|
||||||
Box title_box;
|
int external_dimx = box.x_max - box.x_min;
|
||||||
title_box.left = box.left + 1;
|
int external_dimy = box.y_max - box.y_min;
|
||||||
title_box.right = box.right - 1;
|
|
||||||
title_box.top = box.top;
|
int internal_dimx = std::max(requirement_.min.x, external_dimx);
|
||||||
title_box.bottom = box.top;
|
int internal_dimy = std::max(requirement_.min.y, external_dimy);
|
||||||
children[1]->SetBox(title_box);
|
|
||||||
}
|
auto& selected_box = requirement_.selected_box;
|
||||||
box.left++;
|
int focused_dimx = selected_box.x_max - selected_box.x_min;
|
||||||
box.right--;
|
int focused_dimy = selected_box.y_max - selected_box.y_min;
|
||||||
box.top++;
|
int dx = selected_box.x_min - external_dimx / 2 + focused_dimx / 2;
|
||||||
box.bottom--;
|
int dy = selected_box.y_min - external_dimy / 2 + focused_dimy / 2;
|
||||||
children[0]->SetBox(box);
|
dx = std::max(0, std::min(internal_dimx - external_dimx - 1, dx));
|
||||||
|
dy = std::max(0, std::min(internal_dimy - external_dimy - 1, dy));
|
||||||
|
|
||||||
|
Box children_box = box;
|
||||||
|
children_box.x_min = box.x_min - dx;
|
||||||
|
children_box.y_min = box.y_min - dy;
|
||||||
|
children_box.x_max = box.x_min + internal_dimx - dx;
|
||||||
|
children_box.y_max = box.y_min + internal_dimy - dy;
|
||||||
|
children[0]->SetBox(children_box);
|
||||||
|
|
||||||
|
// int dx = box.x_max - box.x_min;
|
||||||
|
// int dy = box.y_max - box.y_min;
|
||||||
|
// int cdx = std::min(children[0].requirement().min.x
|
||||||
|
|
||||||
|
// Box children_box;
|
||||||
|
// children_box.x_min =
|
||||||
|
// if (box.x_max - box.x_min >= children[0].requirement().min.x && //
|
||||||
|
|
||||||
|
// box.y_max - box.y_min >= children[0].requirement().min.y) {
|
||||||
|
// children_[0]->SetBox(box);
|
||||||
|
// dx = 0;
|
||||||
|
// dy = 0;
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
|
||||||
|
// Box children_box;
|
||||||
|
// children_box.x_min = box.x_min;
|
||||||
|
// children_box.y_min = box.x_min;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Render(Screen& screen) override {
|
void Render(Screen& screen) override {
|
||||||
// Draw content.
|
AutoReset<Box> stencil(&screen.stencil,
|
||||||
|
Box::Intersection(box_, screen.stencil));
|
||||||
children[0]->Render(screen);
|
children[0]->Render(screen);
|
||||||
|
|
||||||
// Draw the frame.
|
|
||||||
if (box_.left >= box_.right || box_.top >= box_.bottom)
|
|
||||||
return;
|
|
||||||
|
|
||||||
screen.at(box_.left, box_.top) = charset[0];
|
|
||||||
screen.at(box_.right, box_.top) = charset[1];
|
|
||||||
screen.at(box_.left, box_.bottom) = charset[2];
|
|
||||||
screen.at(box_.right, box_.bottom) = charset[3];
|
|
||||||
for(float x = box_.left + 1; x<box_.right; ++x) {
|
|
||||||
screen.at(x, box_.top) = charset[4];
|
|
||||||
screen.at(x, box_.bottom) = charset[4];
|
|
||||||
}
|
|
||||||
for(float y = box_.top + 1; y<box_.bottom; ++y) {
|
|
||||||
screen.at(box_.left, y) = charset[5];
|
|
||||||
screen.at(box_.right,y) = charset[5];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw title.
|
|
||||||
if (children.size() == 2)
|
|
||||||
children[1]->Render(screen);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -71,14 +118,4 @@ std::unique_ptr<Node> frame(Element child) {
|
|||||||
return std::make_unique<Frame>(unpack(std::move(child)));
|
return std::make_unique<Frame>(unpack(std::move(child)));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Node> window(Element title, Element content) {
|
|
||||||
return std::make_unique<Frame>(unpack(std::move(content), std::move(title)));
|
|
||||||
}
|
|
||||||
|
|
||||||
Decorator boxed() {
|
|
||||||
return [](Element child) {
|
|
||||||
return frame(std::move(child));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // namespace ftxui
|
}; // namespace ftxui
|
||||||
|
@ -18,14 +18,14 @@ class Gauge : public Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Render(Screen& screen) override {
|
void Render(Screen& screen) override {
|
||||||
float y = box_.top;
|
float y = box_.y_min;
|
||||||
float limit = box_.left + progress_ * (box_.right - box_.left + 1);
|
float limit = box_.x_min + progress_ * (box_.x_max - box_.x_min + 1);
|
||||||
int limit_int = limit;
|
int limit_int = limit;
|
||||||
int x = box_.left;
|
int x = box_.x_min;
|
||||||
while (x < limit_int)
|
while (x < limit_int)
|
||||||
screen.at(x++, y) = charset[9];
|
screen.at(x++, y) = charset[9];
|
||||||
screen.at(x++, y) = charset[int(9*(limit-limit_int))];
|
screen.at(x++, y) = charset[int(9*(limit-limit_int))];
|
||||||
while (x <= box_.right)
|
while (x <= box_.x_max)
|
||||||
screen.at(x++, y) = charset[0];
|
screen.at(x++, y) = charset[0];
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
@ -15,6 +15,12 @@ class HBox : public Node {
|
|||||||
requirement_.flex.y = 0;
|
requirement_.flex.y = 0;
|
||||||
for (auto& child : children) {
|
for (auto& child : children) {
|
||||||
child->ComputeRequirement();
|
child->ComputeRequirement();
|
||||||
|
if (requirement_.selection < child->requirement().selection) {
|
||||||
|
requirement_.selection = child->requirement().selection;
|
||||||
|
requirement_.selected_box = child->requirement().selected_box;
|
||||||
|
requirement_.selected_box.x_min += requirement_.min.x;
|
||||||
|
requirement_.selected_box.x_max += requirement_.min.x;
|
||||||
|
}
|
||||||
requirement_.min.x += child->requirement().min.x;
|
requirement_.min.x += child->requirement().min.x;
|
||||||
requirement_.min.y =
|
requirement_.min.y =
|
||||||
std::max(requirement_.min.y, child->requirement().min.y);
|
std::max(requirement_.min.y, child->requirement().min.y);
|
||||||
@ -28,33 +34,33 @@ class HBox : public Node {
|
|||||||
for (auto& child : children)
|
for (auto& child : children)
|
||||||
flex_sum += child->requirement().flex.x;
|
flex_sum += child->requirement().flex.x;
|
||||||
|
|
||||||
int space = box.right - box.left + 1;
|
int space = box.x_max - box.x_min + 1;
|
||||||
int extra_space = space - requirement_.min.x;
|
int extra_space = space - requirement_.min.x;
|
||||||
|
|
||||||
int remaining_flex = flex_sum;
|
int remaining_flex = flex_sum;
|
||||||
int remaining_extra_space = extra_space;
|
int remaining_extra_space = extra_space;
|
||||||
|
|
||||||
int x = box.left;
|
int x = box.x_min;
|
||||||
for (auto& child : children) {
|
for (auto& child : children) {
|
||||||
if (x > box.right)
|
if (x > box.x_max)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
Box child_box = box;
|
Box child_box = box;
|
||||||
child_box.left = x;
|
child_box.x_min = x;
|
||||||
|
|
||||||
child_box.right = x + child->requirement().min.x - 1;
|
child_box.x_max = x + child->requirement().min.x - 1;
|
||||||
|
|
||||||
if (child->requirement().flex.x && remaining_extra_space > 0) {
|
if (child->requirement().flex.x && remaining_extra_space > 0) {
|
||||||
int added_space = remaining_extra_space * child->requirement().flex.x /
|
int added_space = remaining_extra_space * child->requirement().flex.x /
|
||||||
remaining_flex;
|
remaining_flex;
|
||||||
remaining_extra_space -= added_space;
|
remaining_extra_space -= added_space;
|
||||||
remaining_flex -= child->requirement().flex.x;
|
remaining_flex -= child->requirement().flex.x;
|
||||||
child_box.right += added_space;
|
child_box.x_max += added_space;
|
||||||
}
|
}
|
||||||
child_box.right = std::min(child_box.right, box.right);
|
child_box.x_max = std::min(child_box.x_max, box.x_max);
|
||||||
|
|
||||||
child->SetBox(child_box);
|
child->SetBox(child_box);
|
||||||
x = child_box.right + 1;
|
x = child_box.x_max + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -12,8 +12,8 @@ class Inverted : public NodeDecorator {
|
|||||||
|
|
||||||
void Render(Screen& screen) override {
|
void Render(Screen& screen) override {
|
||||||
Node::Render(screen);
|
Node::Render(screen);
|
||||||
for (int y = box_.top; y <= box_.bottom; ++y) {
|
for (int y = box_.y_min; y <= box_.y_max; ++y) {
|
||||||
for (int x = box_.left; x <= box_.right; ++x) {
|
for (int x = box_.x_min; x <= box_.x_max; ++x) {
|
||||||
screen.PixelAt(x,y).inverted = true;
|
screen.PixelAt(x,y).inverted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,13 +28,14 @@ void Render(Screen& screen, Node* node) {
|
|||||||
node->ComputeRequirement();
|
node->ComputeRequirement();
|
||||||
|
|
||||||
Box box;
|
Box box;
|
||||||
box.left = 0;
|
box.x_min = 0;
|
||||||
box.top = 0;
|
box.y_min = 0;
|
||||||
box.right = screen.dimx() - 1;
|
box.x_max = screen.dimx() - 1;
|
||||||
box.bottom = screen.dimy() - 1;
|
box.y_max = screen.dimy() - 1;
|
||||||
|
|
||||||
// Step 2: Assign a dimension to the element.
|
// Step 2: Assign a dimension to the element.
|
||||||
node->SetBox(box);
|
node->SetBox(box);
|
||||||
|
screen.stencil = box;
|
||||||
|
|
||||||
// Step 3: Draw the element.
|
// Step 3: Draw the element.
|
||||||
node->Render(screen);
|
node->Render(screen);
|
||||||
|
@ -14,8 +14,8 @@ class Separator : public Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Render(Screen& screen) override {
|
void Render(Screen& screen) override {
|
||||||
bool is_column = (box_.right == box_.left);
|
bool is_column = (box_.x_max == box_.x_min);
|
||||||
bool is_line = (box_.top == box_.bottom);
|
bool is_line = (box_.y_min == box_.y_max);
|
||||||
|
|
||||||
wchar_t c = U'+';
|
wchar_t c = U'+';
|
||||||
if (is_line && !is_column)
|
if (is_line && !is_column)
|
||||||
@ -23,8 +23,8 @@ class Separator : public Node {
|
|||||||
else
|
else
|
||||||
c = U'│';
|
c = U'│';
|
||||||
|
|
||||||
for (int y = box_.top; y <= box_.bottom; ++y) {
|
for (int y = box_.y_min; y <= box_.y_max; ++y) {
|
||||||
for (int x = box_.left; x <= box_.right; ++x) {
|
for (int x = box_.x_min; x <= box_.x_max; ++x) {
|
||||||
screen.at(x, y) = c;
|
screen.at(x, y) = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ class Size : public Node {
|
|||||||
~Size() override {}
|
~Size() override {}
|
||||||
void ComputeRequirement() override {
|
void ComputeRequirement() override {
|
||||||
Node::ComputeRequirement();
|
Node::ComputeRequirement();
|
||||||
|
requirement_ = children[0]->requirement();
|
||||||
requirement_.min.x = width_;
|
requirement_.min.x = width_;
|
||||||
requirement_.min.y = height_;
|
requirement_.min.y = height_;
|
||||||
requirement_.flex.x = 0;
|
requirement_.flex.x = 0;
|
||||||
|
@ -15,12 +15,12 @@ class Text : public Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Render(Screen& screen) override {
|
void Render(Screen& screen) override {
|
||||||
int x = box_.left;
|
int x = box_.x_min;
|
||||||
int y = box_.top;
|
int y = box_.y_min;
|
||||||
if (y > box_.bottom)
|
if (y > box_.y_max)
|
||||||
return;
|
return;
|
||||||
for (wchar_t c : text_) {
|
for (wchar_t c : text_) {
|
||||||
if (x > box_.right)
|
if (x > box_.x_max)
|
||||||
return;
|
return;
|
||||||
screen.at(x++, y) = c;
|
screen.at(x++, y) = c;
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,8 @@ class Underlined : public NodeDecorator {
|
|||||||
|
|
||||||
void Render(Screen& screen) override {
|
void Render(Screen& screen) override {
|
||||||
Node::Render(screen);
|
Node::Render(screen);
|
||||||
for (int y = box_.top; y <= box_.bottom; ++y) {
|
for (int y = box_.y_min; y <= box_.y_max; ++y) {
|
||||||
for (int x = box_.left; x <= box_.right; ++x) {
|
for (int x = box_.x_min; x <= box_.x_max; ++x) {
|
||||||
screen.PixelAt(x, y).underlined = true;
|
screen.PixelAt(x, y).underlined = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,12 @@ class VBox : public Node {
|
|||||||
requirement_.flex.y = 1;
|
requirement_.flex.y = 1;
|
||||||
for (auto& child : children) {
|
for (auto& child : children) {
|
||||||
child->ComputeRequirement();
|
child->ComputeRequirement();
|
||||||
|
if (requirement_.selection < child->requirement().selection) {
|
||||||
|
requirement_.selection = child->requirement().selection;
|
||||||
|
requirement_.selected_box = child->requirement().selected_box;
|
||||||
|
requirement_.selected_box.y_min += requirement_.min.y;
|
||||||
|
requirement_.selected_box.y_max += requirement_.min.y;
|
||||||
|
}
|
||||||
requirement_.min.y += child->requirement().min.y;
|
requirement_.min.y += child->requirement().min.y;
|
||||||
requirement_.min.x =
|
requirement_.min.x =
|
||||||
std::max(requirement_.min.x, child->requirement().min.x);
|
std::max(requirement_.min.x, child->requirement().min.x);
|
||||||
@ -28,33 +34,33 @@ class VBox : public Node {
|
|||||||
for (auto& child : children)
|
for (auto& child : children)
|
||||||
flex_sum += child->requirement().flex.y;
|
flex_sum += child->requirement().flex.y;
|
||||||
|
|
||||||
int space = box.bottom - box.top + 1;
|
int space = box.y_max - box.y_min + 1;
|
||||||
int extra_space = space - requirement_.min.y;
|
int extra_space = space - requirement_.min.y;
|
||||||
|
|
||||||
int remaining_flex = flex_sum;
|
int remaining_flex = flex_sum;
|
||||||
int remaining_extra_space = extra_space;
|
int remaining_extra_space = extra_space;
|
||||||
|
|
||||||
int y = box.top;
|
int y = box.y_min;
|
||||||
for (auto& child : children) {
|
for (auto& child : children) {
|
||||||
if (y > box.bottom)
|
if (y > box.y_max)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
Box child_box = box;
|
Box child_box = box;
|
||||||
child_box.top = y;
|
child_box.y_min = y;
|
||||||
|
|
||||||
child_box.bottom = y + child->requirement().min.y - 1;
|
child_box.y_max = y + child->requirement().min.y - 1;
|
||||||
|
|
||||||
if (child->requirement().flex.y && remaining_extra_space > 0) {
|
if (child->requirement().flex.y && remaining_extra_space > 0) {
|
||||||
int added_space = remaining_extra_space * child->requirement().flex.y /
|
int added_space = remaining_extra_space * child->requirement().flex.y /
|
||||||
remaining_flex;
|
remaining_flex;
|
||||||
remaining_extra_space -= added_space;
|
remaining_extra_space -= added_space;
|
||||||
remaining_flex -= child->requirement().flex.y;
|
remaining_flex -= child->requirement().flex.y;
|
||||||
child_box.bottom += added_space;
|
child_box.y_max += added_space;
|
||||||
}
|
}
|
||||||
child_box.bottom = std::min(child_box.bottom, box.bottom);
|
child_box.y_max = std::min(child_box.y_max, box.y_max);
|
||||||
|
|
||||||
child->SetBox(child_box);
|
child->SetBox(child_box);
|
||||||
y = child_box.bottom + 1;
|
y = child_box.y_max + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
14
ftxui/src/ftxui/screen/box.cpp
Normal file
14
ftxui/src/ftxui/screen/box.cpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include "ftxui/screen/box.hpp"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace ftxui {
|
||||||
|
// static
|
||||||
|
Box Box::Intersection(Box a, Box b) {
|
||||||
|
return Box{
|
||||||
|
std::max(a.x_min, b.x_min),
|
||||||
|
std::min(a.x_max, b.x_max),
|
||||||
|
std::max(a.y_min, b.y_min),
|
||||||
|
std::min(a.y_max, b.y_max),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} // namespace ftxui
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
namespace ftxui {
|
namespace ftxui {
|
||||||
|
|
||||||
|
namespace {
|
||||||
static const wchar_t* BOLD_SET = L"\e[1m";
|
static const wchar_t* BOLD_SET = L"\e[1m";
|
||||||
static const wchar_t* BOLD_RESET = L"\e[22m"; // Can't use 21 here.
|
static const wchar_t* BOLD_RESET = L"\e[22m"; // Can't use 21 here.
|
||||||
|
|
||||||
@ -26,8 +27,20 @@ static const char* MOVE_LEFT = "\r";
|
|||||||
static const char* MOVE_UP = "\e[1A";
|
static const char* MOVE_UP = "\e[1A";
|
||||||
static const char* CLEAR_LINE = "\e[2K";
|
static const char* CLEAR_LINE = "\e[2K";
|
||||||
|
|
||||||
|
bool In(const Box& stencil, int x, int y) {
|
||||||
|
return stencil.x_min <= x && x <= stencil.x_max && //
|
||||||
|
stencil.y_min <= y && y <= stencil.y_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pixel dev_null_pixel;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
Screen::Screen(size_t dimx, size_t dimy)
|
Screen::Screen(size_t dimx, size_t dimy)
|
||||||
: dimx_(dimx), dimy_(dimy), pixels_(dimy, std::vector<Pixel>(dimx)) {}
|
: stencil({0, int(dimx) - 1, 0, int(dimy) - 1}),
|
||||||
|
dimx_(dimx),
|
||||||
|
dimy_(dimy),
|
||||||
|
pixels_(dimy, std::vector<Pixel>(dimx)) {}
|
||||||
|
|
||||||
void UpdatePixelStyle(std::wstringstream& ss, Pixel& previous, Pixel& next) {
|
void UpdatePixelStyle(std::wstringstream& ss, Pixel& previous, Pixel& next) {
|
||||||
if (next.bold != previous.bold)
|
if (next.bold != previous.bold)
|
||||||
@ -76,11 +89,11 @@ std::string Screen::ToString() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
wchar_t& Screen::at(size_t x, size_t y) {
|
wchar_t& Screen::at(size_t x, size_t y) {
|
||||||
return pixels_[y][x].character;
|
return PixelAt(x,y).character;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pixel& Screen::PixelAt(size_t x, size_t y) {
|
Pixel& Screen::PixelAt(size_t x, size_t y) {
|
||||||
return pixels_[y][x];
|
return In(stencil, x, y) ? pixels_[y][x] : dev_null_pixel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
62
tutorial.md
62
tutorial.md
@ -5,7 +5,7 @@
|
|||||||
+ [Examples](#examples)
|
+ [Examples](#examples)
|
||||||
* [Widget.](#widget)
|
* [Widget.](#widget)
|
||||||
+ [text](#text)
|
+ [text](#text)
|
||||||
+ [frame](#frame)
|
+ [border](#border)
|
||||||
+ [separator](#separator)
|
+ [separator](#separator)
|
||||||
+ [gauge](#gauge)
|
+ [gauge](#gauge)
|
||||||
* [Decorator](#decorator)
|
* [Decorator](#decorator)
|
||||||
@ -27,21 +27,11 @@ All the dom element are declared in one header:
|
|||||||
It declares the following set of elements:
|
It declares the following set of elements:
|
||||||
|
|
||||||
~~~cpp
|
~~~cpp
|
||||||
// --- Layout ----
|
// --- Widget ---
|
||||||
Element vbox(Elements);
|
|
||||||
Element hbox(Elements);
|
|
||||||
Element dbox(Elements);
|
|
||||||
|
|
||||||
// -- Flexibility --
|
|
||||||
Element filler();
|
|
||||||
Element flex(Element);
|
|
||||||
Decorator size(size_t width, size_t height);
|
|
||||||
|
|
||||||
// --- Widget --
|
|
||||||
Element text(std::wstring text);
|
Element text(std::wstring text);
|
||||||
Element separator();
|
Element separator();
|
||||||
Element gauge(float ratio);
|
Element gauge(float ratio);
|
||||||
Element frame(Element);
|
Element border(Element);
|
||||||
Element window(Element title, Element content);
|
Element window(Element title, Element content);
|
||||||
Element spinner(int charset_index, size_t image_index);
|
Element spinner(int charset_index, size_t image_index);
|
||||||
|
|
||||||
@ -51,19 +41,37 @@ Element dim(Element);
|
|||||||
Element inverted(Element);
|
Element inverted(Element);
|
||||||
Element underlined(Element);
|
Element underlined(Element);
|
||||||
Element blink(Element);
|
Element blink(Element);
|
||||||
|
|
||||||
Decorator color(Color);
|
Decorator color(Color);
|
||||||
Decorator bgcolor(Color);
|
Decorator bgcolor(Color);
|
||||||
Element color(Color, Element);
|
Element color(Color, Element);
|
||||||
Element bgcolor(Color, Element);
|
Element bgcolor(Color, Element);
|
||||||
|
|
||||||
// --- Util ---
|
// --- Layout ---
|
||||||
|
// Horizontal, Vertical or stacked set of elements.
|
||||||
|
Element vbox(Elements);
|
||||||
|
Element hbox(Elements);
|
||||||
|
Element dbox(Elements);
|
||||||
|
|
||||||
|
// -- Flexibility ---
|
||||||
|
// Define how to share the remaining space when not all of it is used inside a
|
||||||
|
// container.
|
||||||
|
Element filler();
|
||||||
|
Element flex(Element);
|
||||||
|
Decorator size(size_t width, size_t height);
|
||||||
|
|
||||||
|
// --- Frame ---
|
||||||
|
// A frame is a scrollable area. The internal area is potentially larger than
|
||||||
|
// the external one. The internal area is scrolled in order to make visible the
|
||||||
|
// focused element.
|
||||||
|
Element frame(Element);
|
||||||
|
Element focus(Element);
|
||||||
|
Element select(Element);
|
||||||
|
|
||||||
|
// --- Util --------------------------------------------------------------------
|
||||||
Element hcenter(Element);
|
Element hcenter(Element);
|
||||||
Element vcenter(Element);
|
Element vcenter(Element);
|
||||||
Element center(Element);
|
Element center(Element);
|
||||||
Element align_right(Element);
|
Element align_right(Element);
|
||||||
|
|
||||||
// --- Util ---
|
|
||||||
Element nothing(Element element);
|
Element nothing(Element element);
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
@ -98,9 +106,9 @@ container.
|
|||||||
#### Examples
|
#### Examples
|
||||||
~~~cpp
|
~~~cpp
|
||||||
hbox(
|
hbox(
|
||||||
text(L"left") | frame ,
|
text(L"left") | border ,
|
||||||
text(L"middle") | frame | flex,
|
text(L"middle") | border | flex,
|
||||||
text(L"right") | frame
|
text(L"right") | border
|
||||||
);
|
);
|
||||||
~~~
|
~~~
|
||||||
~~~bash
|
~~~bash
|
||||||
@ -111,9 +119,9 @@ container.
|
|||||||
|
|
||||||
~~~cpp
|
~~~cpp
|
||||||
hbox(
|
hbox(
|
||||||
text(L"left") | frame ,
|
text(L"left") | border ,
|
||||||
text(L"middle") | frame | flex,
|
text(L"middle") | border | flex,
|
||||||
text(L"right") | frame | flex
|
text(L"right") | border | flex
|
||||||
);
|
);
|
||||||
~~~
|
~~~
|
||||||
~~~bash
|
~~~bash
|
||||||
@ -134,10 +142,10 @@ The most simple widget. It display a text.
|
|||||||
I am a piece of text.
|
I am a piece of text.
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
#### frame
|
#### border
|
||||||
Add a border arround an element
|
Add a border arround an element
|
||||||
~~~cpp
|
~~~cpp
|
||||||
frame(text(L"The element"))
|
border(text(L"The element"))
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
~~~bash
|
~~~bash
|
||||||
@ -152,7 +160,7 @@ Display a vertical or horizontal line to visually split the content of a
|
|||||||
container in two.
|
container in two.
|
||||||
|
|
||||||
~~~cpp
|
~~~cpp
|
||||||
frame(hbox(
|
border(hbox(
|
||||||
vbox(
|
vbox(
|
||||||
text(L"left top"),
|
text(L"left top"),
|
||||||
text(L"left bottom")
|
text(L"left bottom")
|
||||||
@ -176,7 +184,7 @@ frame(hbox(
|
|||||||
|
|
||||||
A gauge. It can be used to represent a progress bar.
|
A gauge. It can be used to represent a progress bar.
|
||||||
~~~c+
|
~~~c+
|
||||||
frame(gauge(0.5))
|
border(gauge(0.5))
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
~~~bash
|
~~~bash
|
||||||
|
Loading…
Reference in New Issue
Block a user