source: Dev/trunk/src/client/dojox/drawing/manager/Anchors.js

Last change on this file was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

  • Property svn:executable set to *
File size: 11.9 KB
Line 
1define(["dojo", "../util/oo", "../defaults"],
2function(dojo, oo, defaults){
3
4var Anchor = oo.declare(
5        function(/* Object */ options){
6                // summary:
7                //              constructor.
8                // options:
9                //              dojox.__stencilArgs plus some additional
10                //              data, like which point this is (pointIdx)
11
12                this.defaults = defaults.copy();
13                this.mouse = options.mouse;
14                this.point = options.point;
15                this.pointIdx = options.pointIdx;
16                this.util = options.util;
17                this.id = options.id || this.util.uid("anchor");
18                this.org = dojo.mixin({}, this.point);
19                this.stencil = options.stencil;
20                if(this.stencil.anchorPositionCheck){
21                        this.anchorPositionCheck = dojo.hitch(this.stencil, this.stencil.anchorPositionCheck);
22                }
23                if(this.stencil.anchorConstrain){
24                        this.anchorConstrain = dojo.hitch(this.stencil, this.stencil.anchorConstrain);
25                }
26                this._zCon = dojo.connect(this.mouse, "setZoom", this, "render");
27                this.render();
28                this.connectMouse();
29        },
30        {
31                // summary:
32                //              An anchor point that is attached to (usually) one of the
33                //              corners of a Stencil.
34                //              Used internally.
35
36                y_anchor:null,
37                x_anchor:null,
38                render: function(){
39                        // summary:
40                        //              Creates the anchor point. Unlike most render methods
41                        //              in Drawing, this is only called once.
42
43                        this.shape && this.shape.removeShape();
44                        var d = this.defaults.anchors,
45                                z = this.mouse.zoom,
46                                b = d.width * z,
47                                s = d.size * z,
48                                p = s/2,
49                                line = {
50                                        width:b,
51                                        style:d.style,
52                                        color:d.color,
53                                        cap:d.cap
54                                };
55                       
56       
57                        var _r = {
58                                x: this.point.x-p,
59                                y: this.point.y-p,
60                                width: s,
61                                height: s
62                        };
63                        this.shape = this.stencil.container.createRect(_r)
64                                .setStroke(line)
65                                .setFill(d.fill);
66                       
67                        this.shape.setTransform({dx:0, dy:0});
68                        this.util.attr(this, "drawingType", "anchor");
69                        this.util.attr(this, "id", this.id);
70                },
71                onRenderStencil: function(/*Anchor*/anchor){
72                        // summary:
73                        //              Event fires when an anchor calls a Stencil's render method
74                },
75                onTransformPoint: function(/*Anchor*/anchor){
76                        // summary:
77                        //              Event fires when an anchor changes the points of a Stencil
78                },
79                onAnchorDown: function(/*Mouse.EventObject*/obj){
80                        // summary:
81                        //              Event fires for mousedown on anchor
82                        this.selected = obj.id == this.id;
83                },
84                onAnchorUp: function(/*Mouse.EventObject*/obj){
85                        // summary:
86                        //              Event fires for mouseup on anchor
87                        this.selected = false;
88                        this.stencil.onTransformEnd(this);
89                },
90               
91                onAnchorDrag: function(/*Mouse.EventObject*/obj){
92                        // summary:
93                        //              Event fires for on dragging of an anchor
94                        if(this.selected){
95                                // mx is the original transform from when the anchor
96                                // was created. It does not change
97                                var mx = this.shape.getTransform();
98                               
99                                var pmx = this.shape.getParent().getParent().getTransform();
100                               
101                                var marginZero = this.defaults.anchors.marginZero;
102                               
103                                var orgx = pmx.dx + this.org.x,
104                                        orgy = pmx.dy + this.org.y,
105                                        x = obj.x - orgx,
106                                        y = obj.y - orgy,
107                                        s = this.defaults.anchors.minSize;
108                               
109                                var conL, conR, conT, conB;
110                               
111                                var chk = this.anchorPositionCheck(x, y, this);
112                                if(chk.x<0){
113                                        console.warn("X<0 Shift");
114                                        while(this.anchorPositionCheck(x, y, this).x<0){
115                                                this.shape.getParent().getParent().applyTransform({dx:2, dy:0});
116                                        }
117                                }
118                                if(chk.y<0){
119                                        console.warn("Y<0 Shift");
120                                        while(this.anchorPositionCheck(x, y, this).y<0){
121                                                this.shape.getParent().getParent().applyTransform({dx:0, dy:2});
122                                        }
123                                }
124                               
125                                if(this.y_anchor){
126                                        // prevent y overlap of opposite anchor
127                                        if(this.org.y > this.y_anchor.org.y){
128                                                // bottom anchor
129                                               
130                                                conT = this.y_anchor.point.y + s - this.org.y;
131                                                conB = Infinity;
132                                               
133                                                if(y < conT){
134                                                        // overlapping other anchor
135                                                        y = conT;
136                                                }
137                                               
138                                               
139                                        }else{
140                                                // top anchor
141                                               
142                                                conT = -orgy + marginZero;
143                                                conB = this.y_anchor.point.y - s - this.org.y;
144                                               
145                                                if(y < conT){
146                                                        // less than zero
147                                                        y = conT;
148                                                }else if(y > conB){
149                                                        // overlapping other anchor
150                                                        y = conB;
151                                                }
152                                        }
153                                }else{
154                                        // Lines - check for zero
155                                        conT = -orgy + marginZero;
156                                        if(y < conT){
157                                                // less than zero
158                                                y = conT;
159                                        }
160                                }
161
162                                if(this.x_anchor){
163                                        // prevent x overlap of opposite anchor
164                                       
165                                        if(this.org.x>this.x_anchor.org.x){
166                                                // right anchor
167                                               
168                                                conL = this.x_anchor.point.x + s - this.org.x;
169                                                conR = Infinity;
170                                               
171                                                if(x < conL){
172                                                        // overlapping other anchor
173                                                        x = conL;
174                                                }
175                                               
176                                        }else{
177                                                // left anchor
178                                               
179                                                conL = -orgx + marginZero;
180                                                conR = this.x_anchor.point.x - s - this.org.x;
181                                               
182                                                if(x < conL){
183                                                        x = conL;
184                                                }else if(x > conR){
185                                                        // overlapping other anchor
186                                                        x = conR;
187                                                }
188                                        }
189                                }else{
190                                        // Lines check for zero
191                                        conL = -orgx + marginZero;
192                                        if(x < conL){
193                                                x = conL;
194                                        }
195                                }
196                                //Constrains anchor point, returns null if not overwritten by stencil
197                                var constrained = this.anchorConstrain(x, y);
198                                if(constrained != null){
199                                        x=constrained.x;
200                                        y=constrained.y;
201                                }
202                               
203                                this.shape.setTransform({
204                                        dx:x,
205                                        dy:y
206                                });
207                                if(this.linkedAnchor){
208                                        // first and last points of a closed-curve-path
209                                        this.linkedAnchor.shape.setTransform({
210                                                dx:x,
211                                                dy:y
212                                        });
213                                }
214                                this.onTransformPoint(this);
215                        }
216                },
217               
218                anchorConstrain: function(/* Number */x,/* Number */ y){
219                        // summary:
220                        //              To be over written by tool!
221                        //              Add an anchorConstrain method to the tool
222                        //              and it will automatically overwrite this stub.
223                        //              Should return a constrained x & y value.
224                        return null;
225                },
226               
227                anchorPositionCheck: function(/* Number */x,/* Number */ y, /* Anchor */anchor){
228                        // summary:
229                        //              To be over written by tool!
230                        //              Add a anchorPositionCheck method to the tool
231                        //              and it will automatically overwrite this stub.
232                        //              Should return x and y coords. Success is both
233                        //              being greater than zero, fail is if one or both
234                        //              are less than zero.
235                        return {x:1, y:1};
236                },
237               
238                setPoint: function(mx){
239                        // summary:
240                        //              Internal. Sets the Stencil's point
241                        this.shape.applyTransform(mx);
242                },
243               
244                connectMouse: function(){
245                        // summary:
246                        //              Internal. Connects anchor to manager.mouse
247                        this._mouseHandle = this.mouse.register(this);
248                },
249               
250                disconnectMouse: function(){
251                        // summary:
252                        //              Internal. Disconnects anchor to manager.mouse
253                        this.mouse.unregister(this._mouseHandle);
254                },
255               
256                reset: function(stencil){
257                        // summary:
258                        //              Called (usually) from a Stencil when that Stencil
259                        //              needed to make modifications to the position of the
260                        //              point. Basically used when teh anchor causes a
261                        //              less than zero condition.
262                },
263               
264                destroy: function(){
265                        // summary:
266                        //              Destroys anchor.
267                        dojo.disconnect(this._zCon);
268                        this.disconnectMouse();
269                        this.shape.removeShape();
270                }
271        }
272);
273
274//dojox.drawing.manager.Anchors =
275return oo.declare(
276        // summary:
277        //              Creates and manages the anchor points that are attached to
278        //              (usually) the corners of a Stencil.
279        // description:
280        //              Used internally, but there are some things that should be known:
281        //              Anchors attach to a Stencil's 'points' (See stencil.points)
282        //              To not display an anchor on a certain point, add noAnchor:true
283        //              to the point.
284       
285        function(/* dojox.__stencilArgs */options){
286                this.mouse = options.mouse;
287                this.undo = options.undo;
288                this.util = options.util;
289                this.drawing = options.drawing;
290                this.items = {};
291        },
292        {
293                onAddAnchor: function(/*Anchor*/anchor){
294                        // summary:
295                        //              Event fires when anchor is created
296                },
297               
298               
299                onReset: function(/*Stencil*/stencil){
300                        // summary:
301                        //              Event fires when an anchor's reset method is called
302
303                        // a desperate hack in order to get the anchor point to reset.
304                        // FIXME: Is this still used? I think its item.deselect();item.select();
305                        var st = this.util.byId("drawing").stencils;
306                        st.onDeselect(stencil);
307                        st.onSelect(stencil);
308                },
309               
310                onRenderStencil: function(){
311                        // summary:
312                        //              Event fires when an anchor calls a Stencil's render method
313
314                        for(var nm in this.items){
315                                dojo.forEach(this.items[nm].anchors, function(a){
316                                        a.shape.moveToFront();
317                                });
318                        }
319                },
320               
321                onTransformPoint: function(/*Anchor*/anchor){
322                        // summary:
323                        //              Event fired on anchor drag
324
325                        // If anchors are a "group", it's corresponding anchor
326                        // is set. All anchors then moved to front.
327                        var anchors = this.items[anchor.stencil.id].anchors;
328                        var item = this.items[anchor.stencil.id].item;
329                        var pts = [];
330                        dojo.forEach(anchors, function(a, i){
331                                if(anchor.id == a.id || anchor.stencil.anchorType!="group"){
332                                        // nothing
333                                }else{
334                                        if(anchor.org.y == a.org.y){
335                                                a.setPoint({
336                                                        dx: 0,
337                                                        dy: anchor.shape.getTransform().dy - a.shape.getTransform().dy
338                                                });
339                                        }else if(anchor.org.x == a.org.x){
340                                                a.setPoint({
341                                                        dx: anchor.shape.getTransform().dx - a.shape.getTransform().dx,
342                                                        dy: 0
343                                                });
344                                        }
345                                        a.shape.moveToFront();
346                                }
347                               
348                                var mx = a.shape.getTransform();
349                                pts.push({x:mx.dx + a.org.x, y:mx.dy+ a.org.y});
350                               
351                                if(a.point.t){
352                                        pts[pts.length-1].t = a.point.t;
353                                }
354                               
355                        }, this);
356                        item.setPoints(pts);
357                        item.onTransform(anchor);
358                        this.onRenderStencil();
359                },
360               
361                onAnchorUp: function(/*Anchor*/anchor){
362                        // summary:
363                        //              Event fired on anchor mouseup
364                },
365               
366                onAnchorDown: function(/*Anchor*/anchor){
367                        // summary:
368                        //              Event fired on anchor mousedown
369                },
370               
371                onAnchorDrag: function(/*Anchor*/anchor){
372                        // summary:
373                        //              Event fired when anchor is moved
374                },
375               
376                onChangeStyle: function(/*Object*/stencil){
377                        // summary:
378                        //              if the Stencil changes color while were's selected
379                        //              this moves the anchors to the back. Fix it.
380                       
381                        for(var nm in this.items){
382                                dojo.forEach(this.items[nm].anchors, function(a){
383                                        a.shape.moveToFront();
384                                });
385                        }
386                },
387               
388                add: function(/*Stencil*/item){
389                        // summary:
390                        //              Creates anchor points on a Stencil, based on the
391                        //              Stencil's points.
392
393                        this.items[item.id] = {
394                                item:item,
395                                anchors:[]
396                        };
397                        if(item.anchorType=="none"){ return; }
398                        var pts = item.points;
399                        dojo.forEach(pts, function(p, i){
400                                if(p.noAnchor){ return; }
401                                if(i==0 || i == item.points.length-1){
402                                        console.log("ITEM TYPE:", item.type, item.shortType);
403                                }
404                                var a = new Anchor({stencil:item, point:p, pointIdx:i, mouse:this.mouse, util:this.util});
405                                this.items[item.id]._cons = [
406                                        dojo.connect(a, "onRenderStencil", this, "onRenderStencil"),
407                                        dojo.connect(a, "reset", this, "onReset"),
408                                        dojo.connect(a, "onAnchorUp", this, "onAnchorUp"),
409                                        dojo.connect(a, "onAnchorDown", this, "onAnchorDown"),
410                                        dojo.connect(a, "onAnchorDrag", this, "onAnchorDrag"),
411                                        dojo.connect(a, "onTransformPoint", this, "onTransformPoint"),
412                                        // FIXME: this will fire for each anchor. yech.
413                                        dojo.connect(item, "onChangeStyle", this, "onChangeStyle")
414                                ];
415                               
416                                this.items[item.id].anchors.push(a);
417                                this.onAddAnchor(a);
418                        }, this);
419                       
420                        if(item.shortType=="path"){
421                                // check if we have a double-point of a closed-curve-path
422                                var f = pts[0], l = pts[pts.length-1], a = this.items[item.id].anchors;
423                                if(f.x ==l.x && f.y==l.y){
424                                        console.warn("LINK ANVHROS", a[0], a[a.length-1]);
425                                        a[0].linkedAnchor = a[a.length-1];
426                                        a[a.length-1].linkedAnchor = a[0];
427                                }
428                        }
429                       
430                        if(item.anchorType=="group"){
431                                dojo.forEach(this.items[item.id].anchors, function(anchor){
432                                        dojo.forEach(this.items[item.id].anchors, function(a){
433                                                if(anchor.id != a.id){
434                                                        if(anchor.org.y == a.org.y){
435                                                                anchor.x_anchor = a;
436                                                        }else if(anchor.org.x == a.org.x){
437                                                                anchor.y_anchor = a;
438                                                        }
439                                                }
440                                        },this);
441                                },this);
442                               
443                        }
444                },
445               
446                remove: function(/*Stencil*/item){
447                        // summary:
448                        //              Destroys the anchor points for a Stencil.
449
450                        if(!this.items[item.id]){
451                                return;
452                        }
453                        dojo.forEach(this.items[item.id].anchors, function(a){
454                                a.destroy();
455                        });
456                        dojo.forEach(this.items[item.id]._cons, dojo.disconnect, dojo);
457                        this.items[item.id].anchors = null;
458                        delete this.items[item.id];
459                }
460        }
461);
462
463});
Note: See TracBrowser for help on using the repository browser.