Skip to content

Commit 609d23f

Browse files
committed
implemented menu width for GFX selection consistency
removed some bugs and fixed stream clean as part of the activate process
1 parent 7d76142 commit 609d23f

File tree

6 files changed

+92
-92
lines changed

6 files changed

+92
-92
lines changed

Examples/menu_test/menu_test.ino

Lines changed: 64 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -7,41 +7,43 @@
77
#include "quadEncoder.h"//quadrature encoder driver and fake stream
88
#include "keyStream.h"//keyboard driver and fake stream (for the encoder button)
99
#include "chainStream.h"// concatenate multiple input streams (this allows adding a button to the encoder)
10-
#include "menuLCD.h"
11-
#include "menuPrint.h"
12-
#include <Adafruit_GFX.h> // Co1re graphics library
13-
#include <Adafruit_ST7735.h> // Hardware-specific library
14-
#include <menuGFX.h>
15-
16-
///////////////////////////////////////////////////////////////////////////
17-
//TFT + SD
18-
//#define sdCS 4
19-
#define tftCS 5
20-
#define dc 6
21-
#define rst 7 // you can also connect this to the Arduino reset
22-
23-
Adafruit_ST7735 tft(tftCS, dc, rst);
24-
25-
//#define LCD_SZ_X 16
26-
//#define LCD_SZ_Y 2
10+
#include "menuPrint.h"//Print (Serial) menu
2711

2812
#define LCDWIRE_NONE 0
2913
#define LCDWIRE_VPINS_I2C 1
3014
#define LCDWIRE_VPINS_SPI 2
3115
#define LCDWIRE_I2C 3
3216
#define LCDWIRE_DIRECT 4
3317

34-
//how the LCS was wired
18+
//how the LCD is wired
3519
//#define LCD_WIRE LCDWIRE_NONE
3620
//#define LCD_WIRE LCDWIRE_VPINS_I2C
37-
#define LCD_WIRE LCDWIRE_VPINS_SPI//not implemented
38-
//#define LCD_WIRE LCDWIRE_I2C//not implemented
39-
//#define LCD_WIRE LCDWIRE_DIRECT//not implemented
21+
#define LCD_WIRE LCDWIRE_VPINS_SPI//on shift registers thru vpins (same library)
22+
//#define LCD_WIRE LCDWIRE_I2C//not tested
23+
//#define LCD_WIRE LCDWIRE_DIRECT//not tested
24+
25+
#define USE_TFT YES//YES|NO
26+
27+
#if (USE_TFT == YES)
28+
#include <Adafruit_GFX.h> // Co1re graphics library
29+
#include <Adafruit_ST7735.h> // Hardware-specific library
30+
#include <menuGFX.h>
31+
32+
///////////////////////////////////////////////////////////////////////////
33+
//TFT + SD
34+
//#define sdCS 4
35+
#define tftCS 5
36+
#define dc 6
37+
#define rst 7 // you can also connect this to the Arduino reset
38+
39+
Adafruit_ST7735 tft(tftCS, dc, rst);
40+
#endif
4041

42+
#define vpinsSPI_CS 9//vpins SPI CS
4143
#if (LCD_WIRE == LCDWIRE_VPINS_SPI)//LCD wired on shift registers using vpins
4244
#include <SPI.h>
4345
#include <VPinsSPI.h>
44-
#define vpinsSPI_CS 9//vpins SPI CS
46+
#include "menuLCD.h"
4547
#define STCP 9//stcp or latch pin
4648

4749
#define RS 26
@@ -53,6 +55,7 @@ Adafruit_ST7735 tft(tftCS, dc, rst);
5355

5456
#if (LCD_WIRE == LCDWIRE_VPINS_I2C)// LCD is wired over i2c to another AVR that uses virtual pins and shift registers to control it and virtual port server to share it
5557
#include <Wire.h>
58+
#include "menuLCD.h"
5659
//remote pins over I2C to VPort server
5760
#define vpinsSPI_CS srv_pb.pin(1)//vpins SPI CS
5861
#define STCP srv_pb.pin(1)//stcp or latch pin
@@ -117,6 +120,7 @@ MENU(mainMenu,"Sistema",
117120
OP("Dutty",setDutty),
118121
OP("Disabled",disabledTest),
119122
OP("Handler test",completeHandlerTest),
123+
/*OP("Handler test",completeHandlerTest),
120124
OP("Handler test",completeHandlerTest),
121125
OP("Handler test",completeHandlerTest),
122126
OP("Handler test",completeHandlerTest),
@@ -126,8 +130,7 @@ MENU(mainMenu,"Sistema",
126130
OP("Handler test",completeHandlerTest),
127131
OP("Handler test",completeHandlerTest),
128132
OP("Handler test",completeHandlerTest),
129-
OP("Handler test",completeHandlerTest),
130-
OP("Handler test",completeHandlerTest),
133+
OP("Handler test",completeHandlerTest),*/
131134
SUBMENU(subMenu)
132135
);
133136

@@ -137,7 +140,7 @@ quadEncoderStream enc(quadEncoder,5);// simple quad encoder fake Stream
137140

138141
//a keyboard with only one key :D, this is the encoder button
139142
keyMap encBtn_map[]={{-encBtn,13}};//negative pin numbers means we have a pull-up, this is on when low
140-
keyLook<2> encButton(encBtn_map);
143+
keyLook<1> encButton(encBtn_map);
141144

142145
//multiple inputs allow conjugation of the quadEncoder with a single key keyboard that is the quadEncoder button
143146
Stream* in[]={&enc,&encButton};
@@ -149,11 +152,16 @@ chainStream<3> allIn(in3);
149152

150153
//describing a menu output, alternatives so far are Serial or LiquidCrystal LCD
151154
menuPrint serial(Serial);
152-
menuLCD lcd(lcd1,16,2);
153-
menuGFX gfx(tft);
155+
#if (LCD_WIRE!=LCDWIRE_NONE)
156+
menuLCD lcd(lcd1,16,2);
157+
#endif
158+
#if (USE_TFT == YES)
159+
menuGFX gfx(tft);
160+
#endif
161+
menuPrint menuSerialOut(Serial);//describe output device
154162

155163
//menuOut* out[]={&lcd,&serial};
156-
//chainOut<2> allOut(out);
164+
//chainOut<2> allOut(out);//not implemented multiple outputs... useless i think
157165

158166
///////////////////////////////////////////////////////////////////////////////
159167

@@ -163,11 +171,15 @@ void setup() {
163171
Serial.begin(9600);
164172
Serial.println("menu system test");
165173

174+
#if ((LCD_WIRE != LCDWIRE_NONE) || (USE_TFT == YES))
166175
pinMode(vpinsSPI_CS,OUTPUT);
167176
digitalWrite(vpinsSPI_CS,LOW);
177+
#endif
168178

169179
#if (LCD_WIRE == LCDWIRE_VPINS_SPI)
170180
SPI.begin();
181+
lcd1.begin(16,2);
182+
lcd1.print("Menu test");
171183
#endif
172184

173185
#if (LCD_WIRE == LCDWIRE_VPINS_I2C)
@@ -176,11 +188,10 @@ void setup() {
176188
srv_vpa.begin();// wait for server ready (all on same server, so)
177189
//srv_vpb.begin();// wait for server ready
178190
Serial.println("all servers ready!");
179-
#endif
180191

181-
lcd1.begin(16,2);
182-
lcd1.print("Menu test");
192+
#endif
183193

194+
#if (USE_TFT == YES)
184195
digitalWrite(vpinsSPI_CS,HIGH);
185196
digitalWrite(tftCS,HIGH);
186197
tft.initR(INITR_BLACKTAB);
@@ -191,17 +202,10 @@ void setup() {
191202
tft.fillScreen(ST7735_BLACK);
192203
tft.print("Menu test on GFX");
193204
tft.setCursor(0,10);
194-
195-
digitalWrite(vpinsSPI_CS,LOW);
196-
digitalWrite(tftCS,LOW);
197-
lcd1.setCursor(0,1);
198-
lcd1.print(mainMenu.width);
199-
digitalWrite(vpinsSPI_CS,HIGH);
200-
digitalWrite(tftCS,HIGH);
201-
202205
//update limits after screen rotation
203206
gfx.maxX=tft.width()/gfx.resX;
204207
gfx.maxY=tft.height()/gfx.resY;
208+
#endif
205209

206210
pinMode(encBtn, INPUT);
207211
digitalWrite(encBtn,1);
@@ -212,14 +216,25 @@ void setup() {
212216
///////////////////////////////////////////////////////////////////////////////
213217
// testing the menu system
214218
void loop() {
215-
gfx.clear();
216-
tft.print("DEBUG");
217-
//mainMenu.activate(Serial,Serial);//show menu to Serial and read keys from Serial
218-
//mainMenu.activate(lcd,allIn);//show menu on LCD and use multiple inputs to navigate (defined encoder, encoder button, serial)
219-
mainMenu.activate(gfx,allIn);//show menu on LCD and use multiple inputs to navigate (defined encoder, encoder button, serial)
220-
//mainMenu.activate(lcd1,allIn);//show menu on LCD and multiple inputs to navigate, defaults to LCD 16x1
221-
//mainMenu.activate(lcd,Serial);//very bad combination!
222-
//mainMenu.activate(Serial,enc);//bad combination! shopw menu on serial and navigate using quadEncoder
219+
//mainMenu.activate(menuSerialOut,Serial);//show menu to Serial and read keys from Serial
220+
//Serial.println("");
221+
//Serial.println("Restarting...");
222+
223+
#if (LCD_WIRE != LCDWIRE_NONE)
224+
//digitalWrite(vpinsSPI_CS,LOW);
225+
//digitalWrite(tftCS,LOW);
226+
//mainMenu.activate(lcd,allIn);//show menu on LCD and use multiple inputs to navigate (defined encoder, encoder button, serial)
227+
//mainMenu.activate(lcd1,allIn);//show menu on LCD and multiple inputs to navigate, defaults to LCD 16x1
228+
//mainMenu.activate(lcd,Serial);//very bad combination!
229+
//mainMenu.activate(Serial,enc);//bad combination! shopw menu on serial and navigate using quadEncoder
230+
#endif
231+
232+
#if (USE_TFT == YES)
233+
digitalWrite(vpinsSPI_CS,HIGH);
234+
digitalWrite(tftCS,HIGH);
235+
mainMenu.activate(gfx,allIn);//show menu on LCD and use multiple inputs to navigate (defined encoder, encoder button, serial)
236+
#endif
237+
223238
}
224239

225240
void nothing() {}
@@ -268,9 +283,9 @@ void setValue(prompt &p,menuOut &o, Stream &i,int &value,const char* text,const
268283
last=pos;
269284
}
270285
//func();
271-
//}
286+
}
272287
delay(100);
273288
while(encButton.read()==13);
274-
}
289+
//}
275290
}
276291

Examples/serial_menu/serial_menu.ino

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,4 @@ void loop() {
3131
mainMenu.activate(menu_out,Serial);
3232
Serial.println("");
3333
Serial.println("Restarting...");
34-
Serial.println("");
35-
Serial.flush();//send all data
36-
while(Serial.available()) Serial.read();//clean the stream
3734
}

menu.cpp

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -41,47 +41,21 @@ int menu::menuKeys(menuOut &p,Stream& c) {
4141
return op;
4242
}
4343

44-
void menu::printMenu(menuOut& p) {
45-
p.clear();
46-
//if (p.style==menuOut::enumerated) {p.print(text); p.print("==========================");}
47-
if (sel-p.top>=p.maxY) p.top=sel-p.maxY+1;//selected option outside device (bottom)
48-
else if (sel<p.top) p.top=sel;//selected option outside device (top)
49-
int i=0;for(;i<sz;i++) {
50-
if ((i>=p.top)&&((i-p.top)<p.maxY)) {
51-
//p.setCursor(0,i-p.top);
52-
if(i-p.top>=p.maxY) break;
53-
/*if (p.style==menuOut::enumerated) {
54-
p.print(i<10?" ":"");
55-
p.print(i+1);
56-
}*/
57-
p.print(*data[i],i==sel,i+1,i-p.top,width);
58-
/*p.print((i==sel)?data[i]->enabled?menu::enabledCursor:menu::disabledCursor:' ');
59-
p.print(data[i]->text);*/
60-
}
61-
}
62-
if (i-p.top<p.maxY) {
63-
//p.setCursor(0,i-p.top);
64-
/*if (p.style==menuOut::enumerated)
65-
p.print(" 0");*/
66-
p.print(exitOption,sel==sz,0,i-p.top,width);
67-
/*p.print(sel==sz?menu::enabledCursor:' ');
68-
p.println(menu::exit);*/
69-
}
70-
}
71-
7244
void menu::activate(menuOut& p,Stream& c) {
7345
sel=0;
7446
p.top=0;
7547
int op=-1;
7648
do {
7749
printMenu(p);
50+
c.flush();//reset the encoder
51+
while(c.available()) c.read();//clean the stream
7852
op=menuKeys(p,c);
7953
if (op>=0&&op<sz) {
8054
sel=op;
81-
if (data[op]->enabled) data[op]->activate(p,c);
55+
if (data[op]->enabled)
56+
data[op]->activate(p,c);
57+
p.drawn=0;//redraw menu
8258
}
83-
c.flush();//reset the encoder
84-
while(c.available()) c.read();//clean the stream
8559
} while(op!=-1);
8660
}
8761

menu.h

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,22 +100,16 @@ for encoders, joysticks, keyboards or touch a stream must be made out of them
100100
// this base class represents the output device either derived to serial, LCD or other
101101
class menuOut {
102102
public:
103+
menu* drawn;//last drawn menu, avoiding clear/redraw on each nav. change
103104
int top;//top for this device
104105
//device size
105106
int maxX;
106107
int maxY;
107108
//device resolution
108109
int resX;
109110
int resY;
110-
/*enum styles {
111-
enumerated, //print numbers or references for options, adequated keyboard or file input
112-
cursor,//print a cursor at selected option, tracking device (encoder)
113-
point,//pointing device (not implemented)
114-
} style;*/
115-
//menuOut(menuOut::styles style=menuOut::enumerated):maxX(0),maxY(0),style(style),top(0) {}
116-
//menuOut(menuOut::styles style=menuOut::enumerated,int width=0x7F,int x=0x7F,int y=0x7F,int resX=1,int resY=1):maxX(x),maxY(y),style(style),top(0),resX(resX),resY(resY) {}
117111
menuOut(int x=0x7F,int y=0x7F,int resX=1,int resY=1)
118-
:maxX(x),maxY(y),top(0),resX(resX),resY(resY) {}
112+
:maxX(x),maxY(y),top(0),resX(resX),resY(resY),drawn(0) {}
119113
virtual void clear()=0;
120114
virtual void setCursor(int x,int y)=0;
121115
virtual void print(char ch)=0;
@@ -124,6 +118,7 @@ for encoders, joysticks, keyboards or touch a stream must be made out of them
124118
virtual void print(int)=0;
125119
virtual void println(int)=0;
126120
virtual void print(prompt &o,bool selected,int idx,int posY,int width)=0;
121+
virtual void printMenu(menu&)=0;
127122
};
128123

129124
////////////////////////////////////////////////////////////////////
@@ -178,7 +173,7 @@ for encoders, joysticks, keyboards or touch a stream must be made out of them
178173
menu(const char * text,int sz,prompt* const data[]):prompt(text),sz(sz),data(data),sel(0),width(16) {}
179174

180175
int menuKeys(menuOut &p,Stream& c);
181-
void printMenu(menuOut& p);
176+
void printMenu(menuOut& p) {p.printMenu(*this);}
182177

183178
void activate(menuOut& p,Stream& c);
184179
};

menuLCD.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,19 @@
2020
print(selected?(o.enabled?menu::enabledCursor:menu::disabledCursor):' ');
2121
print(o.text);
2222
}
23+
virtual void printMenu(menu& m) {
24+
clear();
25+
if (m.sel-top>=maxY) top=m.sel-maxY+1;//selected option outside device (bottom)
26+
else if (m.sel<top) top=m.sel;//selected option outside device (top)
27+
int i=0;for(;i<m.sz;i++) {
28+
if ((i>=top)&&((i-top)<maxY)) {
29+
if(i-top>=maxY) break;
30+
print(*m.data[i],i==m.sel,i+1,i-top,m.width);
31+
}
32+
}
33+
if (i-top<maxY)
34+
print(menu::exitOption,m.sel==m.sz,0,i-top,m.width);
35+
}
2336
};
2437
#endif RSITE_ARDUINOP_MENU_LCD
2538

menuPrint.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@
2121
print(selected?(o.enabled?menu::enabledCursor:menu::disabledCursor):' ');
2222
println(o.text);
2323
}
24+
virtual void printMenu(menu& m) {
25+
clear();
26+
int i=0;for(;i<m.sz;i++)
27+
print(*m.data[i],i==m.sel,i+1,i-top,m.width);
28+
print(menu::exitOption,m.sel==m.sz,0,i-top,m.width);
29+
}
2430
};
2531

2632
#endif RSITE_ARDUINOP_MENU_PRINT

0 commit comments

Comments
 (0)