Showing 1 changed files with 323 additions and 1 deletions
+323 -1
Nasal/softkeys.nas
... ...
@@ -554,6 +554,324 @@ var softkeysClass = {
554 554
                 },
555 555
             },
556 556
             CHKLIST : {
557
+                _showCheckList: func (id, selected) {
558
+                    var tabulate = func (l, r, t = 3, c = '.') {
559
+                        var s = '';
560
+                        for (var i = 0; i < (l - r) + t; i += 1) s ~= c;
561
+                        return s;
562
+                    }
563
+
564
+                    var groupIndex     = me.device.windows.state[id].objects[selected].groupIndex;
565
+                    var checklistIndex = me.device.windows.state[id].objects[selected].checklistIndex;
566
+
567
+                    if (contains(me.device.windows.state[id].objects[selected], 'pageIndex'))
568
+                        pageIndex = me.device.windows.state[id].objects[selected].pageIndex;
569
+                    else
570
+                        pageIndex = -1;
571
+
572
+                    var title = '';
573
+                    if (contains(me.device.windows.state[id].objects[selected], 'checklistTitle'))
574
+                        title = me.device.windows.state[id].objects[selected].checklistTitle;
575
+                    else
576
+                        title = me.device.windows.state[id].objects[selected].text;
577
+
578
+                    me.device.windows.del(id);
579
+
580
+                    if (groupIndex < 0)
581
+                         checklistNode = props.globals.getNode("/sim/checklists")
582
+                                    .getChild('checklist', checklistIndex);
583
+                    else
584
+                         checklistNode = props.globals.getNode("/sim/checklists")
585
+                                    .getChild("group", groupIndex)
586
+                                    .getChild('checklist', checklistIndex);
587
+
588
+                    var pages = checklistNode.getChildren('page');
589
+
590
+                    if (size(pages) and pageIndex == -1)
591
+                        pageIndex = 0;
592
+
593
+                    _previous_text = ' < PREVIOUS ';
594
+                    _next_text     = ' NEXT > ';
595
+
596
+                    var obj_infos = [];
597
+                    var length = size(_previous_text ~ _next_text);
598
+                    var length_cache = [];
599
+                    if (size(pages))
600
+                        checklistNode = pages[pageIndex];
601
+
602
+                    append(obj_infos, {
603
+                        text: sprintf('%s%s',
604
+                                      title,
605
+                                      size(pages) > 1 ? sprintf(' %d / %d',
606
+                                                                pageIndex + 1,
607
+                                                                size(pages)) : ''),
608
+                        type: 'title'
609
+                    });
610
+
611
+                    append(obj_infos, {type: 'separator'});
612
+
613
+                    forindex (var i; checklistNode.getChildren('item')) {
614
+                        var l = size(checklistNode.getChild('item', i).getValue('name'));
615
+                        if (checklistNode.getChild('item', i).getChild('value') != nil)
616
+                            l += size(checklistNode.getChild('item', i).getValue('value'));
617
+                        append(length_cache, l);
618
+                        if (l > length)
619
+                            length = l;
620
+                    }
621
+
622
+                    forindex (var i; checklistNode.getChildren('item')) {
623
+                        var text = pages[pageIndex].getChild('item', i).getValue('name');
624
+                        var item_val = '';
625
+                        if (pages[pageIndex].getChild('item', i).getChild('value') != nil)
626
+                            item_val = pages[pageIndex].getChild('item', i).getValue('value');
627
+                        if (item_val != '')
628
+                            text ~= tabulate(length, length_cache[i]);
629
+                        text ~= item_val;
630
+
631
+                        append(obj_infos, {
632
+                            text: text,
633
+                            groupIndex: groupIndex,
634
+                            checklistIndex: checklistIndex,
635
+                            pageIndex: pageIndex,
636
+                            type: 'normal|end-of-line'
637
+                        });
638
+                    }
639
+
640
+                    append(obj_infos, {type: 'separator'});
641
+
642
+                    if (pageIndex and size(pages))
643
+                        append(obj_infos, {
644
+                                text: _previous_text,
645
+                                groupIndex: groupIndex,
646
+                                checklistIndex: checklistIndex,
647
+                                pageIndex: pageIndex - 1,
648
+                                checklistTitle: title,
649
+                                type: (pageIndex + 1 < size(pages)) ? 'editable' : 'selected',
650
+                                callback: func (id, selected) call(me.device.softkeys.bindings.MFD.CHKLIST._showCheckList, [id, selected], me)
651
+                        });
652
+                    else
653
+                        append(obj_infos, {
654
+                            text: tabulate(length, size(_next_text), 0, ' '),
655
+                            type: 'normal'
656
+                        });
657
+
658
+                    if (pageIndex + 1 < size(pages)) {
659
+                        if (pageIndex and size(pages))
660
+                            append(obj_infos, {
661
+                                text: tabulate(length, size(_previous_text ~ _next_text), 0, ' '),
662
+                                type: 'normal',
663
+                            });
664
+                        append(obj_infos, {
665
+                                text: _next_text,
666
+                                groupIndex: groupIndex,
667
+                                checklistIndex: checklistIndex,
668
+                                pageIndex: pageIndex + 1,
669
+                                checklistTitle: title,
670
+                                type: 'selected|end-of-line',
671
+                                callback: func (id, selected) call(me.device.softkeys.bindings.MFD.CHKLIST._showCheckList, [id, selected], me)
672
+                        });
673
+                    }
674
+
675
+                    me.device.knobs.FmsInner = me.device.knobs.NavigateMenu;
676
+                    me.device.knobs.FmsOuter = me.device.knobs.NavigateMenu;
677
+                    me.device.buttons.ENT    = me.device.buttons.ValidateTMRREF;
678
+                    me.device.buttons.CLR = func {
679
+                        me.device.windows.del(id);
680
+                        me.device.knobs.FmsOuter = func;
681
+                        me.device.knobs.FmsInner = func;
682
+                        foreach (var b; ['ENT', 'CLR'])
683
+                            me.device.buttons[b] = func;
684
+                        me.device.buttons.MENU = func;
685
+                    }
686
+                    me.device.windows.draw( id, {autogeom: 1}, obj_infos );
687
+                },
688
+                LIST: func {
689
+                    # nested function as checklist lists may be organized by group
690
+                    var listChecklists = func (id, selected) {
691
+                        var groupIndex = me.device.windows.state[id].objects[selected].groupIndex;
692
+
693
+                        me.device.windows.del(id);
694
+
695
+                        var checklists = [];
696
+                        var firstEntry = 1;
697
+                        if (groupIndex == -1)
698
+                            checklists = props.globals.getNode("/sim/checklists")
699
+                                            .getChildren('checklist');
700
+                        else
701
+                            checklists = props.globals.getNode("/sim/checklists")
702
+                                            .getChild("group", groupIndex)
703
+                                            .getChildren('checklist');
704
+                        var checklistsQty = size(checklists);
705
+                        var obj_infos = [];
706
+
707
+                        if (checklistsQty) {
708
+                            forindex (var c; checklists) {
709
+                                if (string.uc(checklists[c].getValue('title')) == 'EMERGENCY') {
710
+                                    checklistsQty -= 1;
711
+                                    continue;
712
+                                }
713
+                                var title = checklists[c].getValue('title');
714
+                                append(obj_infos, {
715
+                                    text: title,
716
+                                    groupIndex: groupIndex,
717
+                                    checklistIndex: c,
718
+                                    checklistTitle: title,
719
+                                    type: (firstEntry ? 'selected' : 'editable') ~ '|end-of-line',
720
+                                    callback: func (id, selected) call(me.device.softkeys.bindings.MFD.CHKLIST._showCheckList, [id, selected], me)
721
+                                });
722
+                                if (checklistsQty == 1) { # see comments below for groups
723
+                                    call(me.device.softkeys.bindings.MFD.CHKLIST._showCheckList, [groupIndex, 0], me);
724
+                                    return;
725
+                                }
726
+                                elsif (checklistsQty == 0)
727
+                                    return;
728
+                                firstEntry = 0;
729
+                            }
730
+                        }
731
+
732
+                        id ~= ' CHECKLISTS';
733
+                        me.device.knobs.FmsInner = me.device.knobs.NavigateMenu;
734
+                        me.device.knobs.FmsOuter = me.device.knobs.NavigateMenu;
735
+                        me.device.buttons.ENT    = me.device.buttons.ValidateTMRREF;
736
+                        me.device.buttons.CLR = func {
737
+                            me.device.windows.del(id);
738
+                            me.device.knobs.FmsOuter = func;
739
+                            me.device.knobs.FmsInner = func;
740
+                            foreach (var b; ['ENT', 'CLR'])
741
+                                me.device.buttons[b] = func;
742
+                            me.device.buttons.MENU = func;
743
+                        }
744
+                        me.device.windows.draw(id, {autogeom: 1}, obj_infos);
745
+                    }
746
+
747
+                    var windowId = 'CHKLIST LIST';
748
+                    if (contains(me.device.windows.state, windowId))
749
+                        me.device.windows.del(windowId);
750
+
751
+                    var obj_infos = [];
752
+                    var firstEntry = 1;
753
+                    var groups = props.globals.getNode("/sim/checklists").getChildren("group");
754
+                    var groupsQty = size(groups);
755
+
756
+                    if (groupsQty) {
757
+                        forindex (var g; groups) {
758
+                            # emergency checklists are listed in their own menu
759
+                            if (string.uc(groups[g].getValue('name')) == 'EMERGENCY') {
760
+                                groupsQty -= 1;
761
+                                continue;
762
+                            }
763
+                            # the key groupIndex isn't used by the display system
764
+                            # we use it to keep the information of group node's index
765
+                            append(obj_infos, {
766
+                                text: groups[g].getValue('name'),
767
+                                groupIndex: g,
768
+                                type: (firstEntry ? 'selected' : 'editable') ~ '|end-of-line',
769
+                                callback: func (id, selected) listChecklists(id, selected) });
770
+                            firstEntry = 0;
771
+                            # if there are only one group left, let display it directly
772
+                            if (groupsQty == 1) {
773
+                                listChecklists(windowId, 0);
774
+                                return;
775
+                            }
776
+                            elsif (groupsQty == 0) {
777
+                                return;
778
+                            }
779
+                        }
780
+                    }
781
+                    else {
782
+                        listChecklists(windowId, -1);
783
+                        return;
784
+                    }
785
+
786
+                    me.device.knobs.FmsInner = me.device.knobs.NavigateMenu;
787
+                    me.device.knobs.FmsOuter = me.device.knobs.NavigateMenu;
788
+                    me.device.buttons.ENT    = me.device.buttons.ValidateTMRREF;
789
+                    me.device.buttons.CLR = func {
790
+                        me.device.windows.del(windowId);
791
+                        me.device.knobs.FmsOuter = func;
792
+                        me.device.knobs.FmsInner = func;
793
+                        foreach (var b; ['ENT', 'CLR'])
794
+                            me.device.buttons[b] = func;
795
+                        me.device.buttons.MENU = func;
796
+                    }
797
+                    me.device.windows.draw(windowId, {autogeom: 1}, obj_infos);
798
+                },
799
+                EMERGCY: func {
800
+                    # nested function as checklist lists may be organized by group
801
+                    var listChecklists = func (groupIndex) {
802
+                        var checklists = [];
803
+                        var firstEntry = 1;
804
+                        if (groupIndex == -1)
805
+                            checklists = props.globals.getNode("/sim/checklists")
806
+                                            .getChildren('checklist');
807
+                        else
808
+                            checklists = props.globals.getNode("/sim/checklists")
809
+                                            .getChild("group", groupIndex)
810
+                                            .getChildren('checklist');
811
+                        var checklistsQty = size(checklists);
812
+                        var obj_infos = [];
813
+                        var firstEntry = 1;
814
+
815
+                        if (checklistsQty) {
816
+                            forindex (var c; checklists) {
817
+                                if (groupIndex < 0 and string.uc(checklists[c].getValue('title')) != 'EMERGENCY') {
818
+                                    checklistsQty -= 1;
819
+                                    continue;
820
+                                }
821
+                                append(obj_infos, {
822
+                                    text: checklists[c].getValue('title'),
823
+                                    groupIndex: groupIndex,
824
+                                    checklistIndex: c,
825
+                                    type: (firstEntry ? 'selected' : 'editable') ~ '|end-of-line',
826
+                                    callback: func (id, selected) call(me.device.softkeys.bindings.MFD.CHKLIST._showCheckList, [id, selected], me)
827
+                                });
828
+                                firstEntry = 0;
829
+                            }
830
+                        }
831
+                        id = 'EMERGENCY CHECKLISTS';
832
+                        me.device.knobs.FmsInner = me.device.knobs.NavigateMenu;
833
+                        me.device.knobs.FmsOuter = me.device.knobs.NavigateMenu;
834
+                        me.device.buttons.ENT    = me.device.buttons.ValidateTMRREF;
835
+                        me.device.buttons.CLR = func {
836
+                            me.device.windows.del(id);
837
+                            me.device.knobs.FmsOuter = func;
838
+                            me.device.knobs.FmsInner = func;
839
+                            foreach (var b; ['ENT', 'CLR'])
840
+                                me.device.buttons[b] = func;
841
+                            me.device.buttons.MENU = func;
842
+                        }
843
+                        me.device.windows.draw(id, {autogeom: 1}, obj_infos);
844
+                        if (checklistsQty == 1) { # see comments below for groups
845
+                            call(me.device.softkeys.bindings.MFD.CHKLIST._showCheckList, [groupIndex, 0], me);
846
+                            return;
847
+                        }
848
+                        elsif (checklistsQty == 0)
849
+                            call(me.device.buttons.CLR, [0], me);
850
+                            return;
851
+                    }
852
+
853
+                    var windowId = 'CHKLIST EMERGCY';
854
+                    if (contains(me.device.windows.state, windowId))
855
+                        me.device.windows.del(windowId);
856
+
857
+                    var groups = props.globals.getNode("/sim/checklists").getChildren("group");
858
+
859
+                    var emergency_group_found = 0;
860
+                    if (size(groups)) {
861
+                        forindex (var g; groups) {
862
+                            # emergency checklists are listed in their own menu
863
+                            # we support only one emergency checklists group named EMERGENCY (case insensitive)
864
+                            if (string.uc(groups[g].getValue('name')) != 'EMERGENCY')
865
+                                continue;
866
+                            listChecklists(g);
867
+                            emergency_group_found = !emergency_group_found;
868
+                            break;
869
+                        }
870
+                    }
871
+
872
+                    if (!emergency_group_found)
873
+                        listChecklists(-1);
874
+                },
557 875
                 EXIT: func {
558 876
                     me.path = [];
559 877
                     me.device.display.updateSoftKeys();
... ...
@@ -657,7 +975,7 @@ var keyMap = {
657 975
             },
658 976
         },
659 977
         CHKLIST : {
660
-            texts : ['ENGINE', '', '', '', '', 'DONE', '', '', '', '', 'EXIT', 'EMERGCY'],
978
+            texts : ['ENGINE', '', '', '', 'LIST', 'DONE', '', '', '', '', 'EXIT', 'EMERGCY'],
661 979
         },
662 980
         ENGINE : {
663 981
             texts : ['ENGINE', 'ANTI-ICE', '', 'DCLTR', '', 'ASSIST', '', '', '', '', 'FUEL'],
... ...
@@ -674,4 +992,8 @@ var keyMap = {
674 992
 };
675 993
 if (data['stall-aoa'] == 9999)
676 994
     keyMap.PFD.PFD['AOA/WIND'].texts = ['', 'WIND'];
995
+if (props.globals.getNode('/sim/checklists') == nil) {
996
+    keyMap.MFD.texts[11] = '';
997
+    delete(keyMap.MFD, 'CHKLIST');
998
+}
677 999
 #}}}1