... | ... |
@@ -63,6 +63,85 @@ var knobsClass = { |
63 | 63 |
me.device.display.updateXPDR(); |
64 | 64 |
}, |
65 | 65 |
|
66 |
+ MenuSettings : func (d) { |
|
67 |
+ var (id, selected) = split('-', me.device.windows.selected); |
|
68 |
+ var state = me.device.windows.state[id]; |
|
69 |
+ if (find('choices', state.lines[selected].type) > -1) { |
|
70 |
+ var val = me.device.windows.window[me.device.windows.selected] |
|
71 |
+ .get('text'); |
|
72 |
+ forindex (var i; state.lines[selected].choices) |
|
73 |
+ if (state.lines[selected].choices[i] == val) { |
|
74 |
+ if (i == size(state.lines[selected].choices) - 1) |
|
75 |
+ me.device.windows.window[me.device.windows.selected] |
|
76 |
+ .setText(state.lines[selected].choices[0]); |
|
77 |
+ else |
|
78 |
+ me.device.windows.window[me.device.windows.selected] |
|
79 |
+ .setText(state.lines[selected].choices[i + 1]); |
|
80 |
+ break; |
|
81 |
+ } |
|
82 |
+ } |
|
83 |
+ elsif (find('time', state.lines[selected].type) > -1) { |
|
84 |
+ var val = me.device.windows.window[me.device.windows.selected] |
|
85 |
+ .get('text'); |
|
86 |
+ var (hh, mm, ss) = split(':', val); |
|
87 |
+ var time = hh * 3600 + mm * 60 + ss; |
|
88 |
+ if (time >= 600) # 10 min |
|
89 |
+ d *= 60; |
|
90 |
+ elsif (time >= 300) # 5 minutes |
|
91 |
+ d *= 30; |
|
92 |
+ elsif (time >= 180) # 3 minutes |
|
93 |
+ d *= 10; |
|
94 |
+ |
|
95 |
+ ss += d; |
|
96 |
+ |
|
97 |
+ if (ss > 59) { |
|
98 |
+ ss -= 60; |
|
99 |
+ mm += 1; |
|
100 |
+ if (mm > 59) { |
|
101 |
+ mm = 0; |
|
102 |
+ hh += 1; |
|
103 |
+ } |
|
104 |
+ } |
|
105 |
+ elsif (ss < 0) { |
|
106 |
+ if (mm > 0) { |
|
107 |
+ ss += 60; |
|
108 |
+ mm -= 1; |
|
109 |
+ } |
|
110 |
+ elsif (mm == 0 and hh > 0) { |
|
111 |
+ ss += 60; |
|
112 |
+ mm = 59; |
|
113 |
+ hh -= 1; |
|
114 |
+ } |
|
115 |
+ elsif (mm == 0 and hh == 0) |
|
116 |
+ ss = 0; |
|
117 |
+ } |
|
118 |
+ me.device.windows.window[me.device.windows.selected] |
|
119 |
+ .setText(sprintf('%02i:%02i:%02i', hh, mm, ss)); |
|
120 |
+ } |
|
121 |
+ }, |
|
122 |
+ |
|
123 |
+ NavigateMenu : func (d) { |
|
124 |
+ var (id, selected) = split('-', me.device.windows.selected); |
|
125 |
+ var state = me.device.windows.state[id]; |
|
126 |
+ for (var i = selected + d; i >= 0 and i < size(state.lines); i += d) { |
|
127 |
+ if (find('editable', state.lines[i].type) > -1) { |
|
128 |
+ state.lines[i].type = string.replace(state.lines[i].type, |
|
129 |
+ 'editable', 'selected'); |
|
130 |
+ state.lines[selected].type = string.replace(state.lines[selected].type, |
|
131 |
+ 'selected', 'editable'); |
|
132 |
+ me.device.windows.window[me.device.windows.selected] |
|
133 |
+ .setDrawMode(0x01) |
|
134 |
+ .setColor(0,1,1); |
|
135 |
+ me.device.windows.window[id ~ '-' ~ i] |
|
136 |
+ .setDrawMode(0x05) |
|
137 |
+ .setColorFill(0,1,1) |
|
138 |
+ .setColor(0,0,0); |
|
139 |
+ me.device.windows.selected = id ~ '-' ~ i; |
|
140 |
+ break; |
|
141 |
+ } |
|
142 |
+ } |
|
143 |
+ }, |
|
144 |
+ |
|
66 | 145 |
FmsInner : void, |
67 | 146 |
FmsOuter : void |
68 | 147 |
}; |
... | ... |
@@ -1,86 +1,155 @@ |
1 |
-var ADFDME = func { |
|
2 |
- nyi('AFDME softkey'); |
|
3 |
-} |
|
4 |
- |
|
5 |
-var IDENT = func { |
|
6 |
- nyi('IDENT softkey'); |
|
7 |
-} |
|
8 |
- |
|
9 |
-var VOR1 = func { |
|
10 |
- radios.getNode('nav2-selected').setIntValue(0); |
|
11 |
- radios.getNode('nav1-selected').setIntValue(1); |
|
12 |
- CDIfromNAV(0); |
|
13 |
-} |
|
14 |
- |
|
15 |
-var VOR2 = func { |
|
16 |
- radios.getNode('nav1-selected').setIntValue(0); |
|
17 |
- radios.getNode('nav2-selected').setIntValue(1); |
|
18 |
- CDIfromNAV(1); |
|
19 |
-} |
|
20 |
- |
|
21 |
-var STDBY = func { |
|
22 |
- setprop('/instrumentation/zkv1000/radios/xpdr-mode', 'STBY'); |
|
23 |
- setprop('/instrumentation/transponder/serviceable', 0); |
|
24 |
-} |
|
25 |
- |
|
26 |
-var ON = func { |
|
27 |
- setprop("/instrumentation/zkv1000/radios/xpdr-mode", "ON"); |
|
28 |
-} |
|
29 |
- |
|
30 |
-var ALT = func { |
|
31 |
- setprop("/instrumentation/zkv1000/radios/xpdr-mode", "ALT"); |
|
32 |
-} |
|
33 |
- |
|
34 |
-var GND = func { |
|
35 |
- setprop("/instrumentation/zkv1000/radios/xpdr-mode", "GND"); |
|
36 |
-} |
|
37 |
- |
|
38 |
-var VFR = func { |
|
39 |
- XPDR_old = getprop("/instrumentation/transponder/id-code"); |
|
40 |
- setprop("/instrumentation/transponder/id-code", 1200); |
|
41 |
-} |
|
42 |
- |
|
43 |
-var BKSP = func { |
|
44 |
- if (XPDR_n < 3) XPDR_n += 1; |
|
45 |
-} |
|
46 |
- |
|
47 |
-var LIGHT = func { |
|
48 |
- var b = '/instrumentation/zkv1000/body-emission'; |
|
49 |
- setprop(b, getprop(b) < 0.1 ? 0.5 : 0.0); |
|
50 |
-} |
|
51 |
- |
|
52 |
-var CHECKLIST = func { |
|
53 |
-} |
|
54 |
- |
|
55 |
-var LEAN = func { |
|
56 |
-} |
|
57 |
- |
|
58 |
-var FUEL = func (v) { |
|
59 |
-} |
|
60 |
- |
|
61 |
-var XPDR_n = 3; |
|
62 |
-var XPDR_old = 0; |
|
63 |
- |
|
64 |
- |
|
65 |
-var menuTable = [ |
|
66 |
- ' INSET PFD CDI ADF XPDR IDENT TMR NRST', |
|
67 |
- ' VOR1 VOR2 GPS OFF BACK', |
|
68 |
- ' OFF DCLTR TRAFF TOPO TERR STRM NEXR XMLTG BACK', |
|
69 |
- ' OFF DCLT1 DCLT2 DCLT3 BACK', |
|
70 |
- 'LIGHT DFLTS WIND DME BRG1 HSI BRG2 ALT U BARO BACK', |
|
71 |
- 'VOR1 GPS ADF OFF BACK', |
|
72 |
- 'VOR2 GPS ADF OFF BACK', |
|
73 |
- ' 360 ARC BACK', |
|
74 |
- ' OPT1 OPT2 OPT3 OFF BACK', |
|
75 |
- ' METER IN HPA BACK', |
|
76 |
- ' STBY ON ALT GND VFR CODE IDENT BACK', |
|
77 |
- ' 0 1 2 3 4 5 6 7 IDENT BKSP BACK', |
|
78 |
- ' SFD ENG MAP DCLTR CHKLS', |
|
79 |
- ' DCLT1 DCLT2 DCLT3 BACK', |
|
80 |
- ' TRAFF TOPO TERR STRM NEXR XMLTG BACK', |
|
81 |
- 'ENGN LEAN DECF INCF RSTF', |
|
82 |
- ' MFD INSET PFD CDI ADF XPDR IDENT TMR NRST', |
|
83 |
- ' LCL UTC RL CHRON BACK', |
|
84 |
-]; |
|
85 |
- |
|
86 |
- |
|
1 |
+var pageClass = { |
|
2 |
+ new : func (d) { |
|
3 |
+ var m = { parents : [pageClass] }; |
|
4 |
+ m.page = d.display.screen; |
|
5 |
+ m.window = {}; |
|
6 |
+ m.state = {}; |
|
7 |
+ m.selected = ''; |
|
8 |
+ return m; |
|
9 |
+ }, |
|
10 |
+ |
|
11 |
+ del : func (id = nil) { |
|
12 |
+ if (id != nil and typeof(v) == 'scalar') { |
|
13 |
+ delete(me.state, id); |
|
14 |
+ id = [ id ]; |
|
15 |
+ } |
|
16 |
+ else { |
|
17 |
+ foreach (var s; keys(me.state)) |
|
18 |
+ delete(me.state, s); |
|
19 |
+ id = keys(me.window); |
|
20 |
+ } |
|
21 |
+ foreach (var w; id) { |
|
22 |
+ me.window[w] |
|
23 |
+ .hide() |
|
24 |
+ .del(); |
|
25 |
+ delete(me.window, w); |
|
26 |
+ } |
|
27 |
+ }, |
|
28 |
+ |
|
29 |
+ _selected_text : func (id, text, x, y) { |
|
30 |
+ me.selected = id; |
|
31 |
+ me.window[id] |
|
32 |
+ .setFontSize(16) |
|
33 |
+ .setFont('LiberationFonts/LiberationMono-Regular.ttf') |
|
34 |
+ .setTranslation(x, y) |
|
35 |
+ .setDrawMode(0x01 + 0x04) |
|
36 |
+ .setText(text) |
|
37 |
+ .setColorFill(0,1,1) |
|
38 |
+ .setColor(0,0,0); |
|
39 |
+ }, |
|
40 |
+ |
|
41 |
+ _editable_text : func (id, text, x, y) { |
|
42 |
+ me.window[id] |
|
43 |
+ .setFontSize(16) |
|
44 |
+ .setFont('LiberationFonts/LiberationMono-Regular.ttf') |
|
45 |
+ .setTranslation(x, y) |
|
46 |
+ .setText(text) |
|
47 |
+ .setColorFill(0,0,0) |
|
48 |
+ .setColor(0,1,1); |
|
49 |
+ }, |
|
50 |
+ |
|
51 |
+ _normal_text : func (id, text, x, y) { |
|
52 |
+ me.window[id] |
|
53 |
+ .setFontSize(16) |
|
54 |
+ .setFont('LiberationFonts/LiberationMono-Regular.ttf') |
|
55 |
+ .setTranslation(x, y) |
|
56 |
+ .setText(text) |
|
57 |
+ .setColorFill(0,0,0) |
|
58 |
+ .setColor(1,1,1); |
|
59 |
+ }, |
|
60 |
+ |
|
61 |
+ _title_text : func (id, text, x, y) { |
|
62 |
+ me.window[id] |
|
63 |
+ .setFontSize(16) |
|
64 |
+ .setFont('LiberationFonts/LiberationMono-Regular.ttf') |
|
65 |
+ .setTranslation(x, y) |
|
66 |
+ .setAlignment('center-center') |
|
67 |
+ .setText(text) |
|
68 |
+ .setColorFill(0,0,0) |
|
69 |
+ .setColor(0,1,1); |
|
70 |
+ }, |
|
71 |
+ |
|
72 |
+ fill : func (id) { |
|
73 |
+ var state = me.state[id]; |
|
74 |
+ forindex (var line; state.lines) { |
|
75 |
+ if (find('separator', state.lines[line].type) > -1) { |
|
76 |
+ me.window[id ~ '-' ~ line] = me.page.createChild('path') |
|
77 |
+ .setStrokeLineWidth(1) |
|
78 |
+ .moveTo(state.x_base, state.geometry.y - 12) |
|
79 |
+ .horiz(state.geometry.w - 20) |
|
80 |
+ .setColor(1,1,1); |
|
81 |
+ state.geometry.x = state.x_base; |
|
82 |
+ state.geometry.y += 8; |
|
83 |
+ } |
|
84 |
+ else { |
|
85 |
+ me.window[id ~ '-' ~ line] = me.page.createChild('text'); |
|
86 |
+ if (find('normal', state.lines[line].type) > -1) |
|
87 |
+ me._normal_text( |
|
88 |
+ id ~ '-' ~ line, |
|
89 |
+ state.lines[line].text, |
|
90 |
+ state.geometry.x, |
|
91 |
+ state.geometry.y, |
|
92 |
+ ); |
|
93 |
+ |
|
94 |
+ elsif (find('selected', state.lines[line].type) > -1) |
|
95 |
+ me._selected_text( |
|
96 |
+ id ~ '-' ~ line, |
|
97 |
+ state.lines[line].text, |
|
98 |
+ state.geometry.x, |
|
99 |
+ state.geometry.y, |
|
100 |
+ ); |
|
101 |
+ |
|
102 |
+ elsif (find('editable', state.lines[line].type) > -1) |
|
103 |
+ me._editable_text( |
|
104 |
+ id ~ '-' ~ line, |
|
105 |
+ state.lines[line].text, |
|
106 |
+ state.geometry.x, |
|
107 |
+ state.geometry.y, |
|
108 |
+ ); |
|
109 |
+ |
|
110 |
+ elsif (find('title', state.lines[line].type) > -1) |
|
111 |
+ me._title_text( |
|
112 |
+ id ~ '-' ~ line, |
|
113 |
+ state.lines[line].text, |
|
114 |
+ state.x_base - 10 + state.geometry.w / 2, |
|
115 |
+ state.geometry.y |
|
116 |
+ ); |
|
117 |
+ |
|
118 |
+ if (find('end-of-line', state.lines[line].type) > -1 |
|
119 |
+ or find('title', state.lines[line].type) > -1) { |
|
120 |
+ state.geometry.x = state.x_base; |
|
121 |
+ state.geometry.y += 24; |
|
122 |
+ } |
|
123 |
+ else |
|
124 |
+ state.geometry.x += size(state.lines[line].text) * 10 + 8; |
|
125 |
+ } |
|
126 |
+ } |
|
127 |
+ }, |
|
128 |
+ |
|
129 |
+ draw : func (id, geometry, lines) { |
|
130 |
+ if (contains(me.window, id ~ '-bg')) { |
|
131 |
+ printlog('debug', 'objet ' ~ id ~ ' already exists'); |
|
132 |
+ return; |
|
133 |
+ } |
|
134 |
+ if (!contains(geometry, 'h') and !contains(geometry, 'l')) { |
|
135 |
+ printlog('debug', 'missing parameter l or h'); |
|
136 |
+ return; |
|
137 |
+ } |
|
138 |
+ me.state[id] = { |
|
139 |
+ lines: lines, |
|
140 |
+ geometry: geometry, |
|
141 |
+ x_base : geometry.x + 10, |
|
142 |
+ h_max : contains(geometry, 'h') ? h : geometry.l * 24 + 8 + geometry.sep * 16, |
|
143 |
+ }; |
|
144 |
+ me.state[id].y_max = me.state[id].h_max + me.state[id].geometry.y; |
|
145 |
+ me.window[id ~ '-bg'] = me.page.createChild('path'); |
|
146 |
+ me.window[id ~ '-bg'] |
|
147 |
+ .rect(geometry.x, geometry.y, |
|
148 |
+ geometry.w, me.state[id].h_max) |
|
149 |
+ .setColor(1,1,1) |
|
150 |
+ .setColorFill(0,0,0); |
|
151 |
+ me.state[id].geometry.x += 10; |
|
152 |
+ me.state[id].geometry.y += 16; |
|
153 |
+ me.fill(id); |
|
154 |
+ }, |
|
155 |
+}; |
... | ... |
@@ -81,6 +81,7 @@ Please report bug at <seb.marque@free.fr>. |
81 | 81 |
* ![][70%] |
82 | 82 |
* make booting animation visible ![][pending] |
83 | 83 |
* ![][60%] |
84 |
+ * windows management: selectable items ![][done], modifiable items ![][done], scrolling ![][ongoing] |
|
84 | 85 |
* ![][50%] |
85 | 86 |
* EIS: animations for temperature for YaSim and JSBSim |
86 | 87 |
* ![][40%] |
... | ... |
@@ -8,9 +8,9 @@ files_to_load = [ |
8 | 8 |
'softkeys.nas',# handles softkeys and menus items |
9 | 9 |
'map.nas', # moves the maps |
10 | 10 |
'display.nas', |
11 |
+ 'menu.nas', # manage windows |
|
11 | 12 |
'core.nas', # the scheduler and switch on button |
12 | 13 |
]; |
13 |
-# 'menu.nas', # manages menu entries andd perform some simple actions |
|
14 | 14 |
# 'afcs.nas', # Automatic Flight Control System |
15 | 15 |
# 'routes.nas', # manages flightplans and routes |
16 | 16 |
# 'display.nas', # display messages and popups |