mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2024-11-25 04:08:39 +08:00
Separate a reusable Image class from Screen (#834)
Co-authored-by: ArthurSonzogni <sonzogniarthur@gmail.com>
This commit is contained in:
parent
1f6e1101e8
commit
293ff179f6
4
.gitignore
vendored
4
.gitignore
vendored
@ -3,6 +3,10 @@
|
|||||||
*
|
*
|
||||||
!*/
|
!*/
|
||||||
|
|
||||||
|
# Ignore build directories generated by default MSVC CMake integration
|
||||||
|
# (otherwise causes terribly slow indexing)
|
||||||
|
out/
|
||||||
|
|
||||||
# Allowed top-level files:
|
# Allowed top-level files:
|
||||||
!.clang-format
|
!.clang-format
|
||||||
!.clang-tidy
|
!.clang-tidy
|
||||||
|
@ -32,6 +32,9 @@ current (development)
|
|||||||
reflecting the current scroll position. Proposed by @ibrahimnasson in
|
reflecting the current scroll position. Proposed by @ibrahimnasson in
|
||||||
[issue 752](https://github.com/ArthurSonzogni/FTXUI/issues/752)
|
[issue 752](https://github.com/ArthurSonzogni/FTXUI/issues/752)
|
||||||
|
|
||||||
|
### Screen
|
||||||
|
- Feature: Add `Box::IsEmpty()`.
|
||||||
|
|
||||||
### Build
|
### Build
|
||||||
- Support for cmake's "unity/jumbo" builds. Fixed by @ClausKlein.
|
- Support for cmake's "unity/jumbo" builds. Fixed by @ClausKlein.
|
||||||
|
|
||||||
|
@ -33,11 +33,14 @@ add_library(screen
|
|||||||
include/ftxui/screen/box.hpp
|
include/ftxui/screen/box.hpp
|
||||||
include/ftxui/screen/color.hpp
|
include/ftxui/screen/color.hpp
|
||||||
include/ftxui/screen/color_info.hpp
|
include/ftxui/screen/color_info.hpp
|
||||||
|
include/ftxui/screen/image.hpp
|
||||||
|
include/ftxui/screen/pixel.hpp
|
||||||
include/ftxui/screen/screen.hpp
|
include/ftxui/screen/screen.hpp
|
||||||
include/ftxui/screen/string.hpp
|
include/ftxui/screen/string.hpp
|
||||||
src/ftxui/screen/box.cpp
|
src/ftxui/screen/box.cpp
|
||||||
src/ftxui/screen/color.cpp
|
src/ftxui/screen/color.cpp
|
||||||
src/ftxui/screen/color_info.cpp
|
src/ftxui/screen/color_info.cpp
|
||||||
|
src/ftxui/screen/image.cpp
|
||||||
src/ftxui/screen/screen.cpp
|
src/ftxui/screen/screen.cpp
|
||||||
src/ftxui/screen/string.cpp
|
src/ftxui/screen/string.cpp
|
||||||
src/ftxui/screen/terminal.cpp
|
src/ftxui/screen/terminal.cpp
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include <unordered_map> // for unordered_map
|
#include <unordered_map> // for unordered_map
|
||||||
|
|
||||||
#include "ftxui/screen/color.hpp" // for Color
|
#include "ftxui/screen/color.hpp" // for Color
|
||||||
#include "ftxui/screen/screen.hpp" // for Pixel
|
#include "ftxui/screen/image.hpp" // for Pixel, Image
|
||||||
|
|
||||||
#ifdef DrawText
|
#ifdef DrawText
|
||||||
// Workaround for WinUsr.h (via Windows.h) defining macros that break things.
|
// Workaround for WinUsr.h (via Windows.h) defining macros that break things.
|
||||||
@ -95,6 +95,12 @@ struct Canvas {
|
|||||||
void DrawText(int x, int y, const std::string& value, const Color& color);
|
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);
|
void DrawText(int x, int y, const std::string& value, const Stylizer& style);
|
||||||
|
|
||||||
|
// Draw using directly pixels or images --------------------------------------
|
||||||
|
// x is considered to be a multiple of 2.
|
||||||
|
// y is considered to be a multiple of 4.
|
||||||
|
void DrawPixel(int x, int y, const Pixel&);
|
||||||
|
void DrawImage(int x, int y, const Image&);
|
||||||
|
|
||||||
// Decorator:
|
// Decorator:
|
||||||
// x is considered to be a multiple of 2.
|
// x is considered to be a multiple of 2.
|
||||||
// y is considered to be a multiple of 4.
|
// y is considered to be a multiple of 4.
|
||||||
@ -104,15 +110,18 @@ struct Canvas {
|
|||||||
bool IsIn(int x, int y) const {
|
bool IsIn(int x, int y) const {
|
||||||
return x >= 0 && x < width_ && y >= 0 && y < height_;
|
return x >= 0 && x < width_ && y >= 0 && y < height_;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CellType {
|
enum CellType {
|
||||||
kBraille,
|
kCell, // Units of size 2x4
|
||||||
kBlock,
|
kBlock, // Units of size 2x2
|
||||||
kText,
|
kBraille, // Units of size 1x1
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Cell {
|
struct Cell {
|
||||||
CellType type = kText;
|
CellType type = kCell;
|
||||||
Pixel content;
|
Pixel content;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct XY {
|
struct XY {
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
|
@ -15,6 +15,7 @@ struct Box {
|
|||||||
static auto Intersection(Box a, Box b) -> Box;
|
static auto Intersection(Box a, Box b) -> Box;
|
||||||
static auto Union(Box a, Box b) -> Box;
|
static auto Union(Box a, Box b) -> Box;
|
||||||
bool Contain(int x, int y) const;
|
bool Contain(int x, int y) const;
|
||||||
|
bool IsEmpty();
|
||||||
bool operator==(const Box& other) const;
|
bool operator==(const Box& other) const;
|
||||||
bool operator!=(const Box& other) const;
|
bool operator!=(const Box& other) const;
|
||||||
};
|
};
|
||||||
|
50
include/ftxui/screen/image.hpp
Normal file
50
include/ftxui/screen/image.hpp
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// Copyright 2024 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/box.hpp" // for Box
|
||||||
|
#include "ftxui/screen/pixel.hpp" // for Pixel
|
||||||
|
|
||||||
|
namespace ftxui {
|
||||||
|
|
||||||
|
/// @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
|
48
include/ftxui/screen/pixel.hpp
Normal file
48
include/ftxui/screen/pixel.hpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// Copyright 2024 Arthur Sonzogni. All rights reserved.
|
||||||
|
// Use of this source code is governed by the MIT license that can be found in
|
||||||
|
// the LICENSE file.
|
||||||
|
|
||||||
|
#include <cstdint> // for uint8_t
|
||||||
|
#include <string> // for string, basic_string, allocator
|
||||||
|
#include "ftxui/screen/color.hpp" // for Color, Color::Default
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ftxui
|
@ -9,48 +9,12 @@
|
|||||||
#include <string> // for string, basic_string, allocator
|
#include <string> // for string, basic_string, allocator
|
||||||
#include <vector> // for vector
|
#include <vector> // for vector
|
||||||
|
|
||||||
#include "ftxui/screen/box.hpp" // for Box
|
|
||||||
#include "ftxui/screen/color.hpp" // for Color, Color::Default
|
#include "ftxui/screen/color.hpp" // for Color, Color::Default
|
||||||
|
#include "ftxui/screen/image.hpp" // for Pixel, Image
|
||||||
#include "ftxui/screen/terminal.hpp" // for Dimensions
|
#include "ftxui/screen/terminal.hpp" // for Dimensions
|
||||||
|
|
||||||
namespace ftxui {
|
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.
|
/// @brief Define how the Screen's dimensions should look like.
|
||||||
/// @ingroup screen
|
/// @ingroup screen
|
||||||
namespace Dimension {
|
namespace Dimension {
|
||||||
@ -60,36 +24,24 @@ Dimensions Full();
|
|||||||
|
|
||||||
/// @brief A rectangular grid of Pixel.
|
/// @brief A rectangular grid of Pixel.
|
||||||
/// @ingroup screen
|
/// @ingroup screen
|
||||||
class Screen {
|
class Screen : public Image {
|
||||||
public:
|
public:
|
||||||
// Constructors:
|
// Constructors:
|
||||||
Screen(int dimx, int dimy);
|
Screen(int dimx, int dimy);
|
||||||
static Screen Create(Dimensions dimension);
|
static Screen Create(Dimensions dimension);
|
||||||
static Screen Create(Dimensions width, Dimensions height);
|
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;
|
std::string ToString() const;
|
||||||
|
|
||||||
// Print the Screen on to the terminal.
|
// Print the Screen on to the terminal.
|
||||||
void Print() const;
|
void Print() const;
|
||||||
|
|
||||||
// Get screen dimensions.
|
// Fill the screen with space and reset any screen state, like hyperlinks, and cursor
|
||||||
int dimx() const { return dimx_; }
|
void Clear();
|
||||||
int dimy() const { 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(bool clear = false) const;
|
std::string ResetPosition(bool clear = false) const;
|
||||||
|
|
||||||
// Fill the screen with space.
|
|
||||||
void Clear();
|
|
||||||
|
|
||||||
void ApplyShader();
|
void ApplyShader();
|
||||||
|
|
||||||
struct Cursor {
|
struct Cursor {
|
||||||
@ -107,6 +59,7 @@ class Screen {
|
|||||||
};
|
};
|
||||||
Shape shape;
|
Shape shape;
|
||||||
};
|
};
|
||||||
|
|
||||||
Cursor cursor() const { return cursor_; }
|
Cursor cursor() const { return cursor_; }
|
||||||
void SetCursor(Cursor cursor) { cursor_ = cursor; }
|
void SetCursor(Cursor cursor) { cursor_ = cursor; }
|
||||||
|
|
||||||
@ -115,12 +68,7 @@ class Screen {
|
|||||||
uint8_t RegisterHyperlink(const std::string& link);
|
uint8_t RegisterHyperlink(const std::string& link);
|
||||||
const std::string& Hyperlink(uint8_t id) const;
|
const std::string& Hyperlink(uint8_t id) const;
|
||||||
|
|
||||||
Box stencil;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int dimx_;
|
|
||||||
int dimy_;
|
|
||||||
std::vector<std::vector<Pixel>> pixels_;
|
|
||||||
Cursor cursor_;
|
Cursor cursor_;
|
||||||
std::vector<std::string> hyperlinks_ = {""};
|
std::vector<std::string> hyperlinks_ = {""};
|
||||||
};
|
};
|
||||||
|
@ -810,13 +810,49 @@ void Canvas::DrawText(int x,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Cell& cell = storage_[XY{x / 2, y / 4}];
|
Cell& cell = storage_[XY{x / 2, y / 4}];
|
||||||
cell.type = CellType::kText;
|
cell.type = CellType::kCell;
|
||||||
cell.content.character = it;
|
cell.content.character = it;
|
||||||
style(cell.content);
|
style(cell.content);
|
||||||
x += 2;
|
x += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Directly draw a predefined pixel at the given coordinate
|
||||||
|
/// @param x the x coordinate of the pixel.
|
||||||
|
/// @param y the y coordinate of the pixel.
|
||||||
|
/// @param p the pixel to draw.
|
||||||
|
void Canvas::DrawPixel(int x, int y, const Pixel& p) {
|
||||||
|
Cell& cell = storage_[XY{x / 2, y / 4}];
|
||||||
|
cell.type = CellType::kCell;
|
||||||
|
cell.content = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Draw a predefined image, with top-left corner at the given coordinate
|
||||||
|
/// You can supply negative coordinates to align the image however you like -
|
||||||
|
/// only the 'visible' portion will be drawn
|
||||||
|
/// @param x the x coordinate corresponding to the top-left corner of the image.
|
||||||
|
/// @param y the y coordinate corresponding to the top-left corner of the image.
|
||||||
|
/// @param image the image to draw.
|
||||||
|
void Canvas::DrawImage(int x, int y, const Image& image) {
|
||||||
|
x /= 2;
|
||||||
|
y /= 4;
|
||||||
|
const int dx_begin = std::max(0, -x);
|
||||||
|
const int dy_begin = std::max(0, -y);
|
||||||
|
const int dx_end = std::min(image.dimx(), width_ - x);
|
||||||
|
const int dy_end = std::min(image.dimy(), height_ - y);
|
||||||
|
|
||||||
|
for (int dy = dy_begin; dy < dy_end; ++dy) {
|
||||||
|
for (int dx = dx_begin; dx < dx_end; ++dx) {
|
||||||
|
Cell& cell = storage_[XY{
|
||||||
|
x + dx,
|
||||||
|
y + dy,
|
||||||
|
}];
|
||||||
|
cell.type = CellType::kCell;
|
||||||
|
cell.content = image.PixelAt(dx, dy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Modify a pixel at a given location.
|
/// @brief Modify a pixel at a given location.
|
||||||
/// @param style a function that modifies the pixel.
|
/// @param style a function that modifies the pixel.
|
||||||
void Canvas::Style(int x, int y, const Stylizer& style) {
|
void Canvas::Style(int x, int y, const Stylizer& style) {
|
||||||
|
@ -39,6 +39,12 @@ bool Box::Contain(int x, int y) const {
|
|||||||
y_max >= y;
|
y_max >= y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @return whether the box is empty.
|
||||||
|
/// @ingroup screen
|
||||||
|
bool Box::IsEmpty() {
|
||||||
|
return x_min > x_max || y_min > y_max;
|
||||||
|
}
|
||||||
|
|
||||||
/// @return whether |other| is the same as |this|
|
/// @return whether |other| is the same as |this|
|
||||||
/// @ingroup screen
|
/// @ingroup screen
|
||||||
bool Box::operator==(const Box& other) const {
|
bool Box::operator==(const Box& other) const {
|
||||||
|
68
src/ftxui/screen/image.cpp
Normal file
68
src/ftxui/screen/image.cpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// 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.
|
||||||
|
#include <cstdint> // for size_t
|
||||||
|
#include <iostream> // for operator<<, stringstream, basic_ostream, flush, cout, ostream
|
||||||
|
#include <limits>
|
||||||
|
#include <map> // for _Rb_tree_const_iterator, map, operator!=, operator==
|
||||||
|
#include <memory> // for allocator, allocator_traits<>::value_type
|
||||||
|
#include <sstream> // IWYU pragma: keep
|
||||||
|
#include <utility> // for pair
|
||||||
|
|
||||||
|
#include "ftxui/screen/image.hpp"
|
||||||
|
#include "ftxui/screen/string.hpp" // for string_width
|
||||||
|
|
||||||
|
namespace ftxui {
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
Pixel& dev_null_pixel() {
|
||||||
|
static Pixel pixel;
|
||||||
|
return pixel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Image::Image(int dimx, int dimy)
|
||||||
|
: stencil{0, dimx - 1, 0, dimy - 1},
|
||||||
|
dimx_(dimx),
|
||||||
|
dimy_(dimy),
|
||||||
|
pixels_(dimy, std::vector<Pixel>(dimx)) {}
|
||||||
|
|
||||||
|
/// @brief Access a character in a cell at a given position.
|
||||||
|
/// @param x The cell position along the x-axis.
|
||||||
|
/// @param y The cell position along the y-axis.
|
||||||
|
std::string& Image::at(int x, int y) {
|
||||||
|
return PixelAt(x, y).character;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Access a character in a cell at a given position.
|
||||||
|
/// @param x The cell position along the x-axis.
|
||||||
|
/// @param y The cell position along the y-axis.
|
||||||
|
const std::string& Image::at(int x, int y) const {
|
||||||
|
return PixelAt(x, y).character;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Access a cell (Pixel) at a given position.
|
||||||
|
/// @param x The cell position along the x-axis.
|
||||||
|
/// @param y The cell position along the y-axis.
|
||||||
|
Pixel& Image::PixelAt(int x, int y) {
|
||||||
|
return stencil.Contain(x, y) ? pixels_[y][x] : dev_null_pixel();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Access a cell (Pixel) at a given position.
|
||||||
|
/// @param x The cell position along the x-axis.
|
||||||
|
/// @param y The cell position along the y-axis.
|
||||||
|
const Pixel& Image::PixelAt(int x, int y) const {
|
||||||
|
return stencil.Contain(x, y) ? pixels_[y][x] : dev_null_pixel();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Clear all the pixel from the screen.
|
||||||
|
void Image::Clear() {
|
||||||
|
for (auto& line : pixels_) {
|
||||||
|
for (auto& cell : line) {
|
||||||
|
cell = Pixel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ftxui
|
@ -42,11 +42,6 @@ namespace ftxui {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
Pixel& dev_null_pixel() {
|
|
||||||
static Pixel pixel;
|
|
||||||
return pixel;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
void WindowsEmulateVT100Terminal() {
|
void WindowsEmulateVT100Terminal() {
|
||||||
static bool done = false;
|
static bool done = false;
|
||||||
@ -392,15 +387,11 @@ Screen Screen::Create(Dimensions dimension) {
|
|||||||
return {dimension.dimx, dimension.dimy};
|
return {dimension.dimx, dimension.dimy};
|
||||||
}
|
}
|
||||||
|
|
||||||
Screen::Screen(int dimx, int dimy)
|
Screen::Screen(int dimx, int dimy) : Image{dimx, dimy} {
|
||||||
: stencil{0, dimx - 1, 0, dimy - 1},
|
|
||||||
dimx_(dimx),
|
|
||||||
dimy_(dimy),
|
|
||||||
pixels_(dimy, std::vector<Pixel>(dimx)) {
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
// The placement of this call is a bit weird, however we can assume that
|
// The placement of this call is a bit weird, however we can assume that
|
||||||
// anybody who instantiates a Screen object eventually wants to output
|
// anybody who instantiates a Screen object eventually wants to output
|
||||||
// something to the console.
|
// something to the console. If that is not the case, use an instance of Image instead.
|
||||||
// As we require UTF8 for all input/output operations we will just switch to
|
// As we require UTF8 for all input/output operations we will just switch to
|
||||||
// UTF8 encoding here
|
// UTF8 encoding here
|
||||||
SetConsoleOutputCP(CP_UTF8);
|
SetConsoleOutputCP(CP_UTF8);
|
||||||
@ -450,34 +441,6 @@ void Screen::Print() const {
|
|||||||
std::cout << ToString() << '\0' << std::flush;
|
std::cout << ToString() << '\0' << std::flush;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Access a character in a cell at a given position.
|
|
||||||
/// @param x The cell position along the x-axis.
|
|
||||||
/// @param y The cell position along the y-axis.
|
|
||||||
std::string& Screen::at(int x, int y) {
|
|
||||||
return PixelAt(x, y).character;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Access a character in a cell at a given position.
|
|
||||||
/// @param x The cell position along the x-axis.
|
|
||||||
/// @param y The cell position along the y-axis.
|
|
||||||
const std::string& Screen::at(int x, int y) const {
|
|
||||||
return PixelAt(x, y).character;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Access a cell (Pixel) at a given position.
|
|
||||||
/// @param x The cell position along the x-axis.
|
|
||||||
/// @param y The cell position along the y-axis.
|
|
||||||
Pixel& Screen::PixelAt(int x, int y) {
|
|
||||||
return stencil.Contain(x, y) ? pixels_[y][x] : dev_null_pixel();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Access a cell (Pixel) at a given position.
|
|
||||||
/// @param x The cell position along the x-axis.
|
|
||||||
/// @param y The cell position along the y-axis.
|
|
||||||
const Pixel& Screen::PixelAt(int x, int y) const {
|
|
||||||
return stencil.Contain(x, y) ? pixels_[y][x] : dev_null_pixel();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Return a string to be printed in order to reset the cursor position
|
/// @brief Return a string to be printed in order to reset the cursor position
|
||||||
/// to the beginning of the screen.
|
/// to the beginning of the screen.
|
||||||
///
|
///
|
||||||
@ -517,11 +480,8 @@ std::string Screen::ResetPosition(bool clear) const {
|
|||||||
|
|
||||||
/// @brief Clear all the pixel from the screen.
|
/// @brief Clear all the pixel from the screen.
|
||||||
void Screen::Clear() {
|
void Screen::Clear() {
|
||||||
for (auto& line : pixels_) {
|
Image::Clear();
|
||||||
for (auto& cell : line) {
|
|
||||||
cell = Pixel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cursor_.x = dimx_ - 1;
|
cursor_.x = dimx_ - 1;
|
||||||
cursor_.y = dimy_ - 1;
|
cursor_.y = dimy_ - 1;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user