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"
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

View file

@ -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;

View file

@ -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;

View file

@ -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(

View file

@ -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