mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2025-09-28 17:58:07 +08:00
Add Graph.
This commit is contained in:
@@ -44,14 +44,14 @@ Event GetEvent() {
|
||||
|
||||
}; // namespace
|
||||
|
||||
ScreenInteractive::ScreenInteractive(size_t dimx,
|
||||
size_t dimy,
|
||||
ScreenInteractive::ScreenInteractive(int dimx,
|
||||
int dimy,
|
||||
Dimension dimension)
|
||||
: Screen(dimx, dimy), dimension_(dimension) {}
|
||||
ScreenInteractive::~ScreenInteractive() {}
|
||||
|
||||
// static
|
||||
ScreenInteractive ScreenInteractive::FixedSize(size_t dimx, size_t dimy) {
|
||||
ScreenInteractive ScreenInteractive::FixedSize(int dimx, int dimy) {
|
||||
return ScreenInteractive(dimx, dimy, Dimension::Fixed);
|
||||
}
|
||||
|
||||
@@ -106,8 +106,8 @@ void ScreenInteractive::Loop(Component* component) {
|
||||
|
||||
void ScreenInteractive::Draw(Component* component) {
|
||||
auto document = component->Render();
|
||||
size_t dimx;
|
||||
size_t dimy;
|
||||
int dimx;
|
||||
int dimy;
|
||||
switch (dimension_) {
|
||||
case Dimension::Fixed:
|
||||
dimx = dimx_;
|
||||
|
45
ftxui/src/ftxui/dom/graph.cpp
Normal file
45
ftxui/src/ftxui/dom/graph.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#include "ftxui/dom/elements.hpp"
|
||||
|
||||
namespace ftxui {
|
||||
|
||||
const wchar_t charset[] = L" ▗▐▖▄▟▌▙█";
|
||||
|
||||
class Graph : public Node {
|
||||
public:
|
||||
Graph(GraphFunction& graph_function) : graph_function_(graph_function) {}
|
||||
~Graph() override {}
|
||||
|
||||
void ComputeRequirement() override {
|
||||
requirement_.flex.x = 1;
|
||||
requirement_.flex.y = 1;
|
||||
requirement_.min.x = 1;
|
||||
requirement_.min.y = 1;
|
||||
}
|
||||
|
||||
void Render(Screen& screen) override {
|
||||
int width = (box_.x_max - box_.x_min + 1) * 2;
|
||||
int height = (box_.y_max - box_.y_min + 1) * 2;
|
||||
auto data = graph_function_(width, height);
|
||||
int i = 0;
|
||||
for (int x = box_.x_min; x <= box_.x_max; ++x) {
|
||||
int height_1 = 2 * box_.y_max - data[i++];
|
||||
int height_2 = 2 * box_.y_max - data[i++];
|
||||
for (int y = box_.y_min; y <= box_.y_max; ++y) {
|
||||
int yy = 2 * y;
|
||||
int i_1 = yy < height_1 ? 0 : yy == height_1 ? 3 : 6;
|
||||
int i_2 = yy < height_2 ? 0 : yy == height_2 ? 1 : 2;
|
||||
wchar_t pix = charset[i_1 + i_2];
|
||||
screen.at(x, y) = pix;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
GraphFunction& graph_function_;
|
||||
};
|
||||
|
||||
std::unique_ptr<Node> graph(GraphFunction& graph_function) {
|
||||
return std::make_unique<Graph>(graph_function);
|
||||
}
|
||||
|
||||
}; // namespace ftxui
|
@@ -12,7 +12,7 @@ class HFlow : public Node {
|
||||
requirement_.min.x = 0;
|
||||
requirement_.min.y = 0;
|
||||
requirement_.flex.x = 1;
|
||||
requirement_.flex.y = 0;
|
||||
requirement_.flex.y = 1;
|
||||
for(auto& child : children)
|
||||
child->ComputeRequirement();
|
||||
}
|
||||
|
@@ -19,6 +19,13 @@ Decorator operator|(Decorator a, Decorator b) {
|
||||
return compose(a, b);
|
||||
}
|
||||
|
||||
Elements operator|(Elements es, Decorator d) {
|
||||
Elements output;
|
||||
for (auto& it : es)
|
||||
output.push_back(std::move(it) | d);
|
||||
return output;
|
||||
}
|
||||
|
||||
Element operator|(Element e, Decorator d) {
|
||||
return d(std::move(e));
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#include "ftxui/dom/node.hpp"
|
||||
#include "ftxui/screen/screen.hpp"
|
||||
#include "ftxui/dom/node.hpp"
|
||||
#include "ftxui/screen/string.hpp"
|
||||
#include "ftxui/screen/terminal.hpp"
|
||||
|
||||
@@ -36,8 +36,34 @@ Pixel dev_null_pixel;
|
||||
|
||||
} // namespace
|
||||
|
||||
Screen::Screen(size_t dimx, size_t dimy)
|
||||
: stencil({0, int(dimx) - 1, 0, int(dimy) - 1}),
|
||||
Dimension Dimension::Fixed(int v) {
|
||||
return Dimension{v, v};
|
||||
}
|
||||
|
||||
Dimension Dimension::Fit(std::unique_ptr<Node>& e) {
|
||||
e->ComputeRequirement();
|
||||
Terminal::Dimensions size = Terminal::Size();
|
||||
return Dimension{std::min(e->requirement().min.x, size.dimx),
|
||||
std::min(e->requirement().min.y, size.dimy)};
|
||||
}
|
||||
|
||||
Dimension Dimension::Full() {
|
||||
Terminal::Dimensions size = Terminal::Size();
|
||||
return Dimension{size.dimx, size.dimy};
|
||||
}
|
||||
|
||||
// static
|
||||
Screen Screen::Create(Dimension width, Dimension height) {
|
||||
return Screen(width.dimx, height.dimy);
|
||||
}
|
||||
|
||||
// static
|
||||
Screen Screen::Create(Dimension dimension) {
|
||||
return Screen(dimension.dimx, dimension.dimy);
|
||||
}
|
||||
|
||||
Screen::Screen(int dimx, int dimy)
|
||||
: stencil({0, dimx - 1, 0, dimy - 1}),
|
||||
dimx_(dimx),
|
||||
dimy_(dimy),
|
||||
pixels_(dimy, std::vector<Pixel>(dimx)) {}
|
||||
@@ -72,10 +98,10 @@ std::string Screen::ToString() {
|
||||
|
||||
Pixel previous_pixel;
|
||||
|
||||
for (size_t y = 0; y < dimy_; ++y) {
|
||||
for (int y = 0; y < dimy_; ++y) {
|
||||
if (y != 0)
|
||||
ss << '\n';
|
||||
for (size_t x = 0; x < dimx_; ++x) {
|
||||
for (int x = 0; x < dimx_; ++x) {
|
||||
UpdatePixelStyle(ss, previous_pixel, pixels_[y][x]);
|
||||
ss << pixels_[y][x].character;
|
||||
}
|
||||
@@ -88,42 +114,18 @@ std::string Screen::ToString() {
|
||||
return to_string(ss.str());
|
||||
}
|
||||
|
||||
wchar_t& Screen::at(size_t x, size_t y) {
|
||||
wchar_t& Screen::at(int x, int y) {
|
||||
return PixelAt(x,y).character;
|
||||
}
|
||||
|
||||
Pixel& Screen::PixelAt(size_t x, size_t y) {
|
||||
Pixel& Screen::PixelAt(int x, int y) {
|
||||
return In(stencil, x, y) ? pixels_[y][x] : dev_null_pixel;
|
||||
}
|
||||
|
||||
// static
|
||||
Screen Screen::TerminalFullscreen() {
|
||||
Terminal::Dimensions size = Terminal::Size();
|
||||
return Screen(size.dimx, size.dimy);
|
||||
}
|
||||
|
||||
// static
|
||||
Screen Screen::TerminalOutput(std::unique_ptr<Node>& element) {
|
||||
element->ComputeRequirement();
|
||||
Terminal::Dimensions size = Terminal::Size();
|
||||
return Screen(size.dimx, element->requirement().min.y);
|
||||
}
|
||||
|
||||
// static
|
||||
Screen Screen::FitDocument(std::unique_ptr<Node>& element) {
|
||||
element->ComputeRequirement();
|
||||
Terminal::Dimensions size = Terminal::Size();
|
||||
return
|
||||
Screen(
|
||||
std::min(size.dimx, element->requirement().min.x),
|
||||
std::min(size.dimy, element->requirement().min.y)
|
||||
);
|
||||
}
|
||||
|
||||
std::string Screen::ResetPosition() {
|
||||
std::stringstream ss;
|
||||
ss << MOVE_LEFT << CLEAR_LINE;
|
||||
for (size_t y = 1; y < dimy_; ++y) {
|
||||
for (int y = 1; y < dimy_; ++y) {
|
||||
ss << MOVE_UP << CLEAR_LINE;
|
||||
}
|
||||
return ss.str();
|
||||
@@ -137,8 +139,8 @@ void Screen::Clear() {
|
||||
void Screen::ApplyShader() {
|
||||
|
||||
// Merge box characters togethers.
|
||||
for(size_t y = 1; y<dimy_; ++y) {
|
||||
for(size_t x = 1; x<dimx_; ++x) {
|
||||
for(int y = 1; y<dimy_; ++y) {
|
||||
for(int x = 1; x<dimx_; ++x) {
|
||||
wchar_t& left = at(x - 1, y);
|
||||
wchar_t& top = at(x, y - 1);
|
||||
wchar_t& cur = at(x, y);
|
||||
|
Reference in New Issue
Block a user