mirror of
				https://github.com/ArthurSonzogni/FTXUI.git
				synced 2025-11-04 13:38:14 +08:00 
			
		
		
		
	Add Graph.
This commit is contained in:
		@@ -73,7 +73,7 @@ class MyComponent : public Component {
 | 
			
		||||
        separator(),
 | 
			
		||||
        Render(L"radiobox", radiobox),
 | 
			
		||||
        separator(),
 | 
			
		||||
        Render(L"input", input) | size(WIDTH, EQUAL, 20)
 | 
			
		||||
        Render(L"input", input) | size(WIDTH, LESS_THAN, 30)
 | 
			
		||||
      ) | border;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ example(border)
 | 
			
		||||
example(gauge)
 | 
			
		||||
example(package_manager)
 | 
			
		||||
example(separator)
 | 
			
		||||
example(graph)
 | 
			
		||||
example(spinner)
 | 
			
		||||
example(style_blink)
 | 
			
		||||
example(style_bold)
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,7 @@ int main(int argc, const char *argv[])
 | 
			
		||||
      ),
 | 
			
		||||
      filler()
 | 
			
		||||
    );
 | 
			
		||||
  auto screen = Screen::TerminalOutput(document);
 | 
			
		||||
  auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
 | 
			
		||||
  Render(screen, document.get());
 | 
			
		||||
  std::cout << screen.ToString() << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ int main(int argc, const char *argv[])
 | 
			
		||||
      ) | border,
 | 
			
		||||
      text(L"overlay") | border | center
 | 
			
		||||
    );
 | 
			
		||||
  auto screen = Screen::TerminalOutput(document);
 | 
			
		||||
  auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
 | 
			
		||||
  Render(screen, document.get());
 | 
			
		||||
 | 
			
		||||
  std::cout << screen.ToString();
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										65
									
								
								examples/dom/graph.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								examples/dom/graph.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
#include "ftxui/dom/elements.hpp"
 | 
			
		||||
#include "ftxui/dom/graph.hpp"
 | 
			
		||||
#include "ftxui/screen/screen.hpp"
 | 
			
		||||
#include "ftxui/screen/string.hpp"
 | 
			
		||||
#include <chrono>
 | 
			
		||||
#include <cmath>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <thread>
 | 
			
		||||
 | 
			
		||||
class Graph : public ftxui::GraphFunction {
 | 
			
		||||
 public:
 | 
			
		||||
  std::vector<int> operator()(int width, int height) {
 | 
			
		||||
    std::vector<int> output(width);
 | 
			
		||||
    for (int i = 0; i < width; ++i) {
 | 
			
		||||
      float v = 0;
 | 
			
		||||
      v += 0.1 * sin((i + shift) * 0.1);
 | 
			
		||||
      v += 0.2 * sin((i + shift+10) * 0.15);
 | 
			
		||||
      v += 0.1 * sin((i + shift) * 0.03);
 | 
			
		||||
      // v += 0.2*sin((i+shift)*0.3);
 | 
			
		||||
      // v += 0.1*sin((i+shift)*0.9);
 | 
			
		||||
      v *= height;
 | 
			
		||||
      v += 0.5 * height;
 | 
			
		||||
      output[i] = v;
 | 
			
		||||
    }
 | 
			
		||||
    return output;
 | 
			
		||||
  }
 | 
			
		||||
  int shift = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main(int argc, const char* argv[]) {
 | 
			
		||||
  using namespace ftxui;
 | 
			
		||||
  using namespace std::chrono_literals;
 | 
			
		||||
 | 
			
		||||
  Graph my_graph;
 | 
			
		||||
 | 
			
		||||
  std::string reset_position;
 | 
			
		||||
  for (int i = 0;; ++i) {
 | 
			
		||||
    auto document =
 | 
			
		||||
      window(text(L"Your graphs"),
 | 
			
		||||
        hbox(
 | 
			
		||||
          vbox(
 | 
			
		||||
            graph(my_graph), separator(),
 | 
			
		||||
            graph(my_graph) | inverted
 | 
			
		||||
          ) | flex,
 | 
			
		||||
          separator(),
 | 
			
		||||
          vbox(
 | 
			
		||||
            graph(my_graph) | color(Color::BlueLight), separator(),
 | 
			
		||||
            graph(my_graph) | color(Color::RedLight), separator(),
 | 
			
		||||
            graph(my_graph) | color(Color::YellowLight)
 | 
			
		||||
          ) | flex
 | 
			
		||||
        )
 | 
			
		||||
      ) | size(HEIGHT, GREATER_THAN, 40);
 | 
			
		||||
 | 
			
		||||
    auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
 | 
			
		||||
    Render(screen, document.get());
 | 
			
		||||
    std::cout << reset_position << screen.ToString() << std::flush;
 | 
			
		||||
 | 
			
		||||
    reset_position = screen.ResetPosition();
 | 
			
		||||
 | 
			
		||||
    std::this_thread::sleep_for(0.03s);
 | 
			
		||||
    my_graph.shift++;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -43,7 +43,7 @@ int main(int argc, const char *argv[])
 | 
			
		||||
      | size(WIDTH, LESS_THAN, 50)
 | 
			
		||||
      ;
 | 
			
		||||
 | 
			
		||||
  auto screen = Screen::TerminalOutput(document);
 | 
			
		||||
  auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
 | 
			
		||||
  Render(screen, document.get());
 | 
			
		||||
  std::cout << screen.ToString() << std::endl;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ int main(int argc, const char* argv[]) {
 | 
			
		||||
            paragraph(L" A spinner "), spinner(6, i / 10)) |
 | 
			
		||||
        border;
 | 
			
		||||
 | 
			
		||||
    auto screen = Screen::TerminalFullscreen();
 | 
			
		||||
    auto screen = Screen::Create(Dimension::Full());
 | 
			
		||||
    Render(screen, document.get());
 | 
			
		||||
    std::cout << reset_position << screen.ToString() << std::flush;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -115,7 +115,7 @@ int main(int argc, const char *argv[])
 | 
			
		||||
 | 
			
		||||
    // Draw.
 | 
			
		||||
    auto document = render();
 | 
			
		||||
    auto screen = Screen::TerminalOutput(document);
 | 
			
		||||
    auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
 | 
			
		||||
    Render(screen, document.get());
 | 
			
		||||
    std::cout << reset_position << screen.ToString() << std::flush;
 | 
			
		||||
    reset_position = screen.ResetPosition();
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@ int main(int argc, const char *argv[])
 | 
			
		||||
      ) | flex
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
  auto screen = Screen::TerminalFullscreen();
 | 
			
		||||
  auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
 | 
			
		||||
  Render(screen, document.get());
 | 
			
		||||
  std::cout << screen.ToString();
 | 
			
		||||
  getchar();
 | 
			
		||||
 
 | 
			
		||||
@@ -9,17 +9,18 @@ int main(int argc, const char *argv[])
 | 
			
		||||
    hbox(
 | 
			
		||||
      text(L"left-column"),
 | 
			
		||||
      separator(),
 | 
			
		||||
      flex(vbox(
 | 
			
		||||
        center(text(L"right-column")) | flex,
 | 
			
		||||
      vbox(
 | 
			
		||||
        center(text(L"right-top")) | flex,
 | 
			
		||||
        separator(),
 | 
			
		||||
        center(text(L"bottom-column"))
 | 
			
		||||
      ))
 | 
			
		||||
    );
 | 
			
		||||
  auto screen = Screen::TerminalFullscreen();
 | 
			
		||||
        center(text(L"bottom-bottom"))
 | 
			
		||||
      ) | flex,
 | 
			
		||||
      separator(),
 | 
			
		||||
      text(L"right-column")
 | 
			
		||||
    ) | border;
 | 
			
		||||
  auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
 | 
			
		||||
  Render(screen, document.get());
 | 
			
		||||
 | 
			
		||||
  std::cout << screen.ToString();
 | 
			
		||||
  getchar();
 | 
			
		||||
  std::cout << screen.ToString() << std::endl;
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ int main(int argc, const char *argv[])
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
  auto document = hbox(std::move(content));
 | 
			
		||||
  auto screen = Screen::FitDocument(document);
 | 
			
		||||
  auto screen = Screen::Create(Dimension::Fit(document));
 | 
			
		||||
  Render(screen, document.get());
 | 
			
		||||
  std::cout << screen.ToString() << std::endl;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ int main(int argc, const char *argv[])
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    auto document = hbox(vbox(std::move(entries)) | border, filler());
 | 
			
		||||
    auto screen = Screen::TerminalOutput(document);
 | 
			
		||||
    auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
 | 
			
		||||
    Render(screen, document.get());
 | 
			
		||||
    std::cout << reset_position << screen.ToString() << std::flush;
 | 
			
		||||
    reset_position = screen.ResetPosition();
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ int main(int argc, const char *argv[])
 | 
			
		||||
      text(L"blink") | blink,
 | 
			
		||||
      text(L". Do you like it?")
 | 
			
		||||
    );
 | 
			
		||||
  auto screen = Screen::TerminalOutput(document);
 | 
			
		||||
  auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
 | 
			
		||||
  Render(screen, document.get());
 | 
			
		||||
 | 
			
		||||
  std::cout << screen.ToString();
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ int main(int argc, const char *argv[])
 | 
			
		||||
      text(L"bold") | bold,
 | 
			
		||||
      text(L". Do you like it?")
 | 
			
		||||
    );
 | 
			
		||||
  auto screen = Screen::TerminalOutput(document);
 | 
			
		||||
  auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
 | 
			
		||||
  Render(screen, document.get());
 | 
			
		||||
 | 
			
		||||
  std::cout << screen.ToString();
 | 
			
		||||
 
 | 
			
		||||
@@ -48,7 +48,7 @@ int main(int argc, const char *argv[])
 | 
			
		||||
      filler()
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
  auto screen = Screen::TerminalOutput(document);
 | 
			
		||||
  auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
 | 
			
		||||
  Render(screen, document.get());
 | 
			
		||||
 | 
			
		||||
  std::cout << screen.ToString();
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ int main(int argc, const char *argv[])
 | 
			
		||||
      text(L"dim") | dim,
 | 
			
		||||
      text(L". Do you like it?")
 | 
			
		||||
    );
 | 
			
		||||
  auto screen = Screen::TerminalOutput(document);
 | 
			
		||||
  auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
 | 
			
		||||
  Render(screen, document.get());
 | 
			
		||||
 | 
			
		||||
  std::cout << screen.ToString();
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ int main(int argc, const char *argv[])
 | 
			
		||||
      text(L"color")     | color(Color::Blue)   , text(L" ") ,
 | 
			
		||||
      text(L"bgcolor")   | bgcolor(Color::Blue)
 | 
			
		||||
    );
 | 
			
		||||
  auto screen = Screen::TerminalOutput(document);
 | 
			
		||||
  auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
 | 
			
		||||
  Render(screen, document.get());
 | 
			
		||||
 | 
			
		||||
  std::cout << screen.ToString();
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ int main(int argc, const char *argv[])
 | 
			
		||||
      text(L"inverted") | inverted,
 | 
			
		||||
      text(L". Do you like it?")
 | 
			
		||||
    );
 | 
			
		||||
  auto screen = Screen::TerminalOutput(document);
 | 
			
		||||
  auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
 | 
			
		||||
  Render(screen, document.get());
 | 
			
		||||
 | 
			
		||||
  std::cout << screen.ToString();
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ int main(int argc, const char *argv[])
 | 
			
		||||
      text(L"underlined") | underlined,
 | 
			
		||||
      text(L". Do you like it?")
 | 
			
		||||
    );
 | 
			
		||||
  auto screen = Screen::TerminalOutput(document);
 | 
			
		||||
  auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
 | 
			
		||||
  Render(screen, document.get());
 | 
			
		||||
 | 
			
		||||
  std::cout << screen.ToString();
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@ int main(int argc, const char *argv[])
 | 
			
		||||
        text(L"south-east")
 | 
			
		||||
      )
 | 
			
		||||
    );
 | 
			
		||||
  auto screen = Screen::TerminalFullscreen();
 | 
			
		||||
  auto screen = Screen::Create(Dimension::Full());
 | 
			
		||||
  Render(screen, document.get());
 | 
			
		||||
 | 
			
		||||
  std::cout << screen.ToString();
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@ add_library(dom
 | 
			
		||||
  src/ftxui/dom/flex.cpp
 | 
			
		||||
  src/ftxui/dom/frame.cpp
 | 
			
		||||
  src/ftxui/dom/gauge.cpp
 | 
			
		||||
  src/ftxui/dom/graph.cpp
 | 
			
		||||
  src/ftxui/dom/hbox.cpp
 | 
			
		||||
  src/ftxui/dom/hflow.cpp
 | 
			
		||||
  src/ftxui/dom/inverted.cpp
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ class CheckBox : public Component {
 | 
			
		||||
 | 
			
		||||
  //std::wstring checked = L"[X] ";
 | 
			
		||||
  //std::wstring unchecked = L"[ ] ";
 | 
			
		||||
  std::wstring checked = L"☑ ";
 | 
			
		||||
  std::wstring checked = L"▣ ";
 | 
			
		||||
  std::wstring unchecked = L"☐ ";
 | 
			
		||||
 | 
			
		||||
  Decorator focused_style = inverted;
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ class Component;
 | 
			
		||||
 | 
			
		||||
class ScreenInteractive : public Screen {
 | 
			
		||||
  public:
 | 
			
		||||
    static ScreenInteractive FixedSize(size_t dimx, size_t dimy);
 | 
			
		||||
    static ScreenInteractive FixedSize(int dimx, int dimy);
 | 
			
		||||
    static ScreenInteractive Fullscreen();
 | 
			
		||||
    static ScreenInteractive FitComponent();
 | 
			
		||||
    static ScreenInteractive TerminalOutput();
 | 
			
		||||
@@ -30,7 +30,7 @@ class ScreenInteractive : public Screen {
 | 
			
		||||
     TerminalOutput,
 | 
			
		||||
   };
 | 
			
		||||
   Dimension dimension_ = Dimension::Fixed;
 | 
			
		||||
   ScreenInteractive(size_t dimx, size_t dimy, Dimension dimension);
 | 
			
		||||
   ScreenInteractive(int dimx, int dimy, Dimension dimension);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}  // namespace ftxui
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@
 | 
			
		||||
 | 
			
		||||
#include <functional>
 | 
			
		||||
 | 
			
		||||
#include "ftxui/dom/graph.hpp"
 | 
			
		||||
#include "ftxui/dom/node.hpp"
 | 
			
		||||
#include "ftxui/screen/color.hpp"
 | 
			
		||||
 | 
			
		||||
@@ -20,6 +21,7 @@ Element border(Element);
 | 
			
		||||
Element window(Element title, Element content);
 | 
			
		||||
Element spinner(int charset_index, size_t image_index);
 | 
			
		||||
Elements paragraph(std::wstring text); // Use inside hflow(). Split by space.
 | 
			
		||||
Element graph(GraphFunction&); // See graph.hpp
 | 
			
		||||
 | 
			
		||||
// -- Decorator ---
 | 
			
		||||
Element bold(Element);
 | 
			
		||||
@@ -68,6 +70,7 @@ Element nothing(Element element);
 | 
			
		||||
// Pipe elements into decorator togethers.
 | 
			
		||||
// Examples: text("ftxui") | bold | underlined;
 | 
			
		||||
Element operator|(Element, Decorator);
 | 
			
		||||
Elements operator|(Elements, Decorator);
 | 
			
		||||
Decorator operator|(Decorator, Decorator);
 | 
			
		||||
 | 
			
		||||
// Make container able to take any number of children as input.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								ftxui/include/ftxui/dom/graph.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								ftxui/include/ftxui/dom/graph.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
#ifndef FTXUI_DOM_GRAPH_HPP
 | 
			
		||||
#define FTXUI_DOM_GRAPH_HPP
 | 
			
		||||
 | 
			
		||||
#include "ftxui/dom/elements.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ftxui {
 | 
			
		||||
 | 
			
		||||
class GraphFunction {
 | 
			
		||||
 public:
 | 
			
		||||
  virtual std::vector<int> operator()(int width, int height) = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace ftxui
 | 
			
		||||
 | 
			
		||||
#endif /* end of include guard: FTXUI_DOM_GRAPH_HPP */
 | 
			
		||||
@@ -25,26 +25,32 @@ struct Pixel {
 | 
			
		||||
  Color foreground_color = Color::Default;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Dimension {
 | 
			
		||||
  static Dimension Fixed(int);
 | 
			
		||||
  static Dimension Fit(std::unique_ptr<Node>&);
 | 
			
		||||
  static Dimension Full();
 | 
			
		||||
 | 
			
		||||
  int dimx;
 | 
			
		||||
  int dimy;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class Screen {
 | 
			
		||||
 public:
 | 
			
		||||
  // Constructor.
 | 
			
		||||
  Screen(size_t dimx, size_t dimy);
 | 
			
		||||
 | 
			
		||||
  // Constructor using the terminal.
 | 
			
		||||
  static Screen TerminalFullscreen();
 | 
			
		||||
  static Screen TerminalOutput(std::unique_ptr<Node>& element);
 | 
			
		||||
  static Screen FitDocument(std::unique_ptr<Node>& element);
 | 
			
		||||
  Screen(int dimx, int dimy);
 | 
			
		||||
  static Screen Create(Dimension dimension);
 | 
			
		||||
  static Screen Create(Dimension width, Dimension height);
 | 
			
		||||
 | 
			
		||||
  // Node write into the screen using Screen::at.
 | 
			
		||||
  wchar_t& at(size_t x, size_t y);
 | 
			
		||||
  Pixel& PixelAt(size_t x, size_t y);
 | 
			
		||||
  wchar_t& at(int x, int y);
 | 
			
		||||
  Pixel& PixelAt(int x, int y);
 | 
			
		||||
 | 
			
		||||
  // Convert the screen into a printable string in the terminal.
 | 
			
		||||
  std::string ToString();
 | 
			
		||||
 | 
			
		||||
  // Get screen dimensions.
 | 
			
		||||
  size_t dimx() { return dimx_;}
 | 
			
		||||
  size_t dimy() { return dimy_;}
 | 
			
		||||
  int dimx() { return dimx_;}
 | 
			
		||||
  int dimy() { return dimy_;}
 | 
			
		||||
 | 
			
		||||
  // Move the terminal cursor n-lines up with n = dimy().
 | 
			
		||||
  std::string ResetPosition();
 | 
			
		||||
@@ -56,8 +62,8 @@ class Screen {
 | 
			
		||||
  Box stencil;
 | 
			
		||||
 | 
			
		||||
 protected:
 | 
			
		||||
  size_t dimx_;
 | 
			
		||||
  size_t dimy_;
 | 
			
		||||
  int dimx_;
 | 
			
		||||
  int dimy_;
 | 
			
		||||
  std::vector<std::vector<Pixel>> pixels_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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