Showing 7 changed files with 149 additions and 81 deletions
+2 -2
Nasal/core.nas
... ...
@@ -102,9 +102,9 @@ var deviceClass = {
102 102
         m.node = zkv.getNode('device[' ~ d ~ ']', 1);
103 103
         m.display  = displayClass.new(m, m.role);
104 104
         m.display.showInitProgress(m.role);
105
-        m.buttons  = buttonsClass.new(m.node);
106
-        m.knobs    = knobsClass.new(m.node);
107 105
         m.softkeys = softkeysClass.new(m, m.node, m.role);
106
+        m.buttons  = buttonsClass.new(m.node);
107
+        m.knobs    = knobsClass.new(m);
108 108
         m.display.loadsvg();
109 109
         m.display.loadGroup({
110 110
             hide : [
+12 -10
Nasal/display.nas
... ...
@@ -967,15 +967,17 @@ var displayClass = {
967 967
             me.screenElements['XPDR-DIGIT-' ~ d ~ '-text']
968 968
                 .setText(sprintf('%i', getprop('/instrumentation/transponder/inputs/digit[' ~ d ~ ']')));
969 969
         var tuning = getprop('/instrumentation/zkv1000/radios/xpdr-tuning-digit');
970
-        if (tuning != nil)
971
-            for (var d = 0; d < 4; d+=1) {
972
-                if (d != tuning)
973
-                    me.screenElements['XPDR-DIGIT-' ~ d ~ '-text']
974
-                        .setColor(1,1,1);
975
-                else
976
-                    me.screenElements['XPDR-DIGIT-' ~ d ~ '-text']
977
-                        .setColor(0,1,1);
978
-            }
970
+        var fms = getprop('/instrumentation/zkv1000/radios/xpdr-tuning-fms-method');
971
+        for (var d = 0; d < 4; d+=1)
972
+            me.screenElements['XPDR-DIGIT-' ~ d ~ '-text']
973
+                .setColor(1,1,1);
974
+        if (tuning != nil) {
975
+            me.screenElements['XPDR-DIGIT-' ~ tuning ~ '-text']
976
+                .setColor(0,1,1);
977
+            if (fms)
978
+                me.screenElements['XPDR-DIGIT-' ~ (tuning - 1) ~ '-text']
979
+                    .setColor(0,1,1);
980
+        }
979 981
         else {
980 982
             if (getprop('/instrumentation/transponder/ident'))
981 983
                 var mode = 'IDENT';
... ...
@@ -993,7 +995,7 @@ var displayClass = {
993 995
                 .setColor(color)
994 996
                 .setText(mode);
995 997
         }
996
-},
998
+    },
997 999
 #}}}
998 1000
 
999 1001
     updateOAT : func {
+60 -2
Nasal/knobs.nas
... ...
@@ -1,10 +1,68 @@
1 1
 var knobsClass = {
2
-    new : func (node) {
2
+    new : func (device) {
3 3
         var m = { parents: [ knobsClass ] };
4
-        m.node = node;
4
+        m.device = device;
5 5
         return m;
6 6
     },
7 7
 
8
+    XPDRCodeSetDigits : func (d) {
9
+        # disable SoftKey entering method
10
+        setprop('/instrumentation/zkv1000/radios/xpdr-tuning-fms-method', 1);
11
+        if (!contains(me.device.softkeys.bindings.PFD.XPDR.CODE, 'on_change_inactivity')) {
12
+            me.device.softkeys.bindings.PFD.XPDR.CODE.inactivity.stop();
13
+            me.device.softkeys.bindings.PFD.XPDR.CODE.on_change_inactivity = maketimer(10,
14
+                func {
15
+                    setprop('/instrumentation/zkv1000/radios/xpdr-tuning-digit', 3);
16
+                    call(me.device.softkeys.bindings.PFD.XPDR.CODE.restore, [], me);
17
+                });
18
+            me.device.softkeys.bindings.PFD.XPDR.CODE.on_change_inactivity.singleShot = 1;
19
+            me.device.softkeys.bindings.PFD.XPDR.CODE.on_change_inactivity.start();
20
+        }
21
+        else
22
+            me.device.softkeys.bindings.PFD.XPDR.CODE.on_change_inactivity.restart(10);
23
+        var digit = getprop('/instrumentation/zkv1000/radios/xpdr-tuning-digit');
24
+        var code = getprop('/instrumentation/transponder/id-code');
25
+        if (digit == 3)
26
+            var val = int(code/100) + d;
27
+        else
28
+            var val = math.mod(code, 100) + d;
29
+        if (math.mod(val, 10) == 8) {
30
+            if (val > 77)
31
+                val = 0;
32
+            else
33
+                val += 2;
34
+        }
35
+        elsif (val < 0)
36
+            val = 77;
37
+        elsif (math.mod(val, 10) == 9)
38
+            val -= 2;
39
+        if (digit == 3)
40
+            setprop('/instrumentation/transponder/id-code',
41
+                    sprintf('%i', val * 100 + math.mod(code, 100)));
42
+        else
43
+            setprop('/instrumentation/transponder/id-code',
44
+                    sprintf('%i', int(code/100) * 100 + val));
45
+        me.device.display.updateXPDR();
46
+    },
47
+
48
+    XPDRCodeNextDigits : func {
49
+        setprop('/instrumentation/zkv1000/radios/xpdr-tuning-fms-method', 1);
50
+        if (!contains(me.device.softkeys.bindings.PFD.XPDR.CODE, 'on_change_inactivity')) {
51
+            me.device.softkeys.bindings.PFD.XPDR.CODE.inactivity.stop();
52
+            me.device.softkeys.bindings.PFD.XPDR.CODE.on_change_inactivity = maketimer(10,
53
+                func {
54
+                    setprop('/instrumentation/zkv1000/radios/xpdr-tuning-digit', 3);
55
+                    call(me.device.softkeys.bindings.PFD.XPDR.CODE.restore, [], me);
56
+                });
57
+            me.device.softkeys.bindings.PFD.XPDR.CODE.on_change_inactivity.singleShot = 1;
58
+            me.device.softkeys.bindings.PFD.XPDR.CODE.on_change_inactivity.start();
59
+        }
60
+        else
61
+            me.device.softkeys.bindings.PFD.XPDR.CODE.on_change_inactivity.restart(10);
62
+        setprop('/instrumentation/zkv1000/radios/xpdr-tuning-digit', 1);
63
+        me.device.display.updateXPDR();
64
+    },
65
+
8 66
     FmsInner : void,
9 67
     FmsOuter : void
10 68
 };
+60 -15
Nasal/softkeys.nas
... ...
@@ -146,13 +146,42 @@ var softkeysClass = {
146 146
                 },
147 147
                 CODE : {
148 148
                     '0' : func (n = 0) {
149
+                        if (getprop('/instrumentation/zkv1000/radios/xpdr-tuning-fms-method'))
150
+                            return;
151
+                        me.device.display.timers2.softkeys_inactivity.stop();
149 152
                         me.bindings.PFD.XPDR.CODE.inactivity.restart(me.device.display.softkeys_inactivity_delay);
150
-                        me.device.display.timers2.softkeys_inactivity.restart(me.device.display.softkeys_inactivity_delay);
153
+                        # disable FMS knob entering method
154
+                        me.device.knobs.FmsInner = void;
155
+                        # When entering the code, the next softkey in sequence
156
+                        # must be pressed within 10 seconds, or the entry is cancelled
157
+                        # and restored to the previous code
158
+                        if (!contains(me.bindings.PFD.XPDR.CODE, 'on_change_inactivity')) {
159
+                            me.bindings.PFD.XPDR.CODE.on_change_inactivity = maketimer(10,
160
+                                func {
161
+                                    setprop('/instrumentation/zkv1000/radios/xpdr-tuning-digit', 3);
162
+                                    me.device.knobs.FmsInner = me.device.knobs.XPDRCodeSetDigits;
163
+                                    me.device.knobs.FmsOuter = me.device.knobs.XPDRCodeNextDigits;
164
+                                    call(me.bindings.PFD.XPDR.CODE.restore, [], me);
165
+                                });
166
+                            me.bindings.PFD.XPDR.CODE.on_change_inactivity.singleShot = 1;
167
+                            me.bindings.PFD.XPDR.CODE.on_change_inactivity.start();
168
+                        }
169
+                        else
170
+                            me.bindings.PFD.XPDR.CODE.on_change_inactivity.restart(10);
151 171
                         var tuning = radios.getNode('xpdr-tuning-digit');
152 172
                         var d = tuning.getValue();
153 173
                         setprop('/instrumentation/transponder/inputs/digit[' ~ d ~ ']', n);
154
-                        d += (d > 0) ? -1 : 3;
155
-                        tuning.setValue(d);
174
+                        if (d == 1) {
175
+                            if (!contains(me.bindings.PFD.XPDR.CODE, 'on_change_auto_validation'))
176
+                                me.bindings.PFD.XPDR.CODE.on_change_auto_validation = maketimer(5,
177
+                                    func call(me.bindings.PFD.IDENT, [], me));
178
+                            me.bindings.PFD.XPDR.CODE.on_change_auto_validation.singleShot = 1;
179
+                            me.bindings.PFD.XPDR.CODE.on_change_auto_validation.start();
180
+                        }
181
+                        else {
182
+                            d -= 1;
183
+                            tuning.setValue(d);
184
+                        }
156 185
                         me.device.display.updateXPDR();
157 186
                     },
158 187
                     '1' : func {
... ...
@@ -182,44 +211,60 @@ var softkeysClass = {
182 211
                         call(me.bindings.PFD.IDENT, [], me);
183 212
                     },
184 213
                     BKSP: func {
185
-                        me.bindings.PFD.XPDR.CODE.inactivity.restart(me.device.display.softkeys_inactivity_delay);
186
-                        me.device.display.timers2.softkeys_inactivity.restart(me.device.display.softkeys_inactivity_delay);
214
+                        if (getprop('/instrumentation/zkv1000/radios/xpdr-tuning-fms-method'))
215
+                            return;
216
+                        if (contains(me.bindings.PFD.XPDR.CODE, 'on_change_inactivity'))
217
+                            me.bindings.PFD.XPDR.CODE.on_change_inactivity.restart(10);
218
+                        if (contains(me.bindings.PFD.XPDR.CODE, 'on_change_auto_validation'))
219
+                                me.bindings.PFD.XPDR.CODE.on_change_auto_validation.stop();
187 220
                         var tuning = radios.getNode('xpdr-tuning-digit');
188 221
                         var d = tuning.getValue();
189
-                        d += (d < 3) ? 1 : -3;
190
-                        tuning.setValue(d);
222
+                        if (d < 3) {
223
+                            d += 1;
224
+                            tuning.setValue(d);
225
+                        }
191 226
                         me.device.display.updateXPDR();
192 227
                     },
193 228
                     BACK : func (inactive = 0) {
194
-                        var code = sprintf('%i', getprop('/instrumentation/zkv1000/radios/xpdr-backup-code'));
195
-                        for (var i = 0; i < 4; i += 1)
196
-                            setprop('/instrumentation/transponder/inputs/digit[' ~ (3 - i) ~ ']',
197
-                                    substr(code, i, 1));
229
+                        call(me.bindings.PFD.XPDR.CODE.restore, [], me);
198 230
                         pop(me.path);
199
-                        call(me.bindings.PFD.XPDR.CODE.exit, inactive ? [[]] : [me.path], me);
231
+                        call(me.bindings.PFD.XPDR.CODE.exit, [me.path], me);
232
+                    },
233
+                    restore : func {
234
+                        setprop('/instrumentation/transponder/id-code',
235
+                            sprintf('%s', getprop('/instrumentation/zkv1000/radios/xpdr-backup-code')));
236
+                        me.device.display.updateXPDR();
200 237
                     },
201 238
                     exit : func (p) {
202 239
                         if (contains(me.bindings.PFD.XPDR.CODE, 'inactivity')) # does not exists if IDENT pressed from top-level
203 240
                             me.bindings.PFD.XPDR.CODE.inactivity.stop();
204 241
                         radios.removeChild('xpdr-tuning-digit', 0);
205 242
                         radios.removeChild('xpdr-backup-code', 0);
243
+                        radios.removeChild('xpdr-tuning-fms-method', 0);
206 244
                         me.path = p;
207 245
                         me.device.display.updateXPDR();
208 246
                         me.device.display.updateSoftKeys();
247
+                        me.device.knobs.FmsInner = void;
248
+                        me.device.knobs.FmsOuter = void;
249
+                        me.device.display.timers2.softkeys_inactivity.restart(me.device.display.softkeys_inactivity_delay);
209 250
                     },
210 251
                     hook : func {
211
-                        # this level has its own timer as we may need to revert changes
252
+                        # this level has its own timer as we may need to revert changes, and got different timers
253
+                        me.device.display.timers2.softkeys_inactivity.stop();
212 254
                         me.bindings.PFD.XPDR.CODE.inactivity = maketimer(
213 255
                             me.device.display.softkeys_inactivity_delay,
214
-                            func call(me.bindings.PFD.XPDR.CODE.BACK, [1], me));
256
+                            func call(me.bindings.PFD.XPDR.CODE.BACK, [], me));
215 257
                         me.bindings.PFD.XPDR.CODE.inactivity.singleShot = 1;
216 258
                         me.bindings.PFD.XPDR.CODE.inactivity.start();
217 259
                         var tuning = getprop('/instrument/zkv1000/radios/xpdr-tuning-digit');
218 260
                         if (tuning == nil) {
219 261
                             radios.getNode('xpdr-tuning-digit', 1).setValue(3);
220 262
                             radios.getNode('xpdr-backup-code', 1).setValue(getprop('/instrumentation/transponder/id-code'));
263
+                            radios.getNode('xpdr-tuning-fms-method', 1).setValue(0);
221 264
                             me.device.display.updateXPDR();
222 265
                         }
266
+                        me.device.knobs.FmsInner = me.device.knobs.XPDRCodeSetDigits;
267
+                        me.device.knobs.FmsOuter = me.device.knobs.XPDRCodeNextDigits;
223 268
                     },
224 269
                 },
225 270
             },
... ...
@@ -234,7 +279,7 @@ var softkeysClass = {
234 279
                         });
235 280
                 me.bindings.PFD.XPDR.ident.singleShot = 1;
236 281
                 me.bindings.PFD.XPDR.ident.start();
237
-                call(me.bindings.PFD.XPDR.CODE.exit, [[]], me);
282
+                call(me.bindings.PFD.XPDR.CODE.exit, [], me);
238 283
             },
239 284
             CDI : func {
240 285
                 var list = ['OFF'];
+1 -2
README.md
... ...
@@ -60,7 +60,7 @@ Please report bug at <seb.marque@free.fr>.
60 60
   * 3D knobs rotate
61 61
   * map display on inflight page (with online maps downloading and caching)
62 62
   * display of NavAids on map
63
-  * XPDR from SoftKeys
63
+  * XPDR from SoftKeys and knob, with respect of delays from the manual
64 64
   * Selected altitude bug (widget off if IA within 100ft)
65 65
   * baro settings
66 66
   * SoftKeys menus navigation for PFD and MFD
... ...
@@ -86,7 +86,6 @@ Please report bug at <seb.marque@free.fr>.
86 86
 * ![][10%]
87 87
   * multikey for every part of the device (actually only power on)
88 88
 * ![][0%] (TODO list, unsorted)
89
-  * XPDR from FMS knob
90 89
   * rotating online map on inflight page
91 90
   * some aircraft specific data to retrieve from aircraft XML files (VNE, etc)
92 91
   * display of specific speeds in ruler
+7 -25
mfd.xml
... ...
@@ -799,26 +799,15 @@
799 799
   </animation>
800 800
 
801 801
   <animation>
802
-    <type>pick</type>
802
+    <type>knob</type>
803 803
     <object-name>FmsOuter</object-name>
804 804
     <action>
805
-      <button>3</button>
806 805
       <binding>
807 806
         <condition>
808 807
           <property>/instrumentation/zkv1000/device[1]/status</property>
809 808
         </condition>
810 809
         <command>nasal</command>
811
-        <script>zkv1000.device[1].knobs.FmsOuter(1);</script>
812
-      </binding>
813
-    </action>
814
-    <action>
815
-      <button>4</button>
816
-      <binding>
817
-        <condition>
818
-          <property>/instrumentation/zkv1000/device[1]/status</property>
819
-        </condition>
820
-        <command>nasal</command>
821
-        <script>zkv1000.device[1].knobs.FmsOuter(-1);</script>
810
+        <script>zkv1000.device[1].knobs.FmsOuter(cmdarg().getNode('offset').getValue());</script>
822 811
       </binding>
823 812
     </action>
824 813
   </animation>
... ...
@@ -845,24 +834,17 @@
845 834
         </binding>
846 835
       </mod-up>
847 836
     </action>
837
+  </animation>
838
+  <animation>
839
+    <type>knob</type>
840
+    <object-name>FmsInner</object-name>
848 841
     <action>
849
-      <button>3</button>
850
-      <binding>
851
-        <condition>
852
-          <property>/instrumentation/zkv1000/device[1]/status</property>
853
-        </condition>
854
-        <command>nasal</command>
855
-        <script>zkv1000.device[1].knobs.FmsInner(1);</script>
856
-      </binding>
857
-    </action>
858
-    <action>
859
-      <button>4</button>
860 842
       <binding>
861 843
         <condition>
862 844
           <property>/instrumentation/zkv1000/device[1]/status</property>
863 845
         </condition>
864 846
         <command>nasal</command>
865
-        <script>zkv1000.device[1].knobs.FmsInner(-1);</script>
847
+        <script>zkv1000.device[1].knobs.FmsInner(cmdarg().getNode('offset').getValue());</script>
866 848
       </binding>
867 849
     </action>
868 850
   </animation>
+7 -25
pfd.xml
... ...
@@ -810,26 +810,15 @@
810 810
   </animation>
811 811
 
812 812
   <animation>
813
-    <type>pick</type>
813
+    <type>knob</type>
814 814
     <object-name>FmsOuter</object-name>
815 815
     <action>
816
-      <button>3</button>
817 816
       <binding>
818 817
         <condition>
819 818
           <property>/instrumentation/zkv1000/device[0]/status</property>
820 819
         </condition>
821 820
         <command>nasal</command>
822
-        <script>zkv1000.device[0].knobs.FmsOuter(1);</script>
823
-      </binding>
824
-    </action>
825
-    <action>
826
-      <button>4</button>
827
-      <binding>
828
-        <condition>
829
-          <property>/instrumentation/zkv1000/device[0]/status</property>
830
-        </condition>
831
-        <command>nasal</command>
832
-        <script>zkv1000.device[0].knobs.FmsOuter(-1);</script>
821
+        <script>zkv1000.device[0].knobs.FmsOuter(cmdarg().getNode('offset').getValue());</script>
833 822
       </binding>
834 823
     </action>
835 824
   </animation>
... ...
@@ -856,24 +845,17 @@
856 845
         </binding>
857 846
       </mod-up>
858 847
     </action>
848
+  </animation>
849
+  <animation>
850
+    <type>knob</type>
851
+    <object-name>FmsInner</object-name>
859 852
     <action>
860
-      <button>3</button>
861
-      <binding>
862
-        <condition>
863
-          <property>/instrumentation/zkv1000/device[0]/status</property>
864
-        </condition>
865
-        <command>nasal</command>
866
-        <script>zkv1000.device[0].knobs.FmsInner(1);</script>
867
-      </binding>
868
-    </action>
869
-    <action>
870
-      <button>4</button>
871 853
       <binding>
872 854
         <condition>
873 855
           <property>/instrumentation/zkv1000/device[0]/status</property>
874 856
         </condition>
875 857
         <command>nasal</command>
876
-        <script>zkv1000.device[0].knobs.FmsInner(-1);</script>
858
+        <script>zkv1000.device[0].knobs.FmsInner(cmdarg().getNode('offset').getValue());</script>
877 859
       </binding>
878 860
     </action>
879 861
   </animation>