Skip to content

Commit 218bf95

Browse files
committed
bugfix: serial refresh (reflexivity)
1 parent 8841fd5 commit 218bf95

File tree

7 files changed

+108
-64
lines changed

7 files changed

+108
-64
lines changed

examples/LCD_Demo/LCD_Demo.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ void scrSaver() {
153153

154154
//the quadEncoder
155155
quadEncoder quadEncoder(encA,encB);//simple quad encoder driver
156-
quadEncoderStream enc(quadEncoder,2);// simple quad encoder fake Stream
156+
quadEncoderStream enc(quadEncoder,4);// simple quad encoder fake Stream
157157

158158
//a keyboard with only one key :D, this is the encoder button
159159
keyMap encBtn_map[]={{-encBtn,menu::enterCode}};//negative pin numbers means we have a pull-up, this is on when low

examples/U8GLib_menu/U8GLib_menu.ino

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ promptFeedback quit() {
4646
return true;
4747
}
4848

49+
int selTest=0;
50+
SELECT(selTest,selMenu,"Select",
51+
VALUE("Zero",0),
52+
VALUE("One",1),
53+
VALUE("Two",2)
54+
);
55+
4956
MENU(subMenu,"SubMenu"
5057
,OP("TESTING LONG STRINGS",quit)
5158
,FIELD(param,"Name","%",0,100,10,1)
@@ -69,6 +76,7 @@ CHOOSE(adc_prescale,sample_clock,"Clock"
6976
);
7077

7178
MENU(mainMenu,"Main menu"
79+
,SUBMENU(selMenu)
7280
,SUBMENU(subMenu)
7381
,FIELD(param,"Name","%",0,100,10,1)
7482
,SUBMENU(sample_clock)

examples/gfx_menu/gfx_menu.ino

Lines changed: 83 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ http://www.r-site.net/?at=//op%5B%40id=%273090%27%5D
77
Sept. 2014 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
88
99
creative commons license 3.0: Attribution-ShareAlike CC BY-SA
10-
This software is furnished "as is", without technical support, and with no
10+
This software is furnished "as is", without technical support, and with no
1111
warranty, express or implied, as to its usefulness for any purpose.
1212
1313
Thread Safe: No
@@ -24,6 +24,7 @@ ruihfazevedo@[email protected]
2424
********/
2525
#include <SPI.h>
2626
#include <menu.h>//menu macros and objects
27+
#include <menuFields.h>
2728
#include <pcint.h>//this is incompatible with software serial (arduino needs an handler!)
2829
#include <quadEncoder.h>//quadrature encoder driver and fake stream
2930
#include <keyStream.h>//keyboard driver and fake stream (for the encoder button)
@@ -33,6 +34,8 @@ ruihfazevedo@[email protected]
3334
#include <Adafruit_ST7735.h> // Hardware-specific library
3435
#include <menuGFX.h>
3536

37+
#define LEDPIN A4
38+
3639
#if defined(__AVR_ATmega2560__)
3740
///////////////////////////////////////////////////////////////////////////
3841
//TFT + SD
@@ -49,40 +52,92 @@ ruihfazevedo@[email protected]
4952
///////////////////////////////////////////////////////////////////////////
5053
//TFT + SD
5154
//#define sdCS 9//not using SD card
52-
#define tftCS 10
53-
#define dc 7
54-
#define rst 8
55+
#define TFT_CS A1
56+
#define TFT_DC A0
57+
#define TFT_RST A2
5558
////////////////////////////////////////////
5659
// ENCODER (aka rotary switch) PINS
57-
#define encA A2
58-
#define encB A1
59-
#define encBtn A3
60+
#define encA 2
61+
#define encB 3
62+
#define encBtn 4
6063
#else
6164
#error "Uknown pinout"
6265
#endif
6366

64-
Adafruit_ST7735 tft(tftCS, dc, rst);
67+
Adafruit_ST7735 tft(TFT_CS, TFT_DC, TFT_RST);
68+
69+
//aux vars
70+
int ledCtrl=0;
71+
int percent;//just testing changing this var
72+
int counter=0;
73+
6574
///////////////////////////////////////////////////////////////////////////
6675
//functions to wire as menu actions
76+
bool ledOn() {
77+
Serial.println("set led on!");
78+
digitalWrite(LEDPIN,ledCtrl=1);
79+
return false;
80+
}
6781

68-
//aux function
69-
bool nothing() {return false;}
82+
bool ledOff() {
83+
Serial.println("set led off!");
84+
digitalWrite(LEDPIN,ledCtrl=0);
85+
return false;
86+
}
7087

71-
bool setValue(int &value,prompt &p,menuOut &o, Stream &i,const char* text,const char* units="",int sensivity=5,int low=0,int hi=100,int steps=0,bool (*func)()=nothing);
88+
bool quit() {
89+
Serial.println("Quiting after action call");
90+
return true;
91+
}
7292

7393
/////////////////////////////////////////////////////////////////////////
7494
// MENU DEFINITION
7595
// here we define the menu structure and wire actions functions to it
76-
MENU(subMenu,"Sub-Menu",
77-
OP("Op1",nothing),
78-
OP("Op2",nothing),
79-
OP("Op3",nothing)
96+
// empty options are just for scroll testing
97+
98+
/*bool setLed() {
99+
digitalWrite(LEDPIN,ledCtrl);
100+
return false;
101+
}*/
102+
TOGGLE(ledCtrl,setLed,"Led: ",
103+
VALUE("On",HIGH,ledOn),
104+
VALUE("Off",LOW,ledOff)
105+
);
106+
107+
int selTest=0;
108+
SELECT(selTest,selMenu,"Select",
109+
VALUE("Zero",0),
110+
VALUE("One",1),
111+
VALUE("Two",2)
80112
);
81113

82-
MENU(mainMenu,"Sistema",
83-
OP("A",nothing),
84-
OP("B",nothing),
85-
SUBMENU(subMenu)
114+
int chooseTest=-1;
115+
CHOOSE(chooseTest,chooseMenu,"Choose ",
116+
VALUE("First",1),
117+
VALUE("Second",2),
118+
VALUE("Third",3),
119+
VALUE("Last",-1)
120+
);
121+
122+
MENU(subMenu,"SubMenu"
123+
,OP("A",quit)
124+
,OP("B",quit)
125+
,OP("C",quit)
126+
,OP("D",quit)
127+
,OP("E",quit)
128+
,OP("F",quit)
129+
,OP("G",quit)
130+
,OP("H",quit)
131+
);
132+
133+
MENU(mainMenu,"Main menu",
134+
SUBMENU(setLed),
135+
OP("LED On",ledOn),
136+
OP("LED Off",ledOff),
137+
SUBMENU(selMenu),
138+
SUBMENU(chooseMenu),
139+
SUBMENU(subMenu),
140+
FIELD(percent,"Percent","%",0,100,10,1)
86141
);
87142

88143
//the quadEncoder
@@ -102,39 +157,34 @@ Stream* in3[]={&enc,&encButton};
102157
chainStream<3> allIn(in3);
103158

104159
//describing a menu output, alternatives so far are Serial or LiquidCrystal LCD
105-
menuGFX gfx(tft);
160+
menuGFX gfx(tft,BLUE,BLACK,WHITE,SILVER,6,9);
106161

107162
/////////////////////////////////////////////////////////////////////////
108163
void setup() {
164+
pinMode(LEDPIN,OUTPUT);
109165
SPI.begin();
110166
tft.initR(INITR_BLACKTAB);
111167
tft.setRotation(3);
112168
tft.setTextWrap(false);
113169
tft.setTextColor(ST7735_RED,ST7735_BLACK);
114-
tft.setTextSize(2);
115-
gfx.resX*=2;//update resolution after font size change
116-
gfx.resY*=2;//update resolution after font size change
170+
//tft.setTextSize(2);
171+
//gfx.resX*=2;//update resolution after font size change
172+
//gfx.resY*=2;//update resolution after font size change
117173
tft.fillScreen(ST7735_BLACK);
118174
tft.print("Menu test on GFX");
119175
//testing menu limits (not using all the screen)
120176
//size is within screen limits even after rotation
121177
//this limits are not constrained, please ensure your text fits
122-
gfx.maxX=8;
123-
gfx.maxY=3;
178+
gfx.maxX=16;
179+
gfx.maxY=5;
124180
gfx.bgColor=SILVER;
125-
126-
pinMode(encBtn, INPUT);
127-
digitalWrite(encBtn,1);
128-
181+
pinMode(encBtn, INPUT_PULLUP);
129182
encoder.begin();
130-
131-
delay(300);
132-
tft.fillScreen(GREEN);
133183
}
134184

135185
///////////////////////////////////////////////////////////////////////////////
136186
// testing the menu system
137187
void loop() {
138188
mainMenu.poll(gfx,allIn);
189+
digitalWrite(LEDPIN, ledCtrl);
139190
}
140-

examples/serial_menu/serial_menu.ino

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ SELECT(selTest,selMenu,"Select",
6565
);
6666

6767
int chooseTest=-1;
68-
CHOOSE(chooseTest,chooseMenu,"Choose ",
68+
CHOOSE(chooseTest,chooseMenu,"Choose",
6969
VALUE("First",1),
7070
VALUE("Second",2),
7171
VALUE("Third",3),
@@ -106,4 +106,5 @@ void setup() {
106106
void loop() {
107107
mainMenu.poll(menu_out,Serial);
108108
digitalWrite(LEDPIN,ledCtrl);
109+
delay(300);
109110
}

src/menu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ v2.1 - Add full support of SetPosition(x,y) to move the menu inside the screen (
2828
#include <Stream.h>
2929
#include <HardwareSerial.h>
3030

31+
//#define DEBUG
3132
#ifdef DEBUG
3233
#include <streamFlow.h>
3334
#endif

src/menuFields.h

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ v2.0 - Calling action on every elements
135135
menuVariant(T& target,const char *text,unsigned int sz,menuValue<T>* const data[]):
136136
menu(text,sz,(prompt**)data),target(target) {sync();}
137137
virtual bool needRedraw(menuOut&p,bool selected) {
138+
//Serial<<*(prompt*)this<<".needRedraw?"<<endl;
138139
bool nr=((menuValue<T>*)pgmPtrNear(data[sel]))->value!=target;//||p.lastSel!=sel;
139140
//T v=((menuValue<T>*)pgmPtrNear(data[sel]))->value;
140141
//if (nr) Serial<<"Variant need redraw:"<<*this<<endl<<"value:"<<v<<" target:"<<target<<" sel:"<<sel<<" lastSel:"<<p.lastSel<<endl;;
@@ -158,63 +159,44 @@ v2.0 - Calling action on every elements
158159
template<typename T>
159160
class menuSelect: public menuVariant<T> {
160161
public:
161-
int lastDrawnOp;//using extra var because we are drawing the previous menu with updated field, lastSel refers to it and not the current field.
162-
//lastSel is on the output device (future paralel output devices?) but it should be a focus chain on each output device to preserve
163-
//this kind of information... till there we can not use paralle output devices! RA2016
164162
menuSelect(const char *text,unsigned int sz,menuValue<T>* const data[],T& target):
165163
menuVariant<T>(target,text,sz,data) {menuVariant<T>::sync();}
166-
virtual bool needRedraw(menuOut&p,bool selected) {
167-
if (selected) {
168-
bool nr=lastDrawnOp!=menu::sel;//||((menuValue<T>*)pgmPtrNear(menu::data[menu::sel]))->value==menuVariant<T>::target;
169-
//T v=((menuValue<T>*)pgmPtrNear(menu::data[menu::sel]))->value;
170-
//if (nr) Serial<<"Variant need redraw:"<<*this<<endl
171-
/*Serial
172-
<<" value:"<<v<<endl
173-
<<" target:"<<menuVariant<T>::target
174-
<<" sel:"<<menu::sel
175-
<<" lastSel:"<<p.lastSel
176-
<<" lastDrawnOp:"<<lastDrawnOp
177-
<<endl;;*/
178-
//p.lastSel=menu::sel;
179-
lastDrawnOp=menu::sel;
180-
return nr;
181-
}
182-
return ((menuValue<T>*)pgmPtrNear(menu::data[menu::sel]))->value!=menuVariant<T>::target;
183-
}
184164
virtual void printTo(menuOut& p) {
185-
//Serial<<"drawing menuSelect"<<endl;
186165
menuVariant<T>::sync();
187166
print_P(p,menu::text);
188167
p.print(menu::activeNode==this?':':' ');
189168
((prompt*)pgmPtrNear(menu::data[menu::sel]))->printTo(p);
190169
}
191170
promptFeedback activate(menuOut& p,Stream& c,bool) {
192171
if (menu::activeNode!=this) {
193-
//Serial<<"first select"<<endl;
194172
if (menuVariant<T>::action(*this,p,c)) return true;
195173
this->setPosition(menuNode::activeNode->ox,menuNode::activeNode->oy);
196-
this->menu::previousMenu=(menu*)menu::activeNode;
174+
menu::previousMenu=(menu*)menu::activeNode;
197175
menu::activeNode=this;
198176
this->canExit=false;
199177
if (p.top>menu::sel) p.top=menu::sel;
200178
else if (menu::sel+1>p.maxY) p.top=menu::sel-p.maxY+1;
201179
p.lastSel=-1;//redraw only affected option
202180
}
181+
int lsel=menu::sel;
203182
int op=menu::menuKeys(p,c,false);
204-
menu::previousMenu->menu::printMenu(p,menu::previousMenu->canExit);
205183
if (op>=0&&op<this->menu::sz) {
206-
//Serial<<"Selecting op:"<<op<<endl;
207-
this->menu::sel=op;
184+
menu::sel=op;
208185
menuValue<T>* cp=(menuValue<T>*)pgmPtrNear(this->menu::data[op]);
209186
if (cp->enabled) {
210-
this->menuVariant<T>::target=cp->value;
187+
menuVariant<T>::target=cp->value;
211188
cp->activate(p,c,true);
212189
p.lastSel=-1;//redraw only affected option
213190
//and exit
214191
this->menu::activeNode=this->menu::previousMenu;
215192
c.flush();//reset the encoder
216193
}
217194
}
195+
if (menu::sel!=lsel) {
196+
menuVariant<T>::target=((menuValue<T>*)&operator[](menu::sel))->value;
197+
p.lastSel=-1;//redraw only affected option
198+
}
199+
menu::previousMenu->menu::printMenu(p,menu::previousMenu->canExit);
218200
//Serial<<"sel:"<<menu::sel<<" op:"<<op<<endl;
219201
return false;
220202
}

src/menuPrint.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ www.r-site.net
3131
println();
3232
}
3333
virtual void printMenu(menu& m,bool drawExit) {
34-
if (drawn==&m&&m.sel==lastSel) return;
34+
bool any=false;
35+
for(int i=0;i<m.sz;i++) any|=m[i].needRedraw(*this,i==m.sel);
36+
if ((!any)&&drawn==&m&&m.sel==lastSel) return;
3537
clear();
3638
int i=0;
3739
for(;i<m.sz;i++)

0 commit comments

Comments
 (0)