Skip to content

Commit 2fcdddf

Browse files
committed
Merge pull request #10 from FWeinb/improve-ui-library
Improvements to UI Library
2 parents 4e90728 + b2f8746 commit 2fcdddf

File tree

2 files changed

+79
-72
lines changed

2 files changed

+79
-72
lines changed

SSD1306Ui.cpp

Lines changed: 55 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,22 @@ void SSD1306Ui::init() {
1010
}
1111

1212
void SSD1306Ui::setTargetFPS(byte fps){
13+
int oldInterval = this->updateInterval;
1314
this->updateInterval = ((float) 1.0 / (float) fps) * 1000;
14-
Serial.println(this->updateInterval);
15+
16+
// Calculate new ticksPerFrame
17+
float changeRatio = oldInterval / this->updateInterval;
18+
this->ticksPerFrame *= changeRatio;
19+
this->ticksPerTransition *= changeRatio;
1520
}
1621

1722
// -/------ Automatic controll ------\-
1823

1924
void SSD1306Ui::enableAutoTransition(){
20-
autoTransition = true;
25+
this->autoTransition = true;
2126
}
2227
void SSD1306Ui::disableAutoTransition(){
23-
autoTransition = false;
28+
this->autoTransition = false;
2429
}
2530
void SSD1306Ui::setAutoTransitionForwards(){
2631
this->frameTransitionDirection = 1;
@@ -49,100 +54,96 @@ void SSD1306Ui::setActiveSymbole(const char* symbole) {
4954
this->dirty = true;
5055
}
5156
void SSD1306Ui::setInactiveSymbole(const char* symbole) {
52-
this->inactiveSymbole = symbole;
57+
this->inactiveSymbole = symbole;
5358
this->dirty = true;
5459
}
5560

5661

5762
// -/----- Frame settings -----\-
58-
void SSD1306Ui::setFrameAnimation(AnimationDirection dir) {
63+
void SSD1306Ui::setFrameAnimation(AnimationDirection dir) {
5964
this->frameAnimationDirection = dir;
6065
}
61-
void SSD1306Ui::setFrames(bool (*frameFunctions[])(SSD1306 *display, int x, int y), int frameCount) {
66+
void SSD1306Ui::setFrames(FrameCallback* frameFunctions, int frameCount) {
6267
this->frameCount = frameCount;
6368
this->frameFunctions = frameFunctions;
6469
}
6570

6671
// -/----- Overlays ------\-
67-
void SSD1306Ui::setOverlays(bool (*overlayFunctions[])(SSD1306 *display), int overlayCount){
72+
void SSD1306Ui::setOverlays(OverlayCallback* overlayFunctions, int overlayCount){
6873
this->overlayCount = overlayCount;
6974
this->overlayFunctions = overlayFunctions;
7075
}
7176

7277

7378
// -/----- Manuel control -----\-
7479
void SSD1306Ui::nextFrame() {
75-
this->frameState = IN_TRANSITION;
76-
this->ticksSinceLastStateSwitch = 0;
80+
this->state.frameState = IN_TRANSITION;
81+
this->state.ticksSinceLastStateSwitch = 0;
7782
this->frameTransitionDirection = 1;
7883
}
7984
void SSD1306Ui::previousFrame() {
80-
this->frameState = IN_TRANSITION;
81-
this->ticksSinceLastStateSwitch = 0;
85+
this->state.frameState = IN_TRANSITION;
86+
this->state.ticksSinceLastStateSwitch = 0;
8287
this->frameTransitionDirection = -1;
8388
}
8489

8590

8691
// -/----- State information -----\-
87-
FrameState SSD1306Ui::getFrameState(){
88-
return this->frameState;
89-
}
90-
int SSD1306Ui::getCurrentFrame(){
91-
return this->currentFrame;
92+
SSD1306UiState SSD1306Ui::getUiState(){
93+
return this->state;
9294
}
9395

9496

9597
int SSD1306Ui::update(){
96-
int timeBudget = this->updateInterval - (millis() - this->lastUpdate);
98+
int timeBudget = this->updateInterval - (millis() - this->state.lastUpdate);
9799
if ( timeBudget <= 0) {
98-
99100
// Implement frame skipping to ensure time budget is keept
100-
if (this->autoTransition && this->lastUpdate != 0) this->ticksSinceLastStateSwitch += abs(timeBudget) / this->updateInterval;
101-
102-
this->lastUpdate = millis();
101+
if (this->autoTransition && this->state.lastUpdate != 0) this->state.ticksSinceLastStateSwitch += ceil(-timeBudget / this->updateInterval);
102+
103+
this->state.lastUpdate = millis();
103104
this->tick();
104-
}
105+
}
105106
return timeBudget;
106107
}
107108

108109

109110
void SSD1306Ui::tick() {
110-
this->ticksSinceLastStateSwitch++;
111+
this->state.ticksSinceLastStateSwitch++;
111112

112-
switch (this->frameState) {
113+
switch (this->state.frameState) {
113114
case IN_TRANSITION:
114115
this->dirty = true;
115-
if (this->ticksSinceLastStateSwitch >= this->ticksPerTransition){
116-
this->frameState = FIXED;
117-
this->currentFrame = getNextFrameNumber();
118-
this->ticksSinceLastStateSwitch = 0;
116+
if (this->state.ticksSinceLastStateSwitch >= this->ticksPerTransition){
117+
this->state.frameState = FIXED;
118+
this->state.currentFrame = getNextFrameNumber();
119+
this->state.ticksSinceLastStateSwitch = 0;
119120
}
120121
break;
121122
case FIXED:
122-
if (this->ticksSinceLastStateSwitch >= this->ticksPerFrame){
123+
if (this->state.ticksSinceLastStateSwitch >= this->ticksPerFrame){
123124
if (this->autoTransition){
124-
this->frameState = IN_TRANSITION;
125+
this->state.frameState = IN_TRANSITION;
125126
this->dirty = true;
126127
}
127-
this->ticksSinceLastStateSwitch = 0;
128+
this->state.ticksSinceLastStateSwitch = 0;
128129
}
129130
break;
130131
}
131-
132+
132133
if (this->dirty) {
133134
this->dirty = false;
134135
this->display->clear();
135-
this->drawIndicator();
136+
this->drawIndicator();
136137
this->drawFrame();
137138
this->drawOverlays();
138139
this->display->display();
139140
}
140141
}
141142

142143
void SSD1306Ui::drawFrame(){
143-
switch (this->frameState){
144+
switch (this->state.frameState){
144145
case IN_TRANSITION: {
145-
float progress = (float) this->ticksSinceLastStateSwitch / (float) this->ticksPerTransition;
146+
float progress = (float) this->state.ticksSinceLastStateSwitch / (float) this->ticksPerTransition;
146147
int x, y, x1, y1;
147148
switch(this->frameAnimationDirection){
148149
case SLIDE_LEFT:
@@ -175,36 +176,36 @@ void SSD1306Ui::drawFrame(){
175176
int dir = frameTransitionDirection >= 0 ? 1 : -1;
176177
x *= dir; y *= dir; x1 *= dir; y1 *= dir;
177178

178-
this->dirty |= (*this->frameFunctions[this->currentFrame])(this->display, x, y);
179-
this->dirty |= (*this->frameFunctions[this->getNextFrameNumber()])(this->display, x1, y1);
179+
this->dirty |= (this->frameFunctions[this->state.currentFrame])(this->display, &this->state, x, y);
180+
this->dirty |= (this->frameFunctions[this->getNextFrameNumber()])(this->display, &this->state, x1, y1);
180181
break;
181182
}
182183
case FIXED:
183-
this->dirty |= (*this->frameFunctions[this->currentFrame])(this->display, 0, 0);
184+
this->dirty |= (this->frameFunctions[this->state.currentFrame])(this->display, &this->state, 0, 0);
184185
break;
185186
}
186187
}
187188

188189
void SSD1306Ui::drawIndicator() {
189-
byte posOfCurrentFrame;
190-
190+
byte posOfCurrentFrame;
191+
191192
switch (this->indicatorDirection){
192193
case LEFT_RIGHT:
193-
posOfCurrentFrame = this->currentFrame;
194+
posOfCurrentFrame = this->state.currentFrame;
194195
break;
195196
case RIGHT_LEFT:
196-
posOfCurrentFrame = (this->frameCount - 1) - this->currentFrame;
197+
posOfCurrentFrame = (this->frameCount - 1) - this->state.currentFrame;
197198
break;
198199
}
199-
200+
200201
for (byte i = 0; i < this->frameCount; i++) {
201-
202-
const char *xbm;
203-
202+
203+
const char *image;
204+
204205
if (posOfCurrentFrame == i) {
205-
xbm = this->activeSymbole;
206+
image = this->activeSymbole;
206207
} else {
207-
xbm = this->inactiveSymbole;
208+
image = this->inactiveSymbole;
208209
}
209210

210211
int x,y;
@@ -226,24 +227,23 @@ void SSD1306Ui::drawIndicator() {
226227
y = 32 - (12 * frameCount / 2) + 12 * i;
227228
break;
228229
}
229-
230-
this->display->drawXbm(x, y, 8, 8, xbm);
231-
}
230+
231+
this->display->drawFastImage(x, y, 8, 8, image);
232+
}
232233
}
233234

234235
void SSD1306Ui::drawOverlays() {
235236
for (int i=0;i<this->overlayCount;i++){
236-
this->dirty |= (*this->overlayFunctions[i])(this->display);
237+
this->dirty |= (this->overlayFunctions[i])(this->display, &this->state);
237238
}
238239
}
239240

240241
int SSD1306Ui::getNextFrameNumber(){
241-
int nextFrame = (this->currentFrame + this->frameTransitionDirection) % this->frameCount;
242+
int nextFrame = (this->state.currentFrame + this->frameTransitionDirection) % this->frameCount;
242243
if (nextFrame < 0){
243244
nextFrame = this->frameCount + nextFrame;
244245
}
245-
return nextFrame;
246+
return nextFrame;
246247
}
247248

248249

249-

SSD1306Ui.h

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,19 @@ const char ANIMATION_inactiveSymbole[] PROGMEM = {
6060
0x00, 0x0, 0x0, 0x18, 0x18, 0x0, 0x0, 0x00
6161
};
6262

63+
64+
// Structure of the UiState
65+
struct SSD1306UiState {
66+
int lastUpdate = 0;
67+
int ticksSinceLastStateSwitch = 0;
68+
69+
FrameState frameState = FIXED;
70+
int currentFrame = 0;
71+
};
72+
73+
typedef bool (*FrameCallback)(SSD1306 *display, SSD1306UiState* state, int x, int y);
74+
typedef bool (*OverlayCallback)(SSD1306 *display, SSD1306UiState* state);
75+
6376
class SSD1306Ui {
6477
private:
6578
SSD1306 *display;
@@ -76,29 +89,26 @@ class SSD1306Ui {
7689

7790
// Values for the Frames
7891
AnimationDirection frameAnimationDirection = SLIDE_RIGHT;
79-
FrameState frameState = FIXED;
8092

8193
int frameTransitionDirection = 1;
8294

83-
int ticksPerFrame = 313; // ~ 5000ms at 60 FPS
84-
int ticksPerTransition = 32; // ~ 500ms at 60 FPS
85-
int ticksSinceLastStateSwitch = 0;
86-
int currentFrame = 0;
95+
int ticksPerFrame = 151; // ~ 5000ms at 30 FPS
96+
int ticksPerTransition = 15; // ~ 500ms at 30 FPS
8797

8898
bool autoTransition = true;
8999

90-
bool (**frameFunctions)(SSD1306 *display, int x, int y);
100+
FrameCallback* frameFunctions;
91101
int frameCount = 0;
92102

93103
// Values for Overlays
94-
bool (**overlayFunctions)(SSD1306 *display);
104+
OverlayCallback* overlayFunctions;
95105
int overlayCount = 0;
96106

107+
// UI State
108+
SSD1306UiState state;
97109

98110
// Bookeeping for update
99-
int updateInterval = 16;
100-
unsigned long lastUpdate = 0;
101-
111+
int updateInterval = 33;
102112

103113
int getNextFrameNumber();
104114
void drawIndicator();
@@ -147,7 +157,7 @@ class SSD1306Ui {
147157
*/
148158
void setTimePerTransition(int time);
149159

150-
// Customize Indicator Position and style
160+
// Customize indicator position and style
151161
/**
152162
* Set the position of the indicator bar.
153163
*/
@@ -178,25 +188,22 @@ class SSD1306Ui {
178188
/**
179189
* Add frame drawing functions
180190
*/
181-
void setFrames(bool (*frameFunctions[])(SSD1306 *display, int x, int y), int frameCount);
191+
void setFrames(FrameCallback* frameFunctions, int frameCount);
182192

183193
// Overlay
184194

185195
/**
186196
* Add overlays drawing functions that are draw independent of the Frames
187197
*/
188-
void setOverlays(bool (*overlayFunctions[])(SSD1306 *display), int overlayCount);
198+
void setOverlays(OverlayCallback* overlayFunctions, int overlayCount);
189199

190200
// Manuell Controll
191201
void nextFrame();
192202
void previousFrame();
193203

194204
// State Info
195-
FrameState getFrameState();
196-
int getCurrentFrame();
197-
205+
SSD1306UiState getUiState();
198206

199207
int update();
200208
};
201209

202-

0 commit comments

Comments
 (0)