      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