1
0
Fork 0
fgdata/Nasal/canvas/PFD/DataEntryElement.nas
2018-02-04 22:40:48 +00:00

218 lines
7.1 KiB
Text

# PFD DataEntryElement - Data Entry UI Element.
#
# Uses the FMS Knobs to enter a text value with a given length and character set.
#
# To use, there must be an element called [PageName][ElementName] which will
# be used for the complete string, and a set of [PageName][ElementName]{0...n}
# elements, each consisting of a single character for input.
#
var DataEntryElement =
{
new : func (pagename, svg, name, value, size, charSet, style=nil)
{
var obj = {
parents : [ DataEntryElement, PFD.UIElement ],
_name : pagename ~ name,
_size : size,
_charSet : charSet,
_dataEntryPos : -1,
_dataEntrySymbol : [],
_style : style,
};
if (style == nil) obj._style = PFD.DefaultStyle;
obj._symbol = svg.getElementById(obj._name);
assert(obj._symbol != nil, "Unable to find element" ~ obj._name);
obj.setValue(value);
for (var i = 0; i < size; i = i + 1) {
var nodeName = obj._name ~ i;
append(obj._dataEntrySymbol, svg.getElementById(nodeName));
assert(obj._dataEntrySymbol[i] != nil, "Unable to find element " ~ nodeName);
obj._dataEntrySymbol[i].setVisible(0);
}
# State and timer for flashing highlighting of elements
obj._highlighted = 0;
obj._highlightEnabled = 0;
obj._flashTimer = nil;
obj._highlightChar = 0;
obj._highlightCharEnabled = 0;
obj._flashCharTimer = nil;
return obj;
},
getName : func() { return me._name; },
getValue : func() { return me._symbol.getText(); },
setValue : func(value) { me._symbol.setText(value); },
setVisible : func(vis) {
me._symbol.setVisible(vis);
# Only ever hide the character entry symbols, as they are displayed
# only when editing
if (vis == 0) {
for (var i = 0; i < me._size; i = i + 1) me._dataEntrySymbol[i].setVisible(0);
}
},
_flashElement : func() {
if (me._highlightEnabled == 0) {
me._symbol.setDrawMode(canvas.Text.TEXT);
me._symbol.setColor(me._style.NORMAL_TEXT_COLOR);
me._highlighted = 0;
} else {
if (me._highlighted == 0) {
me._symbol.setDrawMode(canvas.Text.TEXT + canvas.Text.FILLEDBOUNDINGBOX);
me._symbol.setColorFill(me._style.HIGHLIGHT_COLOR);
me._symbol.setColor(me._style.HIGHLIGHT_TEXT_COLOR);
me._highlighted = 1;
} else {
me._symbol.setDrawMode(canvas.Text.TEXT);
me._symbol.setColor(me._style.NORMAL_TEXT_COLOR);
me._highlighted = 0;
}
}
},
highlightElement : func() {
me._highlightEnabled = 1;
me._highlighted = 0;
me._flashElement();
me._flashTimer = maketimer(me._style.CURSOR_BLINK_PERIOD, me, me._flashElement);
me._flashTimer.start();
},
unhighlightElement : func() {
if (me._flashTimer != nil) me._flashTimer.stop();
me._flashTimer = nil;
me._highlightEnabled = 0;
me._highlighted = 0;
me._flashElement();
},
_flashCharElement : func() {
if (me._highlightCharEnabled == 0) {
me._dataEntrySymbol[me._dataEntryPos].setDrawMode(canvas.Text.TEXT);
me._dataEntrySymbol[me._dataEntryPos].setColor(me._style.NORMAL_TEXT_COLOR);
me._highlightChar = 0;
} else {
if (me._highlightChar == 0) {
me._dataEntrySymbol[me._dataEntryPos].setDrawMode(canvas.Text.TEXT + canvas.Text.FILLEDBOUNDINGBOX);
me._dataEntrySymbol[me._dataEntryPos].setColorFill(me._style.HIGHLIGHT_COLOR);
me._dataEntrySymbol[me._dataEntryPos].setColor(me._style.HIGHLIGHT_TEXT_COLOR);
me._highlightChar = 1;
} else {
me._dataEntrySymbol[me._dataEntryPos].setDrawMode(canvas.Text.TEXT);
me._dataEntrySymbol[me._dataEntryPos].setColor(me._style.NORMAL_TEXT_COLOR);
me._highlightChar = 0;
}
}
},
highlightCharElement : func() {
me._highlightCharEnabled = 1;
me._highlightChar = 0;
me._flashCharElement();
me._flashCharTimer = maketimer(me._style.CURSOR_BLINK_PERIOD, me, me._flashCharElement);
me._flashCharTimer.start();
},
unhighlightCharElement : func() {
if (me._flashCharTimer != nil) me._flashCharTimer.stop();
me._flashCharTimer = nil;
me._highlightCharEnabled = 0;
me._highlightChar = 0;
me._flashCharElement();
},
isEditable : func () { return 1; },
isInEdit : func() { return (me._dataEntryPos != -1); },
enterElement : func() {
# Handle pressing enter to confirm this element.
# - Hiding the per-character entry fields
# - concatenating the data that's been entered into a string
# - displaying the string in the (highlighted) top level element
#
# Also pass back the string to the caller.
var val = "";
for (var i = 0; i < me._size; i = i + 1) {
if (me._dataEntrySymbol[i].getText() != "_") {
val = val ~ me._dataEntrySymbol[i].getText();
}
me._dataEntrySymbol[i].setVisible(0);
}
me._symbol.setText(val);
me._symbol.setVisible(1);
me.highlightElement();
me._dataEntryPos = -1;
return val;
},
clearElement : func() {
# Cancel editing this element by
# - Hiding the per-character entry fields
# - Highlighting the top level element
for (var i = 0; i < me._size; i = i + 1) {
me._dataEntrySymbol[i].setVisible(0);
}
me._symbol.setVisible(1);
me.highlightElement();
me._dataEntryPos = -1;
},
incrSmall : func(value) {
# Change the value of this element, or start editing it if we're not already
# doing so.
if (me._dataEntryPos == -1) {
# Start editing by hiding the top level element, and displaying and
# resetting the character entry fields.
me._dataEntryPos = 0;
me._symbol.setVisible(0);
for (var i = 0; i < me._size; i = i + 1) {
me._dataEntrySymbol[i].setText("_");
me._dataEntrySymbol[i].setVisible(1);
}
# Highlight the first character element to indicate we're editing it
me.highlightCharElement();
} else {
var charSym = me._dataEntrySymbol[me._dataEntryPos];
var incr_or_decr = (value > 0) ? 1 : -1;
# Change the value of the data element
var val = charSym.getText();
if (val == "_") {
# Not previously set, so set to the first or last characterset entry
# depending on direction
if (incr_or_decr > 0) {
charSym.setText(chr(me._charSet[0]));
} else {
charSym.setText(chr(me._charSet[size(me._charSet) -1]));
}
} else {
var curIdx = find(val, me._charSet);
if (curIdx == -1) die("Failed to find character " ~ val ~ " in dataEntryElement " ~ element);
curIdx = math.mod(curIdx + incr_or_decr, size(me._charSet));
charSym.setText(chr(me._charSet[curIdx]));
}
}
},
incrLarge : func(value) {
# Change the cursor position within a data element
var incr_or_decr = (value > 0) ? 1 : -1;
if ((me._dataEntryPos == 0) and (incr_or_decr == -1)) return; # Don't scroll off the start
if ((me._dataEntryPos == me._size -1) and (incr_or_decr == 1)) return; # Don't scroll off the end
me.unhighlightCharElement();
me._dataEntryPos = me._dataEntryPos + incr_or_decr;
me.highlightCharElement();
},
};