1 /* 2 Copyright 2008-2011 3 Matthias Ehmann, 4 Michael Gerhaeuser, 5 Carsten Miller, 6 Bianca Valentin, 7 Alfred Wassermann, 8 Peter Wilfahrt 9 10 This file is part of JSXGraph. 11 12 JSXGraph is free software: you can redistribute it and/or modify 13 it under the terms of the GNU Lesser General Public License as published by 14 the Free Software Foundation, either version 3 of the License, or 15 (at your option) any later version. 16 17 JSXGraph is distributed in the hope that it will be useful, 18 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 GNU Lesser General Public License for more details. 21 22 You should have received a copy of the GNU Lesser General Public License 23 along with JSXGraph. If not, see <http://www.gnu.org/licenses/>. 24 */ 25 /** 26 * @fileoverview In this file the class Group is defined, a class for 27 * managing grouping of points. 28 */ 29 30 /** 31 * Creates a new instance of Group. 32 * @class In this class all group management is done. 33 * @param {String} id Unique identifier for this object. If null or an empty string is given, 34 * an unique id will be generated by Board 35 * @param {String} name Not necessarily unique name, displayed on the board. If null or an 36 * empty string is given, an unique name will be generated. 37 * @constructor 38 */ 39 JXG.Group = function(board, id, name) { 40 var number, 41 objArray, 42 i, obj, el; 43 44 this.board = board; 45 this.objects = {}; 46 number = this.board.numObjects; 47 this.board.numObjects++; 48 49 if ((id == '') || !JXG.exists(id)) { 50 this.id = this.board.id + 'Group' + number; 51 } else { 52 this.id = id; 53 } 54 this.board.groups[this.id] = this; 55 56 this.type = JXG.OBJECT_TYPE_POINT; 57 this.elementClass = JXG.OBJECT_CLASS_POINT; 58 59 if ((name == '') || !JXG.exists(name)) { 60 this.name = 'group_' + this.board.generateName(this); 61 } else { 62 this.name = name; 63 } 64 delete(this.type); 65 66 if ( (arguments.length == 4) && (JXG.isArray(arguments[3])) ) 67 objArray = arguments[3]; 68 else { 69 objArray = []; 70 for (i=3; i<arguments.length; i++) { 71 objArray.push(arguments[i]); 72 } 73 } 74 75 for (i=0; i<objArray.length; i++) { 76 obj = JXG.getReference(this.board, objArray[i]); 77 if( (!obj.visProp.fixed) && ( (obj.type == JXG.OBJECT_TYPE_POINT) || (obj.type == JXG.OBJECT_TYPE_GLIDER) ) ) { 78 if (obj.group.length != 0) { 79 this.addGroup(obj.group[obj.group.length-1]); 80 } else { 81 this.addPoint(obj); 82 } 83 } 84 } 85 86 for (el in this.objects) { 87 this.objects[el].group.push(this); 88 } 89 90 this.dX = 0; 91 this.dY = 0; 92 }; 93 94 JXG.extend(JXG.Group.prototype, /** @lends JXG.Group.prototype */ { 95 /** 96 * Releases the group added to the points in this group, but only if this group is the last group. 97 */ 98 ungroup: function() { 99 var el; 100 for (el in this.objects) { 101 if (this.objects[el].group[this.objects[el].group.length-1] == this) { 102 this.objects[el].group.pop(); 103 } 104 delete(this.objects[el]); 105 } 106 // Unregister the group from board 107 // delete(this.board.groups[this.id]); // Not sure if we should delete the group 108 }, 109 110 /** 111 * Sends an update to all group members. 112 * @param {JXG.Point} point The point that caused the update. 113 */ 114 update: function(point) { 115 var obj = null, 116 el; 117 118 for (el in this.objects) { 119 obj = this.objects[el]; 120 if (obj.id != point.id) { 121 obj.coords = new JXG.Coords(JXG.COORDS_BY_SCREEN, [obj.coords.scrCoords[1] + this.dX, 122 obj.coords.scrCoords[2] + this.dY], obj.board); 123 } 124 } 125 126 for (el in this.objects) { 127 /* Wurde das Element vielleicht geloescht? */ 128 if (JXG.exists(this.board.objects[el])) { 129 /* Nein, wurde es nicht, also updaten */ 130 this.objects[el].update(false); 131 } else { /* es wurde geloescht, also aus dem Array entfernen */ 132 delete(this.objects[el]); 133 } 134 } 135 return this; 136 }, 137 138 /** 139 * Adds an Point to this group. 140 * @param {JXG.Point} object The object added to the group. 141 */ 142 addPoint: function(object) { 143 this.objects[object.id] = object; 144 }, 145 146 /** 147 * Adds multiple points to this group. 148 * @param {Array} objects An array of points to add to the group. 149 */ 150 addPoints: function(objects) { 151 var p; 152 for (p in objects) 153 this.objects[p.id] = p; 154 }, 155 156 /** 157 * Adds an Point to this group. 158 * @param {JXG.Point} object The object added to the group. 159 */ 160 addGroup: function(group) { 161 var el; 162 for (el in group.objects) { 163 this.addPoint(group.objects[el]); 164 } 165 }, 166 167 setProperty: function () { 168 var el; 169 170 for (el in this.objects) { 171 this.objects[el].setProperty.apply(this.objects[el], arguments); 172 } 173 } 174 }); 175 176 /** 177 * Groups points. 178 * @param {JXG.Board} board The board the points are on. 179 * @param {Array} parents Array of points to group. 180 * @param {Object} attributes Visual properties. 181 * @type JXG.Group 182 * @return An object of type JXG.Group. 183 */ 184 JXG.createGroup = function(board, parents, attributes) { 185 var i, g = new JXG.Group(board, attributes["id"], attributes["name"], parents); 186 187 g.elType = 'group'; 188 189 g.parents = []; 190 for (i = 0; i < parents.length; i++) { 191 g.parents.push(parents[i].id); 192 } 193 194 return g; 195 }; 196 197 JXG.JSXGraph.registerElement('group', JXG.createGroup); 198