/*! \file * \brief \ref TextWindow provides virtual output windows in text mode */ #pragma once #include "../types.h" #include "cga.h" /*! \brief Virtual windows in text mode * \ingroup io * * Outputs text on a part of the screen in \ref CGA, * a window is defined in by position and size (with its own cursor). * * This allows to separate the output of the application from the debug output * on the screen without having to synchronize. */ class TextWindow { // Prevent copies and assignments TextWindow(const TextWindow&) = delete; TextWindow& operator=(const TextWindow&) = delete; public: /*! \brief Constructor of a text window * * Creates a virtual, rectangular text window on the screen. * The coordinates to construct the window are absolute positions in the * \ref CGA screen. * * \note Overlapping windows are neither supported nor prevented -- better * just try to avoid construction windows with overlapping coordinates! * * \warning Don't use the hardware cursor in more than one window! * * \param from_col Text Window starts in column `from_col`, * the first (leftmost) possible column is `0` * \param to_col Text Window extends to the right to column `to_col` * (exclusive). This column has to be strictly greater than `from_col`, the * maximum allowed value is \ref CGA::COLUMNS (rightmost) * \param from_row Text Window starts in row `from_row`, * the first possible (uppermost) row is `0` * \param to_row Text Window extends down to row `to_row` (exclusive). * This row has to be strictly greater than `from_row`, * the maximum allowed value is \ref CGA::ROWS (bottom-most) * \param use_cursor Specifies whether the hardware cursor (`true`) or a * software cursor/variable (`false`) should be used to * store the current position * * \todo(11) Implement constructor */ TextWindow(unsigned from_col, unsigned to_col, unsigned from_row, unsigned to_row, bool use_cursor = false); /*! \brief Set the cursor position in the window * * Depending on the constructor parameter `use_cursor` either the * hardware cursor (and only the hardware cursor!) is used or the position * is stored internally in the object. * * The coordinates are relative to the upper left starting position of * the window. * * \param rel_x Column in window * \param rel_y Row in window * \todo(11) Implement method, use \ref CGA::setCursor() for the hardware * cursor */ void setPos(unsigned rel_x, unsigned rel_y); /*! \brief Set the cursor position in the window * * Depending on the constructor parameter `use_cursor` either the * hardware cursor (and only the hardware cursor!) is used or the position * is stored internally in the object. * * The coordinates are relative to the upper left starting position of * the window. * Negative coordinates are interpreted relative to the right and bottom * border of the window. * * \todo(11) Implement this method (it can either use or replace * \ref setPos(unsigned, unsigned)) */ void setPos(int rel_x, int rel_y); /*! \brief Get the current cursor position in the window * * Depending on the constructor parameter `use_cursor` either the * hardware cursor (and only the hardware cursor!) is used or the position * is retrieved from the internally stored object. * * \param rel_x Column in window * \param rel_y Row in window * \todo(11) Implement Method, use \ref CGA::getCursor() for the hardware * cursor */ void getPos(unsigned& rel_x, unsigned& rel_y) const; /// \copydoc TextWindow::getPos(unsigned&,unsigned&) const void getPos(int& rel_x, int& rel_y) const; /*! \brief Display multiple characters in the window * * Output a character string, starting at the current cursor position. * Since the string does not need to contain a `\0` termination (unlike the * common C string), a length parameter is required to specify the number * of characters in the string. * When the output is complete, the cursor is positioned after the last * printed character. * The same attributes (colors) are used for the entire text. * * If there is not enough space left at the end of the line, * the output continues on the following line. * As soon as the last window line is filled, the entire window area is * moved up one line: The first line disappears, the bottom line is cleared. * * A line break also occurs whenever the character `\n` appears in the text. * * \param string Text to be printed * \param length Length of text * \param attrib Attribute for text * \todo(11) Implement Method */ void print(const char* string, size_t length, CGA::Attribute attrib = CGA::Attribute()); // NOLINT /*! \brief Delete all contents in the window and reset the cursor. * * \param character Fill character * \param attrib Attribute for fill character * \todo(11) Implement Method */ void reset(char character = ' ', CGA::Attribute attrib = CGA::Attribute()); };