diff --git a/Aircraft/Instruments-3d/FG1000/MFDPages/DirectTo.svg b/Aircraft/Instruments-3d/FG1000/MFDPages/DirectTo.svg
index 542a85ac8..818971566 100644
--- a/Aircraft/Instruments-3d/FG1000/MFDPages/DirectTo.svg
+++ b/Aircraft/Instruments-3d/FG1000/MFDPages/DirectTo.svg
@@ -23,9 +23,9 @@
borderopacity="0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="3.2473958"
- inkscape:cx="817.98224"
- inkscape:cy="351.10971"
+ inkscape:zoom="2.2962556"
+ inkscape:cx="913.04869"
+ inkscape:cy="547.52243"
inkscape:document-units="px"
inkscape:current-layer="DirectToGroup"
showgrid="true"
@@ -89,7 +89,7 @@
style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
diff --git a/Aircraft/Instruments-3d/FG1000/MFDPages/FlightPlanPFD.svg b/Aircraft/Instruments-3d/FG1000/MFDPages/FlightPlanPFD.svg
new file mode 100644
index 000000000..0a4ee5172
--- /dev/null
+++ b/Aircraft/Instruments-3d/FG1000/MFDPages/FlightPlanPFD.svg
@@ -0,0 +1,443 @@
+
+
+
+
diff --git a/Aircraft/Instruments-3d/FG1000/Nasal/Interfaces/GenericFMSPublisher.nas b/Aircraft/Instruments-3d/FG1000/Nasal/Interfaces/GenericFMSPublisher.nas
index 284bf291b..5d55e5429 100644
--- a/Aircraft/Instruments-3d/FG1000/Nasal/Interfaces/GenericFMSPublisher.nas
+++ b/Aircraft/Instruments-3d/FG1000/Nasal/Interfaces/GenericFMSPublisher.nas
@@ -22,84 +22,109 @@ var GenericFMSPublisher =
var obj = {
parents : [
GenericFMSPublisher,
- PeriodicPropertyPublisher.new(notifications.PFDEventNotification.FMSData, frequency)
],
};
- obj.addPropMap("FMSHeadingBug", "/autopilot/settings/heading-bug-deg");
- obj.addPropMap("FMSSelectedAlt", "/autopilot/settings/target-alt-ft");
+ # We have two publishers here:
+ #
+ # 1) a triggered publisher for properties that will change ocassionally, but which
+ # we need to update immediately. These are typically settings.
+ #
+ # 2) a periodic publisher which triggers every 0.5s to update data values.
+ obj._triggeredPublisher = TriggeredPropertyPublisher.new(notifications.PFDEventNotification.FMSData);
+ obj._periodicPublisher = PeriodicPropertyPublisher.new(notifications.PFDEventNotification.FMSData, frequency);
- obj.addPropMap("FMSMode", "/instrumentation/gps/mode");
- obj.addPropMap("FMSLegValid", "/instrumentation/gps/wp/wp[1]/valid");
- obj.addPropMap("FMSPreviousLegID", "/instrumentation/gps/wp/wp[0]/ID");
- obj.addPropMap("FMSLegID", "/instrumentation/gps/wp/wp[1]/ID");
- obj.addPropMap("FMSLegBearingMagDeg", "/instrumentation/gps/wp/wp[1]/bearing-mag-deg");
- obj.addPropMap("FMSLegDistanceNM", "/instrumentation/gps/wp/wp[1]/distance-nm");
- obj.addPropMap("FMSLegCourseError", "/instrumentation/gps/wp/wp[1]/course-error-nm");
- obj.addPropMap("FMSLegDesiredTrack", "/instrumentation/gps/wp/wp[1]/desired-course-deg");
- obj.addPropMap("FMSLegTrackErrorAngle", "/instrumentation/gps/wp/wp[1]/course-deviation-deg");
- obj.addPropMap("FMSWayPointCourseError", "/instrumentation/gps/wp/wp[1]/course-error-nm");
+ obj._triggeredPublisher.addPropMap("FMSHeadingBug", "/autopilot/settings/heading-bug-deg");
+ obj._triggeredPublisher.addPropMap("FMSSelectedAlt", "/autopilot/settings/target-alt-ft");
+ obj._triggeredPublisher.addPropMap("FMSFlightPlanActive", "/autopilot/route-manager/active");
+ obj._triggeredPublisher.addPropMap("FMSFlightPlanCurrentWP", "/autopilot/route-manager/current-wp");
+ obj._triggeredPublisher.addPropMap("FMSFlightPlanSequenced", "/autopilot/route-manager/signals/sequenced");
+ obj._triggeredPublisher.addPropMap("FMSFlightPlanFinished", "/autopilot/route-manager/signals/finished");
+ obj._triggeredPublisher.addPropMap("FMSFlightPlanEdited", "/autopilot/route-manager/signals/edited");
- obj.addPropMap("FMSGroundspeed", "/instrumentation/gps/indicated-ground-speed-kt");
+ obj._triggeredPublisher.addPropMap("FMSMode", "/instrumentation/gps/mode");
- obj.addPropMap("FMSNav1From", "/instrumentation/nav/from-flag");
- obj.addPropMap("FMSNav2From", "/instrumentation/nav[1]/from-flag");
+ obj._periodicPublisher.addPropMap("FMSLegValid", "/instrumentation/gps/wp/wp[1]/valid");
+ obj._periodicPublisher.addPropMap("FMSPreviousLegID", "/instrumentation/gps/wp/wp[0]/ID");
+ obj._periodicPublisher.addPropMap("FMSLegID", "/instrumentation/gps/wp/wp[1]/ID");
+ obj._periodicPublisher.addPropMap("FMSLegBearingMagDeg", "/instrumentation/gps/wp/wp[1]/bearing-mag-deg");
+ obj._periodicPublisher.addPropMap("FMSLegDistanceNM", "/instrumentation/gps/wp/wp[1]/distance-nm");
+ obj._periodicPublisher.addPropMap("FMSLegCourseError", "/instrumentation/gps/wp/wp[1]/course-error-nm");
+ obj._periodicPublisher.addPropMap("FMSLegDesiredTrack", "/instrumentation/gps/wp/wp[1]/desired-course-deg");
+ obj._periodicPublisher.addPropMap("FMSLegTrackErrorAngle", "/instrumentation/gps/wp/wp[1]/course-deviation-deg");
+ obj._periodicPublisher.addPropMap("FMSWayPointCourseError", "/instrumentation/gps/wp/wp[1]/course-error-nm");
+
+ obj._periodicPublisher.addPropMap("FMSGroundspeed", "/instrumentation/gps/indicated-ground-speed-kt");
+
+ obj._periodicPublisher.addPropMap("FMSNav1From", "/instrumentation/nav/from-flag");
+ obj._periodicPublisher.addPropMap("FMSNav2From", "/instrumentation/nav[1]/from-flag");
+
+ # Custom publish method as we need to calculate some particular values manually.
+ obj._periodicPublisher.publish = func() {
+ var gpsdata = {};
+
+ foreach (var propmap; me._propmaps) {
+ var name = propmap.getName();
+ gpsdata[name] = propmap.getValue();
+ }
+
+ # Some GPS properties have odd values to indicate that nothing is set, so
+ # remove them from the data set.
+ if (gpsdata["FMSLegBearingMagDeg"] == -9999) gpsdata["FMSLegBearingMagDeg"] = nil;
+ if (gpsdata["FMSLegDistanceNM"] == -1) gpsdata["FMSLegDistanceNM"] = nil;
+
+ # A couple of calculated values used by the MFD Header display
+ var total_fuel = getprop("/consumables/fuel/tank[0]/indicated-level-gal_us") or 0.0;
+ total_fuel = total_fuel + (getprop("/consumables/fuel/tank[1]/indicated-level-gal_us") or 0.0);
+ var fuel_flow = getprop("/engines/engine[0]/fuel-flow-gph") or 1.0;
+ gpsdata["FuelOnBoard"] = total_fuel;
+ gpsdata["EnduranceHrs"] = total_fuel / fuel_flow;
+
+ var plan = flightplan();
+
+ var dst = 0.0;
+ if (plan.getPlanSize() > 0) {
+ # Determine the distance to travel, based on
+ # - current distance to the next WP,
+ # - length of each subsequent leg.
+ dst = getprop("/instrumentation/gps/wp/wp[1]/distance-nm") or 0.0;
+
+ if (plan.indexOfWP(plan.currentWP()) < (plan.getPlanSize() -1)) {
+ for(var i=plan.indexOfWP(plan.currentWP()) + 1; i < plan.getPlanSize(); i = i+1) {
+ var leg = plan.getWP(i);
+ if (leg != nil ) dst = dst + leg.leg_distance;
+ }
+ }
+ }
+
+ gpsdata["FMSDistance"] = dst;
+ var spd = getprop("/instrumentation/gps/indicated-ground-speed-kt") or 1.0;
+ var time_hrs = dst / spd;
+
+ gpsdata["FMSEstimatedTimeEnroute"] = time_hrs;
+ gpsdata["FMSFuelOverDestination"] = total_fuel - time_hrs * fuel_flow;
+
+ var notification = notifications.PFDEventNotification.new(
+ "MFD",
+ 1,
+ notifications.PFDEventNotification.FMSData,
+ gpsdata);
+
+ me._transmitter.NotifyAll(notification);
+ };
return obj;
},
- # Custom publish method as we need to calculate some particular values manually.
- publish : func() {
- var gpsdata = {};
-
- foreach (var propmap; me._propmaps) {
- var name = propmap.getName();
- gpsdata[name] = propmap.getValue();
- }
-
- # Some GPS properties have odd values to indicate that nothing is set, so
- # remove them from the data set.
- if (gpsdata["FMSLegBearingMagDeg"] == -9999) gpsdata["FMSLegBearingMagDeg"] = nil;
- if (gpsdata["FMSLegDistanceNM"] == -1) gpsdata["FMSLegDistanceNM"] = nil;
-
- # A couple of calculated values used by the MFD Header display
- var total_fuel = getprop("/consumables/fuel/tank[0]/indicated-level-gal_us") or 0.0;
- total_fuel = total_fuel + (getprop("/consumables/fuel/tank[1]/indicated-level-gal_us") or 0.0);
- var fuel_flow = getprop("/engines/engine[0]/fuel-flow-gph") or 1.0;
- gpsdata["FuelOnBoard"] = total_fuel;
- gpsdata["EnduranceHrs"] = total_fuel / fuel_flow;
-
- var plan = flightplan();
-
- var dst = 0.0;
- if (plan.getPlanSize() > 0) {
- # Determine the distance to travel, based on
- # - current distance to the next WP,
- # - length of each subsequent leg.
- dst = getprop("/instrumentation/gps/wp/wp[1]/distance-nm") or 0.0;
-
- if (plan.indexOfWP(plan.currentWP()) < (plan.getPlanSize() -1)) {
- for(var i=plan.indexOfWP(plan.currentWP()) + 1; i < plan.getPlanSize(); i = i+1) {
- var leg = plan.getWP(i);
- if (leg != nil ) dst = dst + leg.leg_distance;
- }
- }
- }
-
- gpsdata["FMSDistance"] = dst;
- var spd = getprop("/instrumentation/gps/indicated-ground-speed-kt") or 1.0;
- var time_hrs = dst / spd;
-
- gpsdata["FMSEstimatedTimeEnroute"] = time_hrs;
- gpsdata["FMSFuelOverDestination"] = total_fuel - time_hrs * fuel_flow;
-
- var notification = notifications.PFDEventNotification.new(
- "MFD",
- 1,
- notifications.PFDEventNotification.FMSData,
- gpsdata);
-
- me._transmitter.NotifyAll(notification);
+ start : func() {
+ me._triggeredPublisher.start();
+ me._periodicPublisher.start();
},
+ stop : func() {
+ me._triggeredPublisher.stop();
+ me._periodicPublisher.stop();
+ },
+
+
};
diff --git a/Aircraft/Instruments-3d/FG1000/Nasal/Interfaces/PropertyPublisher.nas b/Aircraft/Instruments-3d/FG1000/Nasal/Interfaces/PropertyPublisher.nas
index a27ca1945..70d6fdef1 100644
--- a/Aircraft/Instruments-3d/FG1000/Nasal/Interfaces/PropertyPublisher.nas
+++ b/Aircraft/Instruments-3d/FG1000/Nasal/Interfaces/PropertyPublisher.nas
@@ -131,7 +131,7 @@ var TriggeredPropertyPublisher =
# Set up a listener triggering on create (to ensure all values are set at
# start of day) and only on changed values. These are the last two
# arguments to the setlistener call.
- var listener = setlistener(prop, func(p) { me.publish(p); }, 1, 0);
+ var listener = setlistener(prop, func(p) { me.publish(p); }, 1, 1);
append(me._listeners, listener);
}
},
diff --git a/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/PFDInstruments/PFDInstruments.nas b/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/PFDInstruments/PFDInstruments.nas
index 510a47b7a..c782d9813 100644
--- a/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/PFDInstruments/PFDInstruments.nas
+++ b/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/PFDInstruments/PFDInstruments.nas
@@ -81,7 +81,18 @@ var PFDInstruments =
obj._SVGGroup.setInt("z-index", 10);
obj.insetMap = fg1000.NavMap.new(obj, obj.getElement("PFD-Map-Display"), [119,601], "rect(-109px, 109px, 109px, -109px)", 0, 2);
- #obj.topMenu(device, obj, nil);
+ # Flight Plan Window group
+ obj.flightplanList = PFD.GroupElement.new(
+ obj.pageName,
+ svg,
+ [ "FlightPlanArrow", "FlightPlanID", "FlightPlanType", "FlightPlanDTK", "FlightPlanDIS"],
+ 5,
+ "FlightPlanArrow",
+ 1,
+ "FlightPlanScrollTrough",
+ "FlightPlanScrollThumb",
+ 120
+ );
obj.setController(fg1000.PFDInstrumentsController.new(obj, svg));
obj.setWindDisplay(0);
@@ -97,6 +108,7 @@ var PFDInstruments =
obj.updateHDG(0);
obj.updateSelectedALT(0);
obj.updateCRS(0);
+ obj.setFlightPlanVisible(0);
return obj;
},
@@ -705,4 +717,64 @@ var PFDInstruments =
me.getElement("PFD-Map-bg").setVisible(enabled);
me.insetMap.setVisible(enabled);
},
+
+ setFlightPlanVisible : func(enabled) {
+ me.getElement("FlightPlanGroup").setVisible(enabled);
+ },
+
+ # Update the FlightPlan display with an updated flightplan.
+ setFlightPlan : func(fp) {
+ var elements = [];
+
+ if (fp == nil) return;
+
+ for (var i = 0; i < fp.getPlanSize(); i = i + 1) {
+ var wp = fp.getWP(i);
+
+ var element = {
+ FlightPlanArrow : 0,
+ FlightPlanID : "",
+ FlightPlanType : "",
+ FlightPlanDTK : 0,
+ FlightPlanDIS : 0
+ };
+
+ if (wp.wp_name != nil) element.FlightPlanID = substr(wp.wp_name, 0, 7);
+ if (wp.wp_role != nil) element.FlightPlanType = substr(wp.wp_role, 0, 4);
+ if (wp.leg_distance != nil) element.FlightPlanDIS = sprintf("%.1fnm", wp.leg_distance);
+ if (wp.leg_bearing != nil) element.FlightPlanDTK = sprintf("%03d°", wp.leg_bearing);
+ append(elements, element);
+ }
+
+ me.flightplanList.setValues(elements);
+
+ # Determine a suitable name to display, using the flightplan name if there is one,
+ # but falling back to the flightplan departure / destination airports, or failing
+ # that the IDs of the first and last waypoints.
+ if (fp.id == nil) {
+ var from = "????";
+ var dest = "????";
+
+ if ((fp.getWP(0) != nil) and (fp.getWP(0).wp_name != nil)) {
+ from = fp.getWP(0).wp_name;
+ }
+
+ if ((fp.getWP(fp.getPlanSize() -1) != nil) and (fp.getWP(fp.getPlanSize() -1).wp_name != nil)) {
+ dest = fp.getWP(fp.getPlanSize() -1).wp_name;
+ }
+
+ if (fp.departure != nil) from = fp.departure.id;
+ if (fp.destination != nil) dest = fp.destination.id;
+ me.getElement("FlightPlanName").setText(from ~ " / " ~ dest);
+ } else {
+ me.getElement("FlightPlanName").setText(fp.id);
+ }
+ },
+
+ # Update the FlightPlan display to indicate the current waypoint
+ updateFlightPlan : func(current_wp) {
+ if (current_wp == -1) return;
+ me.flightplanList.setCRSR(current_wp);
+ me.flightplanList.displayGroup();
+ },
};
diff --git a/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/PFDInstruments/PFDInstrumentsController.nas b/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/PFDInstruments/PFDInstrumentsController.nas
index 2f43874ab..cd9f1fa2a 100644
--- a/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/PFDInstruments/PFDInstrumentsController.nas
+++ b/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/PFDInstruments/PFDInstrumentsController.nas
@@ -37,9 +37,14 @@ var PFDInstrumentsController =
_last_alt_ft : 0,
_last_trend : systime(),
_selected_alt_ft : 0,
- _heading : 0,
+ _heading_magnetic_deg : 0,
_mag_var : 0,
+ _fp_active : 0,
+ _fp_current_wp : 0,
+ _current_flightplan : nil,
+ _fp_visible : 0,
+
_leg_from :0,
_leg_id : "",
_leg_bearing : 0,
@@ -78,6 +83,12 @@ var PFDInstrumentsController =
_adf_heading_deg : 0.0,
};
+ obj._current_flightplan = obj.getNavData("Flightplan");
+ if (obj._current_flightplan != nil) {
+ obj._fp_current_wp = obj._current_flightplan.current;
+ obj.page.setFlightPlan(obj._current_flightplan);
+ }
+
return obj;
},
@@ -239,6 +250,37 @@ var PFDInstrumentsController =
if (data["FMSLegCourseError"] != nil) me._deflection_dots = data["FMSLegCourseError"] /2.0;
if (data["FMSLegCourseError"] != nil) me._leg_xtrk_nm = data["FMSLegCourseError"];
+ var update_fp = 0;
+
+ if (data["FMSFlightPlanEdited"] != nil) {
+ # The flightplan has changed in some way, so reload it.
+ update_fp = 1;
+ }
+
+ if ((data["FMSFlightPlanActive"] != nil) and (data["FMSFlightPlanActive"] != me._fp_active)) {
+ me._fp_active = data["FMSFlightPlanActive"];
+ me.page.setFlightPlanVisible(me._fp_active);
+ update_fp = 1;
+ }
+
+ if ((data["FMSFlightPlanCurrentWP"] != nil) and (data["FMSFlightPlanCurrentWP"] != me._fp_current_wp)) {
+ me._fp_current_wp = data["FMSFlightPlanCurrentWP"];
+ update_fp = 1;
+ }
+
+ if (update_fp and me._fp_active) {
+ # For some reason the signals to indicate a FP change aren't firing, so reload the
+ # flightplan here
+ me._current_flightplan = me.getNavData("Flightplan");
+ if (me._current_flightplan != nil) {
+ me._fp_current_wp = me._current_flightplan.current;
+ me.page.setFlightPlan(me._current_flightplan);
+ update_fp = 1;
+ }
+
+ me.page.updateFlightPlan(me._fp_current_wp);
+ }
+
if (me.getCDISource() == "GPS") {
if (me._leg_valid == 0) {
# No valid leg data, likely because there's no GPS course set
@@ -357,6 +399,24 @@ var PFDInstrumentsController =
return emesary.Transmitter.ReceiptStatus_OK;
},
+ getNavData : func(type, value=nil) {
+ # Use Emesary to get a piece from the NavData system, using the provided
+ # type and value;
+ var notification = notifications.PFDEventNotification.new(
+ "MFD",
+ me._page.mfd.getDeviceID(),
+ notifications.PFDEventNotification.NavData,
+ {Id: type, Value: value});
+
+ var response = me._transmitter.NotifyAll(notification);
+
+ if (! me._transmitter.IsFailed(response)) {
+ return notification.EventParameter.Value;
+ } else {
+ return nil;
+ }
+ },
+
PFDRegisterWithEmesary : func(transmitter = nil){
if (transmitter == nil)
transmitter = emesary.GlobalTransmitter;
diff --git a/Aircraft/Instruments-3d/FG1000/Nasal/PFD.nas b/Aircraft/Instruments-3d/FG1000/Nasal/PFD.nas
index 8d6caad9f..9f668267a 100644
--- a/Aircraft/Instruments-3d/FG1000/Nasal/PFD.nas
+++ b/Aircraft/Instruments-3d/FG1000/Nasal/PFD.nas
@@ -61,6 +61,11 @@ var PFDDisplay =
'/Aircraft/Instruments-3d/FG1000/MFDPages/PFDInstruments.svg',
{'font-mapper': fontmapper});
+ canvas.parsesvg(obj._svg,
+ '/Aircraft/Instruments-3d/FG1000/MFDPages/FlightPlanPFD.svg',
+ {'font-mapper': fontmapper});
+
+
canvas.parsesvg(obj._svg,
'/Aircraft/Instruments-3d/FG1000/MFDPages/DirectToPFD.svg',
{'font-mapper': fontmapper});
diff --git a/Nasal/canvas/PFD/GroupElement.nas b/Nasal/canvas/PFD/GroupElement.nas
index 4d104f847..529fbbcde 100644
--- a/Nasal/canvas/PFD/GroupElement.nas
+++ b/Nasal/canvas/PFD/GroupElement.nas
@@ -20,9 +20,6 @@ new : func (pageName, svg, elementNames, size, highlightElement, arrow=0, scroll
# must be an SVG Element [pageName][elementName]{0...pageSize}
_size : size,
- # Current size of the selectable elements.
- _currentSize : 0,
-
# ElementName to be highlighted. Must be an hash value from ._elementNames
_highlightElement : highlightElement,
@@ -39,13 +36,14 @@ new : func (pageName, svg, elementNames, size, highlightElement, arrow=0, scroll
# List of SVG elements to display the values
_elements : [],
- # Cursor index into the elements array
+ # Cursor index into the _values array
_crsrIndex : 0,
# Whether the CRSR is enabled
_crsrEnabled : 0,
- # Page index
+ # Page index - which _values index element[0] refers to. The currently
+ # selected _element has index (_crsrIndex - _pageIndex)
_pageIndex : 0,
};
@@ -97,64 +95,64 @@ setValues : func (values_array) {
me._scrollTroughElement.setVisible(0);
}
- me.displayPage();
+ me.displayGroup();
},
-nextPage : func() {
- if (size(me._values) > ((me._pageIndex +1) * me._size)) {
- me._pageIndex = me._pageIndex + 1;
- me._crsrIndex = 0;
- me.displayPage();
- } else {
- me._crsrIndex = me._currentSize -1;
+displayGroup : func () {
+
+ # The _crsrIndex element should be displayed as close to the middle of the
+ # group as possible. So as the user scrolls the list appears to move around
+ # a static cursor position.
+ #
+ # The exceptions to this is as the _crsrIndex approaches the ends of the list.
+ # 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);
+ me._pageIndex = me._crsrIndex - middle_element_index;
+
+ if (me._crsrIndex < middle_element_index) {
+ # Start of list
+ me._pageIndex = 0;
+ } else if (me._crsrIndex > (size(me._values) - middle_element_index - 1)) {
+ # End of list
+ me._pageIndex = size(me._values) - me._size;
}
-},
-previousPage : func() {
- if (me._pageIndex > 0) {
- me._pageIndex = me._pageIndex - 1;
- me._crsrIndex = me._size -1;
- me.displayPage();
- } else {
- me._crsrIndex = 0;
- }
-},
+ for (var i = 0; i < me._size; i = i + 1) {
+ if (me._pageIndex + i < size(me._values)) {
+ var value = me._values[me._pageIndex + i];
+ foreach (var k; keys(value)) {
+ if (k == me._highlightElement) {
+ me._elements[i].unhighlightElement();
-displayPage : func () {
- # Determine how many elements to display in this page
- me._currentSize = math.min(me._size, size(me._values) - me._size * me._pageIndex);
+ if (me._arrow) {
+ # If we're using a HighlightElement, then we only show the element
+ # the cursor is on.
+ if (i + me._pageIndex == me._crsrIndex) {
+ me._elements[i].setVisible(1);
+ if (me._crsrEnabled) me._elements[i].highlightElement();
+ } else {
+ me._elements[i].setVisible(0);
+ }
- for (var i = 0; i < me._currentSize; i = i + 1) {
- var value = me._values[i + me._size * me._pageIndex];
- foreach (var k; keys(value)) {
- if (k == me._highlightElement) {
- me._elements[i].unhighlightElement();
-
- if (me._arrow) {
- # If we're using a HighlightElement, then we only show the element
- # the cursor is on.
- if (i == me._crsrIndex) {
- me._elements[i].setVisible(1);
} else {
- me._elements[i].setVisible(0);
+ me._elements[i].setVisible(1);
+ if (me._crsrEnabled and (i + me._pageIndex == me._crsrIndex))
+ me._elements[i].highlightElement();
}
- } else {
- me._elements[i].setVisible(1);
- }
- me._elements[i].setValue(value[k]);
- } else {
- var name = me._pageName ~ k ~ i;
- var element = me._svg.getElementById(name);
- assert(element != nil, "Unable to find element " ~ name);
- element.setVisible(1);
- element.setText(value[k]);
- }
- }
- }
- # Hide any further elements
- if (me._currentSize < me._size) {
- for (var i = me._currentSize; i < me._size; i = i + 1) {
+ me._elements[i].setValue(value[k]);
+ } else {
+ var name = me._pageName ~ k ~ i;
+ var element = me._svg.getElementById(name);
+ assert(element != nil, "Unable to find element " ~ name);
+ element.setVisible(1);
+ element.setText(value[k]);
+ }
+ }
+ } else {
+ # We've gone off the end of the values list, so hide any further values.
foreach (var k; me._elementNames) {
if (k == me._highlightElement) {
me._elements[i].setVisible(0);
@@ -172,10 +170,9 @@ displayPage : func () {
if ((me._scrollThumbElement != nil) and (me._size < size(me._values))) {
# Shift the scrollbar if it's relevant
- var numScrollPositions = math.ceil(size(me._values) / me._size) -1;
me._scrollThumbElement.setTranslation([
me._scrollBaseTransform[0],
- me._scrollBaseTransform[1] + me._scrollHeight * (me._pageIndex / numScrollPositions)
+ me._scrollBaseTransform[1] + me._scrollHeight * (me._crsrIndex / (size(me._values) -1))
]);
}
},
@@ -190,77 +187,74 @@ addTextElement : func(name, value) {
},
showCRSR : func() {
- if (me._currentSize == 0) return;
+ if (size(me._values) == 0) return;
me._crsrEnabled = 1;
- me._elements[me._crsrIndex].highlightElement();
+ me._elements[me._crsrIndex - me._pageIndex].highlightElement();
},
hideCRSR : func() {
if (me._crsrEnabled == 0) return;
- me._elements[me._crsrIndex].unhighlightElement();
+ me._elements[me._crsrIndex - me._pageIndex].unhighlightElement();
# If we're using a HighlightElement, then we need to make the cursor position visible
- if (me._arrow) me._elements[me._crsrIndex].setVisible(1);
+ if (me._arrow) me._elements[me._crsrIndex - me._pageIndex].setVisible(1);
me._crsrEnabled = 0;
},
setCRSR : func(index) {
- me._crsrIndex = math.min(index, me._currentSize -1);
+ me._crsrIndex = math.min(index, size(me._values) -1);
+ me._crsrIndex = math.max(0, me._crsrIndex);
},
getCursorElementName : func() {
if (me._crsrEnabled == -1) return nil;
- return me._elements[me._crsrIndex].name;
+ return me._elements[me._crsrIndex - me._pageIndex].name;
},
isCursorOnDataEntryElement : func() {
if (me._crsrEnabled == -1) return 0;
- return isa(me._elements[me._crsrIndex], DataEntryElement);
+ return isa(me._elements[me._crsrIndex - me._pageIndex], DataEntryElement);
},
enterElement : func() {
if (me._crsrEnabled == 0) return;
- return me._elements[me._crsrIndex].enterElement();
+ return me._elements[me._crsrIndex - me._pageIndex].enterElement();
},
getValue : func() {
if (me._crsrEnabled == -1) return nil;
- return me._elements[me._crsrIndex].getValue();
+ return me._elements[me._crsrIndex - me._pageIndex].getValue();
+},
+setValue : func(idx, key, value) {
+ me._values[idx][key] = value;
},
clearElement : func() {
if (me._crsrEnabled == 0) return;
- me._elements[me._crsrIndex].clearElement();
+ me._elements[me._crsrIndex - me._pageIndex].clearElement();
},
incrSmall : func(value) {
if (me._crsrEnabled == 0) return;
var incr_or_decr = (value > 0) ? 1 : -1;
- if (me._elements[me._crsrIndex].isInEdit()) {
+ if (me._elements[me._crsrIndex - me._pageIndex].isInEdit()) {
# We're editing, so pass to the element.
#print("Moving cursor to next character entry");
- me._elements[me._crsrIndex].incrSmall();
+ me._elements[me._crsrIndex - me._pageIndex].incrSmall(val);
} else {
# Move to next selection element
- me._elements[me._crsrIndex].unhighlightElement();
-
me._crsrIndex = me._crsrIndex + incr_or_decr;
-
- if (me._crsrIndex < 0 ) me.previousPage();
- if (me._crsrIndex == me._currentSize) me.nextPage();
-
- me._elements[me._crsrIndex].highlightElement();
+ if (me._crsrIndex < 0 ) me._crsrIndex = 0;
+ if (me._crsrIndex == size(me._values)) me._crsrIndex = size(me._values) -1;
+ me.displayGroup();
}
},
incrLarge : func(val) {
if (me._crsrEnabled == 0) return;
var incr_or_decr = (val > 0) ? 1 : -1;
- if (me._elements[me._crsrIndex].isInEdit()) {
+ if (me._elements[me._crsrIndex - me._pageIndex].isInEdit()) {
# We're editing, so pass to the element.
#print("Moving cursor to next character entry");
- me._elements[me._crsrIndex].incrLarge();
+ me._elements[me._crsrIndex - me._pageIndex].incrLarge(val);
} else {
# Move to next selection element
- me._elements[me._crsrIndex].unhighlightElement();
me._crsrIndex = me._crsrIndex + incr_or_decr;
-
- if (me._crsrIndex < 0 ) me.previousPage();
- if (me._crsrIndex == me._currentSize) me.nextPage();
-
- me._elements[me._crsrIndex].highlightElement();
+ if (me._crsrIndex < 0 ) me._crsrIndex = 0;
+ if (me._crsrIndex == size(me._values)) me._crsrIndex = size(me._values) -1;
+ me.displayGroup();
}
},
};