1
0
Fork 0

FG1000 - Improvements to Checklists page, softkeys

This commit is contained in:
Stuart Buchanan 2018-04-12 22:26:58 +01:00
parent 9f7e17a434
commit 63ee35becd
5 changed files with 233 additions and 51 deletions

View file

@ -23,9 +23,9 @@
borderopacity="0" borderopacity="0"
inkscape:pageopacity="0.0" inkscape:pageopacity="0.0"
inkscape:pageshadow="2" inkscape:pageshadow="2"
inkscape:zoom="4" inkscape:zoom="2"
inkscape:cx="834.55454" inkscape:cx="594.53585"
inkscape:cy="123.76123" inkscape:cy="130.11243"
inkscape:document-units="px" inkscape:document-units="px"
inkscape:current-layer="ChecklistMainPane" inkscape:current-layer="ChecklistMainPane"
showgrid="true" showgrid="true"
@ -966,6 +966,30 @@
id="tspan4745" id="tspan4745"
x="946.75195" x="946.75195"
y="694.34045">GO TO NEXT CHECKLIST?</tspan></text> 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> </g>
<rect <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" 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

View file

@ -154,36 +154,67 @@ getFlightplan : func ()
getChecklists : func() getChecklists : func()
{ {
var checklists = {}; var checklists = {};
checklists["Standard"] = {};
checklists["EMERGENCY"] = {};
var checklistprops = props.globals.getNode("/sim/checklists"); var checklistprops = props.globals.getNode("/sim/checklists");
foreach (var chklist; checklistprops.getChildren("checklist")) { var groups = checklistprops.getChildren("group");
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. if (size(groups) > 0) {
foreach (var pg; chklist.getChildren("page")) { foreach (var group; groups) {
foreach (var item; pg.getChildren("item")) { var grp = group.getNode("name", 1).getValue();
var name = item.getNode("name", 1).getValue(); checklists[grp] = {};
var value = item.getNode("value", 1).getValue(); foreach (var chklist; group.getChildren("checklist")) {
append(items, { Name : name, Value: value, Checked: 0 }); 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")) { foreach (var chklist; checklistprops.getChildren("checklist")) {
var name = item.getNode("name", 1).getValue(); var title = chklist.getNode("title", 1).getValue();
var value = item.getNode("value", 1).getValue(); var grp = "Standard";
append(items, { Name : name, Value: value, Checked: 0 }); 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; return checklists;

View file

@ -56,7 +56,7 @@ var Checklist =
); );
obj.checklistDisplay = ChecklistGroupElement.new( obj.checklistDisplay = ChecklistGroupElement.new(
obj.pageName, obj,
svg, svg,
16, 16,
"ScrollTrough", "ScrollTrough",
@ -65,12 +65,14 @@ var Checklist =
); );
# Other dynamic text elements # 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 # 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, # highlighted as a text element. We need to set a value for it explicitly,
# as it'll be set to an empty string otherwise. # as it'll be set to an empty string otherwise.
obj.setTextElement("Next", "GO TO NEXT CHECKLIST?"); obj.setTextElement("Next", "GO TO NEXT CHECKLIST?");
obj.setTextElement("Finished", "* Checklist Finished *");
obj.setTextElement("NotFinished", "* CHECKLIST NOT FINISHED *");
# Hide the various groups # Hide the various groups
obj.hideChecklistSelect(); obj.hideChecklistSelect();
@ -173,8 +175,33 @@ var Checklist =
topMenu : func(device, pg, menuitem) { topMenu : func(device, pg, menuitem) {
pg.clearMenu(); pg.clearMenu();
pg.resetMenuColors(); 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(); 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 = 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 = { var obj = {
parents : [ ChecklistGroupElement ], parents : [ ChecklistGroupElement ],
_pageName : pageName, _page : page,
_pageName : page.pageName,
_svg : svg, _svg : svg,
_style : style, _style : style,
_scrollTroughElement : nil, _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"); "Both the scroll trough element and the scroll thumb element must be defined, or neither");
if (scrollTroughElement != nil) { if (scrollTroughElement != nil) {
obj._scrollTroughElement = svg.getElementById(pageName ~ scrollTroughElement); obj._scrollTroughElement = svg.getElementById(obj._pageName ~ scrollTroughElement);
assert(obj._scrollTroughElement != nil, "Unable to find scroll element " ~ pageName ~ scrollTroughElement); assert(obj._scrollTroughElement != nil, "Unable to find scroll element " ~ obj._pageName ~ scrollTroughElement);
} }
if (scrollThumbElement != nil) { if (scrollThumbElement != nil) {
obj._scrollThumbElement = svg.getElementById(pageName ~ scrollThumbElement); obj._scrollThumbElement = svg.getElementById(obj._pageName ~ scrollThumbElement);
assert(obj._scrollThumbElement != nil, "Unable to find scroll element " ~ pageName ~ scrollThumbElement); assert(obj._scrollThumbElement != nil, "Unable to find scroll element " ~ obj._pageName ~ scrollThumbElement);
obj._scrollBaseTransform = obj._scrollThumbElement.getTranslation(); obj._scrollBaseTransform = obj._scrollThumbElement.getTranslation();
} }
if (style == nil) obj._style = PFD.DefaultStyle; if (style == nil) obj._style = PFD.DefaultStyle;
for (var i = 0; i < displaysize; i = i + 1) { 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.HighlightElement.new(obj._pageName, svg, "ItemSelect" ~ i, i, obj._style));
#append(obj._elements, PFD.TextElement.new(pageName, svg, highlightElement ~ i, i, obj._style));
} }
return obj; return obj;
@ -290,8 +317,8 @@ displayGroup : func () {
var middle_element_index = math.ceil(me._size / 2); var middle_element_index = math.ceil(me._size / 2);
me._pageIndex = me._crsrIndex - middle_element_index; me._pageIndex = me._crsrIndex - middle_element_index;
if (me._crsrIndex < middle_element_index) { if ((size(me._values) <= me._size) or (me._crsrIndex < middle_element_index)) {
# Start of list # Start of list or the list is too short to require scrolling
me._pageIndex = 0; me._pageIndex = 0;
} else if (me._crsrIndex > (size(me._values) - middle_element_index - 1)) { } else if (me._crsrIndex > (size(me._values) - middle_element_index - 1)) {
# End of list # End of list
@ -315,7 +342,7 @@ displayGroup : func () {
assert(element != nil, "Unable to find element " ~ name); assert(element != nil, "Unable to find element " ~ name);
if (k == "ItemSelect") { if (k == "ItemSelect") {
# Display if this is the cursor eleemtn # Display if this is the cursor element
element.setVisible(crsr); element.setVisible(crsr);
} else if (k == "ItemTick") { } else if (k == "ItemTick") {
# Check the box if appropriate # Check the box if appropriate
@ -384,6 +411,27 @@ displayGroup : func () {
me._scrollBaseTransform[1] + me._scrollHeight * (me._crsrIndex / (size(me._values) -1)) 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 # Methods to add dynamic elements to the group. Must be called in the
@ -402,8 +450,8 @@ showCRSR : func() {
}, },
hideCRSR : func() { hideCRSR : func() {
if (me._crsrEnabled == 0) return; if (me._crsrEnabled == 0) return;
me.displayGroup();
me._crsrEnabled = 0; me._crsrEnabled = 0;
me.displayGroup();
}, },
setCRSR : func(index) { setCRSR : func(index) {
me._crsrIndex = math.min(index, size(me._values) -1); me._crsrIndex = math.min(index, size(me._values) -1);
@ -423,11 +471,11 @@ isCursorOnDataEntryElement : func() {
enterElement : func() { enterElement : func() {
if (me._crsrEnabled == 0) return; 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. # indicated by whether the check mark is visible or not.
var name = me._pageName ~ "ItemTick" ~ (me._crsrIndex - me._pageIndex); var name = me._pageName ~ "ItemTick" ~ (me._crsrIndex - me._pageIndex);
var element = me._svg.getElementById(name); var element = me._svg.getElementById(name);
element.setVisible(! element.getVisible()); element.setVisible(1);
return element.getVisible(); return element.getVisible();
}, },
getValue : func() { getValue : func() {
@ -444,7 +492,13 @@ setValue : func(idx, key, value) {
}, },
clearElement : func() { clearElement : func() {
if (me._crsrEnabled == 0) return; 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) { incrSmall : func(value) {
if (me._crsrEnabled == 0) return; if (me._crsrEnabled == 0) return;

View file

@ -50,6 +50,10 @@ var ChecklistController =
selectItems : func() { selectItems : func() {
me.selectGroup(ChecklistController.UIGROUP.ITEMS); me.selectGroup(ChecklistController.UIGROUP.ITEMS);
}, },
selectNext : func() {
me.selectGroup(ChecklistController.UIGROUP.NEXT);
},
getSelectedGroup : func() { getSelectedGroup : func() {
return me._currentGroup; 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 # Input Handling
handleCRSR : func() { handleCRSR : func() {
me._crsrToggle = (! me._crsrToggle); me._crsrToggle = (! me._crsrToggle);
@ -129,6 +153,11 @@ var ChecklistController =
}, },
handleFMSOuter : func(value) { handleFMSOuter : func(value) {
if (me._crsrToggle == 1) { 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 incr_or_decr = (value > 0) ? 1 : -1;
var idx = me._currentGroup + incr_or_decr; var idx = me._currentGroup + incr_or_decr;
if (idx < 0) idx = 0; if (idx < 0) idx = 0;
@ -164,12 +193,22 @@ var ChecklistController =
} }
if (me._currentGroup == ChecklistController.UIGROUP.ITEMS) { 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 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(); if ((idx == (size(me._checklists[me._group_selected][me._list_selected]) -1)) and
me._page.displayChecklist(me._group_selected, me._list_selected, me._checklists); me._page.checklistDisplay.isComplete()) {
me._page.checklistDisplay.incrSmall(1); # 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) { if (me._currentGroup == ChecklistController.UIGROUP.NEXT) {
@ -182,6 +221,7 @@ var ChecklistController =
if (idx < size(lists)) { if (idx < size(lists)) {
me._list_selected = lists[idx]; me._list_selected = lists[idx];
me._page.checklistDisplay.setCRSR(0);
me._page.displayChecklist(me._group_selected, me._list_selected, me._checklists); me._page.displayChecklist(me._group_selected, me._list_selected, me._checklists);
me.selectItems(); 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. # Retrieve the current set of checklists from the system.
getChecklists : func() { getChecklists : func() {
var notification = notifications.PFDEventNotification.new( var notification = notifications.PFDEventNotification.new(

View file

@ -108,11 +108,11 @@ displayGroup : func () {
# In these cases, we let the cursor move to the top or bottom of the list. # In these cases, we let the cursor move to the top or bottom of the list.
# Determine the middle element # 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; me._pageIndex = me._crsrIndex - middle_element_index;
if (me._crsrIndex < middle_element_index) { if ((size(me._values) <= me._size) or (me._crsrIndex < middle_element_index)) {
# Start of list # Start of list or the list is too short to require scrolling
me._pageIndex = 0; me._pageIndex = 0;
} else if (me._crsrIndex > (size(me._values) - middle_element_index - 1)) { } else if (me._crsrIndex > (size(me._values) - middle_element_index - 1)) {
# End of list # End of list