@@ -46,6 +46,7 @@ OLEDDisplayUi::OLEDDisplayUi(OLEDDisplay *display) {
46
46
indicatorDirection = LEFT_RIGHT;
47
47
activeSymbol = ANIMATION_activeSymbol;
48
48
inactiveSymbol = ANIMATION_inactiveSymbol;
49
+ notifyingFrameOffsetAmplitude = 10 ;
49
50
frameAnimationDirection = SLIDE_RIGHT;
50
51
lastTransitionDirection = 1 ;
51
52
frameCount = 0 ;
@@ -56,6 +57,7 @@ OLEDDisplayUi::OLEDDisplayUi(OLEDDisplay *display) {
56
57
updateInterval = 33 ;
57
58
state.lastUpdate = 0 ;
58
59
state.ticksSinceLastStateSwitch = 0 ;
60
+ state.ticks = 0 ;
59
61
state.frameState = FIXED;
60
62
state.currentFrame = 0 ;
61
63
state.frameTransitionDirection = 1 ;
@@ -66,6 +68,7 @@ OLEDDisplayUi::OLEDDisplayUi(OLEDDisplay *display) {
66
68
autoTransition = true ;
67
69
setTimePerFrame (5000 );
68
70
setTimePerTransition (500 );
71
+ frameNotificationCallbackFunction = nullptr ;
69
72
}
70
73
71
74
void OLEDDisplayUi::init () {
@@ -220,6 +223,54 @@ void OLEDDisplayUi::transitionToFrame(uint8_t frame) {
220
223
this ->state .frameTransitionDirection = frame < this ->state .currentFrame ? -1 : 1 ;
221
224
}
222
225
226
+ bool OLEDDisplayUi::addFrameToNotifications (uint32_t frameToAdd, bool force) {
227
+ switch (this ->state .frameState ) {
228
+ case IN_TRANSITION:
229
+ if (!force && this ->state .transitionFrameTarget == frameToAdd)
230
+ // if we're in transition, and being asked to set the to-be-current frame
231
+ // as having a notifiction, just don't (unless we're forced)
232
+ return false ;
233
+ break ;
234
+ case FIXED:
235
+ if (!force && this ->state .currentFrame == frameToAdd)
236
+ // if we're on a fixed frame, and being asked to set the current frame
237
+ // as having a notifiction, just don't (unless we're forced)
238
+ return false ;
239
+ break ;
240
+ }
241
+ // nothing is preventing us from setting the requested frame as having a notification, so
242
+ // do it.
243
+ this ->state .notifyingFrames .push_back (frameToAdd);
244
+ return true ;
245
+ }
246
+
247
+ bool OLEDDisplayUi::removeFrameFromNotifications (uint32_t frameToRemove) {
248
+ // We've been told that a frame no longer needs to be notifying
249
+
250
+ auto it = std::find (this ->state .notifyingFrames .begin (), this ->state .notifyingFrames .end (), frameToRemove);
251
+ if (it != this ->state .notifyingFrames .end ()) {
252
+ using std::swap;
253
+ // swap the one to be removed with the last element
254
+ // and remove the item at the end of the container
255
+ // to prevent moving all items after '5' by one
256
+ swap (*it, this ->state .notifyingFrames .back ());
257
+ this ->state .notifyingFrames .pop_back ();
258
+ return true ;
259
+ }
260
+ return false ;
261
+ }
262
+
263
+ void OLEDDisplayUi::setFrameNotificationCallback (FrameNotificationCallback* frameNotificationCallbackFunction) {
264
+ this ->frameNotificationCallbackFunction = frameNotificationCallbackFunction;
265
+ }
266
+
267
+ uint32_t OLEDDisplayUi::getFirstNotifyingFrame () {
268
+ if (this ->state .notifyingFrames .size () == 0 ){
269
+ return -1 ;
270
+ }
271
+ return this ->state .notifyingFrames [0 ];
272
+ }
273
+
223
274
224
275
// -/----- State information -----\-
225
276
OLEDDisplayUiState* OLEDDisplayUi::getUiState (){
@@ -256,6 +307,7 @@ int16_t OLEDDisplayUi::update(){
256
307
257
308
void OLEDDisplayUi::tick () {
258
309
this ->state .ticksSinceLastStateSwitch ++;
310
+ this ->state .ticks ++;
259
311
260
312
switch (this ->state .frameState ) {
261
313
case IN_TRANSITION:
@@ -350,6 +402,10 @@ void OLEDDisplayUi::drawFrame(){
350
402
this ->state .transitionFrameRelationship = INCOMING;
351
403
// Since we're IN_TRANSITION, draw the mew frame in a sliding-in position
352
404
(this ->frameFunctions [this ->getNextFrameNumber ()])(this ->display , &this ->state , x1, y1);
405
+ // tell the consumer of this API that the frame that's coming into focus
406
+ // normally this would be to remove the notifications for this frame
407
+ if (frameNotificationCallbackFunction != nullptr )
408
+ (*frameNotificationCallbackFunction)(this ->getNextFrameNumber (), this );
353
409
354
410
// Build up the indicatorDrawState
355
411
if (drawenCurrentFrame && !this ->state .isIndicatorDrawen ) {
@@ -377,6 +433,10 @@ void OLEDDisplayUi::drawFrame(){
377
433
this ->state .transitionFrameRelationship = NONE;
378
434
// Since we're not transitioning, just draw the current frame at the origin
379
435
(this ->frameFunctions [this ->state .currentFrame ])(this ->display , &this ->state , 0 , 0 );
436
+ // tell the consumer of this API that the frame that's coming into focus
437
+ // normally this would be to remove the notifications for this frame
438
+ if (frameNotificationCallbackFunction != nullptr )
439
+ (*frameNotificationCallbackFunction)(this ->state .currentFrame , this );
380
440
break ;
381
441
}
382
442
}
@@ -460,17 +520,35 @@ void OLEDDisplayUi::drawIndicator() {
460
520
image = this ->inactiveSymbol ;
461
521
}
462
522
523
+ if (this ->state .notifyingFrames .size () > 0 ) {
524
+ for (uint8_t q=0 ;q<this ->state .notifyingFrames .size ();q++) {
525
+ // if the symbol for the frame we're currently drawing (i)
526
+ // is equal to the symbol in the array we're looking at (notff[q])
527
+ // then we should adjust `y` by the SIN function (actualOffset)
528
+ if (i == (this ->state .notifyingFrames [q])) {
529
+ #define MILISECONDS_PER_BUBBLE_BOUNDS 5000
530
+ uint8_t actualOffset = abs ((sin (this ->state .ticks *PI/(MILISECONDS_PER_BUBBLE_BOUNDS/updateInterval)) * notifyingFrameOffsetAmplitude));
531
+ // is the indicator (symbol / dot) we're currently drawing one that's requesting notification
532
+ y = y - actualOffset;
533
+ // display->drawString(0,0,String(actualOffset));
534
+ // display->drawString(0,30,String(this->state.ticks));
535
+ }
536
+ }
537
+ }
538
+
463
539
this ->display ->drawFastImage (x, y, 8 , 8 , image);
464
540
}
465
541
}
466
542
543
+
467
544
void OLEDDisplayUi::drawOverlays () {
468
545
for (uint8_t i=0 ;i<this ->overlayCount ;i++){
469
546
(this ->overlayFunctions [i])(this ->display , &this ->state );
470
547
}
471
548
}
472
549
473
550
uint8_t OLEDDisplayUi::getNextFrameNumber (){
474
- if (this ->nextFrameNumber != -1 ) return this ->nextFrameNumber ;
551
+ if (this ->nextFrameNumber != -1 )
552
+ return this ->nextFrameNumber ;
475
553
return (this ->state .currentFrame + this ->frameCount + this ->state .frameTransitionDirection ) % this ->frameCount ;
476
554
}
0 commit comments