rlm@46: /*----------------------------------------------------------------------------
rlm@46:  ONLYPATHS 0.1 
rlm@46:  from
rlm@46:  RICHDRAW 1.0
rlm@46:  Vector Graphics Drawing Script
rlm@46:  -----------------------------------------------------------------------------
rlm@46:  Created by Mark Finkle (mark.finkle@gmail.com)
rlm@46:  Implementation of simple vector graphic drawing control using SVG or VML.
rlm@46:  -----------------------------------------------------------------------------
rlm@46:  Copyright (c) 2006 Mark Finkle  
rlm@46:                2008 Antimatter15  
rlm@46:                2008 Josep_ssv
rlm@46: 
rlm@46:  This program is  free software;  you can redistribute  it and/or  modify it
rlm@46:  under the terms of the MIT License.
rlm@46: 
rlm@46:  Permission  is hereby granted,  free of charge, to  any person  obtaining a
rlm@46:  copy of this software and associated documentation files (the "Software"),
rlm@46:  to deal in the  Software without restriction,  including without limitation
rlm@46:  the  rights to use, copy, modify,  merge, publish, distribute,  sublicense,
rlm@46:  and/or  sell copies  of the  Software, and to  permit persons to  whom  the
rlm@46:  Software is  furnished  to do  so, subject  to  the  following  conditions:
rlm@46:  The above copyright notice and this  permission notice shall be included in
rlm@46:  all copies or substantial portions of the Software.
rlm@46: 
rlm@46:  THE SOFTWARE IS PROVIDED "AS IS",  WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
rlm@46:  IMPLIED,  INCLUDING BUT NOT LIMITED TO  THE WARRANTIES  OF MERCHANTABILITY,
rlm@46:  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
rlm@46:  AUTHORS OR  COPYRIGHT  HOLDERS BE  LIABLE FOR  ANY CLAIM,  DAMAGES OR OTHER
rlm@46:  LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT, TORT OR  OTHERWISE,  ARISING
rlm@46:  FROM,  OUT OF OR  IN  CONNECTION  WITH  THE  SOFTWARE OR THE  USE OR  OTHER
rlm@46:  DEALINGS IN THE SOFTWARE.
rlm@46:  -----------------------------------------------------------------------------
rlm@46:  Dependencies: (SVG or VML rendering implementations)
rlm@46:  History:
rlm@46:  2006-04-05 | Created richdraw.js  
rlm@46:  2008       | Update content and added framework ExtJS    
rlm@46:  2008-06-08 | Rename onlypaths.js   
rlm@46:  --------------------------------------------------------------------------*/  
rlm@46:  
rlm@46: var xpArray=new Array();
rlm@46: var ypArray=new Array(); 
rlm@46: var setPoints=new Array(); 
rlm@46: 
rlm@46: var inout='';//true;
rlm@46: var typeTransform='';
rlm@46: 
rlm@46: var contmove=0;  
rlm@46: var zoomx=0;
rlm@46: var zoomy=0;
rlm@46: var zoomscale=1;
rlm@46: var zoommode='frame'; //more minus frame
rlm@46: 
rlm@46: //
rlm@46:  
rlm@46: var data_path_close=true;
rlm@46: var data_text_family='';
rlm@46: var data_text_size=19
rlm@46: var data_text_messaje='';
rlm@46: var data_image_href='';   
rlm@46:  
rlm@46: var numClics=0;  
rlm@46: 
rlm@46: ////////////
rlm@46: 
rlm@46: function RichDrawEditor(elem, renderer) {
rlm@46:  this.container = elem;
rlm@46:  this.gridX = 10;
rlm@46:  this.gridY = 10;
rlm@46:  this.mouseDownX = 0;  
rlm@46:  this.mouseDownY = 0;    
rlm@46:  this.clicX = 0;  
rlm@46:  this.clicY = 0;
rlm@46:  this.nowDraw=false;
rlm@46:  this.mode = '';
rlm@46:  this.fillColor = '';  
rlm@46:  this.lineColor = '';
rlm@46:  this.lineWidth = '';
rlm@46:  this.selected = null;   
rlm@46:  this.squareSelect = null;  
rlm@46:  this.focusin = null;  
rlm@46:  this.lineOpac = 1;
rlm@46:  this.fillOpac = 1;
rlm@46:  this.gridWidth = 1;
rlm@46:  this.opac = 1;          
rlm@46:  //++ ;
rlm@46:  this.text_messaje="";
rlm@46:  this.text_size=19;
rlm@46:  this.text_family="Arial";
rlm@46:  
rlm@46:  this.pathsEdit = false;
rlm@46:  this.previusBox=null; 
rlm@46:  this.initialPath='';
rlm@46:  this.clipboard=null;
rlm@46:  this.moveNow=true;
rlm@46:  
rlm@46:  this.selectedBounds = { x:0, y:0, width:0, height: 0 };
rlm@46:  this.onselect = function() {}
rlm@46:  this.onunselect = function() {}
rlm@46:  
rlm@46:  this.logtext = "";
rlm@46:  
rlm@46:  this.renderer = renderer;
rlm@46:  this.renderer.init(this.container);
rlm@46:  this.renderer.editor = this;
rlm@46:  
rlm@46:  this.initialUnit=1;
rlm@46:  this.unit=this.initialUnit; 
rlm@46: 
rlm@46:  
rlm@46:  this.inputxy = []; 
rlm@46:  this.viewInputxy = [];      
rlm@46:  this.onViewInputXY = function(){};
rlm@46:  this.onInputXY = function(){};   
rlm@46:  
rlm@46:  
rlm@46:  //Ext.get(this.container).on('keypress', function(e){alert(e.keyCode);});
rlm@46:   
rlm@46:  Ext.get(this.container).on( "mousedown", this.onMouseDown,this);
rlm@46:  Ext.get(this.container).on( "mouseup", this.onMouseUp,this);  
rlm@46:  Ext.get(this.container).on( "mousemove", this.onMouseMove,this); 
rlm@46:  //Ext.get(this.container).on( "dblclick", this.onEndLine,this);
rlm@46:  Ext.get(this.container).on( "selectstart", this.onSelectStart,this);
rlm@46:   
rlm@46: 
rlm@46:   
rlm@46: }
rlm@46: 
rlm@46: RichDrawEditor.prototype.log = function(logtext){
rlm@46:   if(document.forms[0].code){
rlm@46:     document.forms[0].code.value = logtext
rlm@46:   }
rlm@46: }
rlm@46: 
rlm@46: 
rlm@46: RichDrawEditor.prototype.getshapes = function(){
rlm@46:  return this.renderer.getshapes();
rlm@46: }
rlm@46: 
rlm@46: RichDrawEditor.prototype.info = function(shape){
rlm@46:  return this.renderer.info(shape)
rlm@46: }
rlm@46: 
rlm@46: 
rlm@46: RichDrawEditor.prototype.clearWorkspace = function() {
rlm@46:   this.container.innerHTML = '';
rlm@46: };
rlm@46: 
rlm@46: RichDrawEditor.prototype.deleteSelection = function() {
rlm@46:  if (this.selected) {
rlm@46:    this.renderer.remove(this.container.ownerDocument.getElementById('tracker'));
rlm@46:    this.renderer.remove(this.selected);
rlm@46:    this.selected = null;
rlm@46:  }
rlm@46: };
rlm@46: 
rlm@46: RichDrawEditor.prototype.toFront = function(order) {
rlm@46:  if (this.selected) { 
rlm@46:    this.renderer.index(this.selected, order);
rlm@46:  }
rlm@46: };
rlm@46: 
rlm@46: RichDrawEditor.prototype.deleteAll = function() {   
rlm@46:  this.renderer.removeAll();
rlm@46: };
rlm@46: 
rlm@46: 
rlm@46: RichDrawEditor.prototype.select = function(elem) {
rlm@46:  if (elem == this.selected){  return;  }
rlm@46:  this.selected = elem;
rlm@46:  this.renderer.showTracker(this.selected,this.pathsEdit);
rlm@46:  this.onselect(this);
rlm@46: };
rlm@46: 
rlm@46: 
rlm@46: RichDrawEditor.prototype.unselect = function() {
rlm@46:  if (this.selected) {
rlm@46:    this.renderer.remove(this.container.ownerDocument.getElementById('tracker'));
rlm@46:    this.selected = null;
rlm@46:    this.onunselect(this);
rlm@46:   }
rlm@46: };
rlm@46: 
rlm@46: RichDrawEditor.prototype.getSelectedElement = function() {
rlm@46:  return this.selected;
rlm@46: };
rlm@46: 
rlm@46: RichDrawEditor.prototype.toCurve = function() {  
rlm@46:  this.renderer.tocurve();
rlm@46: }
rlm@46: 
rlm@46: RichDrawEditor.prototype.submitShape = function(data) {  
rlm@46:  if (this.mode != 'select') {   
rlm@46:    setMode('path', 'Path');  
rlm@46:    this.actualStyle();
rlm@46:    onColorChange();   
rlm@46:    this.selected = this.renderer.create(this.mode, this.fillColor, this.lineColor, this.fillOpac, this.lineOpac, this.lineWidth, this.mouseDownX, this.mouseDownY, 1, 1,this.textMessaje,this.textSize,this.textFamily,this.imageHref, data, '', '');
rlm@46:    this.selected.id = 'shape:' + createUUID();
rlm@46:    Ext.get(this.selected).on("mousedown", this.onHit,this);   
rlm@46:    setMode('select', 'Select'); 
rlm@46:  } else {
rlm@46:    this.renderer.transformShape(this.selected,data,null); 
rlm@46:    this.renderer.remove(this.container.ownerDocument.getElementById('tracker')); 
rlm@46:    this.renderer.showTracker(this.selected,this.pathsEdit);
rlm@46:  }
rlm@46: };
rlm@46: 
rlm@46: RichDrawEditor.prototype.setGrid = function(horizontal, vertical) {
rlm@46:  this.gridX = horizontal;
rlm@46:  this.gridY = vertical;
rlm@46:  this.gridWidth = (vertical+horizontal)/2; //average. ideally, it should be the same
rlm@46: };
rlm@46: 
rlm@46: 
rlm@46: 
rlm@46: RichDrawEditor.prototype.actualStyle = function()
rlm@46: {
rlm@46:  this.textMessaje=$('option_text_message').value;
rlm@46:  this.textSize=parseFloat($('option_text_size').value);
rlm@46:  this.textFamily=$('option_text_family').value;
rlm@46:  this.pathClose = $('option_path_close').checked; 
rlm@46:  this.imageHref = $('option_image_href').value;
rlm@46: 
rlm@46:  return;
rlm@46: };
rlm@46: 
rlm@46: 
rlm@46: RichDrawEditor.prototype.editCommand = function(cmd, value)
rlm@46: {
rlm@46:  if (cmd == 'mode') 
rlm@46:   {
rlm@46:    this.mode = value;
rlm@46:   }
rlm@46:  else if (this.selected == null) 
rlm@46:   {  
rlm@46:    if (cmd == 'fillcolor') 
rlm@46:     {
rlm@46:      this.fillColor = value;
rlm@46:     }
rlm@46:    else if (cmd == 'linecolor') 
rlm@46:     {
rlm@46:      this.lineColor = value;
rlm@46:     }
rlm@46:    else if (cmd == 'linewidth') 
rlm@46:     {
rlm@46:      this.lineWidth = parseInt(value) + 'px';
rlm@46:     } 
rlm@46:    else if (cmd == 'fillopacity') {
rlm@46:      this.fillOpac = parseInt(value);
rlm@46:     } 
rlm@46:    else if (cmd == 'lineopacity') {
rlm@46:      this.lineOpac = parseInt(value);
rlm@46:     }
rlm@46:   }
rlm@46:  else 
rlm@46:   {
rlm@46:     this.renderer.editCommand(this.selected, cmd, value);
rlm@46:   }
rlm@46: }
rlm@46: 
rlm@46: 
rlm@46: RichDrawEditor.prototype.queryCommand = function(cmd)
rlm@46: {
rlm@46:  if (cmd == 'mode') 
rlm@46:   {
rlm@46:    return this.mode;
rlm@46:   }
rlm@46:  else if (this.selected == null) 
rlm@46:   {
rlm@46:    if (cmd == 'fillcolor') 
rlm@46:     {
rlm@46:      return this.fillColor;
rlm@46:     }
rlm@46:    else if (cmd == 'linecolor') 
rlm@46:     {
rlm@46:      return this.lineColor;
rlm@46:     }
rlm@46:    else if (cmd == 'linewidth') 
rlm@46:     {
rlm@46:      return this.lineWidth;
rlm@46:     }
rlm@46:    else if (cmd == 'fillopacity') 
rlm@46:     {
rlm@46:      return  this.fillOpac;
rlm@46:     }
rlm@46:    else if (cmd == 'lineopacity') 
rlm@46:     {
rlm@46:      return  this.fillOpac;
rlm@46:     }
rlm@46:   }
rlm@46:  else 
rlm@46:   {
rlm@46:    return this.renderer.queryCommand(this.selected, cmd);
rlm@46:   }
rlm@46: }
rlm@46: 
rlm@46: 
rlm@46: 
rlm@46: 
rlm@46: RichDrawEditor.prototype.onSelectStart = function(event) {
rlm@46:   return false
rlm@46: }
rlm@46: 
rlm@46: RichDrawEditor.prototype.onMouseDown = function(event) {  
rlm@46:  
rlm@46:  clockdata();
rlm@46:  
rlm@46:  //MODE NO SELECT
rlm@46:  if (this.mode != 'select') 
rlm@46:   {      
rlm@46:    var modeUsed=0;     
rlm@46:    if (this.mode == 'zoom') 
rlm@46:     {     
rlm@46:      var width=this.gridWidth;
rlm@46:      contmove=0;
rlm@46:      this.setGrid(width, width);  
rlm@46:      this.unselect(); 
rlm@46:      xpArray=new Array();
rlm@46:      ypArray=new Array();
rlm@46:      this.mouseDownX = this.viewInputxy[0];
rlm@46:      this.mouseDownY = this.viewInputxy[1];   
rlm@46:      xpArray.push(this.mouseDownX);
rlm@46:      ypArray.push(this.mouseDownY);
rlm@46:      if(zoommode=='window'){
rlm@46:          this.squareSelect= this.renderer.create('rect', 'none', "#000000", 1, 1, 1, this.mouseDownX, this.mouseDownY, 1, 1,this.textMessaje,this.textSize,this.textFamily,this.imageHref,'M0,0 1,1', '', '');
rlm@46:          this.squareSelect.id = 'squareSelectID';   
rlm@46:          Ext.get(this.squareSelect).on( "mousedown", this.onHit,this);  
rlm@46:          Ext.get(this.squareSelect).on( "mousemove", this.onDraw,this);
rlm@46: 
rlm@46:      }else{
rlm@46:         this.renderer.zoom(this.mouseDownX, this.mouseDownY);  
rlm@46:       } 
rlm@46:      modeUsed=1; 
rlm@46:     } //end zoom     
rlm@46:    if (this.mode == 'controlpath') 
rlm@46:     {
rlm@46:      this.actualStyle(); 
rlm@46:      onColorChange();         
rlm@46:      if(numClics<=0)
rlm@46:       {     
rlm@46:        this.nowDraw=true;
rlm@46:        setPoints=new Array();    
rlm@46:        var width=this.gridWidth;  
rlm@46:        contmove=0;
rlm@46:        this.setGrid(width, width);  
rlm@46:        this.unselect(); 
rlm@46:        xpArray=new Array();
rlm@46:        ypArray=new Array();
rlm@46:        this.mouseDownX =  this.viewInputxy[0];
rlm@46:        this.mouseDownY =  this.viewInputxy[1];   
rlm@46:        xpArray.push(this.mouseDownX);
rlm@46:        ypArray.push(this.mouseDownY);
rlm@46:        setPoints.push(this.mouseDownX+','+this.mouseDownY); 
rlm@46:        onColorChange();
rlm@46:        this.actualStyle();                                                                                                                                                  
rlm@46:        this.selected = this.renderer.create(this.mode, this.fillColor, this.lineColor, this.fillOpac, this.lineOpac, this.lineWidth, this.mouseDownX, this.mouseDownY, 1, 1,this.textMessaje,this.textSize,this.textFamily,this.imageHref, 'M0,0 1,1', '', '');
rlm@46:               
rlm@46:        this.selected.id = 'shape:' + createUUID(); 
rlm@46:        Ext.get(this.selected).on( "mousedown", this.onHit,this);  
rlm@46:        this.log(this.selected.id);   
rlm@46:        
rlm@46:        Ext.get(this.selected).on( "dblclick", this.onEndLine,this);  
rlm@46:        Ext.get(this.container).on( "mousemove", this.onDraw,this); 
rlm@46:        numClics++;
rlm@46:      }
rlm@46:       else
rlm@46:      {  
rlm@46:        var coord=this.viewInputxy;
rlm@46:        var X=parseFloat(coord[0]);
rlm@46:        var Y=parseFloat(coord[1]); 
rlm@46:        setPoints.push(X+','+Y);
rlm@46:        this.renderer.clic(this.selected);
rlm@46:        numClics++;
rlm@46:      }
rlm@46:      modeUsed=1; 
rlm@46:     } //end mode controlpath
rlm@46:    if (modeUsed == 0) 
rlm@46:     {   
rlm@46:      var width=this.gridWidth;
rlm@46:      contmove=0; 
rlm@46:      this.setGrid(width, width);  
rlm@46:      this.unselect(); 
rlm@46:      xpArray=new Array();
rlm@46:      ypArray=new Array();
rlm@46:      this.mouseDownX = this.viewInputxy[0];   
rlm@46:      this.mouseDownY= this.viewInputxy[1];
rlm@46:   
rlm@46:      xpArray.push(this.mouseDownX);
rlm@46:      ypArray.push(this.mouseDownY);
rlm@46:      
rlm@46:      this.unselect();   
rlm@46:      onColorChange();
rlm@46:      this.actualStyle(); 
rlm@46:      this.selected = this.renderer.create(this.mode, this.fillColor, this.lineColor, this.fillOpac, this.lineOpac, this.lineWidth, this.mouseDownX, this.mouseDownY, 1, 1,this.textMessaje,this.textSize,this.textFamily,this.imageHref,'M0,0 1,1', '', '');
rlm@46:      this.selected.id = 'shape:' + createUUID();   
rlm@46:      Ext.get(this.selected).on( "mousedown", this.onHit,this);  
rlm@46:      Ext.get(this.container).on( "mousemove", this.onDraw,this);
rlm@46:     }     
rlm@46:   }
rlm@46:    else   //----- MODE SELECT
rlm@46:   {                                            
rlm@46:   if(this.container.ownerDocument.getElementById('tracker')) this.renderer.remove(this.container.ownerDocument.getElementById('tracker')); 
rlm@46:  
rlm@46:   
rlm@46:    var snappedX=this.viewInputxy[0];
rlm@46:    var snappedY=this.viewInputxy[1]
rlm@46: 
rlm@46:    if (this.mouseDownX != snappedX || this.mouseDownY != snappedY)
rlm@46:     { 
rlm@46:       if(this.selected!=null && typeTransform=='Translate' )
rlm@46:        {
rlm@46:         
rlm@46:         Ext.get(this.container).un("mousemove", this.onDrag); 
rlm@46:         this.unselect();
rlm@46:        }
rlm@46:     }     
rlm@46:     
rlm@46:      if(typeTransform=='Translate')
rlm@46:       {  
rlm@46:        inout='move';//true;   
rlm@46:        this.renderer.remove(this.container.ownerDocument.getElementById('tracker')); 
rlm@46: 
rlm@46:       }
rlm@46:      if(typeTransform=='Scale'  || typeTransform=='Rotate') 
rlm@46:       {
rlm@46:        inout='rotate_escale';//false  
rlm@46:        Ext.get(this.container).on( "mousemove", this.onDrag,this);         
rlm@46:        //Ext.get(this.selected).on( "mousedown", this.onHit,this);  
rlm@46:        this.renderer.remove(this.container.ownerDocument.getElementById('tracker')); 
rlm@46:       }  
rlm@46:   } //end mode select
rlm@46:  return false;
rlm@46: };
rlm@46: 
rlm@46: 
rlm@46: RichDrawEditor.prototype.onMouseUp = function(event) 
rlm@46: {
rlm@46:    //MODE NO SELECT
rlm@46:  if (this.mode != 'select') 
rlm@46:   {
rlm@46:    if(this.mode == 'controlpath') 
rlm@46:     {    
rlm@46:         
rlm@46:     }
rlm@46:      else
rlm@46:     {   
rlm@46:      //ZOOM    
rlm@46:       if (this.mode == 'zoom') 
rlm@46:        {
rlm@46:         var snappedX=this.viewInputxy[0];
rlm@46:         var snappedY=this.viewInputxy[1];
rlm@46:         this.renderer.zoom(snappedX, snappedY); 
rlm@46:         this.renderer.remove(this.container.ownerDocument.getElementById('squareSelectID'));
rlm@46:         Ext.get(this.container).un("mousemove", this.onDraw);  
rlm@46:         this.squareSelect = null; 
rlm@46:         this.selected = null;   
rlm@46:        }else{
rlm@46:         Ext.get(this.container).un("mousemove", this.onDraw);  
rlm@46:         this.selected = null;   
rlm@46:        } 
rlm@46:     }
rlm@46:   } 
rlm@46:    else //MODE SELECT
rlm@46:   { 
rlm@46:    Ext.get(this.container).un("mousemove", this.onDraw);  //or drag
rlm@46:    Ext.get(this.container).un("mousemove", this.onDrag);  
rlm@46:    moveNow=false;   
rlm@46:    contmove=0; 
rlm@46:    if(typeTransform=="Rotate" || typeTransform=="Scale" ) 
rlm@46:     {  
rlm@46:      this.renderer.showTracker(this.selected,this.pathsEdit); 
rlm@46:      typeTransform=='';
rlm@46:     } 
rlm@46:    if(typeTransform=="Translate" ) 
rlm@46:     { 
rlm@46:      this.renderer.showTracker(this.selected,this.pathsEdit); 
rlm@46:      typeTransform='';   
rlm@46:      contmove=0; 
rlm@46:      
rlm@46:     }  
rlm@46: 
rlm@46:    if(inout=='multiSelect')
rlm@46:     {
rlm@46: 
rlm@46:     } 
rlm@46:     
rlm@46:    typeTransform=''; 
rlm@46:   }  
rlm@46: };
rlm@46: 
rlm@46: 
rlm@46: RichDrawEditor.prototype.onDrag = function(event) {  
rlm@46: 
rlm@46:   moveNow=true;  
rlm@46:   //var offset = Ext.get(this.selected).getXY()
rlm@46:   //var deltaX = this.viewInputxy[0] - (this.viewInputxy[0] - this.mouseDownX);
rlm@46:   //var deltaY = this.viewInputxy[1] - (this.viewInputxy[1] - this.mouseDownY);
rlm@46:   //var deltaX = offset[0] ;
rlm@46:   //var deltaY = offset[1] ; 
rlm@46: 
rlm@46:   var deltaX = this.viewInputxy[0] ;
rlm@46:   var deltaY = this.viewInputxy[1] ; 
rlm@46:    var deltaX= this.selectedBounds['x']-this.mouseDownX + this.viewInputxy[0];
rlm@46:    var deltaY= this.selectedBounds['y']-this.mouseDownY + this.viewInputxy[1]; 
rlm@46: 
rlm@46:   //var deltX = this.viewInputxy[0]+(this.mouseDownX-this.viewInputxy[0]);
rlm@46:   //var deltY = this.viewInputxy[1]+(this.mouseDownY-this.viewInputxy[1]); 
rlm@46:   
rlm@46:   var modeUsed=0;              
rlm@46:   if(this.mode == 'zoom') 
rlm@46:    {     
rlm@46:         Ext.get(this.container).getXY();
rlm@46:         this.renderer.resize(this.squareSelect, this.clicX,this.clicY, this.viewInputxy[0], this.viewInputxy[1]);
rlm@46:         modeUsed=1; 
rlm@46:    }
rlm@46:   if(this.mode == 'controlpath') 
rlm@46:      {  
rlm@46:       modeUsed=1; 
rlm@46:      } 
rlm@46:   
rlm@46:   if(modeUsed==0)
rlm@46:    {        
rlm@46:     if(inout=='multiSelect')
rlm@46:      { 
rlm@46:          this.renderer.showMultiSelect(this.mouseDownX, this.mouseDownY);  
rlm@46:      }
rlm@46:     if(typeTransform=="Translate")
rlm@46:      {  
rlm@46:       Ext.get(this.container).getXY();  
rlm@46:       //this.log(this.mouseDownX+' '+event.getXY()[0]+' '+ this.selectedBounds.x +'contmove'+contmove); 
rlm@46:       //this.renderer.move(this.selected, this.viewInputxy[0],this.viewInputxy[1],this.clicX,this.clicY);
rlm@46:       //this.renderer.move(this.selected, this.viewInputxy[0],this.viewInputxy[1], this.mouseDownX, this.mouseDownY);
rlm@46:       this.renderer.move(this.selected, deltaX, deltaY, this.mouseDownX, this.mouseDownY);
rlm@46:      }  
rlm@46:     if(typeTransform=="Rotate") 
rlm@46:      { 
rlm@46:       this.renderer.rotateShape(this.selected, this.previusBox,deltaX, deltaY);
rlm@46:      }
rlm@46:     if(typeTransform=="Scale") 
rlm@46:      {
rlm@46:       this.renderer.scaleShape(this.selected, this.previusBox, this.selectedBounds.x + deltaX, this.selectedBounds.y + deltaY); 
rlm@46:      }
rlm@46:     }   
rlm@46: };
rlm@46: 
rlm@46: 
rlm@46: RichDrawEditor.prototype.onResize = function(event) {
rlm@46:   var deltaX = this.viewInputxy[0] - this.mouseDownX;
rlm@46:   var deltaY = this.viewInputxy[1] - this.mouseDownY;
rlm@46:   this.renderer.track(handle, deltaX, deltaY);
rlm@46:   show_tracker();
rlm@46: };
rlm@46: 
rlm@46: 
rlm@46: RichDrawEditor.prototype.onDraw = function(event) {
rlm@46:   if (this.selected == null)
rlm@46:    {  
rlm@46:     if(this.squareSelect != null)
rlm@46:      {
rlm@46:       var offset = Ext.get(this.container).getXY()
rlm@46:       var snappedX = this.viewInputxy[0];//Math.round(zoomx+((event.getXY()[0] - offset[0]) / this.gridX) * this.gridX);
rlm@46:       var snappedY = this.viewInputxy[1];//Math.round(zoomy+((event.getXY()[1] - offset[1]) / this.gridY) * this.gridY);
rlm@46:       this.renderer.resize(this.squareSelect, this.mouseDownX, this.mouseDownY, snappedX, snappedY);
rlm@46:       }
rlm@46:        else
rlm@46:       {
rlm@46:         return;
rlm@46:       }
rlm@46:     }
rlm@46:      else
rlm@46:     {   
rlm@46:   
rlm@46:         var snappedX = this.viewInputxy[0];//Math.round(zoomx+((event.getXY()[0] - offset[0]) / this.gridX) * this.gridX);
rlm@46:         var snappedY = this.viewInputxy[1];// Math.round(zoomy+((event.getXY()[1] - offset[1]) / this.gridY) * this.gridY);
rlm@46:         this.renderer.resize(this.selected, this.mouseDownX, this.mouseDownY, snappedX, snappedY);
rlm@46:       
rlm@46:     }
rlm@46: };
rlm@46: 
rlm@46: RichDrawEditor.prototype.onRotate = function(event) {
rlm@46:   if (this.selected == null)
rlm@46:    {
rlm@46:      
rlm@46:    }else{      
rlm@46:    }
rlm@46: };
rlm@46: 
rlm@46: RichDrawEditor.prototype.onScale = function(event) {
rlm@46:   if (this.selected == null)
rlm@46:    {
rlm@46:      
rlm@46:    }else{      
rlm@46:    }
rlm@46: };
rlm@46: 
rlm@46: RichDrawEditor.prototype.onTransform = function(event) {
rlm@46:   if (this.selected == null)
rlm@46:    {
rlm@46:      
rlm@46:    }else{  
rlm@46:   }
rlm@46: };
rlm@46: 
rlm@46: RichDrawEditor.prototype.onMouseMove = function(event) {
rlm@46:  var offset = Ext.get(c.container).getXY()
rlm@46:  var x = Math.round(event.getXY()[0] - offset[0]);
rlm@46:  var y = Math.round(event.getXY()[1] - offset[1]);
rlm@46:  if (ie || opera) 
rlm@46:   {  
rlm@46:    proporx =1;
rlm@46:    propory =1;
rlm@46:    zoominit2='1 1 1 1';
rlm@46:    this.inputxy = [x,y];    
rlm@46:    this.viewInputxy = [x,y];  
rlm@46:    this.onInputXY(x,y);   
rlm@46:    this.onViewInputXY(x,y);
rlm@46:   }
rlm@46:    else
rlm@46:   {
rlm@46:    ////////////
rlm@46:    
rlm@46:     var X = x ; // x cursor on canvas
rlm@46:     var Y = y ; // y cursor on canvas
rlm@46: 
rlm@46:     var Ex = parseFloat(tokensCanvas[2]) ; // (end) width canvas. Corner down-left
rlm@46:     var Ey = parseFloat(tokensCanvas[3]) ; // (end) height canvas. Corner up-right
rlm@46: 
rlm@46:     var zoomX = 0 ; // ? x unknown
rlm@46:     var zoomY = 0 ; // ? y unknown
rlm@46: 
rlm@46:     var sx = parseFloat(tokensZoom[0]) ; // (start) x origin of the coord zoom.
rlm@46:     var sy = parseFloat(tokensZoom[1]) ; // (start) y origin of the coord zoom.
rlm@46:     var Wz = parseFloat(tokensZoom[2]) ; // width zoom
rlm@46:     var Hz = parseFloat(tokensZoom[3]) ; // height zoom
rlm@46: 
rlm@46:     var ex = parseFloat(sx + Wz) ; // (end) x width zoom. Corner down-left
rlm@46:     var ey = parseFloat(sy + Hz) ; // (end) y height zoom. Corner up-right
rlm@46: 
rlm@46:     var r = X / Ex ; // 0 to 1
rlm@46:     var s = Y / Ey ; // 0 to 1
rlm@46:     this.unit = this.initialUnit * (Hz/Ey) ; // 0 to 1
rlm@46:     zoomX= (1 - r) * sx + ex * r;
rlm@46:     zoomY= (1 - s) * sy + ey * s; 
rlm@46:    
rlm@46:    this.inputxy = [x,y];    
rlm@46:    this.viewInputxy = [zoomX,zoomY];  
rlm@46:    this.onInputXY(x,y);  
rlm@46:    this.onViewInputXY(zoomX,zoomY);  
rlm@46:   }
rlm@46:    
rlm@46: };                                       
rlm@46: 
rlm@46: 
rlm@46: RichDrawEditor.prototype.onHit = function(event) {
rlm@46:   Ext.get(this.container).un("mousemove", this.onDrag); 
rlm@46: 
rlm@46:  if(this.mode == 'select') 
rlm@46:   {   
rlm@46:    if (event.stopPropagation) event.stopPropagation(); // DOM Level 2
rlm@46:    else event.cancelBubble = true; // IE
rlm@46:    // Now prevent any default action.
rlm@46:    if (event.preventDefault) event.preventDefault(); // DOM Level 2
rlm@46:    else event.returnValue = false; // IE      
rlm@46:    
rlm@46:    if(inout=='multiSelect')
rlm@46:     {   
rlm@46:  
rlm@46:     }
rlm@46:      else
rlm@46:     { 
rlm@46:      //Ext.get(this.container).un("mousemove", this.onDrag); 
rlm@46:      typeTransform="Translate";
rlm@46:      contmove=0;
rlm@46:      var width=this.gridWidth;
rlm@46:          
rlm@46:      this.setGrid(width, width);  
rlm@46:      
rlm@46:      this.select(event.getTarget()); 
rlm@46:      this.previusBox=this.selected;     
rlm@46:     
rlm@46:      this.renderer.getProperties(this.selected);
rlm@46:      //var offset = Ext.get(this.container).getXY(); 
rlm@46:  
rlm@46:      this.selectedBounds = this.renderer.bounds(this.selected); 
rlm@46:      
rlm@46:      this.mouseDownX =this.viewInputxy[0];//x;// offset[0];//zoomx+snappedX;
rlm@46:      this.mouseDownY =this.viewInputxy[1];//y;//  offset[1];//zoomy+snappedY;   
rlm@46:      this.log(this.gridX);
rlm@46:      this.renderer.info(this.selected); 
rlm@46:      if(this.container.ownerDocument.getElementById('tracker'))
rlm@46:       {
rlm@46:         this.renderer.remove(this.container.ownerDocument.getElementById('tracker')); 
rlm@46:       } 
rlm@46:      Ext.get(this.container).on( "mousemove", this.onDrag,this);   
rlm@46:     }
rlm@46:   }
rlm@46:    else
rlm@46:   {
rlm@46:     this.mouseDownX = this.viewInputxy[0];//Math.round(zoomx+((event.getXY()[0] - offset[0]) / this.gridX) * this.gridX);
rlm@46:     this.mouseDownY = this.viewInputxy[1];//Math.round(zoomy+((event.getXY()[1] - offset[1]) / this.gridY) * this.gridY);
rlm@46:     Ext.get(this.container).on( "mousemove", this.onDrag,this);   
rlm@46:     
rlm@46:   }
rlm@46: };  
rlm@46: 
rlm@46: 
rlm@46: RichDrawEditor.prototype.onClic = function(event) {
rlm@46:  if(this.mode == 'controlpath') 
rlm@46:   {     
rlm@46:   
rlm@46:   }
rlm@46:    else
rlm@46:   {
rlm@46:        
rlm@46:   }
rlm@46: };   
rlm@46: 
rlm@46: RichDrawEditor.prototype.reflect = function(HorV) {
rlm@46:  this.selected=this.renderer.reflect(HorV);
rlm@46:  this.selected.id = 'shape:' + createUUID();
rlm@46:  Ext.get(this.selected).on( "mousedown", this.onHit,this);  
rlm@46: }
rlm@46: 
rlm@46: RichDrawEditor.prototype.onEndLine = function(event) {   
rlm@46:   
rlm@46:  if(this.mode == 'controlpath') 
rlm@46:   {     
rlm@46:         //alert(numClics);
rlm@46:         numClics=0;    
rlm@46:          Ext.get(this.container).un("mousemove", this.onDraw); 
rlm@46:          //Ext.get(this.selected).un( "mousedown", this.onHit,this);  
rlm@46:          //Ext.get(this.selected).un( "dblclick", this.onEndLine);  
rlm@46:          //Ext.get(this.container).un( "mousemove", this.onDraw,this);    
rlm@46:          //Ext.get(this.container).un( "mousemove", this.onDrag,this); 
rlm@46:          // Ext.get(this.selected).un( "mousedown", this.onHit);  
rlm@46:    
rlm@46:        // Ext.get(this.container).un("mousemove", this.onDraw,this); 
rlm@46:         //Ext.get(this.container).un("mousemove", this.onDrag,this);
rlm@46:         this.selected = null;   
rlm@46:         
rlm@46:           
rlm@46:   }
rlm@46:    else
rlm@46:   {   
rlm@46:   
rlm@46:    this.nowDraw=false;   
rlm@46:    typeTransform='';   
rlm@46:   }
rlm@46: };
rlm@46: 
rlm@46: function noselect(){
rlm@46: }
rlm@46: 
rlm@46: function createUUID()
rlm@46: {
rlm@46:   return [4, 2, 2, 2, 6].map(function(length) {
rlm@46:     var uuidpart = "";
rlm@46:     for (var i=0; i<length; i++) {
rlm@46:       var uuidchar = parseInt((Math.random() * 256)).toString(16);
rlm@46:       if (uuidchar.length == 1)
rlm@46:         uuidchar = "0" + uuidchar;
rlm@46:       uuidpart += uuidchar;
rlm@46:     }
rlm@46:     return uuidpart;
rlm@46:   }).join('-');
rlm@46: }
rlm@46: 
rlm@46: 
rlm@46: //----------------------------------------------------------------------------
rlm@46: // AbstractRenderer
rlm@46: //
rlm@46: // Abstract base class defining the drawing API. Can not be used directly.
rlm@46: //----------------------------------------------------------------------------
rlm@46: 
rlm@46: function AbstractRenderer() {
rlm@46: 
rlm@46: };
rlm@46: 
rlm@46: AbstractRenderer.prototype.init = function(elem) {};
rlm@46: AbstractRenderer.prototype.bounds = function(shape) { return { x:0, y:0, width:0, height: 0 }; };
rlm@46: AbstractRenderer.prototype.create = function(shape, fillColor, lineColor, lineWidth, left, top, width, height, textMessaje, textSize, textFamily, imageHref, transform) {};
rlm@46: AbstractRenderer.prototype.datacreate = function(fillColor, lineColor, lineWidth, fillOpac, strokeOpac, left, top, width, height,data) {};
rlm@46: AbstractRenderer.prototype.index = function(shape, order) {};
rlm@46: AbstractRenderer.prototype.remove = function(shape) {}; 
rlm@46: AbstractRenderer.prototype.copy = function(shape) {};
rlm@46: AbstractRenderer.prototype.paste = function(left,top) {};
rlm@46: AbstractRenderer.prototype.duplicate = function(shape) {};
rlm@46: AbstractRenderer.prototype.move = function(shape, left, top) {};  
rlm@46: AbstractRenderer.prototype.endmove = function(shape) {};
rlm@46: AbstractRenderer.prototype.transform= function(shape, left, top) {};
rlm@46: AbstractRenderer.prototype.scale = function(shape, left, top) {};
rlm@46: AbstractRenderer.prototype.rotate = function(shape, left, top) {};
rlm@46: AbstractRenderer.prototype.track = function(shape) {}; 
rlm@46: AbstractRenderer.prototype.restruct = function(shape) {};
rlm@46: AbstractRenderer.prototype.resize = function(shape, fromX, fromY, toX, toY) {};
rlm@46: AbstractRenderer.prototype.editCommand = function(shape, cmd, value) {};
rlm@46: AbstractRenderer.prototype.queryCommand = function(shape, cmd) {};
rlm@46: AbstractRenderer.prototype.showTracker = function(shape,value) {};
rlm@46: AbstractRenderer.prototype.getMarkup = function() { return null; };
rlm@46: AbstractRenderer.prototype.info = function(shape){}; 
rlm@46: AbstractRenderer.prototype.editShape = function(shape,data){};
rlm@46: AbstractRenderer.prototype.onKeyPress = function(){};
rlm@46: 
rlm@46: AbstractRenderer.prototype.getshapes = function(){};
rlm@46: 
rlm@46: 
rlm@46: //-----------------------------
rlm@46: // Geometry - string functions
rlm@46: //-----------------------------   
rlm@46: 
rlm@46: //two point angle  deg
rlm@46: function ang2v(x1,y1,x2,y2)
rlm@46: {
rlm@46:      /*
rlm@46:       var k=0;
rlm@46: 
rlm@46:       var sum1=u1+v1; 
rlm@46:       var sum2=u2+v2;    
rlm@46: 
rlm@46:       var res1=u1-v1;  
rlm@46:       var res2=u2-v2;   
rlm@46: 
rlm@46:      var ku1=k*u1; 
rlm@46:       var ku2=k*u2;   
rlm@46: 
rlm@46:        var mu= Math.sqrt(u1*u1+u2*u2); 
rlm@46:        var mv= Math.sqrt(v1*v1+v2*v2);
rlm@46: 
rlm@46:        var pesc= u1*v1+u2*v2; 
rlm@46:        //var ang=Math.acos(pesc/(mu*mv))*180/Math.PI;
rlm@46:        var ang=Math.acos(pesc/(mu*mv));  
rlm@46:        */ 
rlm@46:         var resx=x2-x1;  
rlm@46:       var resy=y2-y1;   
rlm@46:        var ang=Math.atan2(resy,resx); 
rlm@46:        //alert(ang);
rlm@46:        return ang;
rlm@46: }     
rlm@46: 
rlm@46: function dist2p(a,b,c,d) 
rlm@46:  {
rlm@46:    with (Math) 
rlm@46:     {
rlm@46:         //var d2p=sqrt(abs(((d-b)*(d-b) )+((c-a)*(c-a))));   //decimas(d2p,3);     return d2p;
rlm@46:           return sqrt(abs((d-b)*(d-b)+ (c-a)*(c-a)));
rlm@46: 
rlm@46:     }
rlm@46:  }
rlm@46: function pmd2pb(a,b,c,d,q) {
rlm@46: 	pmdx= (1-q)*a+c*q;
rlm@46: 	pmdy= (1-q)*b+d*q;
rlm@46: //pmdx=decimas(pmdx,3);
rlm@46: //pmdy=decimas(pmdy,3);
rlm@46: var cad=pmdx+','+pmdy;
rlm@46: var sol= new Array();
rlm@46: sol= [cad,pmdx,pmdy];
rlm@46: return sol
rlm@46: 
rlm@46: } 
rlm@46: 
rlm@46: function getAngle(dx,dy) {
rlm@46:   var angle = Math.atan2(dy, dx);
rlm@46:   //angle *= 180 / Math.PI;
rlm@46:   return angle;  
rlm@46:   
rlm@46: }
rlm@46: 
rlm@46: /*
rlm@46: 
rlm@46: A = y2-y1
rlm@46: B = x1-x2
rlm@46: C = A*x1+B*y1
rlm@46: Regardless of how the lines are specified, you should be able to generate two different points along the line, and then generate A, B and C. Now, lets say that you have lines, given by the equations:
rlm@46: A1x + B1y = C1
rlm@46: A2x + B2y = C2
rlm@46: To find the point at which the two lines intersect, we simply need to solve the two equations for the two unknowns, x and y.
rlm@46: 
rlm@46:     double det = A1*B2 - A2*B1
rlm@46:     if(det == 0){
rlm@46:         //Lines are parallel
rlm@46:     }else{
rlm@46:         double x = (B2*C1 - B1*C2)/det
rlm@46:         double y = (A1*C2 - A2*C1)/det
rlm@46:     }
rlm@46: 
rlm@46: 
rlm@46: 
rlm@46: 
rlm@46: */  
rlm@46: // interseccion 2 rectas
rlm@46: function ntrsccn2rb(a,b,c,d,e,f,g,h){
rlm@46:  var solution= new Array();
rlm@46:  var i2rx=0;var i2ry=0;
rlm@46:  var w= (c-a)*(f-h)-(e-g)*(d-b);
rlm@46:  if(w==0){
rlm@46:   n=1;
rlm@46:   i2rx= (1-n)*a+n*c;
rlm@46:   i2ry= (1-n)*b+n*d;
rlm@46:   solution= ['',i2rx,i2ry];  
rlm@46:   //Lines are parallel
rlm@46:   return solution
rlm@46:   //return (i2rx+' '+i2ry);
rlm@46:  }
rlm@46:  var n = (((e-a)*(f-h))-((e-g)*(f-b)))/w;
rlm@46:  i2rx=(1-n)*a+n*c;
rlm@46:  i2ry=(1-n)*b+n*d;
rlm@46:  //return (i2rx+' '+i2ry);
rlm@46:  solution= ['',i2rx,i2ry];
rlm@46:  return solution
rlm@46: 
rlm@46: }
rlm@46: 
rlm@46: //ecuacion implicita de la recta
rlm@46: function ccnmplct(a,b,c,d) { 
rlm@46:   var solution= new Array();
rlm@46:   //a1 a2, b1 b2    vector direccion b1-a1 , b2-a2
rlm@46:   var v1m=c-a;
rlm@46:   var v1n=d-b;
rlm@46:   var c1x= v1m;
rlm@46:   var c1y= v1n;
rlm@46:   // ecuacion continua (x - a) /c -a =  (y - b)/d - b
rlm@46:   //(x - a) * v1n =  (y - b) * v1m 
rlm@46:   //x * v1n - v1n*a = y * v1m - b* v1m
rlm@46:   eia= v1n ;
rlm@46:   eib= - v1m;
rlm@46:   eic=  (b* v1m) - ( v1n*a)
rlm@46:   solution= [eia,eib,eic];
rlm@46:   return solution
rlm@46: }
rlm@46: function GetString(source, start, end){
rlm@46: var st = source.indexOf(start) + start.length;
rlm@46: var en = source.indexOf(end, start);
rlm@46:  return source.substring(st, en);//trimAll(source.substring(st, en));
rlm@46: }
rlm@46:  
rlm@46: function deg2rad(angle){
rlm@46: return (angle/180) * Math.PI;
rlm@46: } 
rlm@46:  
rlm@46: String.prototype.trim = function(){ return this.replace(/^\s+|\s+$/g,'') }
rlm@46:  
rlm@46: function objectOffset(obj)
rlm@46: {
rlm@46:  var posX=0;
rlm@46:  var posY=0;
rlm@46:  if(typeof(obj.offsetParent) != "undefined")
rlm@46:   {
rlm@46:    for(var x=0, y=0;obj; obj=obj.offsetParent)
rlm@46:    {
rlm@46:     x += obj.offsetLeft;
rlm@46:     y += obj.offsetTop;
rlm@46:    }
rlm@46:    posX=x;
rlm@46:    posY=y;
rlm@46:   }
rlm@46:    else
rlm@46:   {
rlm@46:    posX=obj.offsetLeft;
rlm@46:    posY=obj.offsetTop;
rlm@46:   }
rlm@46:  alert(obj.id+" "+"X: "+posX+" Y: "+posY);
rlm@46: }
rlm@46: 
rlm@46: function generateJSON(cssEnv)
rlm@46: {    
rlm@46:  //string=string.replace(/;/g,'",') ;
rlm@46:  //string=string.replace(/:/g,':"') ; 
rlm@46:  //style="fill:#7e0000;fill-opacity:1" 
rlm@46:  
rlm@46:  var css=cssEnv.split(';')
rlm@46: 
rlm@46:   var strJSON = '{';
rlm@46:   ch = ',';
rlm@46:   for (i = 0 ; i < css.length; i++)
rlm@46:   { 
rlm@46:    var data=css[i].split(':'); 
rlm@46:    if(data[0]!=''){ 
rlm@46:      //if(i == (css.length-2)){   ch = ''; }   
rlm@46:      strJSON += "'"+data[0].trim()+"':'"+data[1].trim()+"'"+",";
rlm@46:    } 
rlm@46:       
rlm@46:    
rlm@46:   } 
rlm@46:   var num=  strJSON.length;
rlm@46:   strJSON=strJSON.substr(0, num-1);
rlm@46: 
rlm@46:   strJSON += '}';
rlm@46: 
rlm@46:   return strJSON;
rlm@46: }