Source canvas api group.nas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#-------------------------------------------------------------------------------
# canvas.Group
#-------------------------------------------------------------------------------
# Class for a group element on a canvas
#
var Group = {
new: func(ghost) {
var obj = {
parents: [Group, Element.new(ghost)],
};
return obj;
},
# 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 (!isvec(type)) {
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 isvec(color[-1])) {
types = color[-1];
color = subvec(color, 0, arg_c - 1);
}
var children = me.getChildrenOfType(types);
if (isvec(color)) {
var first = color[0];
if (isvec(first)) {
color = first;
}
}
foreach(var c; children) {
c.setColor(color);
}
},
# 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) {
var factory = me._getFactory(node.getName());
return factory(me._getChild(node._g));
},
_getFactory: func(type) {
var factory = me._element_factories[type];
if (factory == nil) {
logprint(DEV_ALERT, "canvas.Group.createChild(): unknown type ("~type~")");
}
return factory;
}
};