Separated Image from Screen to avoid tinkering with Windows console; Added Canvas methods for drawing Pixels/Images directly

This commit is contained in:
Epixu
2024-03-29 17:08:09 +02:00
parent ce5ac6b12f
commit 3d6c48e800
10 changed files with 232 additions and 102 deletions

View File

@@ -10,7 +10,7 @@
#include <unordered_map> // for unordered_map
#include "ftxui/screen/color.hpp" // for Color
#include "ftxui/screen/screen.hpp" // for Pixel
#include "ftxui/screen/image.hpp" // for Pixel, Image
#ifdef DrawText
// Workaround for WinUsr.h (via Windows.h) defining macros that break things.
@@ -94,6 +94,11 @@ struct Canvas {
void DrawText(int x, int y, const std::string& value);
void DrawText(int x, int y, const std::string& value, const Color& color);
void DrawText(int x, int y, const std::string& value, const Stylizer& style);
// Draw using directly pixels or images --------------------------------------
// Pixel/image coordinates correspond 1:1
void DrawPixel(int x, int y, const Pixel&);
void DrawImage(int x, int y, const Image&);
// Decorator:
// x is considered to be a multiple of 2.

View File

@@ -15,6 +15,7 @@ struct Box {
static auto Intersection(Box a, Box b) -> Box;
static auto Union(Box a, Box b) -> Box;
bool Contain(int x, int y) const;
int Area() const noexcept;
bool operator==(const Box& other) const;
bool operator!=(const Box& other) const;
};

View File

@@ -0,0 +1,87 @@
// Copyright 2020 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#ifndef FTXUI_SCREEN_IMAGE_HPP
#define FTXUI_SCREEN_IMAGE_HPP
#include <cstdint> // for uint8_t
#include <memory>
#include <string> // for string, basic_string, allocator
#include <vector> // for vector
#include "ftxui/screen/color.hpp" // for Color, Color::Default
#include "ftxui/screen/box.hpp" // for Box
namespace ftxui {
/// @brief A unicode character and its associated style.
/// @ingroup screen
struct Pixel {
Pixel()
: blink(false),
bold(false),
dim(false),
inverted(false),
underlined(false),
underlined_double(false),
strikethrough(false),
automerge(false) {}
// A bit field representing the style:
bool blink : 1;
bool bold : 1;
bool dim : 1;
bool inverted : 1;
bool underlined : 1;
bool underlined_double : 1;
bool strikethrough : 1;
bool automerge : 1;
// The hyperlink associated with the pixel.
// 0 is the default value, meaning no hyperlink.
// It's an index for accessing Screen meta data
uint8_t hyperlink = 0;
// The graphemes stored into the pixel. To support combining characters,
// like: a?, this can potentially contain multiple codepoints.
std::string character = " ";
// Colors:
Color background_color = Color::Default;
Color foreground_color = Color::Default;
};
/// @brief A rectangular grid of Pixel.
/// @ingroup screen
class Image {
public:
// Constructors:
Image() = delete;
Image(int dimx, int dimy);
// Access a character in the grid at a given position.
std::string& at(int x, int y);
const std::string& at(int x, int y) const;
// Access a cell (Pixel) in the grid at a given position.
Pixel& PixelAt(int x, int y);
const Pixel& PixelAt(int x, int y) const;
// Get screen dimensions.
int dimx() const { return dimx_; }
int dimy() const { return dimy_; }
// Fill the image with space and default style
void Clear();
Box stencil;
protected:
int dimx_;
int dimy_;
std::vector<std::vector<Pixel>> pixels_;
};
} // namespace ftxui
#endif // FTXUI_SCREEN_IMAGE_HPP

View File

@@ -9,48 +9,12 @@
#include <string> // for string, basic_string, allocator
#include <vector> // for vector
#include "ftxui/screen/box.hpp" // for Box
#include "ftxui/screen/color.hpp" // for Color, Color::Default
#include "ftxui/screen/image.hpp" // for Pixel, Image
#include "ftxui/screen/terminal.hpp" // for Dimensions
namespace ftxui {
/// @brief A unicode character and its associated style.
/// @ingroup screen
struct Pixel {
Pixel()
: blink(false),
bold(false),
dim(false),
inverted(false),
underlined(false),
underlined_double(false),
strikethrough(false),
automerge(false) {}
// A bit field representing the style:
bool blink : 1;
bool bold : 1;
bool dim : 1;
bool inverted : 1;
bool underlined : 1;
bool underlined_double : 1;
bool strikethrough : 1;
bool automerge : 1;
// The hyperlink associated with the pixel.
// 0 is the default value, meaning no hyperlink.
uint8_t hyperlink = 0;
// The graphemes stored into the pixel. To support combining characters,
// like: a⃦, this can potentially contain multiple codepoints.
std::string character = " ";
// Colors:
Color background_color = Color::Default;
Color foreground_color = Color::Default;
};
/// @brief Define how the Screen's dimensions should look like.
/// @ingroup screen
namespace Dimension {
@@ -60,36 +24,24 @@ Dimensions Full();
/// @brief A rectangular grid of Pixel.
/// @ingroup screen
class Screen {
class Screen : public Image {
public:
// Constructors:
Screen(int dimx, int dimy);
static Screen Create(Dimensions dimension);
static Screen Create(Dimensions width, Dimensions height);
// Access a character in the grid at a given position.
std::string& at(int x, int y);
const std::string& at(int x, int y) const;
// Access a cell (Pixel) in the grid at a given position.
Pixel& PixelAt(int x, int y);
const Pixel& PixelAt(int x, int y) const;
std::string ToString() const;
// Print the Screen on to the terminal.
void Print() const;
// Get screen dimensions.
int dimx() const { return dimx_; }
int dimy() const { return dimy_; }
// Fill the screen with space and reset any screen state, like hyperlinks, and cursor
void Clear();
// Move the terminal cursor n-lines up with n = dimy().
std::string ResetPosition(bool clear = false) const;
// Fill the screen with space.
void Clear();
void ApplyShader();
struct Cursor {
@@ -107,6 +59,7 @@ class Screen {
};
Shape shape;
};
Cursor cursor() const { return cursor_; }
void SetCursor(Cursor cursor) { cursor_ = cursor; }
@@ -115,12 +68,7 @@ class Screen {
uint8_t RegisterHyperlink(const std::string& link);
const std::string& Hyperlink(uint8_t id) const;
Box stencil;
protected:
int dimx_;
int dimy_;
std::vector<std::vector<Pixel>> pixels_;
Cursor cursor_;
std::vector<std::string> hyperlinks_ = {""};
};