summaryrefslogtreecommitdiff
path: root/js/dojo/dojox/drawing/util
diff options
context:
space:
mode:
Diffstat (limited to 'js/dojo/dojox/drawing/util')
-rw-r--r--js/dojo/dojox/drawing/util/common.js284
-rw-r--r--js/dojo/dojox/drawing/util/oo.js126
-rw-r--r--js/dojo/dojox/drawing/util/positioning.js69
-rw-r--r--js/dojo/dojox/drawing/util/typeset.js72
4 files changed, 551 insertions, 0 deletions
diff --git a/js/dojo/dojox/drawing/util/common.js b/js/dojo/dojox/drawing/util/common.js
new file mode 100644
index 0000000..af740a0
--- /dev/null
+++ b/js/dojo/dojox/drawing/util/common.js
@@ -0,0 +1,284 @@
+//>>built
+// wrapped by build app
+define("dojox/drawing/util/common", ["dijit","dojo","dojox","dojo/require!dojox/math/round"], function(dijit,dojo,dojox){
+dojo.provide("dojox.drawing.util.common");
+dojo.require("dojox.math.round");
+
+(function(){
+
+ var uidMap = {};
+ var start = 0;
+ dojox.drawing.util.common = {
+ // summary:
+ // A collection of common methods used for DojoX Drawing.
+ // This singleton is accessible in most Drawing classes
+ // as this.util
+ //
+ // NOTE:
+ // A lot of functions use a EventObject
+ // as an argument. An attempt was made to accept
+ // either that object or a list of numbers. That wasn't
+ // finished (it didn't work well in all cases) but is
+ // likely to happen in the future.
+ // In cases where you are not sending a Mouse object,
+ // form your argument like so:
+ // var obj = {
+ // start:{
+ // x:Number, // start x
+ // y:Number // start y
+ // },
+ // x: Number, // end x
+ // y:Number // end y
+ // }
+ //
+ //
+ radToDeg: function(/*Numer*/n){
+ // summary:
+ // Convert the passed number to degrees.
+ return (n*180)/Math.PI; // Number
+ },
+
+ degToRad: function(/*Numer*/n){
+ // summary:
+ // Convert the passed number to radians.
+ return (n*Math.PI)/180; // Number
+ },
+
+ angle: function(/*EventObject*/obj, /* ? Float */snap){
+ // summary:
+ // Return angle based on mouse object
+ // arguments:
+ // obj: EventObject
+ // Manager.Mouse event.
+ // snap: Float
+ // Returns nearest angle within snap limits
+ //
+ //obj = this.argsToObj.apply(this, arguments);
+ if(snap){
+ snap = snap/180;
+ var radians = this.radians(obj),
+ seg = Math.PI * snap,
+ rnd = dojox.math.round(radians/seg),
+ new_radian = rnd*seg;
+ return dojox.math.round(this.radToDeg(new_radian)); // Whole Number
+
+ }else{
+ return this.radToDeg(this.radians(obj)); // Float
+ }
+ },
+
+ oppAngle: function(/*Angle*/ang){
+ (ang+=180) > 360 ? ang = ang - 360 : ang;
+ return ang;
+ },
+
+ radians: function(/*EventObject*/o){
+ // summary:
+ // Return the radians derived from the coordinates
+ // in the Mouse object.
+ //
+ //var o = this.argsToObj.apply(this, arguments);
+ return Math.atan2(o.start.y-o.y,o.x-o.start.x);
+ },
+
+ length: function(/*EventObject*/o){
+ // summary:
+ // Return the length derived from the coordinates
+ // in the Mouse object.
+ //
+ return Math.sqrt(Math.pow(o.start.x-o.x, 2)+Math.pow(o.start.y-o.y, 2));
+ },
+
+ lineSub: function(/*Number*/x1, /*Number*/y1, /*Number*/x2, /*Number*/y2, /*Number*/amt){
+ // summary:
+ // Subtract an amount from a line
+ // description:
+ // x1,y1,x2,y2 represents the Line. 'amt' represents the amount
+ // to subtract from it.
+ //
+ var len = this.distance(this.argsToObj.apply(this, arguments));
+ len = len < amt ? amt : len;
+ var pc = (len-amt)/len;
+ var x = x1 - (x1-x2) * pc;
+ var y = y1 - (y1-y2) * pc;
+ return {x:x, y:y}; // Object
+ },
+
+ argsToObj: function(){
+ // summary:
+ // Attempts to determine in a Mouse Object
+ // was passed or indiviual numbers. Returns
+ // an object.
+ //
+ var a = arguments;
+ if(a.length < 4){ return a[0]; }
+ return {
+ start:{
+ x:a[0],
+ y:a[1]
+ },
+ x:a[2],
+ y:a[3]//,
+ //snap:a[4]
+ }; // Object
+ },
+
+ distance: function(/*EventObject or x1,y1,x2,y2*/){
+ // summary:
+ // Return the length derived from the coordinates
+ // in the Mouse object. Different from util.length
+ // in that this always returns an absolute value.
+ //
+ var o = this.argsToObj.apply(this, arguments);
+ return Math.abs(Math.sqrt(Math.pow(o.start.x-o.x, 2)+Math.pow(o.start.y-o.y, 2))); // Number
+ },
+
+ slope:function(/*Object*/p1, /*Object*/p2){
+ // summary:
+ // Given two poits of a line, returns the slope.
+ if(!(p1.x-p2.x)){ return 0; }
+ return ((p1.y-p2.y)/(p1.x-p2.x)); // Number
+ },
+
+ pointOnCircle: function(/*Number*/cx, /*Number*/cy, /*Number*/radius, /*Number*/angle){
+ // summary:
+ // A *very* helpful method. If you know the center
+ // (or starting) point, length and angle, find the
+ // x,y point at the end of that line.
+ //
+ var radians = angle * Math.PI / 180.0;
+ var x = radius * Math.cos(radians);
+ var y = radius * Math.sin(radians);
+ return {
+ x:cx+x,
+ y:cy-y
+ }; // Object
+ },
+
+ constrainAngle: function(/*EventObject*/obj, /*Number*/min, /*Number*/max){
+ // summary:
+ // Ensures the angle in the Mouse Object is within the
+ // min and max limits. If not one of those limits is used.
+ // Returns an x,y point for the angle used.
+ //
+ var angle = this.angle(obj);
+ if(angle >= min && angle <= max){
+ return obj; // Object
+ }
+ var radius = this.length(obj);
+ var new_angle = angle > max ? max : min - angle < 100 ? min : max;
+ return this.pointOnCircle(obj.start.x,obj.start.y,radius, new_angle); // Object
+ },
+
+ snapAngle: function(/*EventObject*/obj, /*Float*/ca){
+ // summary:
+ // Snaps a line to the nearest angle
+ // obj: Mouse object (see dojox.drawing.Mouse)
+ // ca: Fractional amount to snap to
+ // A decimal number fraction of a half circle
+ // .5 would snap to 90 degrees
+ // .25 would snap to 45 degrees
+ // .125 would snap to 22.5 degrees, etc.
+ //
+ var radians = this.radians(obj),
+ radius = this.length(obj),
+ seg = Math.PI * ca,
+ rnd = Math.round(radians/seg),
+ new_radian = rnd*seg,
+ new_angle = this.radToDeg(new_radian),
+ pt = this.pointOnCircle(obj.start.x,obj.start.y,radius,new_angle);
+ return pt; // Object
+ },
+
+ // helpers
+ idSetStart: function(num){
+ start=num;
+ },
+
+ uid: function(/* ? String */str){
+ // summary:
+ // Creates a unique ID.
+ // arguments:
+ // str: String
+ // If provided, kept in a map, incremented
+ // and used in the id. Otherwise 'shape' is used.
+ //
+ str = str || "shape";
+ uidMap[str] = uidMap[str]===undefined ? start : uidMap[str] + 1;
+ return str + uidMap[str]; // String
+ },
+
+ abbr: function(type){
+ // summary:
+ // Converts a namespace (typically a tool or a stencil) into
+ // an abbreviation
+ return type.substring(type.lastIndexOf(".")+1).charAt(0).toLowerCase()
+ + type.substring(type.lastIndexOf(".")+2);
+ },
+ mixin: function(o1, o2){
+ // TODO: make faster
+ //return dojo.mixin(dojo.clone(o1), dojo.clone(o2));
+ },
+
+ objects:{}, //private?
+ register: function(/*Object*/obj){
+ // summary:
+ // Since util is the only Singleton in Drawing (besides
+ // keys) it is used to help connect the Drawing object
+ // the Toolbar. Since multiple drawings can be on one
+ // page, this function serves a little more use than
+ // on first apearance.
+ this.objects[obj.id] = obj;
+ },
+ byId: function(/*String*/id){
+ // summary:
+ // Get an object that was registered with util.register
+ //
+ return this.objects[id];
+ },
+ attr: function(/* Object */ elem, /* property */ prop, /* ? value */ value, squelchErrors){
+ // summary:
+ // Helper function to attach attributes to SVG and VML raw nodes.
+ //
+
+ if(!elem){ return false; }
+ try{
+
+ // util is a crappy check, but we need to tell the diff
+ // between a Drawing shape and a GFX shape
+ if(elem.shape && elem.util){
+ elem = elem.shape;
+ }
+
+ if(!value && prop=="id" && elem.target){
+
+ var n = elem.target;
+ while(!dojo.attr(n, "id")){
+ n = n.parentNode;
+ }
+ return dojo.attr(n, "id");
+ }
+
+ if(elem.rawNode || elem.target){
+ var args = Array.prototype.slice.call(arguments);
+ args[0] = elem.rawNode || elem.target;
+ return dojo.attr.apply(dojo, args);
+ }
+ return dojo.attr(elem, "id");
+
+
+
+ }catch(e){
+ if(!squelchErrors){
+ // For debugging only. These errors actually cause errors in IE's console
+ //console.error("BAD ATTR: prop:", prop, "el:", elem)
+ //console.error(e)
+ //console.trace();
+ }
+ return false;
+ }
+ }
+ };
+
+})();
+});
diff --git a/js/dojo/dojox/drawing/util/oo.js b/js/dojo/dojox/drawing/util/oo.js
new file mode 100644
index 0000000..33048f9
--- /dev/null
+++ b/js/dojo/dojox/drawing/util/oo.js
@@ -0,0 +1,126 @@
+//>>built
+// wrapped by build app
+define("dojox/drawing/util/oo", ["dijit","dojo","dojox"], function(dijit,dojo,dojox){
+dojo.provide("dojox.drawing.util.oo");
+
+// TODO:
+// allow a declare without a mixin
+
+dojox.drawing.util.oo = {
+ // summary:
+ // Inheritance utilities used in DojoX Drawing
+ // description:
+ // Inheritance utilities used in DojoX Drawing.
+ // There were designed in a effort to make Drawing as
+ // fast as possible - especially in a case where thousands
+ // of objects are being loaded. Drawing declare performs
+ // about 3 times faster than Dojo declare and 2 times
+ // faster than Dojox declare. This is not to say Drawing
+ // declare is wthout limitations. It doesn't have the same
+ // syntatic sugar and extensibility of the other two. You
+ // can't inhert methods. It won't work with Dijit. But it
+ // is simple and effective.
+ //
+ declare: function(){
+ // summary:
+ // Creates a constructor Function from a
+ // Function, and collection of methods, and
+ // more Functions that are extended.
+ // description:
+ // Similar in look and feel to Dojo declare as
+ // far as order and number of arguments, although
+ // constructed a little closer to prototypical
+ // inheritance. All arguments passed into the
+ // constructor are passed into all sub constructors.
+ // arguments:
+ // Function, [Object|Function....]
+ // The first argument is always the base
+ // constructor. The last argument is always
+ // an object of methods (or empty object) to
+ // be mixed in (in the future would like to
+ // make that object optional). Remaining
+ // arguments are other constructors mixed in
+ // using extend() (See below).
+ // example:
+ // | MyFunction = dojox.drawing.util.oo.declare(
+ // | MyOtherFunction,
+ // | YetAnotherFunction,
+ // | function(options){
+ // | // This is my constructor. It will fire last.
+ // | // The other constructors will fire before this.
+ // | },
+ // | {
+ // | customType:"equation", // mixed in property
+ // | doThing: function(){ // mixed in method
+ // |
+ // | }
+ // | }
+ // | );
+ // |
+ // | var f = new MyFunction();
+ //
+ var f, o, ext=0, a = arguments;
+
+ if(a.length<2){ console.error("drawing.util.oo.declare; not enough arguments")}
+ if(a.length==2){
+ f = a[0]; o = a[1];
+ }else{
+ a = Array.prototype.slice.call(arguments);
+ o = a.pop();
+ f = a.pop();
+ ext = 1;
+ }
+ for(var n in o){
+ f.prototype[n] = o[n];
+ }
+ if(ext){
+ a.unshift(f);
+ f = this.extend.apply(this, a);
+ }
+ return f; // Function
+ },
+ extend: function(){
+ // summary:
+ // Extends constructors to inherit from other
+ // constructors .
+ // description:
+ // Typically not used by itself - it's used as
+ // part of declare(). Could be used by itself
+ // however, to mix together two or more
+ // constructors.
+ // arguments:
+ // Function, [ Function...]
+ // Any number of arguments, all must be
+ // function constructors. The first is
+ // considered the base object and its
+ // constructor will fire first.
+ // example:
+ // | var A = function(){};
+ // | var B = function(){};
+ // | var C = function(){};
+ // | var D = dojox.drawing.util.oo.extend(A, B, C);
+ // | var e = new D();
+ //
+ var a = arguments, sub = a[0];
+ if(a.length<2){ console.error("drawing.util.oo.extend; not enough arguments")}
+ var f = function (){
+ for(var i=1;i<a.length;i++){
+ a[i].prototype.constructor.apply(this, arguments);
+ }
+ // sub should fire last
+ sub.prototype.constructor.apply(this, arguments);
+
+ }
+ for(var i=1;i<a.length;i++){
+ for(var n in a[i].prototype){
+ f.prototype[n] = a[i].prototype[n];
+ }
+ }
+
+ for(n in sub.prototype){
+ f.prototype[n] = sub.prototype[n];
+ }
+ return f; // Function
+ }
+};
+});
diff --git a/js/dojo/dojox/drawing/util/positioning.js b/js/dojo/dojox/drawing/util/positioning.js
new file mode 100644
index 0000000..13afcad
--- /dev/null
+++ b/js/dojo/dojox/drawing/util/positioning.js
@@ -0,0 +1,69 @@
+//>>built
+// wrapped by build app
+define("dojox/drawing/util/positioning", ["dijit","dojo","dojox"], function(dijit,dojo,dojox){
+dojo.provide("dojox.drawing.util.positioning");
+
+(function(){
+
+ var textOffset = 4; // distance from line to text box
+ var textYOffset = 20; // height of text box
+
+
+ dojox.drawing.util.positioning.label = function(/*Object*/start, /*Object*/end){
+ // summary:
+ // Returns the optimal text positions for annotations.Label.
+
+ // label at middle of vector
+ var x = 0.5*(start.x+end.x);
+ var y = 0.5*(start.y+end.y);
+
+ // move label a set distance from the line
+ var slope = dojox.drawing.util.common.slope(start, end);
+ var deltay = textOffset/Math.sqrt(1.0+slope*slope);
+
+ if(end.y>start.y && end.x>start.x || end.y<start.y && end.x<start.x){
+ // Position depending on quadrant. Y offset
+ // positions box aligned vertically from top
+ deltay = -deltay;
+ y -= textYOffset;
+ }
+ x += -deltay*slope;
+ y += deltay;
+
+ // want text to be away from start of vector
+ // This will make force diagrams less crowded
+ var align = end.x<start.x ? "end" : "start";
+
+ return { x:x, y:y, foo:"bar", align:align}; // Object
+ };
+
+ dojox.drawing.util.positioning.angle = function(/*Object*/start, /*Object*/end){
+ // summary:
+ // Returns the optimal position for annotations.Angle.
+ //
+ // angle at first third of vector
+ var x = 0.7*start.x+0.3*end.x;
+ var y = 0.7*start.y+0.3*end.y;
+ // move label a set distance from the line
+ var slope = dojox.drawing.util.common.slope(start, end);
+ var deltay = textOffset/Math.sqrt(1.0+slope*slope);
+
+ if(end.x<start.x){deltay = -deltay;}
+ x += -deltay * slope;
+ y += deltay;
+
+ // want text to be clockwise from vector
+ // to match angle measurement from x-axis
+ var align = end.y>start.y ? "end" : "start";
+ // box vertical aligned from middle
+ y += end.x > start.x ? 0.5*textYOffset : -0.5*textYOffset;
+
+ return { x:x, y:y, align:align}; // Object
+ }
+
+})();
+
+
+
+
+});
diff --git a/js/dojo/dojox/drawing/util/typeset.js b/js/dojo/dojox/drawing/util/typeset.js
new file mode 100644
index 0000000..c9c81c1
--- /dev/null
+++ b/js/dojo/dojox/drawing/util/typeset.js
@@ -0,0 +1,72 @@
+//>>built
+// wrapped by build app
+define("dojox/drawing/util/typeset", ["dijit","dojo","dojox","dojo/require!dojox/drawing/library/greek"], function(dijit,dojo,dojox){
+dojo.provide("dojox.drawing.util.typeset");
+dojo.require("dojox.drawing.library.greek");
+// Summary:
+// Singleton used for converting characters and typsetting. Required by _base.
+//
+// Description:
+// Eventually, this is supposed to turn input strings of mathematical
+// expressions into typeset expressions that can be displayed on the
+// canvas. For now, we just generate Greek letters based on LaTeX style
+// entity codes.
+
+(function(){
+
+ var greeks = dojox.drawing.library.greek;
+
+ dojox.drawing.util.typeset = {
+
+ convertHTML: function(inText){
+ if(inText){
+ return inText.replace(/&([^;]+);/g,function(match,code){
+ if(code.charAt(0)=='#'){
+ //coerce remainder of string to int
+ var number=+code.substr(1);
+ if(!isNaN(number)){
+ return String.fromCharCode(number);
+ }
+ }else if(greeks[code]){
+ return String.fromCharCode(greeks[code]);
+ }
+ // This is generally for server code, so there
+ // is no point bothering the user in the case of an error.
+ console.warn("no HTML conversion for ",match);
+ return match;
+ });
+ }
+ return inText;
+ },
+
+ convertLaTeX: function(inText){
+ // console.log("***** convertLaTeX for ",inText);
+ if(inText){
+ return inText.replace(/\\([a-zA-Z]+)/g,function(match,word){
+ if(greeks[word]){
+ return String.fromCharCode(greeks[word]);
+ }else if(word.substr(0,2)=="mu"){
+ // special handling for \mu since it is
+ // a unit prefix for micro.
+ return String.fromCharCode(greeks["mu"])+word.substr(2);
+ }else if(word.substr(0,5)=="theta"){
+ // special handling for \theta since it is
+ // a standard prefix for angle associated with a vector.
+ return String.fromCharCode(greeks["theta"])+word.substr(5);
+ }else if(word.substr(0,3)=="phi"){
+ // special handling for \phi since it is
+ // a standard prefix for angle associated with a z-axis vector.
+ return String.fromCharCode(greeks["phi"])+word.substr(3);
+ }
+ console.log("no match for ",match," in ",inText);
+ console.log("Need user-friendly error handling here!");
+ }).replace(/\\\\/g,'\\');
+ }
+ return inText;
+ }
+
+ };
+
+})();
+
+});