mirror of
				https://github.com/ArthurSonzogni/FTXUI.git
				synced 2025-11-01 02:58:12 +08:00 
			
		
		
		
	Gauge direction (#326)
Add `gauge` with all the different directions. Co-authored-by: Aleksandar Brakmic <13668697+brakmic-aleksandar@users.noreply.github.com>
This commit is contained in:
		
							
								
								
									
										14
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @@ -4,6 +4,20 @@ Changelog | |||||||
| current (development)  | current (development)  | ||||||
| --------------------- | --------------------- | ||||||
|  |  | ||||||
|  | ### Features: | ||||||
|  |  | ||||||
|  | #### DOM: | ||||||
|  | - The `inverted` decorator now toggle in the inverted attribute. | ||||||
|  | - Add `gauge` for the 4 directions. Expose the following API: | ||||||
|  | ```cpp | ||||||
|  | Element gauge(float ratio); | ||||||
|  | Element gaugeLeft(float ratio); | ||||||
|  | Element gaugeRight(float ratio); | ||||||
|  | Element gaugeUp(float ratio); | ||||||
|  | Element gaugeDown(float ratio); | ||||||
|  | Element gaugeDirection(float ratio, GaugeDirection); | ||||||
|  | ``` | ||||||
|  |  | ||||||
| 2.0.0 | 2.0.0 | ||||||
| ----- | ----- | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ example(color_truecolor_RGB) | |||||||
| example(dbox) | example(dbox) | ||||||
| example(canvas) | example(canvas) | ||||||
| example(gauge) | example(gauge) | ||||||
|  | example(gauge_direction) | ||||||
| example(graph) | example(graph) | ||||||
| example(gridbox) | example(gridbox) | ||||||
| example(hflow) | example(hflow) | ||||||
|   | |||||||
							
								
								
									
										79
									
								
								examples/dom/gauge_direction.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								examples/dom/gauge_direction.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | |||||||
|  | #include <chrono>                  // for operator""s, chrono_literals | ||||||
|  | #include <ftxui/dom/elements.hpp>  // for text, gauge, operator|, flex, hbox, Element | ||||||
|  | #include <ftxui/screen/screen.hpp>  // for Screen | ||||||
|  | #include <iostream>                 // for cout, endl, ostream | ||||||
|  | #include <string>  // for allocator, operator+, char_traits, operator<<, string, to_string, basic_string | ||||||
|  | #include <thread>  // for sleep_for | ||||||
|  |  | ||||||
|  | #include "ftxui/dom/node.hpp"      // for Render | ||||||
|  | #include "ftxui/screen/color.hpp"  // for ftxui | ||||||
|  |  | ||||||
|  | int main(int argc, const char* argv[]) { | ||||||
|  |   using namespace ftxui; | ||||||
|  |   using namespace std::chrono_literals; | ||||||
|  |  | ||||||
|  |   std::string reset_position; | ||||||
|  |   for (float percentage = 0.0f; percentage <= 1.0f; percentage += 0.002f) { | ||||||
|  |     std::string data_downloaded = | ||||||
|  |         std::to_string(int(percentage * 5000)) + "/5000"; | ||||||
|  |  | ||||||
|  |     auto gauge_up =  // | ||||||
|  |         hbox({ | ||||||
|  |             vtext("gauge vertical"), | ||||||
|  |             separator(), | ||||||
|  |             gaugeUp(percentage), | ||||||
|  |         }) | | ||||||
|  |         border; | ||||||
|  |  | ||||||
|  |     auto gauge_down =  // | ||||||
|  |         hbox({ | ||||||
|  |             vtext("gauge vertical"), | ||||||
|  |             separator(), | ||||||
|  |             gaugeDown(percentage), | ||||||
|  |         }) | | ||||||
|  |         border; | ||||||
|  |  | ||||||
|  |     auto gauge_right =  // | ||||||
|  |         vbox({ | ||||||
|  |             text("gauge horizontal"), | ||||||
|  |             separator(), | ||||||
|  |             gaugeRight(percentage), | ||||||
|  |         }) | | ||||||
|  |         border; | ||||||
|  |  | ||||||
|  |     auto gauge_left =  // | ||||||
|  |         vbox({ | ||||||
|  |             text("gauge horizontal"), | ||||||
|  |             separator(), | ||||||
|  |             gaugeLeft(percentage), | ||||||
|  |         }) | | ||||||
|  |         border; | ||||||
|  |  | ||||||
|  |     auto document = hbox({ | ||||||
|  |         gauge_up, | ||||||
|  |         filler(), | ||||||
|  |         vbox({ | ||||||
|  |             gauge_right, | ||||||
|  |             filler(), | ||||||
|  |             text(data_downloaded) | border | center, | ||||||
|  |             filler(), | ||||||
|  |             gauge_left, | ||||||
|  |         }), | ||||||
|  |         filler(), | ||||||
|  |         gauge_down, | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     auto screen = Screen(32, 16); | ||||||
|  |     Render(screen, document); | ||||||
|  |     std::cout << reset_position; | ||||||
|  |     screen.Print(); | ||||||
|  |     reset_position = screen.ResetPosition(); | ||||||
|  |  | ||||||
|  |     std::this_thread::sleep_for(0.01s); | ||||||
|  |   } | ||||||
|  |   std::cout << std::endl; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Copyright 2022 Arthur Sonzogni. All rights reserved. | ||||||
|  | // Use of this source code is governed by the MIT license that can be found in | ||||||
|  | // the LICENSE file. | ||||||
| @@ -21,6 +21,7 @@ using Decorator = std::function<Element(Element)>; | |||||||
| using GraphFunction = std::function<std::vector<int>(int, int)>; | using GraphFunction = std::function<std::vector<int>(int, int)>; | ||||||
|  |  | ||||||
| enum BorderStyle { LIGHT, HEAVY, DOUBLE, ROUNDED, EMPTY }; | enum BorderStyle { LIGHT, HEAVY, DOUBLE, ROUNDED, EMPTY }; | ||||||
|  | enum class GaugeDirection { Left, Up, Right, Down }; | ||||||
|  |  | ||||||
| // Pipe elements into decorator togethers. | // Pipe elements into decorator togethers. | ||||||
| // For instance the next lines are equivalents: | // For instance the next lines are equivalents: | ||||||
| @@ -42,6 +43,11 @@ Element separatorStyled(BorderStyle); | |||||||
| Element separator(Pixel); | Element separator(Pixel); | ||||||
| Element separatorCharacter(std::string); | Element separatorCharacter(std::string); | ||||||
| Element gauge(float ratio); | Element gauge(float ratio); | ||||||
|  | Element gaugeLeft(float ratio); | ||||||
|  | Element gaugeRight(float ratio); | ||||||
|  | Element gaugeUp(float ratio); | ||||||
|  | Element gaugeDown(float ratio); | ||||||
|  | Element gaugeDirection(float ratio, GaugeDirection); | ||||||
| Element border(Element); | Element border(Element); | ||||||
| Element borderLight(Element); | Element borderLight(Element); | ||||||
| Element borderHeavy(Element); | Element borderHeavy(Element); | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ | |||||||
|  |  | ||||||
| namespace ftxui { | namespace ftxui { | ||||||
|  |  | ||||||
| static std::string charset[11] = { | static std::string charset_horizontal[11] = { | ||||||
| #if defined(FTXUI_MICROSOFT_TERMINAL_FALLBACK) | #if defined(FTXUI_MICROSOFT_TERMINAL_FALLBACK) | ||||||
|     // Microsoft's terminals often use fonts not handling the 8 unicode |     // Microsoft's terminals often use fonts not handling the 8 unicode | ||||||
|     // characters for representing the whole gauge. Fallback with less. |     // characters for representing the whole gauge. Fallback with less. | ||||||
| @@ -22,38 +22,229 @@ static std::string charset[11] = { | |||||||
|     // int(9 * (limit - limit_int) = 9 |     // int(9 * (limit - limit_int) = 9 | ||||||
|     "█"}; |     "█"}; | ||||||
|  |  | ||||||
|  | static std::string charset_vertical[10] = { | ||||||
|  |     "█", | ||||||
|  |     "▇", | ||||||
|  |     "▆", | ||||||
|  |     "▅", | ||||||
|  |     "▄", | ||||||
|  |     "▃", | ||||||
|  |     "▂", | ||||||
|  |     "▁", | ||||||
|  |     " ", | ||||||
|  |     // An extra character in case when the fuzzer manage to have: | ||||||
|  |     // int(8 * (limit - limit_int) = 8 | ||||||
|  |     " ", | ||||||
|  | }; | ||||||
|  |  | ||||||
| class Gauge : public Node { | class Gauge : public Node { | ||||||
|  public: |  public: | ||||||
|   Gauge(float progress) : progress_(std::min(std::max(progress, 0.f), 1.f)) {} |   Gauge(float progress, GaugeDirection direction) | ||||||
|  |       : progress_(std::min(std::max(progress, 0.f), 1.f)), | ||||||
|  |         direction_(direction) {} | ||||||
|  |  | ||||||
|   void ComputeRequirement() override { |   void ComputeRequirement() override { | ||||||
|     requirement_.flex_grow_x = 1; |     switch (direction_) { | ||||||
|     requirement_.flex_grow_y = 0; |       case GaugeDirection::Right: | ||||||
|     requirement_.flex_shrink_x = 1; |       case GaugeDirection::Left: | ||||||
|     requirement_.flex_shrink_y = 0; |         requirement_.flex_grow_x = 1; | ||||||
|  |         requirement_.flex_grow_y = 0; | ||||||
|  |         requirement_.flex_shrink_x = 1; | ||||||
|  |         requirement_.flex_shrink_y = 0; | ||||||
|  |         break; | ||||||
|  |       case GaugeDirection::Up: | ||||||
|  |       case GaugeDirection::Down: | ||||||
|  |         requirement_.flex_grow_x = 0; | ||||||
|  |         requirement_.flex_grow_y = 1; | ||||||
|  |         requirement_.flex_shrink_x = 0; | ||||||
|  |         requirement_.flex_shrink_y = 1; | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|     requirement_.min_x = 1; |     requirement_.min_x = 1; | ||||||
|     requirement_.min_y = 1; |     requirement_.min_y = 1; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void Render(Screen& screen) override { |   void Render(Screen& screen) override { | ||||||
|  |     switch (direction_) { | ||||||
|  |       case GaugeDirection::Right: | ||||||
|  |         RenderHorizontal(screen, /*invert=*/false); | ||||||
|  |         break; | ||||||
|  |       case GaugeDirection::Up: | ||||||
|  |         RenderVertical(screen, /*invert=*/false); | ||||||
|  |         break; | ||||||
|  |       case GaugeDirection::Left: | ||||||
|  |         RenderHorizontal(screen, /*invert=*/true); | ||||||
|  |         break; | ||||||
|  |       case GaugeDirection::Down: | ||||||
|  |         RenderVertical(screen, /*invert=*/true); | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void RenderHorizontal(Screen& screen, bool invert) { | ||||||
|     int y = box_.y_min; |     int y = box_.y_min; | ||||||
|     if (y > box_.y_max) |     if (y > box_.y_max) | ||||||
|       return; |       return; | ||||||
|  |  | ||||||
|     float limit = box_.x_min + progress_ * (box_.x_max - box_.x_min + 1); |     // Draw the progress bar horizontally. | ||||||
|     int limit_int = limit; |     { | ||||||
|  |       float progress = invert ? 1.f - progress_ : progress_; | ||||||
|  |       float limit = box_.x_min + progress * (box_.x_max - box_.x_min + 1); | ||||||
|  |       int limit_int = limit; | ||||||
|  |       int x = box_.x_min; | ||||||
|  |       while (x < limit_int) | ||||||
|  |         screen.at(x++, y) = charset_horizontal[9]; | ||||||
|  |       screen.at(x++, y) = charset_horizontal[int(9 * (limit - limit_int))]; | ||||||
|  |       while (x <= box_.x_max) | ||||||
|  |         screen.at(x++, y) = charset_horizontal[0]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (invert) { | ||||||
|  |       for (int x = box_.x_min; x <= box_.x_max; x++) | ||||||
|  |         screen.PixelAt(x, y).inverted ^= true; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void RenderVertical(Screen& screen, bool invert) { | ||||||
|     int x = box_.x_min; |     int x = box_.x_min; | ||||||
|     while (x < limit_int) |     if (x > box_.x_max) | ||||||
|       screen.at(x++, y) = charset[9]; |       return; | ||||||
|     screen.at(x++, y) = charset[int(9 * (limit - limit_int))]; |  | ||||||
|     while (x <= box_.x_max) |     // Draw the progress bar vertically: | ||||||
|       screen.at(x++, y) = charset[0]; |     { | ||||||
|  |       float progress = invert ? progress_ : 1.f - progress_; | ||||||
|  |       float limit = box_.y_min + progress * (box_.y_max - box_.y_min + 1); | ||||||
|  |       int limit_int = limit; | ||||||
|  |       int y = box_.y_min; | ||||||
|  |       while (y < limit_int) | ||||||
|  |         screen.at(x, y++) = charset_vertical[8]; | ||||||
|  |       screen.at(x, y++) = charset_vertical[int(8 * (limit - limit_int))]; | ||||||
|  |       while (y <= box_.y_max) | ||||||
|  |         screen.at(x, y++) = charset_vertical[0]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (invert) { | ||||||
|  |       for (int y = box_.y_min; y <= box_.y_max; y++) | ||||||
|  |         screen.PixelAt(x, y).inverted ^= true; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   float progress_; |   float progress_; | ||||||
|  |   GaugeDirection direction_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /// @brief Draw a high definition progress bar progressing in specified | ||||||
|  | /// direction. | ||||||
|  | /// @param progress The proportion of the area to be filled. Belong to [0,1]. | ||||||
|  | //  @param direction Direction of progress bars progression. | ||||||
|  | /// @ingroup dom | ||||||
|  | Element gaugeDirection(float progress, GaugeDirection direction) { | ||||||
|  |   return std::make_shared<Gauge>(progress, direction); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /// @brief Draw a high definition progress bar progressing from left to right. | ||||||
|  | /// @param progress The proportion of the area to be filled. Belong to [0,1]. | ||||||
|  | /// @ingroup dom | ||||||
|  | /// | ||||||
|  | /// ### Example | ||||||
|  | /// | ||||||
|  | /// A gauge. It can be used to represent a progress bar. | ||||||
|  | /// ~~~cpp | ||||||
|  | /// border(gaugeRight(0.5)) | ||||||
|  | /// ~~~ | ||||||
|  | /// | ||||||
|  | /// #### Output | ||||||
|  | /// | ||||||
|  | /// ~~~bash | ||||||
|  | /// ┌──────────────────────────────────────────────────────────────────────────┐ | ||||||
|  | /// │█████████████████████████████████████                                     │ | ||||||
|  | /// └──────────────────────────────────────────────────────────────────────────┘ | ||||||
|  | /// ~~~ | ||||||
|  | Element gaugeRight(float progress) { | ||||||
|  |   return gaugeDirection(progress, GaugeDirection::Right); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /// @brief Draw a high definition progress bar progressing from right to left. | ||||||
|  | /// @param progress The proportion of the area to be filled. Belong to [0,1]. | ||||||
|  | /// @ingroup dom | ||||||
|  | /// | ||||||
|  | /// ### Example | ||||||
|  | /// | ||||||
|  | /// A gauge. It can be used to represent a progress bar. | ||||||
|  | /// ~~~cpp | ||||||
|  | /// border(gaugeLeft(0.5)) | ||||||
|  | /// ~~~ | ||||||
|  | /// | ||||||
|  | /// #### Output | ||||||
|  | /// | ||||||
|  | /// ~~~bash | ||||||
|  | /// ┌──────────────────────────────────────────────────────────────────────────┐ | ||||||
|  | /// │                                     █████████████████████████████████████│ | ||||||
|  | /// └──────────────────────────────────────────────────────────────────────────┘ | ||||||
|  | /// ~~~ | ||||||
|  | Element gaugeLeft(float progress) { | ||||||
|  |   return gaugeDirection(progress, GaugeDirection::Left); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /// @brief Draw a high definition progress bar progressing from bottom to top. | ||||||
|  | /// @param progress The proportion of the area to be filled. Belong to [0,1]. | ||||||
|  | /// @ingroup dom | ||||||
|  | /// | ||||||
|  | /// ### Example | ||||||
|  | /// | ||||||
|  | /// A gauge. It can be used to represent a progress bar. | ||||||
|  | /// ~~~cpp | ||||||
|  | /// border(gaugeUp(0.5)) | ||||||
|  | /// ~~~ | ||||||
|  | /// | ||||||
|  | /// #### Output | ||||||
|  | /// | ||||||
|  | /// ~~~bash | ||||||
|  | ///  ┌─┐ | ||||||
|  | ///  │ │ | ||||||
|  | ///  │ │ | ||||||
|  | ///  │ │ | ||||||
|  | ///  │ │ | ||||||
|  | ///  │█│ | ||||||
|  | ///  │█│ | ||||||
|  | ///  │█│ | ||||||
|  | ///  │█│ | ||||||
|  | ///  └─┘ | ||||||
|  | /// ~~~ | ||||||
|  | Element gaugeUp(float progress) { | ||||||
|  |   return gaugeDirection(progress, GaugeDirection::Up); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /// @brief Draw a high definition progress bar progressing from top to bottom. | ||||||
|  | /// @param progress The proportion of the area to be filled. Belong to [0,1]. | ||||||
|  | /// @ingroup dom | ||||||
|  | /// | ||||||
|  | /// ### Example | ||||||
|  | /// | ||||||
|  | /// A gauge. It can be used to represent a progress bar. | ||||||
|  | /// ~~~cpp | ||||||
|  | /// border(gaugeDown(0.5)) | ||||||
|  | /// ~~~ | ||||||
|  | /// | ||||||
|  | /// #### Output | ||||||
|  | /// | ||||||
|  | /// ~~~bash | ||||||
|  | ///  ┌─┐ | ||||||
|  | ///  │█│ | ||||||
|  | ///  │█│ | ||||||
|  | ///  │█│ | ||||||
|  | ///  │█│ | ||||||
|  | ///  │ │ | ||||||
|  | ///  │ │ | ||||||
|  | ///  │ │ | ||||||
|  | ///  │ │ | ||||||
|  | ///  └─┘ | ||||||
|  | /// ~~~ | ||||||
|  | Element gaugeDown(float progress) { | ||||||
|  |   return gaugeDirection(progress, GaugeDirection::Down); | ||||||
|  | } | ||||||
|  |  | ||||||
| /// @brief Draw a high definition progress bar. | /// @brief Draw a high definition progress bar. | ||||||
| /// @param progress The proportion of the area to be filled. Belong to [0,1]. | /// @param progress The proportion of the area to be filled. Belong to [0,1]. | ||||||
| /// @ingroup dom | /// @ingroup dom | ||||||
| @@ -73,7 +264,7 @@ class Gauge : public Node { | |||||||
| /// └──────────────────────────────────────────────────────────────────────────┘ | /// └──────────────────────────────────────────────────────────────────────────┘ | ||||||
| /// ~~~ | /// ~~~ | ||||||
| Element gauge(float progress) { | Element gauge(float progress) { | ||||||
|   return std::make_shared<Gauge>(progress); |   return gaugeRight(progress); | ||||||
| } | } | ||||||
|  |  | ||||||
| }  // namespace ftxui | }  // namespace ftxui | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
| using namespace ftxui; | using namespace ftxui; | ||||||
| using namespace ftxui; | using namespace ftxui; | ||||||
|  |  | ||||||
| TEST(GaugeTest, zero) { | TEST(GaugeTest, ZeroHorizontal) { | ||||||
|   auto root = gauge(0); |   auto root = gauge(0); | ||||||
|   Screen screen(11, 1); |   Screen screen(11, 1); | ||||||
|   Render(screen, root); |   Render(screen, root); | ||||||
| @@ -19,16 +19,15 @@ TEST(GaugeTest, zero) { | |||||||
|   EXPECT_EQ("           ", screen.ToString()); |   EXPECT_EQ("           ", screen.ToString()); | ||||||
| } | } | ||||||
|  |  | ||||||
| TEST(GaugeTest, half) { | TEST(GaugeTest, HalfHorizontal) { | ||||||
|   auto root = gauge(0.5); |   auto root = gauge(0.5); | ||||||
|   Screen screen(11, 1); |   Screen screen(11, 1); | ||||||
|   Render(screen, root); |   Render(screen, root); | ||||||
|  |  | ||||||
|   EXPECT_EQ("█████▍     ", screen.ToString()); |   EXPECT_EQ("█████▍     ", screen.ToString()); | ||||||
|   //"  ▏▎▍▌▊▉█"; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| TEST(GaugeTest, one) { | TEST(GaugeTest, OneHorizontal) { | ||||||
|   auto root = gauge(1.0); |   auto root = gauge(1.0); | ||||||
|   Screen screen(11, 1); |   Screen screen(11, 1); | ||||||
|   Render(screen, root); |   Render(screen, root); | ||||||
| @@ -36,6 +35,66 @@ TEST(GaugeTest, one) { | |||||||
|   EXPECT_EQ("███████████", screen.ToString()); |   EXPECT_EQ("███████████", screen.ToString()); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | TEST(GaugeTest, ZeroVertical) { | ||||||
|  |   auto root = gaugeUp(0); | ||||||
|  |   Screen screen(1, 11); | ||||||
|  |   Render(screen, root); | ||||||
|  |  | ||||||
|  |   EXPECT_EQ( | ||||||
|  |       " \r\n" | ||||||
|  |       " \r\n" | ||||||
|  |       " \r\n" | ||||||
|  |       " \r\n" | ||||||
|  |       " \r\n" | ||||||
|  |       " \r\n" | ||||||
|  |       " \r\n" | ||||||
|  |       " \r\n" | ||||||
|  |       " \r\n" | ||||||
|  |       " \r\n" | ||||||
|  |       " ", | ||||||
|  |       screen.ToString()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(GaugeTest, HalfVertical) { | ||||||
|  |   auto root = gaugeUp(0.5); | ||||||
|  |   Screen screen(1, 11); | ||||||
|  |   Render(screen, root); | ||||||
|  |  | ||||||
|  |   EXPECT_EQ( | ||||||
|  |       " \r\n" | ||||||
|  |       " \r\n" | ||||||
|  |       " \r\n" | ||||||
|  |       " \r\n" | ||||||
|  |       " \r\n" | ||||||
|  |       "▄\r\n" | ||||||
|  |       "█\r\n" | ||||||
|  |       "█\r\n" | ||||||
|  |       "█\r\n" | ||||||
|  |       "█\r\n" | ||||||
|  |       "█", | ||||||
|  |       screen.ToString()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST(GaugeTest, OneVertical) { | ||||||
|  |   auto root = gaugeUp(1.0); | ||||||
|  |   Screen screen(1, 11); | ||||||
|  |   Render(screen, root); | ||||||
|  |  | ||||||
|  |   EXPECT_EQ( | ||||||
|  |       "█\r\n" | ||||||
|  |       "█\r\n" | ||||||
|  |       "█\r\n" | ||||||
|  |       "█\r\n" | ||||||
|  |       "█\r\n" | ||||||
|  |       "█\r\n" | ||||||
|  |       "█\r\n" | ||||||
|  |       "█\r\n" | ||||||
|  |       "█\r\n" | ||||||
|  |       "█\r\n" | ||||||
|  |       "█", | ||||||
|  |       screen.ToString()); | ||||||
|  | } | ||||||
|  |  | ||||||
| // Copyright 2020 Arthur Sonzogni. All rights reserved. | // Copyright 2020 Arthur Sonzogni. All rights reserved. | ||||||
| // Use of this source code is governed by the MIT license that can be found in | // Use of this source code is governed by the MIT license that can be found in | ||||||
| // the LICENSE file. | // the LICENSE file. | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ class Inverted : public NodeDecorator { | |||||||
|     Node::Render(screen); |     Node::Render(screen); | ||||||
|     for (int y = box_.y_min; y <= box_.y_max; ++y) { |     for (int y = box_.y_min; y <= box_.y_max; ++y) { | ||||||
|       for (int x = box_.x_min; x <= box_.x_max; ++x) { |       for (int x = box_.x_min; x <= box_.x_max; ++x) { | ||||||
|         screen.PixelAt(x, y).inverted = true; |         screen.PixelAt(x, y).inverted ^= true; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Arthur Sonzogni
					Arthur Sonzogni