Files
pip/libs/main/console/piscreen.h

249 lines
7.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! \file piscreen.h
//! \ingroup Console
//! \brief
//! \~english Console tiling manager
//! \~russian Консольный тайловый менеджер
//! \details
//! \~english Main console screen manager providing tile-based UI rendering and keyboard input.
//! \~russian Основной менеджер консольного экрана, обеспечивающий отрисовку UI на основе тайлов и ввод с клавиатуры.
/*
PIP - Platform Independent Primitives
Console GUI
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PISCREEN_H
#define PISCREEN_H
#include "pip_console_export.h"
#include "piscreendrawer.h"
#include "piscreentile.h"
//! \brief
//! \~english Console tiling manager
//! \~russian Консольный тайловый менеджер
class PIP_CONSOLE_EXPORT PIScreen
: public PIThread
, public PIScreenTypes::PIScreenBase {
PIOBJECT_SUBCLASS(PIScreen, PIThread);
class SystemConsole;
public:
//! \brief
//! \~english Constructs PIScreen
//! \~russian Создает PIScreen
//! \param startNow Start immediately / Запустить немедленно
//! \param slot Keyboard handler function / Обработчик клавиатуры
PIScreen(bool startNow = true, PIKbdListener::KBFunc slot = 0);
//! \brief
//! \~english Destructor
//! \~russian Деструктор
~PIScreen();
//! \brief
//! \~english Enables exit capture with key
//! \~russian Включает захват выхода по клавише
void enableExitCapture(int key = 'Q') { listener->enableExitCapture(key); }
//! \brief
//! \~english Disables exit capture
//! \~russian Отключает захват выхода
void disableExitCapture() { listener->disableExitCapture(); }
//! \brief
//! \~english Checks if exit is captured
//! \~russian Проверяет, захвачен ли выход
bool exitCaptured() const { return listener->exitCaptured(); }
//! \brief
//! \~english Returns exit key
//! \~russian Возвращает клавишу выхода
int exitKey() const { return listener->exitKey(); }
//! \brief
//! \~english Returns window width
//! \~russian Возвращает ширину окна
int windowWidth() const { return console.width; }
//! \brief
//! \~english Returns window height
//! \~russian Возвращает высоту окна
int windowHeight() const { return console.height; }
//! \brief
//! \~english Checks if mouse is enabled
//! \~russian Проверяет, включена ли мышь
bool isMouseEnabled() const { return mouse_; }
//! \brief
//! \~english Sets mouse enabled state
//! \~russian Устанавливает состояние мыши
void setMouseEnabled(bool on);
//! \brief
//! \~english Returns root tile
//! \~russian Возвращает корневой тайл
PIScreenTile * rootTile() { return &root; }
//! \brief
//! \~english Finds tile by name
//! \~russian Находит тайл по имени
PIScreenTile * tileByName(const PIString & name);
//! \brief
//! \~english Sets dialog tile
//! \~russian Устанавливает диалоговый тайл
void setDialogTile(PIScreenTile * t);
//! \brief
//! \~english Returns current dialog tile
//! \~russian Возвращает текущий диалоговый тайл
PIScreenTile * dialogTile() const { return tile_dialog; }
//! \brief
//! \~english Returns screen drawer
//! \~russian Возвращает отрисовщик экрана
PIScreenDrawer * drawer() { return &drawer_; }
//! \brief
//! \~english Clears the screen
//! \~russian Очищает экран
void clear() { drawer_.clear(); }
//! \brief
//! \~english Resizes screen
//! \~russian Изменяет размер экрана
void resize(int w, int h) { console.resize(w, h); }
//! \brief
//! \~english Waits for finish
//! \~russian Ожидает завершения
EVENT_HANDLER0(void, waitForFinish);
//! \brief
//! \~english Starts screen
//! \~russian Запускает экран
EVENT_HANDLER0(void, start) { start(false); }
//! \brief
//! \~english Starts screen
//! \~russian Запускает экран
EVENT_HANDLER1(void, start, bool, wait);
//! \brief
//! \~english Stops screen
//! \~russian Останавливает экран
EVENT_HANDLER0(void, stop) { stop(false); }
//! \brief
//! \~english Stops screen
//! \~russian Останавливает экран
EVENT_HANDLER1(void, stop, bool, clear);
//! \brief
//! \~english Raised on key pressed
//! \~russian Вызывается при нажатии клавиши
EVENT2(keyPressed, PIKbdListener::KeyEvent, key, void *, data);
//! \brief
//! \~english Raised on tile event
//! \~russian Вызывается при событии тайла
EVENT2(tileEvent, PIScreenTile *, tile, PIScreenTypes::TileEvent, e);
//! \handlers
//! \{
//! \fn void waitForFinish()
//! \brief block until finished (exit key will be pressed)
//! \fn void start(bool wait = false)
//! \brief Start console output and if "wait" block until finished (exit key will be pressed)
//! \fn void stop(bool clear = false)
//! \brief Stop console output and if "clear" clear the screen
//! \}
//! \events
//! \{
//! \fn void keyPressed(PIKbdListener::KeyEvent key, void * data)
//! \brief Raise on key "key" pressed, "data" is pointer to %PIConsole object
//! \fn void tileEvent(PIScreenTile * tile, PIScreenTypes::TileEvent e)
//! \brief Raise on some event "e" from tile "tile"
//! \}
private:
class PIP_CONSOLE_EXPORT SystemConsole {
public:
SystemConsole();
~SystemConsole();
void begin();
void end();
void prepare();
void clear();
void print();
void resize(int w, int h);
void toUpperLeft();
void moveTo(int x = 0, int y = 0);
void hideCursor();
void showCursor();
void clearScreen();
void clearScreenLower();
#ifdef WINDOWS
void getWinCurCoord();
void clearLine();
void newLine();
ushort attributes(const PIScreenTypes::Cell & c);
#else
PIString formatString(const PIScreenTypes::Cell & c);
#endif
PRIVATE_DECLARATION(PIP_CONSOLE_EXPORT)
int width, height, pwidth, pheight;
int mouse_x, mouse_y;
PIVector<PIVector<PIScreenTypes::Cell>> cells, pcells;
};
void begin() override;
void run() override;
void end() override;
void key_event(PIKbdListener::KeyEvent key);
EVENT_HANDLER1(void, mouse_event, PIKbdListener::MouseEvent, me);
EVENT_HANDLER1(void, wheel_event, PIKbdListener::WheelEvent, we);
static void key_eventS(PIKbdListener::KeyEvent key, void * t) { ((PIScreen *)t)->key_event(key); }
PIVector<PIScreenTile *> tiles() { return root.children(); }
PIVector<PIScreenTile *> prepareMouse(PIKbdListener::MouseEvent * e);
PIVector<PIScreenTile *> tilesUnderMouse(int x, int y);
bool nextFocus(PIScreenTile * rt, PIKbdListener::KeyEvent key = PIKbdListener::KeyEvent());
void tileEventInternal(PIScreenTile * t, PIScreenTypes::TileEvent e) override;
void tileRemovedInternal(PIScreenTile * t) override;
void tileSetFocusInternal(PIScreenTile * t) override;
bool mouse_;
SystemConsole console;
PIScreenDrawer drawer_;
PIKbdListener * listener;
PIKbdListener::KBFunc ret_func;
PIScreenTile root;
PIScreenTile *tile_focus, *tile_dialog;
};
#endif // PISCREEN_H