/
view.h
186 lines (163 loc) · 6.11 KB
/
view.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
183
184
185
186
#pragma once // Please format this file with clang before check-in to GitHub
/*
File: view.h
Software: Barry Hansen, K7BWH, barry@k7bwh.com, Seattle, WA
Hardware: John Vanderbeck, KM7O, Seattle, WA
Purpose: Abstract base class for all Griduino "view" modules.
Contains default implementation for common functions
and for templates to be used in derived classes.
*/
#include <Arduino.h>
#include <Adafruit_ILI9341.h> // TFT color display library
#include "constants.h" // Griduino constants and colors
#include "logger.h" // conditional printing to Serial port
#include "icons.h" // bitmaps for icons
extern bool showTouchTargets; // Griduino.ino
extern bool showCenterline; // Griduino.ino
// ========== abstract base class ViewCfgAudioType ================
class View {
public:
// public member variables go here
Adafruit_ILI9341 *tft; // an instance of the TFT Display
const int screenID; // unique identifier of which screen this is
int screenRotation; // 1=landscape, 3=landscape 180-degrees
uint16_t background; // screen background color
public:
/**
* Constructor
*/
// View() { } // no default ctor (must be told 'tft')
View(Adafruit_ILI9341 *vtft, int vid)
: tft(vtft), screenID(vid), background(0x000) // default black background
{
}
/**
* Called on every pass through main()
*/
virtual void updateScreen() {
}
/**
* Called once each time this view becomes active
*/
virtual void startScreen() {
// todo - make this pure virtual
}
/**
* Called once each time this view becomes INactive
* This is a 'goodbye kiss' for a view handler to do cleanup work, such as saving its settings
*/
virtual void endScreen() {
}
/**
* Called whenever the touchscreen has an event for this view
*/
virtual bool onTouch(Point touch) {
logger.info("->->-> Touched screen.");
return false; // true=handled, false=controller uses default action
}
/**
* Call to load/save configuration from non-volatile RAM
*/
virtual void loadConfig() {
// default: loads nothing
}
virtual void saveConfig() {
// default: saves nothing
}
protected:
const int xPanel = 34; // screen placement of "1 of 6" config panel legend
/**
* The One and Only True Clear Screen (TOOTCS) function
*/
void clearScreen(uint16_t color = cBACKGROUND) { // clear entire screen
tft->fillScreen(color);
}
void clearScreen(int startRow, int numRows, uint16_t color = cBACKGROUND) { // clear selected rows
tft->fillRect(0, startRow, tft->width(), numRows, color);
}
void drawAllIcons() {
// draw gear (settings) and arrow (next screen)
// ul x,y w,h color
tft->drawBitmap(5, 5, iconGear20, 20, 20, cFAINT); // "settings" upper left
tft->drawBitmap(300, 5, iconRightArrow18, 14, 18, cFAINT); // "next screen" upper right
}
void showScreenBorder() { // optionally outline visible area
#ifdef SHOW_SCREEN_BORDER
tft->drawRect(0, 0, gScreenWidth, gScreenHeight, ILI9341_BLUE); // debug: border around screen
#endif
}
void showScreenCenterline() {
if (showCenterline) {
// show centerline at x1,y1 x2,y2 color
tft->drawLine(tft->width() / 2, 0, tft->width() / 2, tft->height(), cWARN);
}
}
void showNameOfView(String sName, uint16_t fgd, uint16_t bkg) {
// Some of the "view" modules want to label themselves in the upper left corner
// Caution: this function changes font. The caller needs to change it back, if needed.
tft->setFont();
tft->setTextSize(2); // setFontSize(0);
tft->setTextColor(fgd, bkg);
tft->setCursor(1, 1);
tft->print(sName);
}
void showProgressBar(int screen, int numScreens) {
// draw marker for advancing through settings, eg, 1 of 6, 2 of 6, etc.
// we try to make it look like a filled rectangle
int x0 = 74; // lhs bounding box
int y0 = 28; // top bounding box
int w = 320 - x0 - x0; // width of bounding box
int h = 10; // height bounding box
int c = cBUTTONOUTLINE;
int wi = w / numScreens; // width of each item
for (int ii = 0; ii < numScreens; ii++) {
// x, y, w, h, color
int xOuter = x0 + ii * wi;
tft->drawRect(xOuter, y0, wi, h, cFAINTER);
if (ii == (screen - 1)) {
tft->fillRect(xOuter + 1, y0, wi - 2, h, cLABEL);
}
}
}
/**
* Rotate screen right-side-up / upside-down
* 1=landscape, 3=landscape 180-degrees
* This is a "protected" method in base class to ensure *only* the Settings page will set rotation.
*/
void setScreenRotation(int rot) {
this->screenRotation = rot;
tft->setRotation(rot); // 0=portrait (default), 1=landscape, 3=180 degrees
clearScreen(); // todo - necessary?
startScreen(); // todo - necessary?
updateScreen(); // todo - necessary?
}
/**
* Some views include function-specific buttons
*/
void showMyTouchTargets(FunctionButton buttons[], int numButtons) {
if (showTouchTargets) { // if feature is turned off, return
if (buttons) { // if a view has no buttons, return
for (int ii = 0; ii < numButtons; ii++) {
FunctionButton item = buttons[ii];
tft->drawRect(item.hitTarget.ul.x, item.hitTarget.ul.y, // debug: draw outline around hit target
item.hitTarget.size.x, item.hitTarget.size.y,
cTOUCHTARGET);
}
}
}
}
}; // end class View
// ----------------------------------------------------------
// Derived classes
class ViewGrid : public View {
public:
// ---------- public interface ----------
// This derived class must implement the public interface:
ViewGrid(Adafruit_ILI9341 *vtft, int vid) // ctor
: View{vtft, vid} {
background = 0; // every view can have its own background color; this screen is black
}
void updateScreen();
void startScreen();
bool onTouch(Point touch);
}; // end class ViewGrid