FG1000 - Improvements to Checklists page, softkeys
This commit is contained in:
parent
9f7e17a434
commit
63ee35becd
5 changed files with 233 additions and 51 deletions
|
@ -23,9 +23,9 @@
|
|||
borderopacity="0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="4"
|
||||
inkscape:cx="834.55454"
|
||||
inkscape:cy="123.76123"
|
||||
inkscape:zoom="2"
|
||||
inkscape:cx="594.53585"
|
||||
inkscape:cy="130.11243"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="ChecklistMainPane"
|
||||
showgrid="true"
|
||||
|
@ -966,6 +966,30 @@
|
|||
id="tspan4745"
|
||||
x="946.75195"
|
||||
y="694.34045">GO TO NEXT CHECKLIST?</tspan></text>
|
||||
<text
|
||||
transform="scale(0.96688562,1.0342485)"
|
||||
sodipodi:linespacing="100%"
|
||||
id="ChecklistNotFinished"
|
||||
y="694.34045"
|
||||
x="206.58603"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.99999998px;line-height:100%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow, Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr;text-anchor:start;fill:#ffff00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;"
|
||||
xml:space="preserve"
|
||||
inkscape:label="#text4232"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4340">* CHECKLIST NOT FINISHED *</tspan></text>
|
||||
<text
|
||||
inkscape:label="#text4232"
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:100%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow, Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#00ff00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;"
|
||||
x="206.58603"
|
||||
y="694.34045"
|
||||
id="ChecklistFinished"
|
||||
sodipodi:linespacing="100%"
|
||||
transform="scale(0.96688562,1.0342485)"><tspan
|
||||
y="694.34045"
|
||||
x="206.58603"
|
||||
id="tspan4334"
|
||||
sodipodi:role="line">* CHECKLIST FINISHED *</tspan></text>
|
||||
</g>
|
||||
<rect
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#c0c0c0;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:0;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
|
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 76 KiB |
|
@ -154,36 +154,67 @@ getFlightplan : func ()
|
|||
getChecklists : func()
|
||||
{
|
||||
var checklists = {};
|
||||
checklists["Standard"] = {};
|
||||
checklists["EMERGENCY"] = {};
|
||||
|
||||
var checklistprops = props.globals.getNode("/sim/checklists");
|
||||
|
||||
foreach (var chklist; checklistprops.getChildren("checklist")) {
|
||||
var title = chklist.getNode("title", 1).getValue();
|
||||
var grp = "Standard";
|
||||
var items = [];
|
||||
if (find("emergency", string.lc(title)) != -1) {
|
||||
grp = "EMERGENCY";
|
||||
}
|
||||
var groups = checklistprops.getChildren("group");
|
||||
|
||||
# Checklists can optionally be broken down into individual pages.
|
||||
foreach (var pg; chklist.getChildren("page")) {
|
||||
foreach (var item; pg.getChildren("item")) {
|
||||
var name = item.getNode("name", 1).getValue();
|
||||
var value = item.getNode("value", 1).getValue();
|
||||
append(items, { Name : name, Value: value, Checked: 0 });
|
||||
if (size(groups) > 0) {
|
||||
foreach (var group; groups) {
|
||||
var grp = group.getNode("name", 1).getValue();
|
||||
checklists[grp] = {};
|
||||
foreach (var chklist; group.getChildren("checklist")) {
|
||||
var items = [];
|
||||
var title = chklist.getNode("title", 1).getValue();
|
||||
|
||||
# Checklists can optionally be broken down into individual pages.
|
||||
foreach (var pg; chklist.getChildren("page")) {
|
||||
foreach (var item; pg.getChildren("item")) {
|
||||
var name = item.getNode("name", 1).getValue();
|
||||
var value = item.getNode("value", 1).getValue();
|
||||
append(items, { Name : name, Value: value, Checked: 0 });
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item; chklist.getChildren("item")) {
|
||||
var name = item.getNode("name", 1).getValue();
|
||||
var value = item.getNode("value", 1).getValue();
|
||||
append(items, { Name : name, Value: value, Checked: 0 });
|
||||
}
|
||||
|
||||
# items now contains a list of all the checklists for
|
||||
checklists[grp][title] = items;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
# Checklist doesn't contain any groups, so try to split into Standard
|
||||
# and Emergency groups by looking at the checklist titles.
|
||||
|
||||
foreach (var item; chklist.getChildren("item")) {
|
||||
var name = item.getNode("name", 1).getValue();
|
||||
var value = item.getNode("value", 1).getValue();
|
||||
append(items, { Name : name, Value: value, Checked: 0 });
|
||||
foreach (var chklist; checklistprops.getChildren("checklist")) {
|
||||
var title = chklist.getNode("title", 1).getValue();
|
||||
var grp = "Standard";
|
||||
var items = [];
|
||||
if (find("emergency", string.lc(title)) != -1) {
|
||||
grp = "EMERGENCY";
|
||||
}
|
||||
|
||||
# Checklists can optionally be broken down into individual pages.
|
||||
foreach (var pg; chklist.getChildren("page")) {
|
||||
foreach (var item; pg.getChildren("item")) {
|
||||
var name = item.getNode("name", 1).getValue();
|
||||
var value = item.getNode("value", 1).getValue();
|
||||
append(items, { Name : name, Value: value, Checked: 0 });
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item; chklist.getChildren("item")) {
|
||||
var name = item.getNode("name", 1).getValue();
|
||||
var value = item.getNode("value", 1).getValue();
|
||||
append(items, { Name : name, Value: value, Checked: 0 });
|
||||
}
|
||||
|
||||
# items now contains a list of all the checklists for
|
||||
checklists[grp][title] = items;
|
||||
}
|
||||
|
||||
# items now contains a list of all the checklists for
|
||||
checklists[grp][title] = items;
|
||||
}
|
||||
|
||||
return checklists;
|
||||
|
|
|
@ -56,7 +56,7 @@ var Checklist =
|
|||
);
|
||||
|
||||
obj.checklistDisplay = ChecklistGroupElement.new(
|
||||
obj.pageName,
|
||||
obj,
|
||||
svg,
|
||||
16,
|
||||
"ScrollTrough",
|
||||
|
@ -65,12 +65,14 @@ var Checklist =
|
|||
);
|
||||
|
||||
# Other dynamic text elements
|
||||
obj.addTextElements(["GroupName", "Name", "Next"]);
|
||||
obj.addTextElements(["GroupName", "Name", "Next", "Finished", "NotFinished"]);
|
||||
|
||||
# The "Next" element isn't technically dynamic, though we want it to be
|
||||
# highlighted as a text element. We need to set a value for it explicitly,
|
||||
# as it'll be set to an empty string otherwise.
|
||||
obj.setTextElement("Next", "GO TO NEXT CHECKLIST?");
|
||||
obj.setTextElement("Finished", "* Checklist Finished *");
|
||||
obj.setTextElement("NotFinished", "* CHECKLIST NOT FINISHED *");
|
||||
|
||||
# Hide the various groups
|
||||
obj.hideChecklistSelect();
|
||||
|
@ -173,8 +175,33 @@ var Checklist =
|
|||
topMenu : func(device, pg, menuitem) {
|
||||
pg.clearMenu();
|
||||
pg.resetMenuColors();
|
||||
pg.addMenuItem(0, "ENGINE", pg, pg.mfd.EIS.engineMenu);
|
||||
pg.addMenuItem(2, "MAP", pg, pg.mfd.NavigationMap.mapMenu);
|
||||
pg.addMenuItem(5, "CHECK", pg,
|
||||
func(dev, pg, mi) { pg.getController().toggleCurrentItem(); dev.updateMenus(); }, # callback
|
||||
func(svg, mi) { pg.displayCheckUncheck(svg); } # Display function
|
||||
);
|
||||
pg.addMenuItem(10, "EXIT", pg,
|
||||
# This should return to the previous page...
|
||||
func(dev, pg, mi) { dev.selectPage(pg.getMFD().getPage("NavigationMap")); },
|
||||
);
|
||||
|
||||
pg.addMenuItem(11, "EMERGENCY", pg,
|
||||
func(dev, pg, mi) { pg.getController().selectEmergencyChecklist(); }, # callback
|
||||
);
|
||||
|
||||
device.updateMenus();
|
||||
},
|
||||
|
||||
# Display function for the CHECK/UNCHECK softkey
|
||||
displayCheckUncheck : func (svg) {
|
||||
if (me.checklistDisplay.getValue()) {
|
||||
svg.setText("UNCHECK");
|
||||
} else {
|
||||
svg.setText("CHECK");
|
||||
}
|
||||
svg.setVisible(1);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
@ -187,11 +214,12 @@ var Checklist =
|
|||
var ChecklistGroupElement =
|
||||
{
|
||||
|
||||
new : func (pageName, svg, displaysize, scrollTroughElement=nil, scrollThumbElement=nil, scrollHeight=0, style=nil)
|
||||
new : func (page, svg, displaysize, scrollTroughElement=nil, scrollThumbElement=nil, scrollHeight=0, style=nil)
|
||||
{
|
||||
var obj = {
|
||||
parents : [ ChecklistGroupElement ],
|
||||
_pageName : pageName,
|
||||
_page : page,
|
||||
_pageName : page.pageName,
|
||||
_svg : svg,
|
||||
_style : style,
|
||||
_scrollTroughElement : nil,
|
||||
|
@ -234,20 +262,19 @@ new : func (pageName, svg, displaysize, scrollTroughElement=nil, scrollThumbElem
|
|||
"Both the scroll trough element and the scroll thumb element must be defined, or neither");
|
||||
|
||||
if (scrollTroughElement != nil) {
|
||||
obj._scrollTroughElement = svg.getElementById(pageName ~ scrollTroughElement);
|
||||
assert(obj._scrollTroughElement != nil, "Unable to find scroll element " ~ pageName ~ scrollTroughElement);
|
||||
obj._scrollTroughElement = svg.getElementById(obj._pageName ~ scrollTroughElement);
|
||||
assert(obj._scrollTroughElement != nil, "Unable to find scroll element " ~ obj._pageName ~ scrollTroughElement);
|
||||
}
|
||||
if (scrollThumbElement != nil) {
|
||||
obj._scrollThumbElement = svg.getElementById(pageName ~ scrollThumbElement);
|
||||
assert(obj._scrollThumbElement != nil, "Unable to find scroll element " ~ pageName ~ scrollThumbElement);
|
||||
obj._scrollThumbElement = svg.getElementById(obj._pageName ~ scrollThumbElement);
|
||||
assert(obj._scrollThumbElement != nil, "Unable to find scroll element " ~ obj._pageName ~ scrollThumbElement);
|
||||
obj._scrollBaseTransform = obj._scrollThumbElement.getTranslation();
|
||||
}
|
||||
|
||||
if (style == nil) obj._style = PFD.DefaultStyle;
|
||||
|
||||
for (var i = 0; i < displaysize; i = i + 1) {
|
||||
append(obj._elements, PFD.HighlightElement.new(pageName, svg, "ItemSelect" ~ i, i, obj._style));
|
||||
#append(obj._elements, PFD.TextElement.new(pageName, svg, highlightElement ~ i, i, obj._style));
|
||||
append(obj._elements, PFD.HighlightElement.new(obj._pageName, svg, "ItemSelect" ~ i, i, obj._style));
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
@ -290,8 +317,8 @@ displayGroup : func () {
|
|||
var middle_element_index = math.ceil(me._size / 2);
|
||||
me._pageIndex = me._crsrIndex - middle_element_index;
|
||||
|
||||
if (me._crsrIndex < middle_element_index) {
|
||||
# Start of list
|
||||
if ((size(me._values) <= me._size) or (me._crsrIndex < middle_element_index)) {
|
||||
# Start of list or the list is too short to require scrolling
|
||||
me._pageIndex = 0;
|
||||
} else if (me._crsrIndex > (size(me._values) - middle_element_index - 1)) {
|
||||
# End of list
|
||||
|
@ -315,7 +342,7 @@ displayGroup : func () {
|
|||
assert(element != nil, "Unable to find element " ~ name);
|
||||
|
||||
if (k == "ItemSelect") {
|
||||
# Display if this is the cursor eleemtn
|
||||
# Display if this is the cursor element
|
||||
element.setVisible(crsr);
|
||||
} else if (k == "ItemTick") {
|
||||
# Check the box if appropriate
|
||||
|
@ -384,6 +411,27 @@ displayGroup : func () {
|
|||
me._scrollBaseTransform[1] + me._scrollHeight * (me._crsrIndex / (size(me._values) -1))
|
||||
]);
|
||||
}
|
||||
|
||||
# Indicate whether we're finished with this checklist or not
|
||||
var finished = me.isComplete();
|
||||
me._page.getTextElement("Finished").setVisible(finished);
|
||||
me._page.getTextElement("NotFinished").setVisible(! finished);
|
||||
|
||||
# Update the softkeys, which will in particular change the CHECK/UNCHECK softkeys
|
||||
# appropriately.
|
||||
me._page.device.updateMenus();
|
||||
},
|
||||
|
||||
isComplete : func() {
|
||||
var finished = 1;
|
||||
foreach (var entry; me._values) {
|
||||
if (entry["ItemTick"] == 0) {
|
||||
finished = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return finished;
|
||||
},
|
||||
|
||||
# Methods to add dynamic elements to the group. Must be called in the
|
||||
|
@ -402,8 +450,8 @@ showCRSR : func() {
|
|||
},
|
||||
hideCRSR : func() {
|
||||
if (me._crsrEnabled == 0) return;
|
||||
me.displayGroup();
|
||||
me._crsrEnabled = 0;
|
||||
me.displayGroup();
|
||||
},
|
||||
setCRSR : func(index) {
|
||||
me._crsrIndex = math.min(index, size(me._values) -1);
|
||||
|
@ -423,11 +471,11 @@ isCursorOnDataEntryElement : func() {
|
|||
enterElement : func() {
|
||||
if (me._crsrEnabled == 0) return;
|
||||
|
||||
# ENT on an element of the checklist simply toggles the item itself,
|
||||
# ENT on an element of the checklist checks the box,
|
||||
# indicated by whether the check mark is visible or not.
|
||||
var name = me._pageName ~ "ItemTick" ~ (me._crsrIndex - me._pageIndex);
|
||||
var element = me._svg.getElementById(name);
|
||||
element.setVisible(! element.getVisible());
|
||||
element.setVisible(1);
|
||||
return element.getVisible();
|
||||
},
|
||||
getValue : func() {
|
||||
|
@ -444,7 +492,13 @@ setValue : func(idx, key, value) {
|
|||
},
|
||||
clearElement : func() {
|
||||
if (me._crsrEnabled == 0) return;
|
||||
me._elements[me._crsrIndex - me._pageIndex].clearElement();
|
||||
|
||||
# CLR on an element of the checklist unchecks the box,
|
||||
# indicated by whether the check mark is visible or not.
|
||||
var name = me._pageName ~ "ItemTick" ~ (me._crsrIndex - me._pageIndex);
|
||||
var element = me._svg.getElementById(name);
|
||||
element.setVisible(0);
|
||||
return element.getVisible();
|
||||
},
|
||||
incrSmall : func(value) {
|
||||
if (me._crsrEnabled == 0) return;
|
||||
|
|
|
@ -50,6 +50,10 @@ var ChecklistController =
|
|||
selectItems : func() {
|
||||
me.selectGroup(ChecklistController.UIGROUP.ITEMS);
|
||||
},
|
||||
selectNext : func() {
|
||||
me.selectGroup(ChecklistController.UIGROUP.NEXT);
|
||||
},
|
||||
|
||||
|
||||
getSelectedGroup : func() {
|
||||
return me._currentGroup;
|
||||
|
@ -85,6 +89,26 @@ var ChecklistController =
|
|||
}
|
||||
},
|
||||
|
||||
selectEmergencyChecklist : func() {
|
||||
# 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() {
|
||||
me._crsrToggle = (! me._crsrToggle);
|
||||
|
@ -129,6 +153,11 @@ var ChecklistController =
|
|||
},
|
||||
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;
|
||||
|
@ -164,12 +193,22 @@ var ChecklistController =
|
|||
}
|
||||
|
||||
if (me._currentGroup == ChecklistController.UIGROUP.ITEMS) {
|
||||
# Toggle the status of the selected Checklist item
|
||||
# Check the selected Checklist item
|
||||
me.checkCurrentItem();
|
||||
var idx = me._page.checklistDisplay.getCRSR();
|
||||
var checked = me._page.checklistDisplay.getValue();
|
||||
me._checklists[me._group_selected][me._list_selected][idx]["Checked"] = me._page.checklistDisplay.enterElement();
|
||||
me._page.displayChecklist(me._group_selected, me._list_selected, me._checklists);
|
||||
me._page.checklistDisplay.incrSmall(1);
|
||||
|
||||
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) {
|
||||
|
@ -182,6 +221,7 @@ var ChecklistController =
|
|||
|
||||
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();
|
||||
}
|
||||
|
@ -194,6 +234,39 @@ var ChecklistController =
|
|||
}
|
||||
},
|
||||
|
||||
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(
|
||||
|
|
|
@ -108,11 +108,11 @@ displayGroup : func () {
|
|||
# In these cases, we let the cursor move to the top or bottom of the list.
|
||||
|
||||
# Determine the middle element
|
||||
var middle_element_index = int(me._size / 2);
|
||||
var middle_element_index = math.ceil(me._size / 2);
|
||||
me._pageIndex = me._crsrIndex - middle_element_index;
|
||||
|
||||
if (me._crsrIndex < middle_element_index) {
|
||||
# Start of list
|
||||
if ((size(me._values) <= me._size) or (me._crsrIndex < middle_element_index)) {
|
||||
# Start of list or the list is too short to require scrolling
|
||||
me._pageIndex = 0;
|
||||
} else if (me._crsrIndex > (size(me._values) - middle_element_index - 1)) {
|
||||
# End of list
|
||||
|
|
Loading…
Reference in a new issue