Library globals

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;
    }
};