-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathDisplayInterface.h
182 lines (155 loc) · 7.43 KB
/
DisplayInterface.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/*
* © 2025 Peter Cole
* © 2024 Peter Cole
*
* This is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* It 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this code. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef DISPLAYINTERFACE_H
#define DISPLAYINTERFACE_H
#include "Logger.h"
#include "Screen.h"
/// @brief Structure for row attributes
struct RowAttributes {
bool colourSet; /** This row has had a custom colour set, use textColour, set with '#' */
bool isUnderlined; /** This row needs to be underlined, set with '_' */
bool isLine; /** This row is a horizontal line, set with '-' */
bool alwaysTicker; /** This row should always scroll horizontally, set with '~' */
bool neverTicker; /** This row should never scroll horizontally, set with '!' */
uint16_t textColour; /** 16bit colour for text */
};
/// @brief Class to abstract away all physical display implementation to enable multiple display types
class DisplayInterface {
public:
/// @brief Perform any initial once off setup or configuration here and call only once
virtual void begin() = 0;
/// @brief Clear the entire screen
virtual void clearScreen() = 0;
/// @brief Display the specified Screen on this display
/// @param screen Pointer to the Screen to display
virtual void displayScreen(Screen *screen) = 0;
/// @brief Display the startup screen with software version
/// @param version EX-Display version
virtual void displayStartupInfo(const char *version) = 0;
/// @brief Display a row using formatting modifiers
/// @param row Row ID to display
/// @param column Column at which to display text (not pixels)
/// @param attributes RowAttributes structure containing modifier details
/// @param text Text to display
/// @param append Flag if this is appending to an existing row and should not clear the row first
virtual void displayFormattedRow(uint8_t row, uint8_t column, RowAttributes attributes, const char *text,
bool append) = 0;
/// @brief Set the next DisplayInterface derived instance in the list
/// @param display Pointer to the next instance
void setNext(DisplayInterface *display);
/// @brief Get the next DisplayInterface derived instance in the list
/// @return Pointer to the next instance
DisplayInterface *getNext();
/// @brief Set the logger instance to use for diagnostic logging
/// @param logger Pointer to the Logger instance to use
void setLogger(Logger *logger);
/// @brief Set the ID for this display instance
/// @param displayId ID of this display
void setId(uint8_t displayId);
/// @brief Get the ID of this display instance
/// @return ID of this display
uint8_t getId();
/// @brief Set the Screen ID this display is currently displaying
/// @param screenId Screen ID
void setScreenId(int screenId);
/// @brief Get the Screen ID this display is currently displaing
/// @return Screen ID
int getScreenId();
/// @brief Get the defined CS pin for this display to see if it needs manual SPI switching
/// @return Pin number of the SPI CS pin for this display (default -1 for no switching)
int getCSPin();
/// @brief Set the flag for whether this display needs redrawing or not - individual row updates are not affected
/// @param redraw true if entire redraw, otherwise false
void setNeedsRedraw(bool redraw);
/// @brief Test if this display needs an entire redraw
/// @return true|false
bool needsRedraw();
/// @brief Static method to enable calling back to a derived class with a formatted row
/// @param row Row to display
/// @param text Text containing formatting
void formatRow(int row, const char *text);
/// @brief Destructor for a DisplayInterface
virtual ~DisplayInterface() = default;
protected:
/// @brief Pointer to the next DisplayInterface derived instance in the list
DisplayInterface *_next = nullptr;
/// @brief Default text colour for the display
uint16_t _textColour;
/// @brief Default background colour for the display
uint16_t _backgroundColour;
/// @brief Pointer to the Logger instance for the DisplayInterface derived classes
Logger *_logger = nullptr;
/// @brief ID for this display instance
uint8_t _displayId = 0;
/// @brief ID of the screen this display is currently displaying, defaults to -1 to flag it is not a valid ID
int _screenId = -1;
/// @brief Orientation of this display, most displays require this setting otherwise ignore it
uint8_t _rotation = 0;
/// @brief Multiplier for text size, most displays require this setting otherwise ignore it
uint8_t _textSize = 1;
/// @brief Maximum row number (not count) that will fit on this display (based on font height, not pixels)
uint8_t _maxRow = 0;
/// @brief Maximum column number (not count) that will fit on this display (based on font width, not pixels)
uint8_t _maxColumn = 0;
/// @brief Calculated font height to determine row positioning
uint8_t _fontHeight = 0;
/// @brief Calculated font width to determine column positioning
uint8_t _fontWidth = 0;
/// @brief If there are more than one SPI displays that libraries don't officially support, the CS pin can be provided
/// to switch between them (default -1 disables this)
int _csPin = -1;
/// @brief Flag that this display needs redrawing - needed for switching between screens
bool _needsRedraw = true;
/**
* @brief Sanitise the provided struct of RowAttributes
* @details If isLine is set, all other attributes except colour are overridden to false. If both alwaysTicker and
* neverTicker are set, both will be set to false as they conflict.
* @param attributes RowAttributes struct to sanitise
* @return RowAttributes Sanitised struct according to the precedence rules
*/
RowAttributes _sanitiseAttributes(RowAttributes attributes);
/**
* @brief Validates the provided char is a valid modifier
* @param check Contains the char to be validated
* @return true If modifier is valid (_, -, ~, !, #)
* @return false If modifier is invalid
*/
bool _isModifier(char check);
/**
* @brief Update the provided RowAttributes struct according to the provided modifier
* @param attributes RowAttribute to be updated
* @param modifier Modifier to apply
* @param colour If applied modifier is colour, set this 16bit colour, otherwise this is ignored
* @return RowAttributes The updated struct
*/
RowAttributes _setAttribute(RowAttributes attributes, char modifier, uint16_t colour = 0xFFFF);
/**
* @brief Check if the provided string constant translates to a valid RGB colour code
* @param colour String constant containing RGB colour codes to check
* @return true If valid - #000000 to #FFFFFF
* @return false If invalid
*/
bool _isRGB(const char *colour);
/**
* @brief Convert the provided RGB colour code string constant to a uint16_t RGB565 colour
* @param colour String constant containing the RGB colour code
* @return uint16_t RGB565 colour code
*/
uint16_t _convertRGBtoRGB565(const char *colour);
};
#endif // DISPLAYINTERFACE_H