2020-04-27 07:44:19 +00:00
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
# canvas.Group
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
# Class for a group element on a canvas
|
|
|
|
#
|
|
|
|
var Group = {
|
|
|
|
new: func(ghost) {
|
2020-04-28 11:19:01 +00:00
|
|
|
var obj = {
|
|
|
|
parents: [Group, Element.new(ghost)],
|
|
|
|
};
|
|
|
|
return obj;
|
2020-04-27 07:44:19 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
# Create a child of given type with specified id.
|
|
|
|
# type can be group, text
|
|
|
|
createChild: func(type, id = nil) {
|
|
|
|
var ghost = me._createChild(type, id);
|
|
|
|
var factory = me._getFactory(type);
|
|
|
|
if (factory == nil) {
|
|
|
|
return ghost;
|
|
|
|
}
|
|
|
|
return factory(ghost);
|
|
|
|
},
|
|
|
|
|
|
|
|
# Create multiple children of given type
|
|
|
|
createChildren: func(type, count) {
|
|
|
|
var factory = me._getFactory(type);
|
|
|
|
if (factory == nil) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
var nodes = props._addChildren(me._node._g, [type, count, 0, 0]);
|
|
|
|
for (var i = 0; i < count; i += 1) {
|
|
|
|
nodes[i] = factory(me._getChild(nodes[i]));
|
|
|
|
}
|
|
|
|
return nodes;
|
|
|
|
},
|
|
|
|
|
|
|
|
# Create a path child drawing a (rounded) rectangle
|
|
|
|
#
|
|
|
|
# @param x Position of left border
|
|
|
|
# @param y Position of top border
|
|
|
|
# @param w Width
|
|
|
|
# @param h Height
|
|
|
|
# @param cfg Optional settings (eg. {"border-top-radius": 5})
|
|
|
|
rect: func(x, y, w, h, cfg = nil) {
|
|
|
|
return me.createChild("path").rect(x, y, w, h, cfg);
|
|
|
|
},
|
|
|
|
|
|
|
|
# Get a vector of all child elements
|
|
|
|
getChildren: func() {
|
|
|
|
var children = [];
|
|
|
|
foreach(var c; me._node.getChildren()) {
|
|
|
|
if (me._isElementNode(c)) {
|
|
|
|
append(children, me._wrapElement(c));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return children;
|
|
|
|
},
|
|
|
|
|
|
|
|
# Recursively get all children of class specified by first param
|
|
|
|
getChildrenOfType: func(type, array = nil) {
|
|
|
|
var children = array;
|
|
|
|
if (children == nil) {
|
|
|
|
children = [];
|
|
|
|
}
|
|
|
|
var my_children = me.getChildren();
|
|
|
|
if (typeof(type) != "vector") {
|
|
|
|
type = [type];
|
|
|
|
}
|
|
|
|
foreach(var c; my_children) {
|
|
|
|
foreach(var t; type) {
|
|
|
|
if (isa(c, t)) {
|
|
|
|
append(children, c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (isa(c, canvas.Group)) {
|
|
|
|
c.getChildrenOfType(type, children);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return children;
|
|
|
|
},
|
|
|
|
|
|
|
|
# Set color to children of type Path and Text. It is possible to optionally
|
|
|
|
# specify which types of children should be affected by passing a vector as
|
|
|
|
# the last agrument, ie. my_group.setColor(1,1,1,[Path]);
|
|
|
|
setColor: func() {
|
|
|
|
var color = arg;
|
|
|
|
var types = [Path, Text];
|
|
|
|
var arg_c = size(color);
|
|
|
|
if (arg_c > 1 and typeof(color[-1]) == "vector") {
|
|
|
|
types = color[-1];
|
|
|
|
color = subvec(color, 0, arg_c - 1);
|
|
|
|
}
|
|
|
|
var children = me.getChildrenOfType(types);
|
|
|
|
if (typeof(color) == "vector") {
|
|
|
|
var first = color[0];
|
|
|
|
if (typeof(first) == "vector")
|
|
|
|
color = first;
|
|
|
|
}
|
2020-04-28 11:19:01 +00:00
|
|
|
foreach(var c; children) {
|
|
|
|
c.setColor(color);
|
|
|
|
}
|
2020-04-27 07:44:19 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
# Get first child with given id (breadth-first search)
|
|
|
|
#
|
|
|
|
# @note Use with care as it can take several miliseconds (for me eg. ~2ms).
|
|
|
|
# TODO check with new C++ implementation
|
|
|
|
getElementById: func(id) {
|
|
|
|
var ghost = me._getElementById(id);
|
|
|
|
if (ghost == nil) { return nil; }
|
|
|
|
|
|
|
|
var node = props.wrapNode(ghost._node_ghost);
|
|
|
|
var factory = me._getFactory(node.getName());
|
|
|
|
if (factory == nil) { return ghost; }
|
|
|
|
return factory(ghost);
|
|
|
|
},
|
|
|
|
|
|
|
|
# Remove all children
|
|
|
|
removeAllChildren: func() {
|
|
|
|
foreach(var type; keys(me._element_factories)) {
|
|
|
|
me._node.removeChildren(type, 0);
|
|
|
|
}
|
|
|
|
return me;
|
|
|
|
},
|
|
|
|
|
|
|
|
# private:
|
|
|
|
# element nodes have type NONE and valid element names (those in the factory
|
|
|
|
# list)
|
|
|
|
_isElementNode: func(el) {
|
|
|
|
return el.getType() == "NONE" and me._element_factories[el.getName()] != nil;
|
|
|
|
},
|
|
|
|
|
|
|
|
# Create element from existing node
|
|
|
|
_wrapElement: func(node) {
|
2020-04-28 11:19:01 +00:00
|
|
|
var factory = me._getFactory(node.getName());
|
|
|
|
return factory(me._getChild(node._g));
|
2020-04-27 07:44:19 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
_getFactory: func(type) {
|
|
|
|
var factory = me._element_factories[type];
|
2020-04-28 11:19:01 +00:00
|
|
|
if (factory == nil) {
|
|
|
|
logprint(DEV_ALERT, "canvas.Group.createChild(): unknown type ("~type~")");
|
|
|
|
}
|
2020-04-27 07:44:19 +00:00
|
|
|
return factory;
|
|
|
|
}
|
|
|
|
};
|