zkv1000 / Nasal / softkeys.nas /
28b8897 7 years ago
1 contributor
366 lines | 18.667kb
var softkeysClass = {
    new : func (device, node, role) {
        var m = { parents: [ softkeysClass ] };
        m.node = node;
        m.device = device;
        m.role = substr(role, 0, 3);
        m.path = [];
        return m;
    },

    SoftKey : func (n, a) {
        # released key not yet managed
        if (a == 1)
            return;

        var key = me.device.display.screenElements[sprintf("SoftKey%02i-text",n)].get('text');
        if (key == '' or key == nil)
            return;

        var path = keyMap[me.role];
        foreach(var p; me.path) {
            if (contains(path, p))
                path = path[p];
            else
                break;
        }

        var bindings = me.bindings[me.role];
        foreach(var p; me.path) {
            if (contains(bindings, p))
                bindings = bindings[p];
            else
                break;
        }

        if (contains(path, key)) {
            append(me.path, key);
            if (contains(bindings, key))
                if (contains(bindings[key], 'hook'))
                    call(bindings[key].hook, [], me);
            me.device.display.updateSoftKeys();
        }
        elsif (contains(bindings, key)) {
            call(bindings[key], [], me);
        }
        elsif (key == 'BACK') {
            pop(me.path);
            me.device.display.updateSoftKeys();
        }
        else {
            var list_path = '';
            foreach(var p; me.path) list_path ~= p ~ '/';
            print(me.device.role ~ ':' ~ list_path ~ key ~ ' : not yet implemented');
        }
    },

    bindings : {
        PFD : {
            INSET: {
                OFF: func {
                    pop(me.path);
                    me.device.display.updateSoftKeys();
                },
            },
            PFD: {
                'AOA/WIND' : {
                    WIND : {
                        OPTN1 : func {
                            me.device.display._winddata_optn = 1;
                            me.device.display.screenElements['WindData'].show();
                            me.device.display.screenElements['WindData-OPTN1'].show();
                            me.device.display.screenElements['WindData-OPTN1-HDG'].show();
                            me.device.display.screenElements['WindData-OPTN2'].hide();
                            me.device.display.updateWindData();
                        },
                        OPTN2 : func {
                            me.device.display._winddata_optn = 2;
                            me.device.display.screenElements['WindData'].show();
                            me.device.display.screenElements['WindData-OPTN1'].hide();
                            me.device.display.screenElements['WindData-OPTN2'].show();
                            me.device.display.screenElements['WindData-OPTN2-symbol'].show();
                            me.device.display.screenElements['WindData-OPTN2-headwind'].show();
                            me.device.display.screenElements['WindData-OPTN2-crosswind'].show();
                            me.device.display.updateWindData();
                        },
                        OFF : func {
                            me.device.display._winddata_optn = 0;
                            me.device.display.screenElements['WindData'].hide();
                            me.device.display.screenElements['WindData-OPTN1'].hide();
                            me.device.display.screenElements['WindData-OPTN2'].hide();
                        },
                    },
                },
                BRG1 : func (brg = 1){
                    var source = 'brg' ~ brg ~ '-source';
                    var list = ['NAV' ~ brg, 'GPS', 'ADF', 'OFF'];
                    var index = std.Vector
                                   .new(list)
                                   .index(radios.getNode(source).getValue());
                    var next = (index == size(list) -1) ?  0 : index + 1;
                    radios.getNode(source).setValue(list[next]);
                },
                BRG2 : func {
                    call(me.bindings.PFD.PFD.BRG1, [ 2 ], me);
                },
                'STD BARO' : func {
                    setprop('/instrumentation/altimeter/setting-inhg', 29.92);
                    me.device.display.updateBARO();
                    pop(me.path);
                    me.device.display.updateSoftKeys();
                },
                IN :  func {
                    me.device.display._baro_unit = 'inhg';
                    me.device.display.updateBARO();
                },
                HPA : func {
                    me.device.display._baro_unit = 'hpa';
                    me.device.display.updateBARO();
                },
            },
            XPDR: {
                STBY : func {
                    setprop('/instrumentation/transponder/ident', 0);
                    setprop('/instrumentation/transponder/knob-mode', 1);
                    setprop('/instrumentation/zkv1000/radio/xpdr-mode', 'STBY');
                    me.device.display.updateXPDR();
                },
                ON : func {
                    setprop('/instrumentation/transponder/ident', 1);
                    setprop('/instrumentation/transponder/knob-mode', 4);
                    setprop('/instrumentation/zkv1000/radio/xpdr-mode', 'ON');
                    me.device.display.updateXPDR();
                },
                ALT : func {
                    setprop('/instrumentation/transponder/ident', 1);
                    setprop('/instrumentation/transponder/knob-mode', 5);
                    setprop('/instrumentation/zkv1000/radio/xpdr-mode', 'ALT');
                    me.device.display.updateXPDR();
                },
                VFR : func {
                    setprop('/instrumentation/transponder/id-code', '1200');
                    me.device.display.updateXPDR();
                },
                IDENT : func {
                    call(me.bindings.PFD.IDENT, [], me);
                },
                CODE : {
                    '0' : func (n = 0) {
                        if (getprop('/instrumentation/zkv1000/radios/xpdr-tuning-fms-method'))
                            return;
                        me.device.display.timers2.softkeys_inactivity.stop();
                        me.bindings.PFD.XPDR.CODE.inactivity.restart(me.device.display.softkeys_inactivity_delay);
                        # disable FMS knob entering method
                        me.device.knobs.FmsInner = void;
                        # When entering the code, the next softkey in sequence
                        # must be pressed within 10 seconds, or the entry is cancelled
                        # and restored to the previous code
                        if (!contains(me.bindings.PFD.XPDR.CODE, 'on_change_inactivity')) {
                            me.bindings.PFD.XPDR.CODE.on_change_inactivity = maketimer(10,
                                func {
                                    setprop('/instrumentation/zkv1000/radios/xpdr-tuning-digit', 3);
                                    me.device.knobs.FmsInner = me.device.knobs.XPDRCodeSetDigits;
                                    me.device.knobs.FmsOuter = me.device.knobs.XPDRCodeNextDigits;
                                    call(me.bindings.PFD.XPDR.CODE.restore, [], me);
                                });
                            me.bindings.PFD.XPDR.CODE.on_change_inactivity.singleShot = 1;
                            me.bindings.PFD.XPDR.CODE.on_change_inactivity.start();
                        }
                        else
                            me.bindings.PFD.XPDR.CODE.on_change_inactivity.restart(10);
                        var tuning = radios.getNode('xpdr-tuning-digit');
                        var d = tuning.getValue();
                        setprop('/instrumentation/transponder/inputs/digit[' ~ d ~ ']', n);
                        if (d == 1) {
                            if (!contains(me.bindings.PFD.XPDR.CODE, 'on_change_auto_validation'))
                                me.bindings.PFD.XPDR.CODE.on_change_auto_validation = maketimer(5,
                                    func call(me.bindings.PFD.IDENT, [], me));
                            me.bindings.PFD.XPDR.CODE.on_change_auto_validation.singleShot = 1;
                            me.bindings.PFD.XPDR.CODE.on_change_auto_validation.start();
                        }
                        else {
                            d -= 1;
                            tuning.setValue(d);
                        }
                        me.device.display.updateXPDR();
                    },
                    '1' : func {
                        call(me.bindings.PFD.XPDR.CODE['0'], [ 1 ], me);
                    },
                    '2' : func {
                        call(me.bindings.PFD.XPDR.CODE['0'], [ 2 ], me);
                    },
                    '3' : func {
                        call(me.bindings.PFD.XPDR.CODE['0'], [ 3 ], me);
                    },
                    '4' : func {
                        call(me.bindings.PFD.XPDR.CODE['0'], [ 4 ], me);
                    },
                    '5' : func {
                        call(me.bindings.PFD.XPDR.CODE['0'], [ 5 ], me);
                    },
                    '6' : func {
                        call(me.bindings.PFD.XPDR.CODE['0'], [ 6 ], me);
                    },
                    '7' : func {
                        call(me.bindings.PFD.XPDR.CODE['0'], [ 7 ], me);
                    },
                    IDENT: func {
                        me.bindings.PFD.XPDR.CODE.inactivity.restart(me.device.display.softkeys_inactivity_delay);
                        me.device.display.timers2.softkeys_inactivity.restart(me.device.display.softkeys_inactivity_delay);
                        call(me.bindings.PFD.IDENT, [], me);
                    },
                    BKSP: func {
                        if (getprop('/instrumentation/zkv1000/radios/xpdr-tuning-fms-method'))
                            return;
                        if (contains(me.bindings.PFD.XPDR.CODE, 'on_change_inactivity'))
                            me.bindings.PFD.XPDR.CODE.on_change_inactivity.restart(10);
                        if (contains(me.bindings.PFD.XPDR.CODE, 'on_change_auto_validation'))
                                me.bindings.PFD.XPDR.CODE.on_change_auto_validation.stop();
                        var tuning = radios.getNode('xpdr-tuning-digit');
                        var d = tuning.getValue();
                        if (d < 3) {
                            d += 1;
                            tuning.setValue(d);
                        }
                        me.device.display.updateXPDR();
                    },
                    BACK : func (inactive = 0) {
                        call(me.bindings.PFD.XPDR.CODE.restore, [], me);
                        pop(me.path);
                        call(me.bindings.PFD.XPDR.CODE.exit, [me.path], me);
                    },
                    restore : func {
                        setprop('/instrumentation/transponder/id-code',
                            sprintf('%s', getprop('/instrumentation/zkv1000/radios/xpdr-backup-code')));
                        me.device.display.updateXPDR();
                    },
                    exit : func (p) {
                        if (contains(me.bindings.PFD.XPDR.CODE, 'inactivity')) # does not exists if IDENT pressed from top-level
                            me.bindings.PFD.XPDR.CODE.inactivity.stop();
                        radios.removeChild('xpdr-tuning-digit', 0);
                        radios.removeChild('xpdr-backup-code', 0);
                        radios.removeChild('xpdr-tuning-fms-method', 0);
                        me.path = p;
                        me.device.display.updateXPDR();
                        me.device.display.updateSoftKeys();
                        me.device.knobs.FmsInner = void;
                        me.device.knobs.FmsOuter = void;
                        me.device.display.timers2.softkeys_inactivity.restart(me.device.display.softkeys_inactivity_delay);
                    },
                    hook : func {
                        # this level has its own timer as we may need to revert changes, and got different timers
                        me.device.display.timers2.softkeys_inactivity.stop();
                        me.bindings.PFD.XPDR.CODE.inactivity = maketimer(
                            me.device.display.softkeys_inactivity_delay,
                            func call(me.bindings.PFD.XPDR.CODE.BACK, [], me));
                        me.bindings.PFD.XPDR.CODE.inactivity.singleShot = 1;
                        me.bindings.PFD.XPDR.CODE.inactivity.start();
                        var tuning = getprop('/instrument/zkv1000/radios/xpdr-tuning-digit');
                        if (tuning == nil) {
                            radios.getNode('xpdr-tuning-digit', 1).setValue(3);
                            radios.getNode('xpdr-backup-code', 1).setValue(getprop('/instrumentation/transponder/id-code'));
                            radios.getNode('xpdr-tuning-fms-method', 1).setValue(0);
                            me.device.display.updateXPDR();
                        }
                        me.device.knobs.FmsInner = me.device.knobs.XPDRCodeSetDigits;
                        me.device.knobs.FmsOuter = me.device.knobs.XPDRCodeNextDigits;
                    },
                },
            },
            IDENT : func {
                if (getprop('/instrumentation/zkv1000/radio/xpdr-mode') == 'STBY')
                    return;
                setprop('/instrumentation/transponder/ident', 1);
                me.bindings.PFD.XPDR.ident = maketimer(18,
                        func {
                            setprop('/instrumentation/transponder/ident', 0);
                            me.device.display.updateXPDR();
                        });
                me.bindings.PFD.XPDR.ident.singleShot = 1;
                me.bindings.PFD.XPDR.ident.start();
                call(me.bindings.PFD.XPDR.CODE.exit, [], me);
            },
            CDI : func {
                var list = ['OFF'];
                if (getprop('/instrumentation/gps/route-distance-nm') != nil)
                    append(list, 'GPS');
                if (getprop('/instrumentation/nav/in-range') != nil)
                    append(list, 'NAV1');
                if (getprop('/instrumentation/nav[1]/in-range') != nil)
                    append(list, 'NAV2');
                var index = std.Vector
                               .new(list)
                               .index(cdi.getNode('source').getValue());
                var next = (index == size(list) -1) ?  0 : index + 1;
                cdi.getNode('source').setValue(list[next]);
                CDIfromSOURCE(list[next]);
                me.device.display.updateCDI();
            },
            'TMR/REF' : func {
                if (!contains(me.device.windows.state, 'TMR/REF')) {
                    me.device.windows.draw(
                        'TMR/REF',
                        {x: 720, y: 535, w: 300, l: 5, sep: 3},
                        [ # objects infos
                            {text: 'REFERENCES', type: 'title'},
                            {type: 'separator'},
                            {text: 'TIMER', type: 'normal'},
                            {text: '00:00:00', type: 'selected|time', },
                            {text: '  UP >', type: 'editable', choices: ['  UP >', '<DOWN '], callback: func},
                            {text: 'START?', type: 'editable|end-of-line|choices', choices: ['START?', 'RESET?', 'STOP?'], callback: func},
                            {type: 'separator'},
                            {text: sprintf('Vx     % 3iKT', alerts.getNode('Vx').getValue()), type: 'normal', scrollgroup:0},
                            {text: '   ON >', type: 'editable|end-of-line', choices: ['   ON >', '< OFF  '], scrollgroup:0, callback: func},
                            {text: sprintf('Vy     % 3iKT', alerts.getNode('Vy').getValue()), type: 'normal', scrollgroup:1},
                            {text: '   ON >', type: 'editable|end-of-line', choices: ['   ON >', '< OFF  '], scrollgroup:1, callback: func},
                            {text: sprintf('Vr     % 3iKT', alerts.getNode('Vr').getValue()), type: 'normal', scrollgroup:2},
                            {text: '   ON >', type: 'editable|end-of-line', choices: ['   ON >', '< OFF  '], scrollgroup:2, callback: func},
                            {text: sprintf('Vglide % 3iKT', alerts.getNode('Vglide').getValue()), type: 'normal', scrollgroup:3},
                            {text: '   ON >', type: 'editable|end-of-line', choices: ['   ON >', '< OFF  '], scrollgroup:3, callback: func},
                            {type: 'separator'},
                            {text: 'MINIMUMS', type: 'normal'},
                            {text: '  BARO >', type: 'editable', choices: ['  BARO >','< TST1 >','< TST2  '], callback: func},
                            {text: ' 1000FT', type: 'editable', format: '% 5iFT', factor: 100, callback: func},
                        ],
                        { # scrolling info, see menu.nas
                            lines : 3,
                            columns : 2,
                        }
                    );
                    me.device.knobs.FmsInner = me.device.knobs.MenuSettings;
                    me.device.knobs.FmsOuter = me.device.knobs.NavigateMenu;
                }
                else {
                    me.device.knobs.FmsInner = func;
                    me.device.knobs.FmsOuter = func;
                    me.device.windows.del();
                }
            },
        },
        MFD : {
            ENGINE: {
                FUEL: {
                    UNDO: func {
                        pop(me.path);
                        me.device.display.updateSoftKeys();
                    },
                    ENTER: func {
                        pop(me.path);
                        me.device.display.updateSoftKeys();
                    },
                },
                ENGINE: func {
                    me.path = [];
                    me.device.display.updateSoftKeys();
                },
            },
            CHKLIST : {
                EXIT: func {
                    me.path = [];
                    me.device.display.updateSoftKeys();
                },
            },
        },
    },
};