Skip to content

Commit 52f9fc2

Browse files
authored
Merge pull request #149 from cbpdk/master
Added OzOled menuIO and example
2 parents aed3fcd + b7e0707 commit 52f9fc2

File tree

2 files changed

+210
-0
lines changed

2 files changed

+210
-0
lines changed
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
2+
//using https://github.com/kdkanishka/ozoled-oled-display-096-i2c-driver-library
3+
4+
#include <Arduino.h>
5+
#include "OzOLED.h"
6+
7+
#include <menu.h>
8+
#include <menuIO/OzOledAsciiOut.h>
9+
#include <menuIO/serialIn.h>
10+
using namespace Menu;
11+
12+
//Redefine already existing object
13+
#define oled OzOled
14+
15+
result doAlert(eventMask e, prompt &item);
16+
17+
result showEvent(eventMask e,navNode& nav,prompt& item) {
18+
Serial.print("event: ");
19+
Serial.println(e);
20+
return proceed;
21+
}
22+
23+
int test=55;
24+
25+
result action1(eventMask e) {
26+
Serial.print(e);
27+
Serial.println(" action1 executed, proceed menu");Serial.flush();
28+
return proceed;
29+
}
30+
31+
result action2(eventMask e,navNode& nav, prompt &item) {
32+
Serial.print(e);
33+
Serial.println(" action2 executed, quiting menu");
34+
return quit;
35+
}
36+
37+
int ledCtrl=LOW;
38+
39+
result ledOn() {
40+
ledCtrl=HIGH;
41+
return proceed;
42+
}
43+
result ledOff() {
44+
ledCtrl=LOW;
45+
return proceed;
46+
}
47+
48+
TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,noStyle//,doExit,enterEvent,noStyle
49+
,VALUE("On",HIGH,doNothing,noEvent)
50+
,VALUE("Off",LOW,doNothing,noEvent)
51+
);
52+
53+
int selTest=0;
54+
SELECT(selTest,selMenu,"Select",doNothing,noEvent,noStyle
55+
,VALUE("Zero",0,doNothing,noEvent)
56+
,VALUE("One",1,doNothing,noEvent)
57+
,VALUE("Two",2,doNothing,noEvent)
58+
);
59+
60+
int chooseTest=-1;
61+
CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
62+
,VALUE("First",1,doNothing,noEvent)
63+
,VALUE("Second",2,doNothing,noEvent)
64+
,VALUE("Third",3,doNothing,noEvent)
65+
,VALUE("Last",-1,doNothing,noEvent)
66+
);
67+
68+
//customizing a prompt look!
69+
//by extending the prompt class
70+
class altPrompt:public prompt {
71+
public:
72+
altPrompt(constMEM promptShadow& p):prompt(p) {}
73+
Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t) override {
74+
return out.printRaw("special prompt!",len);
75+
}
76+
};
77+
78+
MENU(subMenu,"Sub-Menu",showEvent,anyEvent,noStyle
79+
,OP("Sub1",showEvent,anyEvent)
80+
,OP("Sub2",showEvent,anyEvent)
81+
,OP("Sub3",showEvent,anyEvent)
82+
,altOP(altPrompt,"",showEvent,anyEvent)
83+
,EXIT("<Back")
84+
);
85+
86+
MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
87+
,OP("Op1",action1,anyEvent)
88+
,OP("Op2",action2,enterEvent)
89+
,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
90+
,SUBMENU(subMenu)
91+
,SUBMENU(setLed)
92+
,OP("LED On",ledOn,enterEvent)
93+
,OP("LED Off",ledOff,enterEvent)
94+
,SUBMENU(selMenu)
95+
,SUBMENU(chooseMenu)
96+
,OP("Alert test",doAlert,enterEvent)
97+
,EXIT("<Back")
98+
);
99+
100+
101+
102+
#define MAX_DEPTH 2
103+
//Only one build-in font
104+
#define fontW 8
105+
#define fontH 8
106+
107+
//describing a menu output device without macros
108+
//define at least one panel for menu output
109+
const panel panels[] MEMMODE={{0,0,128/fontW,64/fontH}};
110+
navNode* nodes[sizeof(panels)/sizeof(panel)];//navNodes to store navigation status
111+
panelsList pList(panels,nodes,1);//a list of panels and nodes
112+
idx_t tops[MAX_DEPTH]={0,0};//store cursor positions for each level
113+
OzOledAsciiOut outOLED(&oled,tops,pList);//oled output device menu driver
114+
menuOut* constMEM outputs[] MEMMODE={&outOLED};//list of output devices
115+
outputsList out(outputs,1);//outputs list
116+
117+
//macro to create navigation control root object (nav) using mainMenu
118+
serialIn serial(Serial);
119+
NAVROOT(nav,mainMenu,MAX_DEPTH,serial,out);
120+
121+
result alert(menuOut& o,idleEvent e) {
122+
if (e==idling) {
123+
o.setCursor(0,0);
124+
o.print("alert test");
125+
o.setCursor(0,1);
126+
o.print("press [select]");
127+
o.setCursor(0,2);
128+
o.print("to continue...");
129+
}
130+
return proceed;
131+
}
132+
133+
result doAlert(eventMask e, prompt &item) {
134+
nav.idleOn(alert);
135+
return proceed;
136+
}
137+
138+
//when menu is suspended
139+
result idle(menuOut &o, idleEvent e) {
140+
o.clear();
141+
switch(e) {
142+
case idleStart:o.println("suspending menu!");break;
143+
case idling:o.println("suspended...");break;
144+
case idleEnd:o.println("resuming menu.");break;
145+
}
146+
return proceed;
147+
}
148+
149+
void setup() {
150+
Serial.begin(115200);
151+
while(!Serial);
152+
Serial.println("menu 4.x test");Serial.flush();
153+
oled.init();
154+
oled.clearDisplay();
155+
//Vertical flip, comment out if display upside down.
156+
oled.sendCommand(0xC8);
157+
oled.sendCommand(0xA1);
158+
//End Vertical flip
159+
oled.printString("Hello world!");
160+
nav.idleTask=idle;//point a function to be used when menu is suspended
161+
}
162+
163+
void loop() {
164+
nav.poll();
165+
delay(100);//simulate a delay when other tasks are done
166+
}

src/menuIO/OzOledAsciiOut.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/* -*- C++ -*- */
2+
3+
//using OzOled
4+
//using https://github.com/kdkanishka/ozoled-oled-display-096-i2c-driver-library
5+
6+
#ifndef RSITE_ARDUINO_MENU_OZOLEDASCIIOUT
7+
#define RSITE_ARDUINO_MENU_OZOLEDASCIIOUT
8+
9+
#include "../menu.h"
10+
// #include <Wire.h>
11+
// #include <LCD.h>
12+
13+
namespace Menu {
14+
15+
class OzOledAsciiOut:public menuOut {
16+
public:
17+
OzOLED* device;
18+
inline OzOledAsciiOut(OzOLED* o,idx_t *t,panelsList &p,menuOut::styles s=menuOut::minimalRedraw)
19+
:menuOut(t,p,s),device(o) {}
20+
size_t write(uint8_t ch) override { device->printChar(ch); return 1;}
21+
void clearLine(idx_t ln,idx_t panelNr=0,colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
22+
setCursor(0,ln,panelNr);
23+
for(int n=0;n<maxX();n++) print(' ');
24+
setCursor(0,ln,panelNr);
25+
}
26+
void clear() override {
27+
device->clearDisplay();
28+
panels.reset();
29+
}
30+
void clear(idx_t panelNr) override {
31+
const panel p=panels[panelNr];
32+
fill(p.x,p.y,p.x+p.w-1,p.y+p.h-1);
33+
setCursor(0,0,panelNr);
34+
panels.nodes[panelNr]=NULL;
35+
}
36+
void setCursor(idx_t x,idx_t y,idx_t panelNr=0) override {
37+
const panel p=panels[panelNr];
38+
device->setCursorXY(p.x+x,p.y+y);
39+
}
40+
};
41+
42+
}//namespace Menu
43+
44+
#endif

0 commit comments

Comments
 (0)