313 lines
10 KiB
Text
313 lines
10 KiB
Text
# Copyright 2018 Stuart Buchanan
|
|
# This file is part of FlightGear.
|
|
#
|
|
# Foobar is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# FlightGear is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with FlightGear. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
# Checklist Controller
|
|
var ChecklistController =
|
|
{
|
|
UIGROUP : {
|
|
GROUP : 0,
|
|
CHECKLIST: 1,
|
|
ITEMS : 2,
|
|
NEXT : 3,
|
|
},
|
|
|
|
new : func (page, svg)
|
|
{
|
|
var obj = {
|
|
parents : [ ChecklistController, MFDPageController.new(page) ],
|
|
_crsrToggle : 0,
|
|
_recipient : nil,
|
|
_page : page,
|
|
_currentGroup : -1,
|
|
_group_selected : nil,
|
|
_list_selected : nil,
|
|
_checklists : nil,
|
|
};
|
|
|
|
obj.selectGroup(-1);
|
|
return obj;
|
|
},
|
|
|
|
selectGroup : func() {
|
|
me.selectGroup(ChecklistController.UIGROUP.GROUP)
|
|
},
|
|
selectChecklist : func() {
|
|
me.selectGroup(ChecklistController.UIGROUP.CHECKLIST);
|
|
},
|
|
selectItems : func() {
|
|
me.selectGroup(ChecklistController.UIGROUP.ITEMS);
|
|
},
|
|
selectNext : func() {
|
|
me.selectGroup(ChecklistController.UIGROUP.NEXT);
|
|
},
|
|
|
|
|
|
getSelectedGroup : func() {
|
|
return me._currentGroup;
|
|
},
|
|
|
|
selectGroup : func(grp) {
|
|
me._page.hideGroupSelect();
|
|
me._page.hideChecklistSelect();
|
|
|
|
me._currentGroup = grp;
|
|
if (grp == ChecklistController.UIGROUP.GROUP) {
|
|
me._page.highlightTextElement("GroupName");
|
|
} else {
|
|
me._page.unhighlightTextElement("GroupName");
|
|
}
|
|
|
|
if (grp == ChecklistController.UIGROUP.CHECKLIST) {
|
|
me._page.highlightTextElement("Name");
|
|
} else {
|
|
me._page.unhighlightTextElement("Name");
|
|
}
|
|
|
|
if (grp == ChecklistController.UIGROUP.ITEMS) {
|
|
me._page.checklistDisplay.showCRSR();
|
|
} else {
|
|
me._page.checklistDisplay.hideCRSR();
|
|
}
|
|
|
|
if (grp == ChecklistController.UIGROUP.NEXT) {
|
|
me._page.highlightTextElement("Next");
|
|
} else {
|
|
me._page.unhighlightTextElement("Next");
|
|
}
|
|
},
|
|
|
|
selectEmergencyChecklist : func() {
|
|
if (me._checklist == nil) return;
|
|
# Select the EMERGENCY checklist group, if available.
|
|
var emergency_labels = ["EMERGENCY", "Emergency", "emergency"];
|
|
var group = nil;
|
|
foreach (var l; emergency_labels) {
|
|
if (me._checklists[l] != nil) {
|
|
group = l;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (group != nil) {
|
|
me._group_selected = group;
|
|
me._list_selected = keys(me._checklists[me._group_selected])[0];
|
|
me._page.hideGroupSelect();
|
|
me._page.displayChecklist(me._group_selected, me._list_selected, me._checklists);
|
|
me.selectChecklist();
|
|
}
|
|
},
|
|
|
|
# Input Handling
|
|
handleCRSR : func() {
|
|
# If there are no checklists then we don't allow the CRSR to be enabled as
|
|
# there's nothing to do.
|
|
if (me._checklists == nil) return emesary.Transmitter.ReceiptStatus_Finished;
|
|
me._crsrToggle = (! me._crsrToggle);
|
|
if (me._crsrToggle) {
|
|
me.selectGroup(0);
|
|
} else {
|
|
me.selectGroup(-1);
|
|
}
|
|
return emesary.Transmitter.ReceiptStatus_Finished;
|
|
},
|
|
handleFMSInner : func(value) {
|
|
if (me._crsrToggle == 1) {
|
|
# Either display the select group or scroll through whatever is the current list
|
|
|
|
if (me._currentGroup == ChecklistController.UIGROUP.GROUP) {
|
|
if (me._page.isGroupSelectVisible()) {
|
|
me._page.checklistGroupSelect.incrSmall(value);
|
|
} else {
|
|
me._page.displayGroupSelect();
|
|
me._page.unhighlightTextElement("GroupName");
|
|
}
|
|
}
|
|
|
|
if (me._currentGroup == ChecklistController.UIGROUP.CHECKLIST) {
|
|
if (me._page.isChecklistSelectVisible()) {
|
|
me._page.checklistSelect.incrSmall(value);
|
|
} else {
|
|
me._page.displayChecklistSelect();
|
|
me._page.unhighlightTextElement("Name");
|
|
}
|
|
}
|
|
|
|
if (me._currentGroup == ChecklistController.UIGROUP.ITEMS) {
|
|
me._page.checklistDisplay.incrSmall(value);
|
|
}
|
|
|
|
return emesary.Transmitter.ReceiptStatus_Finished;
|
|
} else {
|
|
# Pass to the page group controller to display and scroll through the page group menu
|
|
return me._page.mfd.SurroundController.handleFMSInner(value);
|
|
}
|
|
},
|
|
handleFMSOuter : func(value) {
|
|
if (me._crsrToggle == 1) {
|
|
# Manual explicitly documents that _either_ FMS knob may be used to scroll through the checklist.
|
|
# However, that means that there is no way to navigate from the checklist itself other
|
|
# than to disable and then re-enable the CRSR. Odd.
|
|
if (me._currentGroup == ChecklistController.UIGROUP.ITEMS) return me.handleFMSInner(value);
|
|
|
|
var incr_or_decr = (value > 0) ? 1 : -1;
|
|
var idx = me._currentGroup + incr_or_decr;
|
|
if (idx < 0) idx = 0;
|
|
if (idx > (size(ChecklistController.UIGROUP) -1)) idx = size(ChecklistController.UIGROUP) -1;
|
|
me.selectGroup(idx);
|
|
return emesary.Transmitter.ReceiptStatus_Finished;
|
|
} else {
|
|
# Pass to the page group controller to display and scroll through the page group menu
|
|
return me._page.mfd.SurroundController.handleFMSOuter(value);
|
|
}
|
|
},
|
|
handleEnter : func(value) {
|
|
if (me._crsrToggle == 1) {
|
|
if (me._checklists ==nil) return emesary.Transmitter.ReceiptStatus_Finished;
|
|
if (me._currentGroup == ChecklistController.UIGROUP.GROUP) {
|
|
# Load the new group, selecting the first checklist in the group
|
|
me._group_selected = me._page.checklistGroupSelect.getValue();
|
|
me._list_selected = keys(me._checklists[me._group_selected])[0];
|
|
me._page.hideGroupSelect();
|
|
me._page.displayChecklist(me._group_selected, me._list_selected, me._checklists);
|
|
me._page.checklistDisplay.setCRSR(0);
|
|
me.selectChecklist();
|
|
return emesary.Transmitter.ReceiptStatus_Finished;
|
|
}
|
|
|
|
if (me._currentGroup == ChecklistController.UIGROUP.CHECKLIST) {
|
|
# Load the selected checking from the group
|
|
me._list_selected = me._page.checklistSelect.getValue();
|
|
me._page.hideChecklistSelect();
|
|
me._page.displayChecklist(me._group_selected, me._list_selected, me._checklists);
|
|
me._page.checklistDisplay.setCRSR(0);
|
|
me.selectItems();
|
|
return emesary.Transmitter.ReceiptStatus_Finished;
|
|
}
|
|
|
|
if (me._currentGroup == ChecklistController.UIGROUP.ITEMS) {
|
|
# Check the selected Checklist item
|
|
me.checkCurrentItem();
|
|
var idx = me._page.checklistDisplay.getCRSR();
|
|
|
|
if ((idx == (size(me._checklists[me._group_selected][me._list_selected]) -1)) and
|
|
me._page.checklistDisplay.isComplete()) {
|
|
# If we're right at the end of this checklist then move onto the "Next Checklist"
|
|
# button. Manual isn't clear on whether this is only if the checklist is complete,
|
|
# but we will assume that is the case.
|
|
me.selectNext();
|
|
} else {
|
|
# Automatically go to the next item.
|
|
me.handleFMSInner(1);
|
|
}
|
|
|
|
return emesary.Transmitter.ReceiptStatus_Finished;
|
|
}
|
|
|
|
if (me._currentGroup == ChecklistController.UIGROUP.NEXT) {
|
|
# Select the next checklist if there's one available
|
|
var lists = keys(me._checklists[me._group_selected]);
|
|
var idx = 0;
|
|
for (i = 0; i < size(lists); i = i +1) {
|
|
if (lists[i] == me._list_selected) idx = i + 1;
|
|
}
|
|
|
|
if (idx < size(lists)) {
|
|
me._list_selected = lists[idx];
|
|
me._page.checklistDisplay.setCRSR(0);
|
|
me._page.displayChecklist(me._group_selected, me._list_selected, me._checklists);
|
|
me.selectItems();
|
|
}
|
|
return emesary.Transmitter.ReceiptStatus_Finished;
|
|
}
|
|
|
|
return emesary.Transmitter.ReceiptStatus_NotProcessed;
|
|
} else {
|
|
return emesary.Transmitter.ReceiptStatus_NotProcessed;
|
|
}
|
|
},
|
|
|
|
handleClear : func() {
|
|
if ((me._crsrToggle == 1) and
|
|
(me._currentGroup == ChecklistController.UIGROUP.ITEMS)) {
|
|
# Uncheck the selected Checklist item
|
|
me.clearCurrentItem();
|
|
return emesary.Transmitter.ReceiptStatus_Finished;
|
|
}
|
|
|
|
return emesary.Transmitter.ReceiptStatus_NotProcessed;
|
|
},
|
|
|
|
checkCurrentItem : func() {
|
|
me._page.checklistDisplay.enterElement();
|
|
var idx = me._page.checklistDisplay.getCRSR();
|
|
me._checklists[me._group_selected][me._list_selected][idx]["Checked"] = 1;
|
|
me._page.displayChecklist(me._group_selected, me._list_selected, me._checklists);
|
|
},
|
|
|
|
clearCurrentItem : func() {
|
|
me._page.checklistDisplay.clearElement();
|
|
var idx = me._page.checklistDisplay.getCRSR();
|
|
me._checklists[me._group_selected][me._list_selected][idx]["Checked"] = 0;
|
|
me._page.displayChecklist(me._group_selected, me._list_selected, me._checklists);
|
|
},
|
|
|
|
toggleCurrentItem : func() {
|
|
if (me._page.checklistDisplay.getValue()) {
|
|
me.clearCurrentItem();
|
|
} else {
|
|
me.checkCurrentItem();
|
|
}
|
|
},
|
|
|
|
# Retrieve the current set of checklists from the system.
|
|
getChecklists : func() {
|
|
var notification = notifications.PFDEventNotification.new(
|
|
"MFD",
|
|
me.getDeviceID(),
|
|
notifications.PFDEventNotification.NavData,
|
|
{Id: "GetChecklists", Value: nil});
|
|
|
|
var response = me._transmitter.NotifyAll(notification);
|
|
if (! me._transmitter.IsFailed(response)) {
|
|
me._checklists = notification.EventParameter.Value;
|
|
}
|
|
|
|
me._page.displayChecklist("", "", nil);
|
|
|
|
# Find the first checklist of the first group to display;
|
|
if ((me._checklists != nil) and size(keys(me._checklists)) != 0) {
|
|
me._group_selected = keys(me._checklists)[0];
|
|
if (size(keys(me._checklists[me._group_selected])) != 0) {
|
|
me._list_selected = keys(me._checklists[me._group_selected])[0];
|
|
me._page.displayChecklist(me._group_selected, me._list_selected, me._checklists);
|
|
}
|
|
}
|
|
},
|
|
|
|
# Reset controller if required when the page is displayed or hidden
|
|
ondisplay : func() {
|
|
me.RegisterWithEmesary();
|
|
|
|
# Get the list of checklists if we don't already have it. This has to
|
|
# be done here rather than in the Constructor because the appropriate
|
|
# Emesary interface may not have been initialized in time.
|
|
if (me._checklists == nil) me.getChecklists();
|
|
},
|
|
offdisplay : func() {
|
|
me.DeRegisterWithEmesary();
|
|
},
|
|
|
|
};
|