extract base class SVGCanvas from EFIS framework to canvas/api/svgcanvas.nas
This commit is contained in:
parent
63fc1cf06d
commit
486797d6c6
4 changed files with 331 additions and 230 deletions
|
@ -27,6 +27,7 @@ io.include(include_path~"map.nas");
|
||||||
io.include(include_path~"text.nas");
|
io.include(include_path~"text.nas");
|
||||||
io.include(include_path~"path.nas");
|
io.include(include_path~"path.nas");
|
||||||
io.include(include_path~"image.nas");
|
io.include(include_path~"image.nas");
|
||||||
|
io.include(include_path~"svgcanvas.nas");
|
||||||
|
|
||||||
# Element factories used by #Group elements to create children
|
# Element factories used by #Group elements to create children
|
||||||
Group._element_factories = {
|
Group._element_factories = {
|
||||||
|
|
303
Nasal/canvas/api/svgcanvas.nas
Normal file
303
Nasal/canvas/api/svgcanvas.nas
Normal file
|
@ -0,0 +1,303 @@
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
#
|
||||||
|
# NOTE! This copyright does *not* cover user models that use these Nasal
|
||||||
|
# services by normal function calls - this is merely considered normal use
|
||||||
|
# of the code, and does *not* fall under the heading of "derived work."
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
# svgcanvas.nas - base class to populate canvas from SVG and animate elements
|
||||||
|
# author: jsb
|
||||||
|
# created: 06/2020
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
# Examples:
|
||||||
|
# var myCanvas = SVGCanvas.new("mySVG");
|
||||||
|
# myCanvas.loadsvg("myfile.svg", ["foo", "bar"]);
|
||||||
|
#
|
||||||
|
# to hide/show a SVG element based on a property you can use:
|
||||||
|
# var L = setlistener("/controls/foo", myCanvas._makeListener_showHide("foo"));
|
||||||
|
#
|
||||||
|
# to animate a SVG element you can use:
|
||||||
|
# myCanvas["bar"].setTranslation(10,20);
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
var SVGCanvas = {
|
||||||
|
|
||||||
|
colors: canvas.colors,
|
||||||
|
|
||||||
|
# constructor
|
||||||
|
# name: name of canvas
|
||||||
|
# settings: hash with canvas settings
|
||||||
|
new: func(name, settings=nil) {
|
||||||
|
var canvas_settings = {
|
||||||
|
"name": "SVG_canvas",
|
||||||
|
"size": [1024,1024],
|
||||||
|
"view": [1024,1024],
|
||||||
|
"mipmapping": 1
|
||||||
|
};
|
||||||
|
|
||||||
|
if (settings != nil) {
|
||||||
|
# override defaults
|
||||||
|
foreach (var key; keys(settings)) {
|
||||||
|
canvas_settings[key] = settings[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
canvas_settings["name"] = name;
|
||||||
|
|
||||||
|
var obj = {
|
||||||
|
parents: [me],
|
||||||
|
_canvas: canvas.new(canvas_settings),
|
||||||
|
_root: nil,
|
||||||
|
name: name,
|
||||||
|
};
|
||||||
|
obj._root = obj._canvas.createGroup();
|
||||||
|
return obj;
|
||||||
|
},
|
||||||
|
|
||||||
|
# loadSVG - loads SVG file and create canvas.element objects for given IDs
|
||||||
|
# file: filename to load
|
||||||
|
# svg_keys: vector of id strings
|
||||||
|
# options: options to canvas.parsesvg
|
||||||
|
loadSVG: func(file, svg_keys, options=nil) {
|
||||||
|
var default_options = {
|
||||||
|
"default-font-family": "LiberationSans",
|
||||||
|
"default-font-weight": "",
|
||||||
|
"default-font-style": "",
|
||||||
|
};
|
||||||
|
if (ishash(options)) {
|
||||||
|
# override defaults
|
||||||
|
foreach (var key; keys(options)) {
|
||||||
|
default_options[key] = options[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (canvas.parsesvg(me._root, file, default_options)) {
|
||||||
|
# create nasal variables for SVG elements;
|
||||||
|
foreach (var key; svg_keys) {
|
||||||
|
me[key] = me._root.getElementById(key);
|
||||||
|
if (me[key] != nil) {
|
||||||
|
me._updateClip(key);
|
||||||
|
}
|
||||||
|
else logprint(DEV_WARN, " loadSVG: id '", key, "' not found in SVG file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return me;
|
||||||
|
},
|
||||||
|
|
||||||
|
# openInWindow - opens the canvas in a window
|
||||||
|
# window_size: vector [size_x, size_y] passed to canvas.Window.new
|
||||||
|
# returns canvas.window object
|
||||||
|
asWindow: func(window_size) {
|
||||||
|
if (me["window"] != nil)
|
||||||
|
return me.window;
|
||||||
|
|
||||||
|
me.window = canvas.Window.new(window_size, "dialog");
|
||||||
|
me.window.set('title', me.name)
|
||||||
|
.set("resize", 1)
|
||||||
|
.setCanvas(me._canvas);
|
||||||
|
me.window.lockAspectRatio(1);
|
||||||
|
me.window.del = func() {
|
||||||
|
call(canvas.Window.del, [], me, var err = []);
|
||||||
|
me.window = nil;
|
||||||
|
}
|
||||||
|
return me.window
|
||||||
|
},
|
||||||
|
|
||||||
|
getPath: func {
|
||||||
|
return me._canvas.getPath();
|
||||||
|
},
|
||||||
|
|
||||||
|
getCanvas: func {
|
||||||
|
return me._canvas;
|
||||||
|
},
|
||||||
|
|
||||||
|
getRoot: func {
|
||||||
|
return me._root;
|
||||||
|
},
|
||||||
|
|
||||||
|
# svgkey: id of text element to updateTextElement
|
||||||
|
# text: new text
|
||||||
|
updateTextElement: func(svgkey, text, color = nil) {
|
||||||
|
if (me[svgkey] == nil or !isa(me[svgkey], canvas.Text)) {
|
||||||
|
logprint(DEV_ALERT, "updateTextElement(): Invalid argument ", svgkey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
me[svgkey].setText(text);
|
||||||
|
if (color != nil) {
|
||||||
|
if (isvec(color)) me[svgkey].setColor(color);
|
||||||
|
elsif (isstr(color)) me[svgkey].setColor(me.colors[color]);
|
||||||
|
}
|
||||||
|
return me;
|
||||||
|
},
|
||||||
|
|
||||||
|
#--------------------------------------------------------------
|
||||||
|
# private methods, to be used in this and derived classes only
|
||||||
|
#--------------------------------------------------------------
|
||||||
|
_updateClip: func(key) {
|
||||||
|
var clip_elem = me._root.getElementById(key~"_clip");
|
||||||
|
if (clip_elem != nil) {
|
||||||
|
clip_elem.setVisible(0);
|
||||||
|
me[key].setClipByElement(clip_elem);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
# returns generic listener to show/hide element(s)
|
||||||
|
# svgkeys: can be a string referring to a single element
|
||||||
|
# or vector of strings referring to SVG elements
|
||||||
|
# (hint: if possible, group elements in SVG and animate group)
|
||||||
|
# value: optional value to trigger show(); otherwise node.value will be implicitly treated as bool
|
||||||
|
_makeListener_showHide: func(svgkeys, value=nil) {
|
||||||
|
if (value == nil) {
|
||||||
|
if (isvec(svgkeys)) {
|
||||||
|
return func(n) {
|
||||||
|
if (n.getValue())
|
||||||
|
foreach (var key; svgkeys) me[key].show();
|
||||||
|
else
|
||||||
|
foreach (var key; svgkeys) me[key].hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return func(n) {
|
||||||
|
if (n.getValue()) me[svgkeys].show();
|
||||||
|
else me[svgkeys].hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (isvec(svgkeys)) {
|
||||||
|
return func(n) {
|
||||||
|
if (n.getValue() == value)
|
||||||
|
foreach (var key; svgkeys) me[key].show();
|
||||||
|
else
|
||||||
|
foreach (var key; svgkeys) me[key].hide();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return func(n) {
|
||||||
|
if (n.getValue() == value) me[svgkeys].show();
|
||||||
|
else me[svgkeys].hide();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
# returns listener to set rotation of element(s)
|
||||||
|
# svgkeys: can be a string referring to a single element
|
||||||
|
# or vector of strings referring to SVG elements
|
||||||
|
# factors: optional, number (if svgkeys is a single key) or hash of numbers
|
||||||
|
# {"svgkey" : factor}, missing keys will be treated as 1
|
||||||
|
_makeListener_rotate: func(svgkeys, factors=nil) {
|
||||||
|
if (factors == nil) {
|
||||||
|
if (isvec(svgkeys)) {
|
||||||
|
return func(n) {
|
||||||
|
var value = n.getValue() or 0;
|
||||||
|
foreach (var key; svgkeys) {
|
||||||
|
me[key].setRotation(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return func(n) {
|
||||||
|
var value = n.getValue() or 0;
|
||||||
|
me[svgkeys].setRotation(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (isvec(svgkeys)) {
|
||||||
|
return func(n) {
|
||||||
|
var value = n.getValue() or 0;
|
||||||
|
foreach (var key; svgkeys) {
|
||||||
|
var factor = factors[key] or 1;
|
||||||
|
me[key].setRotation(value * factor);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return func(n) {
|
||||||
|
var value = n.getValue() or 0;
|
||||||
|
var factor = num(factors) or 1;
|
||||||
|
me[svgkeys].setRotation(value * factor);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
# returns listener to set translation of element(s)
|
||||||
|
# svgkeys: can be a string referring to a single element
|
||||||
|
# or vector of strings referring to SVG elements
|
||||||
|
# factors: number (if svgkeys is a single key) or hash of numbers
|
||||||
|
# {"svgkey" : factor}, missing keys will be treated as 0 (=no op)
|
||||||
|
_makeListener_translate: func(svgkeys, fx, fy) {
|
||||||
|
if (isvec(svgkeys)) {
|
||||||
|
var x = num(fx) or 0;
|
||||||
|
var y = num(fy) or 0;
|
||||||
|
if (ishash(fx) or ishash(fy)) {
|
||||||
|
return func(n) {
|
||||||
|
foreach (var key; svgkeys) {
|
||||||
|
var value = n.getValue() or 0;
|
||||||
|
if (ishash(fx)) x = fx[key] or 0;
|
||||||
|
if (ishash(fy)) y = fy[key] or 0;
|
||||||
|
me[key].setTranslation(value * x, value * y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return func(n) {
|
||||||
|
foreach (var key; svgkeys) {
|
||||||
|
var value = n.getValue() or 0;
|
||||||
|
me[key].setTranslation(value * x, value * y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (num(fx) == nil or num(fy) == nil) {
|
||||||
|
logprint(DEV_ALERT, "_makeListener_translate(): Error, factor not a number.");
|
||||||
|
return func ;
|
||||||
|
}
|
||||||
|
return func(n) {
|
||||||
|
var value = n.getValue() or 0;
|
||||||
|
if (num(value) == nil)
|
||||||
|
value = 0;
|
||||||
|
me[svgkeys].setTranslation(value * fx, value * fy);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
# returns generic listener to change element color
|
||||||
|
# svgkeys: can be a string referring to a single element
|
||||||
|
# or vector of strings referring to SVG elements
|
||||||
|
# (hint: putting elements in a SVG group (if possible) might be easier)
|
||||||
|
# colors can be either a vector e.g. [r,g,b] or "name" from me.colors
|
||||||
|
_makeListener_setColor: func(svgkeys, color_true, color_false) {
|
||||||
|
var col_0 = isvec(color_false) ? color_false : me.colors[color_false];
|
||||||
|
var col_1 = isvec(color_true) ? color_true : me.colors[color_true];
|
||||||
|
if (isvec(svgkeys) ) {
|
||||||
|
return func(n) {
|
||||||
|
if (n.getValue())
|
||||||
|
foreach (var key; svgkeys) me[key].setColor(col_1);
|
||||||
|
else
|
||||||
|
foreach (var key; svgkeys) me[key].setColor(col_0);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return func(n) {
|
||||||
|
if (n.getValue()) me[svgkeys].setColor(col_1);
|
||||||
|
else me[svgkeys].setColor(col_0);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_makeListener_updateText: func(svgkeys, format="%s", default="") {
|
||||||
|
if (isvec(svgkeys)) {
|
||||||
|
return func(n) {
|
||||||
|
foreach (var key; svgkeys) {
|
||||||
|
me.updateTextElement(key, sprintf(format, n.getValue() or default));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return func(n) {
|
||||||
|
me.updateTextElement(svgkeys, sprintf(format, n.getValue() or default));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
23
Nasal/canvas/api/svgcanvas.nut
Normal file
23
Nasal/canvas/api/svgcanvas.nut
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
#
|
||||||
|
# NOTE! This copyright does *not* cover user models that use these Nasal
|
||||||
|
# services by normal function calls - this is merely considered normal use
|
||||||
|
# of the code, and does *not* fall under the heading of "derived work."
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
# svgcanvas.nut - Nasal unit test vor svgcanvas.nas
|
||||||
|
# author: jsb
|
||||||
|
# created: 07/2020
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
var test_SVGCanvas = func {
|
||||||
|
var svgc = canvas.SVGCanvas.new("test");
|
||||||
|
unitTest.assert(isa(svgc, canvas.SVGCanvas), "SVGCanvas.new");
|
||||||
|
var tmp = svgc.getCanvas();
|
||||||
|
unitTest.assert(isghost(tmp) and ghosttype(tmp) == "Canvas", "SVGCanvas.getCanvas");
|
||||||
|
var prefix = "canvas://by-index/texture";
|
||||||
|
unitTest.assert(left(svgc.getPath(), size(prefix)) == prefix, "SVGCanvas.getPath");
|
||||||
|
unitTest.assert(isa(svgc.getRoot(), canvas.Group), "SVGCanvas.getRoot");
|
||||||
|
var win = svgc.asWindow([300,300]);
|
||||||
|
unitTest.assert(isa(win, canvas.Window), "SVGCanvas.asWindow");
|
||||||
|
win.del();
|
||||||
|
};
|
|
@ -34,19 +34,17 @@ var EFISCanvas = {
|
||||||
},
|
},
|
||||||
|
|
||||||
colors: canvas.colors,
|
colors: canvas.colors,
|
||||||
defaultcanvas_settings: EFIS.defaultcanvas_settings,
|
canvas_settings: EFIS.defaultcanvas_settings,
|
||||||
|
|
||||||
new: func(name, svgfile=nil) {
|
new: func(name) {
|
||||||
var obj = {
|
var obj = {
|
||||||
parents: [me],
|
parents: [me, canvas.SVGCanvas.new(name, me.canvas_settings)],
|
||||||
_id: size(EFISCanvas._instances), # internal ID for EFIS window mgmt.
|
_id: size(EFISCanvas._instances), # internal ID for EFIS window mgmt.
|
||||||
id: 0, # instance id e.g. for PFD/MFD
|
id: 0, # instance id e.g. for PFD/MFD
|
||||||
name: name,
|
name: name,
|
||||||
|
svg_keys: [],
|
||||||
# for reload support while efis development
|
# for reload support while efis development
|
||||||
_timers: [],
|
_timers: [],
|
||||||
_canvas: nil,
|
|
||||||
_root: nil,
|
|
||||||
svg_keys: [],
|
|
||||||
updateN: nil, # to be used in update() to pause updates
|
updateN: nil, # to be used in update() to pause updates
|
||||||
_instr_props: {},
|
_instr_props: {},
|
||||||
};
|
};
|
||||||
|
@ -56,56 +54,15 @@ var EFISCanvas = {
|
||||||
obj.updateCountN.setIntValue(0);
|
obj.updateCountN.setIntValue(0);
|
||||||
obj.debugN = EFIS_root_node.getNode("debug/"~n, 1);
|
obj.debugN = EFIS_root_node.getNode("debug/"~n, 1);
|
||||||
obj.debugN.setBoolValue(0);
|
obj.debugN.setBoolValue(0);
|
||||||
var settings = obj.defaultcanvas_settings;
|
|
||||||
settings["name"] = name;
|
|
||||||
obj._canvas = canvas.new(settings);
|
|
||||||
obj._root = obj._canvas.createGroup();
|
|
||||||
if (svgfile != nil) {
|
|
||||||
obj.loadsvg(svgfile);
|
|
||||||
}
|
|
||||||
return obj;
|
return obj;
|
||||||
},
|
},
|
||||||
|
|
||||||
#used by EFIS._setDisplaySource()
|
|
||||||
getPath: func {
|
|
||||||
return me._canvas.getPath();
|
|
||||||
},
|
|
||||||
|
|
||||||
getCanvas: func {
|
|
||||||
return me._canvas;
|
|
||||||
},
|
|
||||||
|
|
||||||
getRoot: func {
|
|
||||||
return me._root;
|
|
||||||
},
|
|
||||||
|
|
||||||
#set node that en-/dis-ables canvas updates
|
#set node that en-/dis-ables canvas updates
|
||||||
setUpdateN: func(n) {
|
setUpdateN: func(n) {
|
||||||
me.updateN = n;
|
me.updateN = n;
|
||||||
},
|
},
|
||||||
|
|
||||||
loadsvg: func(file) {
|
|
||||||
logprint(LOG_INFO, "EFIS loading "~file);
|
|
||||||
var options = {
|
|
||||||
"default-font-family": "LiberationSans",
|
|
||||||
"default-font-weight": "",
|
|
||||||
"default-font-style": "",
|
|
||||||
};
|
|
||||||
canvas.parsesvg(me._root, file, options);
|
|
||||||
|
|
||||||
# create nasal variables for SVG elements;
|
|
||||||
# in a class derived from EFISCanvas, add IDs to the svg_keys member in the constructor (new)
|
|
||||||
var svg_keys = me.svg_keys;
|
|
||||||
foreach (var key; svg_keys) {
|
|
||||||
me[key] = me._root.getElementById(key);
|
|
||||||
if (me[key] != nil) {
|
|
||||||
me._updateClip(key);
|
|
||||||
}
|
|
||||||
#else logprint(DEV_ALERT, " loadsvg: invalid key ",key);
|
|
||||||
}
|
|
||||||
return me;
|
|
||||||
},
|
|
||||||
|
|
||||||
# register an update function with a certain update interval
|
# register an update function with a certain update interval
|
||||||
# f: function
|
# f: function
|
||||||
# f_me: if there is any "me" reference in "f", you can set "me" with this
|
# f_me: if there is any "me" reference in "f", you can set "me" with this
|
||||||
|
@ -163,187 +120,4 @@ var EFISCanvas = {
|
||||||
if (value != nil) return value;
|
if (value != nil) return value;
|
||||||
else return default;
|
else return default;
|
||||||
},
|
},
|
||||||
|
|
||||||
updateTextElement: func(svgkey, text, color = nil) {
|
|
||||||
if (me[svgkey] == nil or !isa(me[svgkey], canvas.Text)) {
|
|
||||||
print("updateTextElement(): Invalid argument ", svgkey);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
me[svgkey].setText(text);
|
|
||||||
if (color != nil and me[svgkey].setColor != nil) {
|
|
||||||
if (isvec(color)) me[svgkey].setColor(color);
|
|
||||||
else me[svgkey].setColor(me.colors[color]);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
## private methods, to be used in this and derived classes only
|
|
||||||
_updateClip: func(key) {
|
|
||||||
var clip_elem = me._root.getElementById(key ~ "_clip");
|
|
||||||
if (clip_elem != nil) {
|
|
||||||
clip_elem.setVisible(0);
|
|
||||||
me[key].setClipByElement(clip_elem);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
# returns generic listener to show/hide element(s)
|
|
||||||
# svgkeys: can be a string referring to a single element
|
|
||||||
# or vector of strings referring to SVG elements
|
|
||||||
# (hint: putting elements in a SVG group (if possible) might be easier)
|
|
||||||
# value: optional value to trigger show(); otherwise node.value will be implicitly treated as bool
|
|
||||||
_makeListener_showHide: func(svgkeys, value=nil) {
|
|
||||||
if (value == nil) {
|
|
||||||
if (isvec(svgkeys)) {
|
|
||||||
return func(n) {
|
|
||||||
if (n.getValue())
|
|
||||||
foreach (var key; svgkeys) me[key].show();
|
|
||||||
else
|
|
||||||
foreach (var key; svgkeys) me[key].hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return func(n) {
|
|
||||||
if (n.getValue()) me[svgkeys].show();
|
|
||||||
else me[svgkeys].hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (isvec(svgkeys)) {
|
|
||||||
return func(n) {
|
|
||||||
if (n.getValue() == value)
|
|
||||||
foreach (var key; svgkeys) me[key].show();
|
|
||||||
else
|
|
||||||
foreach (var key; svgkeys) me[key].hide();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return func(n) {
|
|
||||||
if (n.getValue() == value) me[svgkeys].show();
|
|
||||||
else me[svgkeys].hide();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
# returns listener to set rotation of element(s)
|
|
||||||
# svgkeys: can be a string referring to a single element
|
|
||||||
# or vector of strings referring to SVG elements
|
|
||||||
# factors: optional, number (if svgkeys is a single key) or hash of numbers
|
|
||||||
# {"svgkey" : factor}, missing keys will be treated as 1
|
|
||||||
_makeListener_rotate: func(svgkeys, factors=nil) {
|
|
||||||
if (factors == nil) {
|
|
||||||
if (isvec(svgkeys)) {
|
|
||||||
return func(n) {
|
|
||||||
var value = n.getValue() or 0;
|
|
||||||
foreach (var key; svgkeys) {
|
|
||||||
me[key].setRotation(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return func(n) {
|
|
||||||
var value = n.getValue() or 0;
|
|
||||||
me[svgkeys].setRotation(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (isvec(svgkeys)) {
|
|
||||||
return func(n) {
|
|
||||||
var value = n.getValue() or 0;
|
|
||||||
foreach (var key; svgkeys) {
|
|
||||||
var factor = factors[key] or 1;
|
|
||||||
me[key].setRotation(value * factor);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return func(n) {
|
|
||||||
var value = n.getValue() or 0;
|
|
||||||
var factor = num(factors) or 1;
|
|
||||||
me[svgkeys].setRotation(value * factor);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
# returns listener to set translation of element(s)
|
|
||||||
# svgkeys: can be a string referring to a single element
|
|
||||||
# or vector of strings referring to SVG elements
|
|
||||||
# factors: number (if svgkeys is a single key) or hash of numbers
|
|
||||||
# {"svgkey" : factor}, missing keys will be treated as 0 (=no op)
|
|
||||||
_makeListener_translate: func(svgkeys, fx, fy) {
|
|
||||||
if (isvec(svgkeys)) {
|
|
||||||
var x = num(fx) or 0;
|
|
||||||
var y = num(fy) or 0;
|
|
||||||
if (ishash(fx) or ishash(fy)) {
|
|
||||||
return func(n) {
|
|
||||||
foreach (var key; svgkeys) {
|
|
||||||
var value = n.getValue() or 0;
|
|
||||||
if (ishash(fx)) x = fx[key] or 0;
|
|
||||||
if (ishash(fy)) y = fy[key] or 0;
|
|
||||||
me[key].setTranslation(value * x, value * y);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return func(n) {
|
|
||||||
foreach (var key; svgkeys) {
|
|
||||||
var value = n.getValue() or 0;
|
|
||||||
me[key].setTranslation(value * x, value * y);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (num(fx) == nil or num(fy) == nil) {
|
|
||||||
print("EFISCanvas._makeListener_translate(): Error, factor not a number.");
|
|
||||||
return func ;
|
|
||||||
}
|
|
||||||
return func(n) {
|
|
||||||
var value = n.getValue() or 0;
|
|
||||||
if (num(value) == nil)
|
|
||||||
value = 0;
|
|
||||||
me[svgkeys].setTranslation(value * fx, value * fy);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
# returns generic listener to change element color
|
|
||||||
# svgkeys: can be a string referring to a single element
|
|
||||||
# or vector of strings referring to SVG elements
|
|
||||||
# (hint: putting elements in a SVG group (if possible) might be easier)
|
|
||||||
# colors can be either a vector e.g. [r,g,b] or "name" from me.colors
|
|
||||||
_makeListener_setColor: func(svgkeys, color_true, color_false) {
|
|
||||||
var col_0 = isvec(color_false) ? color_false : me.colors[color_false];
|
|
||||||
var col_1 = isvec(color_true) ? color_true : me.colors[color_true];
|
|
||||||
if (isvec(svgkeys) ) {
|
|
||||||
return func(n) {
|
|
||||||
if (n.getValue())
|
|
||||||
foreach (var key; svgkeys) me[key].setColor(col_1);
|
|
||||||
else
|
|
||||||
foreach (var key; svgkeys) me[key].setColor(col_0);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return func(n) {
|
|
||||||
if (n.getValue()) me[svgkeys].setColor(col_1);
|
|
||||||
else me[svgkeys].setColor(col_0);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_makeListener_updateText: func(svgkeys, format="%s", default="") {
|
|
||||||
if (isvec(svgkeys)) {
|
|
||||||
return func(n) {
|
|
||||||
foreach (var key; svgkeys) {
|
|
||||||
me.updateTextElement(key, sprintf(format, n.getValue() or default));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return func(n) {
|
|
||||||
me.updateTextElement(svgkeys, sprintf(format, n.getValue() or default));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue