neyric/wireit

View on GitHub
src/wire-base/js/wire.js.old

Summary

Maintainability
Test Coverage
YUI.add("wire", function (Y){

/**
 * The wire widget that uses a canvas to render
 * @class Wire
 * @extends WireCanvasElement
 * @constructor
 * @param  {WireIt.Terminal}    terminal1   Source terminal
 * @param  {WireIt.Terminal}    terminal2   Target terminal
 * @param  {HTMLElement} parentEl    Container of the CANVAS tag
 * @param  {Obj}                options      Wire configuration (see options property)
 */
Y.WireWire = function ( terminal1, terminal2, parentEl, options) {
   
   /**
    * Reference to the parent dom element
    * @attribute parentEl
    * @type HTMLElement
    */
   this.parentEl = parentEl;
   
   /**
    * Source terminal
    * @attribute terminal1
    * @type Y.Terminal
    */
   this.terminal1 = terminal1;
   
   /**
    * Target terminal
    * @attribute terminal2
    * @type Y.Terminal || Y.TerminalProxy
    */
   this.terminal2 = terminal2;

    
   /**
    * Event that is fired when a wire is clicked (on the wire, not the canvas)
    * You can register this event with myWire.on('eventWireClick', function (e,params) { var wire = params[0], xy = params[1];}, scope);
    * @event eventMouseClick
    */
   //this.publish('eventMouseClick');

    /**
    * Event that is fired when the mouse enter the wire
    * You can register this event with myWire.on('eventMouseIn', function (e,params) { var wire = params[0], xy = params[1];}, scope);
    * @event eventMouseIn
    */
    //this.publish('eventMouseIn');
    
    /**
    * Event that is fired when the mouse exits the wire
    * You can register this event with myWire.on('eventMouseOut', function (e,params) { var wire = params[0], xy = params[1];}, scope);
    * @event eventMouseOut
    */
    //this.publish('eventMouseOut');
    
    /**
    * Event that is fired when the mouse moves inside the wire
    * You can register this event with myWire.on('eventMouseMove', function (e,params) { var wire = params[0], xy = params[1];}, scope);
    * @event eventMouseMove
    */
    //this.publish('eventMouseMove');


   
   // Init the options property
   this.setOptions(options || {});
   
   // Create the canvas element and append it to parentEl
   Y.WireWire.superclass.constructor.call(this, this.parentEl);
   
   // CSS classname
   Y.one(this.element).addClass(this.className);

   // Label
    if(this.label) {
        this.renderLabel();
    }

   // Call addWire on both terminals
   this.terminal1.addWire(this);
   this.terminal2.addWire(this);
};


Y.extend(Y.WireWire, Y.WireCanvasElement, {

    /** 
    * @attribute xtype
    * @description String representing this class for exporting as JSON
    * @default "WireIt.Wire"
    * @type String
    */
   xtype: "Y.WireWire",

    /** 
    * @attribute className
    * @description CSS class name for the wire element
    * @default "WireIt-Wire"
    * @type String
    */
    className: "WireIt-Wire",

    /** 
    * @attribute cap
    * @description TODO
    * @default "round"
    * @type String
    */
    cap: 'round',
    
    /** 
    * @attribute bordercap
    * @description TODO
    * @default "round"
    * @type String
    */
    bordercap: 'round',
    
    /** 
    * @attribute width
    * @description Wire width
    * @default 3
    * @type Integer
    */
    width: 3,
    
    /** 
    * @attribute borderwidth
    * @description Border width
    * @default 1
    * @type Integer
    */
    borderwidth: 1,
    
    /** 
    * @attribute color
    * @description Wire color
    * @default 'rgb(173, 216, 230)'
    * @type String
    */
    color: 'rgb(173, 216, 230)',
    
    /** 
    * @attribute bordercolor
    * @description Border color
    * @default '#0000ff'
    * @type String
    */
    bordercolor: '#0000ff',
    
    /** 
    * @attribute label
    * @description Wire label
    * @default null
    * @type String
    */
    label: null,
    
    /** 
    * @attribute labelStyle
    * @description Wire label style
    * @default null
    * @type Object
    */
    labelStyle: null,
    
    /** 
    * @attribute labelEditor
    * @description inputEx field definition for the label editor
    * @default null
    * @type Object
    */
    labelEditor: null,
    
    // TODO !
    on: function () {}, 
    
   /**
    * Set the options by putting them in this (so it overrides the prototype default)
    * @method setOptions
    */
   setOptions: function (options) {
      for(var k in options) {
            if( options.hasOwnProperty(k) ) {
                this[k] = options[k];
            }
        }
   },
   
   /**
    * Remove a Wire from the Dom
    * @method remove
    */
   remove: function () {
   
      // Remove the canvas from the dom
      this.parentEl.removeChild(this.element);
   
      // Remove the wire reference from the connected terminals
        if(this.terminal1 && this.terminal1.removeWire) {
            this.terminal1.removeWire(this);
        }
        if(this.terminal2 && this.terminal2.removeWire) {
            this.terminal2.removeWire(this);
        }

        // Remove references to old terminals
        this.terminal1 = null;
        this.terminal2 = null;

        // Remove Label
        if(this.labelEl) {
            if(this.labelField) {
                this.labelField.destroy();
            }
            this.labelEl.innerHTML = "";
        }
   },


   /**
    * This function returns terminal1 if the first argument is terminal2 and vice-versa
    * @method getOtherTerminal
    * @param   {WireIt.Terminal} terminal    
    * @return  {WireIt.Terminal} terminal    the terminal that is NOT passed as argument
    */
   getOtherTerminal: function (terminal) {
      return (terminal == this.terminal1) ? this.terminal2 : this.terminal1;
   },
   
   
   
   /**
    * Drawing method
    */
   draw: function () {
      var margin = [4,4];

      // Get the positions of the terminals
      var p1 = this.terminal1.getXY();
      var p2 = this.terminal2.getXY();

      var min=[ Math.min(p1[0],p2[0])-margin[0], Math.min(p1[1],p2[1])-margin[1]];
      var max=[ Math.max(p1[0],p2[0])+margin[0], Math.max(p1[1],p2[1])+margin[1]];

        // Store the min, max positions to display the label later
        this.min = min;
        this.max = max;      

      // Redimensionnement du canvas
      var lw=Math.abs(max[0]-min[0]);
      var lh=Math.abs(max[1]-min[1]);

      // Convert points in canvas coordinates
      p1[0] = p1[0]-min[0];
      p1[1] = p1[1]-min[1];
      p2[0] = p2[0]-min[0];
      p2[1] = p2[1]-min[1];

      this.SetCanvasRegion(min[0],min[1],lw,lh);

      var ctxt=this.getContext();
      
      // Draw the border
      ctxt.lineCap=this.bordercap;
      ctxt.strokeStyle=this.bordercolor;
      ctxt.lineWidth=this.width+this.borderwidth*2;
      ctxt.beginPath();
      ctxt.moveTo(p1[0],p1[1]);
      ctxt.lineTo(p2[0],p2[1]);
      ctxt.stroke();

      // Draw the inner bezier curve
      ctxt.lineCap=this.cap;
      ctxt.strokeStyle=this.color;
      ctxt.lineWidth=this.width;
      ctxt.beginPath();
      ctxt.moveTo(p1[0],p1[1]);
      ctxt.lineTo(p2[0],p2[1]);
      ctxt.stroke();
   },

   /**
    * Redraw the wire and label
    * @method redraw
    */
   redraw: function () {
                
      this.draw();

        if(this.label) {
            this.positionLabel();
        }
   },

    /**
     * Render the label container
     */
    renderLabel: function () {
        
        this.labelEl = Y.WireIt.cn('div',{className:"WireIt-Wire-Label"}, this.labelStyle );
        
        if(this.labelEditor) {
            this.labelField = new Y.inputEx.InPlaceEdit({parentEl: this.labelEl, editorField: this.labelEditor, animColors:{from:"#FFFF99" , to:"#DDDDFF"} });
            this.labelField.setValue(this.label);
        }
        else {
            this.labelEl.innerHTML = this.label;
        }
        
        this.element.parentNode.appendChild(this.labelEl);
        
    },
    
    /**
     * Set the label
     */
    setLabel: function (val) {
        if(this.labelEditor) {
            this.labelField.setValue(val);
        }
        else {
            this.labelEl.innerHTML = val;
        }
    },

    /**
     * Position the label element to the center
     */
    positionLabel: function () {
       var el = Y.one(this.labelEl);
       el.setStyle("left",(this.min[0]+this.max[0]-this.labelEl.clientWidth)/2 + "px");
       el.setStyle("top",(this.min[1]+this.max[1]-this.labelEl.clientHeight)/2 + "px");
    },
   
   /**
    * Determine if the wire is drawn at position (x,y) relative to the canvas element. This is used for mouse events.
    * @method wireDrawnAt
    * @return {Boolean} true if the wire is drawn at position (x,y) relative to the canvas element
    */
   wireDrawnAt: function (x,y) {
      var ctxt = this.getContext();
       var imgData = ctxt.getImageData(x,y,1,1);
       var pixel = imgData.data;
       return !( pixel[0] === 0 && pixel[1] === 0 && pixel[2] === 0 && pixel[3] === 0 );
   },
   
   /**
    * Called by the Layer when the mouse moves over the canvas element.
    * Note: the event is not listened directly, to receive the event event if the wire is behind another wire
    * @method onMouseMove
    * @param {Integer} x left position of the mouse (relative to the canvas)
    * @param {Integer} y top position of the mouse (relative to the canvas)
    */
   onMouseMove: function (x,y) {
      
      if(this.mouseInState === undefined) {
         this.mouseInState = false;
      }

       if( this.wireDrawnAt(x,y) ) {
            if(!this.mouseInState) {
               this.mouseInState=true;
               this.onWireIn(x,y);
            }    
            
            this.onWireMove(x,y);
       }
       else {
          if(this.mouseInState) {
             this.mouseInState=false;
               this.onWireOut(x,y);
          }
       }
      
   },
   
   /**
    * When the mouse moves over a wire
    * Note: this will only work within a layer
    * @method onWireMove
    * @param {Integer} x left position of the mouse (relative to the canvas)
    * @param {Integer} y top position of the mouse (relative to the canvas)
    */
   onWireMove: function (x,y) {
        this.eventMouseMove.fire(this, [x,y]);
   },
   
   /**
    * When the mouse comes into the wire
    * Note: this will only work within a layer
    * @method onWireIn
    * @param {Integer} x left position of the mouse (relative to the canvas)
    * @param {Integer} y top position of the mouse (relative to the canvas)
    */
   onWireIn: function (x,y) {
        this.eventMouseIn.fire(this, [x,y]);
   },
   
   /**
    * When the mouse comes out of the wire
    * Note: this will only work within a layer
    * @method onWireOut
    * @param {Integer} x left position of the mouse (relative to the canvas)
    * @param {Integer} y top position of the mouse (relative to the canvas)
    */
   onWireOut: function (x,y) {
        this.eventMouseOut.fire(this, [x,y]);
   },
   
   /**
    * When the mouse clicked on the canvas
    * Note: this will only work within a layer
    * @method onClick
    * @param {Integer} x left position of the mouse (relative to the canvas)
    * @param {Integer} y top position of the mouse (relative to the canvas)
    */
   onClick: function (x,y) {
        if( this.wireDrawnAt(x,y) ) {
            this.onWireClick(x,y);
      }
   },
   
   /**
    * When the mouse clicked on the wire
    * Note: this will only work within a layer
    * @method onWireClick
    * @param {Integer} x left position of the mouse (relative to the canvas)
    * @param {Integer} y top position of the mouse (relative to the canvas)
    */
   onWireClick: function (x,y) {
        this.eventMouseClick.fire(this, [x,y]);
   },


    /**
    * Return the config of this Wire
    * @method getConfig
    */
    getConfig: function () {
      var obj = {
            xtype: this.xtype
        };

        // Export the label value
        if(this.labelEditor) {
            obj.label = this.labelField.getValue();
        }

      return obj;
   }


});

}, '0.7.0',{
  requires: ['']
});