mirror of
				https://github.com/ArthurSonzogni/FTXUI.git
				synced 2025-11-01 02:58:12 +08:00 
			
		
		
		
	Add Graph.
This commit is contained in:
		| @@ -73,7 +73,7 @@ class MyComponent : public Component { | |||||||
|         separator(), |         separator(), | ||||||
|         Render(L"radiobox", radiobox), |         Render(L"radiobox", radiobox), | ||||||
|         separator(), |         separator(), | ||||||
|         Render(L"input", input) | size(WIDTH, EQUAL, 20) |         Render(L"input", input) | size(WIDTH, LESS_THAN, 30) | ||||||
|       ) | border; |       ) | border; | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ example(border) | |||||||
| example(gauge) | example(gauge) | ||||||
| example(package_manager) | example(package_manager) | ||||||
| example(separator) | example(separator) | ||||||
|  | example(graph) | ||||||
| example(spinner) | example(spinner) | ||||||
| example(style_blink) | example(style_blink) | ||||||
| example(style_bold) | example(style_bold) | ||||||
|   | |||||||
| @@ -41,7 +41,7 @@ int main(int argc, const char *argv[]) | |||||||
|       ), |       ), | ||||||
|       filler() |       filler() | ||||||
|     ); |     ); | ||||||
|   auto screen = Screen::TerminalOutput(document); |   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||||
|   Render(screen, document.get()); |   Render(screen, document.get()); | ||||||
|   std::cout << screen.ToString() << std::endl; |   std::cout << screen.ToString() << std::endl; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ int main(int argc, const char *argv[]) | |||||||
|       ) | border, |       ) | border, | ||||||
|       text(L"overlay") | border | center |       text(L"overlay") | border | center | ||||||
|     ); |     ); | ||||||
|   auto screen = Screen::TerminalOutput(document); |   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||||
|   Render(screen, document.get()); |   Render(screen, document.get()); | ||||||
|  |  | ||||||
|   std::cout << screen.ToString(); |   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) |       | size(WIDTH, LESS_THAN, 50) | ||||||
|       ; |       ; | ||||||
|  |  | ||||||
|   auto screen = Screen::TerminalOutput(document); |   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||||
|   Render(screen, document.get()); |   Render(screen, document.get()); | ||||||
|   std::cout << screen.ToString() << std::endl; |   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)) | |             paragraph(L" A spinner "), spinner(6, i / 10)) | | ||||||
|         border; |         border; | ||||||
|  |  | ||||||
|     auto screen = Screen::TerminalFullscreen(); |     auto screen = Screen::Create(Dimension::Full()); | ||||||
|     Render(screen, document.get()); |     Render(screen, document.get()); | ||||||
|     std::cout << reset_position << screen.ToString() << std::flush; |     std::cout << reset_position << screen.ToString() << std::flush; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -115,7 +115,7 @@ int main(int argc, const char *argv[]) | |||||||
|  |  | ||||||
|     // Draw. |     // Draw. | ||||||
|     auto document = render(); |     auto document = render(); | ||||||
|     auto screen = Screen::TerminalOutput(document); |     auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(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; | ||||||
|     reset_position = screen.ResetPosition(); |     reset_position = screen.ResetPosition(); | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ int main(int argc, const char *argv[]) | |||||||
|       ) | flex |       ) | flex | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|   auto screen = Screen::TerminalFullscreen(); |   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||||
|   Render(screen, document.get()); |   Render(screen, document.get()); | ||||||
|   std::cout << screen.ToString(); |   std::cout << screen.ToString(); | ||||||
|   getchar(); |   getchar(); | ||||||
|   | |||||||
| @@ -9,17 +9,18 @@ int main(int argc, const char *argv[]) | |||||||
|     hbox( |     hbox( | ||||||
|       text(L"left-column"), |       text(L"left-column"), | ||||||
|       separator(), |       separator(), | ||||||
|       flex(vbox( |       vbox( | ||||||
|         center(text(L"right-column")) | flex, |         center(text(L"right-top")) | flex, | ||||||
|         separator(), |         separator(), | ||||||
|         center(text(L"bottom-column")) |         center(text(L"bottom-bottom")) | ||||||
|       )) |       ) | flex, | ||||||
|     ); |       separator(), | ||||||
|   auto screen = Screen::TerminalFullscreen(); |       text(L"right-column") | ||||||
|  |     ) | border; | ||||||
|  |   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||||
|   Render(screen, document.get()); |   Render(screen, document.get()); | ||||||
|  |  | ||||||
|   std::cout << screen.ToString(); |   std::cout << screen.ToString() << std::endl; | ||||||
|   getchar(); |  | ||||||
|  |  | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ int main(int argc, const char *argv[]) | |||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|   auto document = hbox(std::move(content)); |   auto document = hbox(std::move(content)); | ||||||
|   auto screen = Screen::FitDocument(document); |   auto screen = Screen::Create(Dimension::Fit(document)); | ||||||
|   Render(screen, document.get()); |   Render(screen, document.get()); | ||||||
|   std::cout << screen.ToString() << std::endl; |   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 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()); |     Render(screen, document.get()); | ||||||
|     std::cout << reset_position << screen.ToString() << std::flush; |     std::cout << reset_position << screen.ToString() << std::flush; | ||||||
|     reset_position = screen.ResetPosition(); |     reset_position = screen.ResetPosition(); | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ int main(int argc, const char *argv[]) | |||||||
|       text(L"blink") | blink, |       text(L"blink") | blink, | ||||||
|       text(L". Do you like it?") |       text(L". Do you like it?") | ||||||
|     ); |     ); | ||||||
|   auto screen = Screen::TerminalOutput(document); |   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||||
|   Render(screen, document.get()); |   Render(screen, document.get()); | ||||||
|  |  | ||||||
|   std::cout << screen.ToString(); |   std::cout << screen.ToString(); | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ int main(int argc, const char *argv[]) | |||||||
|       text(L"bold") | bold, |       text(L"bold") | bold, | ||||||
|       text(L". Do you like it?") |       text(L". Do you like it?") | ||||||
|     ); |     ); | ||||||
|   auto screen = Screen::TerminalOutput(document); |   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||||
|   Render(screen, document.get()); |   Render(screen, document.get()); | ||||||
|  |  | ||||||
|   std::cout << screen.ToString(); |   std::cout << screen.ToString(); | ||||||
|   | |||||||
| @@ -48,7 +48,7 @@ int main(int argc, const char *argv[]) | |||||||
|       filler() |       filler() | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|   auto screen = Screen::TerminalOutput(document); |   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||||
|   Render(screen, document.get()); |   Render(screen, document.get()); | ||||||
|  |  | ||||||
|   std::cout << screen.ToString(); |   std::cout << screen.ToString(); | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ int main(int argc, const char *argv[]) | |||||||
|       text(L"dim") | dim, |       text(L"dim") | dim, | ||||||
|       text(L". Do you like it?") |       text(L". Do you like it?") | ||||||
|     ); |     ); | ||||||
|   auto screen = Screen::TerminalOutput(document); |   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||||
|   Render(screen, document.get()); |   Render(screen, document.get()); | ||||||
|  |  | ||||||
|   std::cout << screen.ToString(); |   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"color")     | color(Color::Blue)   , text(L" ") , | ||||||
|       text(L"bgcolor")   | bgcolor(Color::Blue) |       text(L"bgcolor")   | bgcolor(Color::Blue) | ||||||
|     ); |     ); | ||||||
|   auto screen = Screen::TerminalOutput(document); |   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||||
|   Render(screen, document.get()); |   Render(screen, document.get()); | ||||||
|  |  | ||||||
|   std::cout << screen.ToString(); |   std::cout << screen.ToString(); | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ int main(int argc, const char *argv[]) | |||||||
|       text(L"inverted") | inverted, |       text(L"inverted") | inverted, | ||||||
|       text(L". Do you like it?") |       text(L". Do you like it?") | ||||||
|     ); |     ); | ||||||
|   auto screen = Screen::TerminalOutput(document); |   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||||
|   Render(screen, document.get()); |   Render(screen, document.get()); | ||||||
|  |  | ||||||
|   std::cout << screen.ToString(); |   std::cout << screen.ToString(); | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ int main(int argc, const char *argv[]) | |||||||
|       text(L"underlined") | underlined, |       text(L"underlined") | underlined, | ||||||
|       text(L". Do you like it?") |       text(L". Do you like it?") | ||||||
|     ); |     ); | ||||||
|   auto screen = Screen::TerminalOutput(document); |   auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document)); | ||||||
|   Render(screen, document.get()); |   Render(screen, document.get()); | ||||||
|  |  | ||||||
|   std::cout << screen.ToString(); |   std::cout << screen.ToString(); | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ int main(int argc, const char *argv[]) | |||||||
|         text(L"south-east") |         text(L"south-east") | ||||||
|       ) |       ) | ||||||
|     ); |     ); | ||||||
|   auto screen = Screen::TerminalFullscreen(); |   auto screen = Screen::Create(Dimension::Full()); | ||||||
|   Render(screen, document.get()); |   Render(screen, document.get()); | ||||||
|  |  | ||||||
|   std::cout << screen.ToString(); |   std::cout << screen.ToString(); | ||||||
|   | |||||||
| @@ -18,6 +18,7 @@ add_library(dom | |||||||
|   src/ftxui/dom/flex.cpp |   src/ftxui/dom/flex.cpp | ||||||
|   src/ftxui/dom/frame.cpp |   src/ftxui/dom/frame.cpp | ||||||
|   src/ftxui/dom/gauge.cpp |   src/ftxui/dom/gauge.cpp | ||||||
|  |   src/ftxui/dom/graph.cpp | ||||||
|   src/ftxui/dom/hbox.cpp |   src/ftxui/dom/hbox.cpp | ||||||
|   src/ftxui/dom/hflow.cpp |   src/ftxui/dom/hflow.cpp | ||||||
|   src/ftxui/dom/inverted.cpp |   src/ftxui/dom/inverted.cpp | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ class CheckBox : public Component { | |||||||
|  |  | ||||||
|   //std::wstring checked = L"[X] "; |   //std::wstring checked = L"[X] "; | ||||||
|   //std::wstring unchecked = L"[ ] "; |   //std::wstring unchecked = L"[ ] "; | ||||||
|   std::wstring checked = L"☑ "; |   std::wstring checked = L"▣ "; | ||||||
|   std::wstring unchecked = L"☐ "; |   std::wstring unchecked = L"☐ "; | ||||||
|  |  | ||||||
|   Decorator focused_style = inverted; |   Decorator focused_style = inverted; | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ class Component; | |||||||
|  |  | ||||||
| class ScreenInteractive : public Screen { | class ScreenInteractive : public Screen { | ||||||
|   public: |   public: | ||||||
|     static ScreenInteractive FixedSize(size_t dimx, size_t dimy); |     static ScreenInteractive FixedSize(int dimx, int dimy); | ||||||
|     static ScreenInteractive Fullscreen(); |     static ScreenInteractive Fullscreen(); | ||||||
|     static ScreenInteractive FitComponent(); |     static ScreenInteractive FitComponent(); | ||||||
|     static ScreenInteractive TerminalOutput(); |     static ScreenInteractive TerminalOutput(); | ||||||
| @@ -30,7 +30,7 @@ class ScreenInteractive : public Screen { | |||||||
|      TerminalOutput, |      TerminalOutput, | ||||||
|    }; |    }; | ||||||
|    Dimension dimension_ = Dimension::Fixed; |    Dimension dimension_ = Dimension::Fixed; | ||||||
|    ScreenInteractive(size_t dimx, size_t dimy, Dimension dimension); |    ScreenInteractive(int dimx, int dimy, Dimension dimension); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }  // namespace ftxui | }  // namespace ftxui | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ | |||||||
|  |  | ||||||
| #include <functional> | #include <functional> | ||||||
|  |  | ||||||
|  | #include "ftxui/dom/graph.hpp" | ||||||
| #include "ftxui/dom/node.hpp" | #include "ftxui/dom/node.hpp" | ||||||
| #include "ftxui/screen/color.hpp" | #include "ftxui/screen/color.hpp" | ||||||
|  |  | ||||||
| @@ -20,6 +21,7 @@ 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); | ||||||
| Elements paragraph(std::wstring text); // Use inside hflow(). Split by space. | Elements paragraph(std::wstring text); // Use inside hflow(). Split by space. | ||||||
|  | Element graph(GraphFunction&); // See graph.hpp | ||||||
|  |  | ||||||
| // -- Decorator --- | // -- Decorator --- | ||||||
| Element bold(Element); | Element bold(Element); | ||||||
| @@ -68,6 +70,7 @@ Element nothing(Element element); | |||||||
| // Pipe elements into decorator togethers. | // Pipe elements into decorator togethers. | ||||||
| // Examples: text("ftxui") | bold | underlined; | // Examples: text("ftxui") | bold | underlined; | ||||||
| Element operator|(Element, Decorator); | Element operator|(Element, Decorator); | ||||||
|  | Elements operator|(Elements, Decorator); | ||||||
| Decorator operator|(Decorator, Decorator); | Decorator operator|(Decorator, Decorator); | ||||||
|  |  | ||||||
| // Make container able to take any number of children as input. | // 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; |   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 { | class Screen { | ||||||
|  public: |  public: | ||||||
|   // Constructor. |   // Constructor. | ||||||
|   Screen(size_t dimx, size_t dimy); |   Screen(int dimx, int dimy); | ||||||
|  |   static Screen Create(Dimension dimension); | ||||||
|   // Constructor using the terminal. |   static Screen Create(Dimension width, Dimension height); | ||||||
|   static Screen TerminalFullscreen(); |  | ||||||
|   static Screen TerminalOutput(std::unique_ptr<Node>& element); |  | ||||||
|   static Screen FitDocument(std::unique_ptr<Node>& element); |  | ||||||
|  |  | ||||||
|   // Node write into the screen using Screen::at. |   // Node write into the screen using Screen::at. | ||||||
|   wchar_t& at(size_t x, size_t y); |   wchar_t& at(int x, int y); | ||||||
|   Pixel& PixelAt(size_t x, size_t y); |   Pixel& PixelAt(int x, int y); | ||||||
|  |  | ||||||
|   // Convert the screen into a printable string in the terminal. |   // Convert the screen into a printable string in the terminal. | ||||||
|   std::string ToString(); |   std::string ToString(); | ||||||
|  |  | ||||||
|   // Get screen dimensions. |   // Get screen dimensions. | ||||||
|   size_t dimx() { return dimx_;} |   int dimx() { return dimx_;} | ||||||
|   size_t dimy() { return dimy_;} |   int dimy() { return dimy_;} | ||||||
|  |  | ||||||
|   // Move the terminal cursor n-lines up with n = dimy(). |   // Move the terminal cursor n-lines up with n = dimy(). | ||||||
|   std::string ResetPosition(); |   std::string ResetPosition(); | ||||||
| @@ -56,8 +62,8 @@ class Screen { | |||||||
|   Box stencil; |   Box stencil; | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   size_t dimx_; |   int dimx_; | ||||||
|   size_t dimy_; |   int dimy_; | ||||||
|   std::vector<std::vector<Pixel>> pixels_; |   std::vector<std::vector<Pixel>> pixels_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -44,14 +44,14 @@ Event GetEvent() { | |||||||
|  |  | ||||||
| };  // namespace | };  // namespace | ||||||
|  |  | ||||||
| ScreenInteractive::ScreenInteractive(size_t dimx, | ScreenInteractive::ScreenInteractive(int dimx, | ||||||
|                                      size_t dimy, |                                      int dimy, | ||||||
|                                      Dimension dimension) |                                      Dimension dimension) | ||||||
|     : Screen(dimx, dimy), dimension_(dimension) {} |     : Screen(dimx, dimy), dimension_(dimension) {} | ||||||
| ScreenInteractive::~ScreenInteractive() {} | ScreenInteractive::~ScreenInteractive() {} | ||||||
|  |  | ||||||
| // static | // static | ||||||
| ScreenInteractive ScreenInteractive::FixedSize(size_t dimx, size_t dimy) { | ScreenInteractive ScreenInteractive::FixedSize(int dimx, int dimy) { | ||||||
|   return ScreenInteractive(dimx, dimy, Dimension::Fixed); |   return ScreenInteractive(dimx, dimy, Dimension::Fixed); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -106,8 +106,8 @@ void ScreenInteractive::Loop(Component* component) { | |||||||
|  |  | ||||||
| void ScreenInteractive::Draw(Component* component) { | void ScreenInteractive::Draw(Component* component) { | ||||||
|   auto document = component->Render(); |   auto document = component->Render(); | ||||||
|   size_t dimx; |   int dimx; | ||||||
|   size_t dimy; |   int dimy; | ||||||
|   switch (dimension_) { |   switch (dimension_) { | ||||||
|     case Dimension::Fixed: |     case Dimension::Fixed: | ||||||
|       dimx = dimx_; |       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.x = 0; | ||||||
|     requirement_.min.y = 0; |     requirement_.min.y = 0; | ||||||
|     requirement_.flex.x = 1; |     requirement_.flex.x = 1; | ||||||
|     requirement_.flex.y = 0; |     requirement_.flex.y = 1; | ||||||
|     for(auto& child : children) |     for(auto& child : children) | ||||||
|       child->ComputeRequirement(); |       child->ComputeRequirement(); | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -19,6 +19,13 @@ Decorator operator|(Decorator a, Decorator b) { | |||||||
|   return compose(a, 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) { | Element operator|(Element e, Decorator d) { | ||||||
|   return d(std::move(e)); |   return d(std::move(e)); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| #include "ftxui/dom/node.hpp" |  | ||||||
| #include "ftxui/screen/screen.hpp" | #include "ftxui/screen/screen.hpp" | ||||||
|  | #include "ftxui/dom/node.hpp" | ||||||
| #include "ftxui/screen/string.hpp" | #include "ftxui/screen/string.hpp" | ||||||
| #include "ftxui/screen/terminal.hpp" | #include "ftxui/screen/terminal.hpp" | ||||||
|  |  | ||||||
| @@ -36,8 +36,34 @@ Pixel dev_null_pixel; | |||||||
|  |  | ||||||
| } // namespace | } // namespace | ||||||
|  |  | ||||||
| Screen::Screen(size_t dimx, size_t dimy) | Dimension Dimension::Fixed(int v) { | ||||||
|     : stencil({0, int(dimx) - 1, 0, int(dimy) - 1}), |   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), |       dimx_(dimx), | ||||||
|       dimy_(dimy), |       dimy_(dimy), | ||||||
|       pixels_(dimy, std::vector<Pixel>(dimx)) {} |       pixels_(dimy, std::vector<Pixel>(dimx)) {} | ||||||
| @@ -72,10 +98,10 @@ std::string Screen::ToString() { | |||||||
|  |  | ||||||
|   Pixel previous_pixel; |   Pixel previous_pixel; | ||||||
|  |  | ||||||
|   for (size_t y = 0; y < dimy_; ++y) { |   for (int y = 0; y < dimy_; ++y) { | ||||||
|     if (y != 0) |     if (y != 0) | ||||||
|       ss << '\n'; |       ss << '\n'; | ||||||
|     for (size_t x = 0; x < dimx_; ++x) { |     for (int x = 0; x < dimx_; ++x) { | ||||||
|       UpdatePixelStyle(ss, previous_pixel, pixels_[y][x]); |       UpdatePixelStyle(ss, previous_pixel, pixels_[y][x]); | ||||||
|       ss << pixels_[y][x].character; |       ss << pixels_[y][x].character; | ||||||
|     } |     } | ||||||
| @@ -88,42 +114,18 @@ std::string Screen::ToString() { | |||||||
|   return to_string(ss.str()); |   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; |   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; |   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::string Screen::ResetPosition() { | ||||||
|   std::stringstream ss; |   std::stringstream ss; | ||||||
|   ss << MOVE_LEFT << CLEAR_LINE; |   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; |     ss << MOVE_UP << CLEAR_LINE; | ||||||
|   } |   } | ||||||
|   return ss.str(); |   return ss.str(); | ||||||
| @@ -137,8 +139,8 @@ void Screen::Clear() { | |||||||
| void Screen::ApplyShader() { | void Screen::ApplyShader() { | ||||||
|  |  | ||||||
|   // Merge box characters togethers. |   // Merge box characters togethers. | ||||||
|   for(size_t y = 1; y<dimy_; ++y) { |   for(int y = 1; y<dimy_; ++y) { | ||||||
|     for(size_t x = 1; x<dimx_; ++x) { |     for(int x = 1; x<dimx_; ++x) { | ||||||
|       wchar_t& left = at(x - 1, y); |       wchar_t& left = at(x - 1, y); | ||||||
|       wchar_t& top = at(x, y - 1); |       wchar_t& top = at(x, y - 1); | ||||||
|       wchar_t& cur = at(x, y); |       wchar_t& cur = at(x, y); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 ArthurSonzogni
					ArthurSonzogni