From e4fae95600ece6e7534ee07caeaa89bbc4edc2eb Mon Sep 17 00:00:00 2001 From: Allison Corey Date: Fri, 20 Feb 2015 15:22:28 -0500 Subject: [PATCH 001/644] Prep version and changelog for 0.8.0 (tickless model changes). --- CHANGELOG.md | 10 ++++++++++ support/client/lib/version.js | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67eedef47..9cd00e200 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,16 @@ VIRTUAL WORLD FRAMEWORK CHANGE LOG ================================== +---------------------------------- +0.8.0 +---------------------------------------------------------------------------------------------------- +Note: (*) indicates an API change. + +- CHG*: Handle reflector actions as they arrive, without waiting for a tick. +- CHG*: Don't record ticks in the queue. Don't tick nodes and model drivers. +- CHG*: Remove ticking function from model drivers. + + ---------------------------------- 0.7.0 ---------------------------------------------------------------------------------------------------- diff --git a/support/client/lib/version.js b/support/client/lib/version.js index c29ff9e29..b40d88927 100644 --- a/support/client/lib/version.js +++ b/support/client/lib/version.js @@ -30,7 +30,7 @@ define( function() { /// particuarly clever about it. Take care to keep the comment and formatting intact when /// bumping the version number. - var version = [ 0, 7, 0, "development", "" ]; // version-identifier + var version = [ 0, 8, 0, "development", "" ]; // version-identifier /// Render the version identifier as a SemVer-style string. From d54776ffc4d20fae92895a43e89a760cb6bec2f2 Mon Sep 17 00:00:00 2001 From: Scott Haynes Date: Mon, 6 Apr 2015 16:54:55 -0400 Subject: [PATCH 002/644] Moves these components from the application to the shared location --- .../proxy/vwf.example.com/kinetic/drawing.js | 59 +++++-- .../vwf.example.com/kinetic/drawing.vwf.yaml | 2 +- .../vwf.example.com/mil-sym/modifier.vwf.yaml | 33 ++++ support/proxy/vwf.example.com/mil-sym/unit.js | 13 ++ .../vwf.example.com/mil-sym/unit.vwf.yaml | 51 ++++++ .../vwf.example.com/mil-sym/unitGroup.js | 159 ++++++++++++++++++ .../mil-sym/unitGroup.vwf.yaml | 61 +++++++ .../proxy/vwf.example.com/mil-sym/unitIcon.js | 37 ++++ .../vwf.example.com/mil-sym/unitIcon.vwf.yaml | 41 +++++ 9 files changed, 440 insertions(+), 16 deletions(-) create mode 100755 support/proxy/vwf.example.com/mil-sym/modifier.vwf.yaml create mode 100755 support/proxy/vwf.example.com/mil-sym/unit.js create mode 100755 support/proxy/vwf.example.com/mil-sym/unit.vwf.yaml create mode 100755 support/proxy/vwf.example.com/mil-sym/unitGroup.js create mode 100755 support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml create mode 100755 support/proxy/vwf.example.com/mil-sym/unitIcon.js create mode 100755 support/proxy/vwf.example.com/mil-sym/unitIcon.vwf.yaml diff --git a/support/proxy/vwf.example.com/kinetic/drawing.js b/support/proxy/vwf.example.com/kinetic/drawing.js index 938402359..e9fc28b9b 100644 --- a/support/proxy/vwf.example.com/kinetic/drawing.js +++ b/support/proxy/vwf.example.com/kinetic/drawing.js @@ -21,15 +21,20 @@ this.clientWatch = function() { }; -this.isValid = function( obj ) { - var objType = ( {} ).toString.call( obj ).match( /\s([a-zA-Z]+)/ )[ 1 ].toLowerCase(); - return ( objType != 'null' && objType != 'undefined' ); -}; +// this.isValid = function( obj ) { +// var objType = ( {} ).toString.call( obj ).match( /\s([a-zA-Z]+)/ )[ 1 ].toLowerCase(); +// return ( objType != 'null' && objType != 'undefined' ); +// }; this.clientJoin = function( moniker ) { + function isValid( obj ) { + var objType = ( {} ).toString.call( obj ).match( /\s([a-zA-Z]+)/ )[ 1 ].toLowerCase(); + return ( objType != 'null' && objType != 'undefined' ); + }; + // mirrors the initial state of the toolbar - if ( !this.isValid( this.drawing_clients ) ) { + if ( !isValid( this.drawing_clients ) ) { this.drawing_clients = {}; } if ( this.drawing_clients[ moniker ] === undefined ) { @@ -77,10 +82,15 @@ this.setUpPrivate = function( moniker ) { this.setClientUIState = function( stateObj ) { + function isValid( obj ) { + var objType = ( {} ).toString.call( obj ).match( /\s([a-zA-Z]+)/ )[ 1 ].toLowerCase(); + return ( objType != 'null' && objType != 'undefined' ); + }; + //console.info( "setClientUIState " + JSON.stringify( stateObj ) ); if ( stateObj !== undefined ) { - if ( !this.isValid( this.drawing_clients ) || - !this.isValid( this.drawing_clients[ this.client ] ) ) { + if ( !isValid( this.drawing_clients ) || + !isValid( this.drawing_clients[ this.client ] ) ) { this.clientJoin( this.client ); } var clients = this.drawing_clients; @@ -94,12 +104,16 @@ this.setClientUIState = function( stateObj ) { this.down = function( eventData, nodeData, touch ) { - if ( !this.isValid( this.drawing_clients ) || - !this.isValid( this.drawing_clients[ this.client ] ) ) { + function isValid( obj ) { + var objType = ( {} ).toString.call( obj ).match( /\s([a-zA-Z]+)/ )[ 1 ].toLowerCase(); + return ( objType != 'null' && objType != 'undefined' ); + }; + if ( !isValid( this.drawing_clients ) || + !isValid( this.drawing_clients[ this.client ] ) ) { this.clientJoin( this.client ); } - if ( !this.isValid( this.drawing_private ) || - !this.isValid( this.drawing_private[ this.client ] ) ) { + if ( !isValid( this.drawing_private ) || + !isValid( this.drawing_private[ this.client ] ) ) { this.setUpPrivate( this.client ); } @@ -107,7 +121,7 @@ this.down = function( eventData, nodeData, touch ) { var privateState = this.drawing_private[ this.client ]; var drawingMode = userState.drawing_mode; - if ( privateState.drawingObject !== null ) { + if ( privateState.drawingObject !== null || drawingMode === 'none' ) { return; } @@ -274,8 +288,13 @@ this.down = function( eventData, nodeData, touch ) { this.move = function( eventData, nodeData, touch ) { - if ( !this.isValid( this.drawing_clients ) || - !this.isValid( this.drawing_clients[ this.client ] ) ) { + function isValid( obj ) { + var objType = ( {} ).toString.call( obj ).match( /\s([a-zA-Z]+)/ )[ 1 ].toLowerCase(); + return ( objType != 'null' && objType != 'undefined' ); + }; + + if ( !isValid( this.drawing_clients ) || + !isValid( this.drawing_clients[ this.client ] ) ) { this.clientJoin( this.client ); } if ( this.drawing_private === undefined || @@ -283,6 +302,11 @@ this.move = function( eventData, nodeData, touch ) { this.setUpPrivate( this.client ); } + var userState = this.drawing_clients[ this.client ]; + if ( userState.drawing_mode === 'none' ) { + return; + } + this.update( eventData, nodeData, false ); }; @@ -327,10 +351,15 @@ this.up = function( eventData, nodeData, touch ) { }; this.update = function( eventData, nodeData, upEvent ) { + + function isValid( obj ) { + var objType = ( {} ).toString.call( obj ).match( /\s([a-zA-Z]+)/ )[ 1 ].toLowerCase(); + return ( objType != 'null' && objType != 'undefined' ); + }; if ( this.drawing_private === undefined || this.drawing_private[ this.client ] === undefined || - !this.isValid( this.drawing_clients ) ) { + !isValid( this.drawing_clients ) ) { return; } diff --git a/support/proxy/vwf.example.com/kinetic/drawing.vwf.yaml b/support/proxy/vwf.example.com/kinetic/drawing.vwf.yaml index 5919fc277..da3de0afb 100644 --- a/support/proxy/vwf.example.com/kinetic/drawing.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/drawing.vwf.yaml @@ -14,7 +14,7 @@ methods: clientLeave: setUpPrivate: setClientUIState: - isValid: + #isValid: getStageRelativePoint: events: pointerDown: diff --git a/support/proxy/vwf.example.com/mil-sym/modifier.vwf.yaml b/support/proxy/vwf.example.com/mil-sym/modifier.vwf.yaml new file mode 100755 index 000000000..291852360 --- /dev/null +++ b/support/proxy/vwf.example.com/mil-sym/modifier.vwf.yaml @@ -0,0 +1,33 @@ +--- +extends: http://vwf.example.com/node.vwf +properties: + pixelSize: 35 + icon: true + keepUnitRatio: + symbologyStandard: + quantity: + additionalInfo1: + additionalInfo2: + additionalInfo3: + altitudeDepth: + combatEffectiveness: + directionOfMovement: + DTG1: + DTG2: + evaluationRating: + higherFormation: + hostile: + iffSif: + location: + reinforcedReduced: + signatureEquip: + staffComments: + equipType: + uniqueDesignation1: + uniqueDesignation2: + speed: + validModifiers: +scripts: +- | + this.initialize = function() { + } //@ sourceURL=modifier.vwf \ No newline at end of file diff --git a/support/proxy/vwf.example.com/mil-sym/unit.js b/support/proxy/vwf.example.com/mil-sym/unit.js new file mode 100755 index 000000000..689c02e07 --- /dev/null +++ b/support/proxy/vwf.example.com/mil-sym/unit.js @@ -0,0 +1,13 @@ +this.initialize = function() { + this.future( 0.3 ).render(); +} + +// the driver will be handling this function +//this.render = function() {} + +this.handleRender = function( img, iconSize, symbolCenter, symbolBounds ){ + if ( this.parent !== undefined ) { + this.parent.handleRender( img, iconSize, symbolCenter, symbolBounds ); + } +} +//@ sourceURL=unit.js \ No newline at end of file diff --git a/support/proxy/vwf.example.com/mil-sym/unit.vwf.yaml b/support/proxy/vwf.example.com/mil-sym/unit.vwf.yaml new file mode 100755 index 000000000..e68f4a202 --- /dev/null +++ b/support/proxy/vwf.example.com/mil-sym/unit.vwf.yaml @@ -0,0 +1,51 @@ +--- +extends: http://vwf.example.com/node2.vwf +properties: + + echelon: + set: | + if ( this.echelon !== value ) { + this.echelon = value; + this.echelonChanged( value ); + } + + affiliation: + set: | + if ( this.affiliation !== value ) { + this.affiliation = value; + this.affiliationChanged( value ); + } + + fullName: + + tagName: + + description: + + symbolID: + set: | + if ( this.symbolID !== value ) { + this.symbolID = value; + this.symbolIDChanged( value ); + } + + image: + +methods: + + render: + + handleRender: + +events: + + imageRendered: + + echelonChanged: + + affiliationChanged: + + symbolIDChanged: + +scripts: +- source: "unit.js" \ No newline at end of file diff --git a/support/proxy/vwf.example.com/mil-sym/unitGroup.js b/support/proxy/vwf.example.com/mil-sym/unitGroup.js new file mode 100755 index 000000000..5e682c424 --- /dev/null +++ b/support/proxy/vwf.example.com/mil-sym/unitGroup.js @@ -0,0 +1,159 @@ +this.initialize = function() { + + if ( this.icon !== undefined && this.icon.imageGenerator !== undefined ) { + + this.icon.imageGenerator.affiliationChanged = this.events.add( function( affiliation ) { + + if ( this.threatArea ) { + switch ( affiliation ) { + case "hostile": + this.threatArea.fill = 'red'; + break; + case "neutral": + this.threatArea.fill = 'lime'; + break; + case "friendly": + this.threatArea.fill = 'lightblue'; + break; + default: + this.threatArea.fill = 'yellow'; + break; + } + } + + }, this ); + + this.icon.imageGenerator.imageRendered = this.events.add( function( img, iconSize, symbolCenter, symbolBounds ) { + + if ( this.threatArea ) { + this.threatArea.position = this.icon.symbolCenter; + } + if ( this.border ) { + this.border.points = [ + 0, 0, + iconSize.width, 0, + iconSize.width, iconSize.height, + 0, iconSize.height, + 0, 0 + ]; + } + + }, this ); + } + +} + +this.handleRender = function( img, iconSize, symbolCenter, symbolBounds ){ + + if ( this.threatArea ) { + this.threatArea.position = this.icon.symbolCenter; + } + + if ( this.border ) { + this.border.points = [ + 0, 0, + iconSize.width, 0, + iconSize.width, iconSize.height, + 0, iconSize.height, + 0, 0 + ]; + } + +} + +this.updateThreatShape = function() { + + var visible = false; + if ( this.threatArea ) { + visible = this.threatArea.visible; + this.children.delete( this.threatArea ); + } + + var newShape = undefined; + var color = 'yellow'; + + if ( this.icon && this.icon.imageGenerator ) { + switch ( this.icon.imageGenerator.affiliation ) { + case "hostile": + color = 'red'; + break; + case "neutral": + color = 'lime'; + break; + case "friendly": + color = 'lightblue'; + break; + }; + } + + switch ( this.threatShape ) { + + case "rect": + newShape = { + "extends": "http://vwf.example.com/kinetic/rect.vwf", + "properties": { + "x": 20, + "y": 20, + "visible": visible, + "width": 40, + "height": 40, + "opacity": 0.3, + "fill": color, + "fillEnabled": true, + "draggable": false, + "zIndex": 2 + } + }; + break; + + case "circle": + newShape = { + "extends": "http://vwf.example.com/kinetic/circle.vwf", + "properties": { + "x": 16, + "y": 16, + "visible": visible, + "radius": 32, + "opacity": 0.3, + "fill": color, + "fillEnabled": true, + "draggable": false, + "zIndex": 2 + } + }; + break; + + case "wedge": + newShape = { + "extends": "http://vwf.example.com/kinetic/wedge.vwf", + "properties": { + "x": 16, + "y": 16, + "visible": visible, + "width": 40, + "height": 40, + "angle": 40, + "radius": 32, + "opacity": 0.3, + "fill": color, + "fillEnabled": true, + "draggable": false, + "zIndex": 2 + } + }; + break; + + default: + this.logger.info( "Unknown threat shape: " + this.threatShape ); + break; + + } + + if ( newShape ) { + this.children.create( "threatArea", newShape ); + this.threatShapeChanged( this.threatShape ); + } + +} + +//@ sourceURL=unitGroup.js \ No newline at end of file diff --git a/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml b/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml new file mode 100755 index 000000000..51f5e0eb6 --- /dev/null +++ b/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml @@ -0,0 +1,61 @@ +--- +extends: http://vwf.example.com/kinetic/group.vwf +properties: + + mapPosition: + set: | + if ( value !== undefined ) { + this.mapPosition = value; + if ( this.icon && this.icon.symbolCenter ) { + this.position = { + "x": this.mapPosition.x - this.icon.symbolCenter.x, + "y": this.mapPosition.y - this.icon.symbolCenter.y + }; + } else { + this.position = value; + } + } + value: { "x": 0, "y": 0 } + + threatShape: + set: | + if ( this.threatShape !== value ) { + this.threatShape = value; + this.updateThreatShape(); + } + value: "circle" + + showThreat: + set: | + if ( this.threatArea !== undefined ) { + this.threatArea.visible = value; + } + get: | + if ( this.threatArea !== undefined ) { + return this.threatArea.visible; + } + return false; + value: false + + showBorder: + set: | + if ( this.border !== undefined ) { + this.border.visible = value; + } + get: | + if ( this.border !== undefined ) { + return this.border.visible; + } + return false; + value: false + +methods: + updateThreatShape: + + handleRender: + +events: + threatShapeChanged: + +scripts: +- source: "unitGroup.js" diff --git a/support/proxy/vwf.example.com/mil-sym/unitIcon.js b/support/proxy/vwf.example.com/mil-sym/unitIcon.js new file mode 100755 index 000000000..39dd30488 --- /dev/null +++ b/support/proxy/vwf.example.com/mil-sym/unitIcon.js @@ -0,0 +1,37 @@ +this.initialize = function() { + + if ( this.imageGenerator !== undefined ) { + this.imageGenerator.imageRendered = this.events.add( function( img, iconSize, symbolCenter, symbolBounds ) { + + var mp = this.parent.mapPosition; + + this.image = img; + this.size = iconSize; + this.width = iconSize.width; + this.height = iconSize.height; + this.symbolCenter = symbolCenter; + + this.parent.mapPosition = mp; + + }, this ); + } + +} + +this.handleRender = function( img, iconSize, symbolCenter, symbolBounds ){ + + var mp = this.parent.mapPosition; + + this.image = img; + this.size = iconSize; + this.width = iconSize.width; + this.height = iconSize.height; + this.symbolCenter = symbolCenter; + + this.parent.mapPosition = mp; + + if ( this.parent !== undefined ) { + this.parent.handleRender( img, iconSize, symbolCenter, symbolBounds ); + } +} +//@ sourceURL=unitIcon.js \ No newline at end of file diff --git a/support/proxy/vwf.example.com/mil-sym/unitIcon.vwf.yaml b/support/proxy/vwf.example.com/mil-sym/unitIcon.vwf.yaml new file mode 100755 index 000000000..001ce9a20 --- /dev/null +++ b/support/proxy/vwf.example.com/mil-sym/unitIcon.vwf.yaml @@ -0,0 +1,41 @@ +--- +extends: http://vwf.example.com/kinetic/image.vwf +properties: + + image: + set: | + if ( value !== undefined ) { + this.image = value; + this.imageChanged( value ); + } + + iconSize: + set: | + if ( value !== undefined ) { + this.iconSize = value; + this.iconSizeChanged( value ); + } + value: { "width": 32, "height": 32 } + + symbolCenter: + set: | + if ( value !== undefined ) { + this.symbolCenter = value; + this.symbolCenterChanged( value ); + } + value: { "x": 16, "y": 16 } + +events: + + imageChanged: + + iconSizeChanged: + + symbolCenterChanged: + +methods: + + handleRender: + +scripts: +- source: "unitIcon.js" From 47b5cc2a8002e19df2e2fa06c2efbaddfb67c081 Mon Sep 17 00:00:00 2001 From: Scott Haynes Date: Mon, 6 Apr 2015 16:56:50 -0400 Subject: [PATCH 003/644] Updates to match moving the mil-sym components --- support/client/lib/vwf/model/mil-sym.js | 26 +++++++++++++++---------- support/client/lib/vwf/view/mil-sym.js | 4 ++++ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/support/client/lib/vwf/model/mil-sym.js b/support/client/lib/vwf/model/mil-sym.js index f30941d0e..9e139303f 100644 --- a/support/client/lib/vwf/model/mil-sym.js +++ b/support/client/lib/vwf/model/mil-sym.js @@ -24,7 +24,7 @@ define( [ "module", "jquery" ], function( module, model, utility, Color, cws, $ ) { - var self; + var modelDriver; return model.load( module, { @@ -34,7 +34,7 @@ define( [ "module", initialize: function( options ) { - self = this; + modelDriver = this; this.arguments = Array.prototype.slice.call( arguments ); @@ -58,7 +58,6 @@ define( [ "module", } }; - // turns on logger debugger console messages this.debug = { "creation": false, @@ -109,6 +108,7 @@ define( [ "module", var protos = getPrototypes( childExtendsID ); var node = this.state.nodes[ childID ]; + if ( node === undefined ) { if ( isUnitNode( protos ) ) { @@ -430,7 +430,7 @@ define( [ "module", while ( id !== undefined ) { prototypes.push( id ); - id = self.kernel.prototype( id ); + id = modelDriver.kernel.prototype( id ); } return prototypes; @@ -440,7 +440,7 @@ define( [ "module", var found = false; if ( prototypes ) { for ( var i = 0; i < prototypes.length && !found; i++ ) { - found = ( prototypes[i] == "unit.vwf" ); + found = ( prototypes[i] == "http://vwf.example.com/mil-sym/unit.vwf" ); } } return found; @@ -450,7 +450,7 @@ define( [ "module", var found = false; if ( prototypes ) { for ( var i = 0; i < prototypes.length && !found; i++ ) { - found = ( prototypes[i] == "modifier.vwf" ); + found = ( prototypes[i] == "http://vwf.example.com/mil-sym/modifier.vwf" ); } } return found; @@ -459,6 +459,11 @@ define( [ "module", function render( node ) { + + if ( node === undefined ) { + return; + } + var value = undefined; if ( node !== undefined && node.nodeType === "unit" && node.symbolID !== undefined ) { @@ -475,9 +480,9 @@ define( [ "module", // getting the events to replicate, this should be switched // back to the event when the replication is fixed. handleRender // can then be completely removed - //self.kernel.fireEvent( node.ID, "imageRendered", [ node.image, imgSize, centerPt, symbolBounds ] ); + //modelDriver.kernel.fireEvent( node.ID, "imageRendered", [ node.image, imgSize, centerPt, symbolBounds ] ); - self.kernel.callMethod( node.ID, "handleRender", [ node.image, imgSize, centerPt, symbolBounds ] ); + modelDriver.kernel.callMethod( node.ID, "handleRender", [ node.image, imgSize, centerPt, symbolBounds ] ); } @@ -505,7 +510,7 @@ define( [ "module", break; default: - self.logger.errorx( "setModifier", "Unknown type (", modObj.type, ") specified." ); + modelDriver.logger.errorx( "setModifier", "Unknown type (", modObj.type, ") specified." ); return modifierSet; } @@ -558,7 +563,7 @@ define( [ "module", break; default: - self.logger.errorx( "getModifier", "Unknown type (", modObj.type, ") specified." ); + modelDriver.logger.errorx( "getModifier", "Unknown type (", modObj.type, ") specified." ); return value; } @@ -567,5 +572,6 @@ define( [ "module", return value; } + } ); diff --git a/support/client/lib/vwf/view/mil-sym.js b/support/client/lib/vwf/view/mil-sym.js index 5454f60c0..69d2298ed 100644 --- a/support/client/lib/vwf/view/mil-sym.js +++ b/support/client/lib/vwf/view/mil-sym.js @@ -96,15 +96,19 @@ define( [ "module", "vwf/view", "mil-sym/cws" ], function( module, view, cws ) { // -- calledMethod ----------------------------------------------------------------------------- calledMethod: function( nodeID, methodName, methodParameters, methodValue ) { + + //console.info( nodeID + " " + methodName ); if ( nodeID === this.kernel.application() ) { var clientThatCalledMethod = this.kernel.client(); var me = this.kernel.moniker(); switch ( methodName ) { + case "insertUnits": if ( clientThatCalledMethod === me ) { addInsertableUnits( methodParameters[ 0 ] ); } break; + case "getUnitSymbol": if ( clientThatCalledMethod === me ) { getUnitSymbol( methodParameters[ 0 ], methodParameters[ 1 ], methodParameters[ 2 ], methodParameters[ 3 ], methodParameters[ 4 ], methodParameters[ 5 ] ); From 27dbae6f5086dbae093934aff3b3b625d4765d58 Mon Sep 17 00:00:00 2001 From: youngca Date: Wed, 8 Apr 2015 13:32:49 -0400 Subject: [PATCH 004/644] Add an unknown unit symbol type to mil-sym. --- support/client/lib/mil-sym/cws.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/support/client/lib/mil-sym/cws.js b/support/client/lib/mil-sym/cws.js index 14a14ba1e..4802f3255 100644 --- a/support/client/lib/mil-sym/cws.js +++ b/support/client/lib/mil-sym/cws.js @@ -1194,6 +1194,14 @@ define( function(){ "ZOR": "ZONE OF RESPONSIBILITY (ZOR)" }, + "unk": { + + "WAR.UNK": { + "symbolID": "SUZP------*****", + "tag": "UNK" + } + }, + "space": { "WAR.SPC": { From 05e9b77d1bfe01280268adccfa66d49d2bcb50e7 Mon Sep 17 00:00:00 2001 From: youngca Date: Tue, 21 Apr 2015 15:11:17 -0400 Subject: [PATCH 005/644] Use property settings to attach mouse and touch events. For each kinetic object class, add properties of supportMouseEvents and supportTouchEvents. If these properties are true, then when the object is created and initialized, the mouse and/or touch events will be added. --- support/client/lib/vwf/view/kineticjs.js | 241 ++++++++++-------- .../kinetic/container.vwf.yaml | 2 + .../kinetic/drawingGroup.vwf.yaml | 5 +- .../kinetic/fastLayer.vwf.yaml | 2 + .../vwf.example.com/kinetic/group.vwf.yaml | 5 +- .../vwf.example.com/kinetic/layer.vwf.yaml | 2 + .../vwf.example.com/kinetic/line.vwf.yaml | 2 + .../vwf.example.com/kinetic/node.vwf.yaml | 2 + .../vwf.example.com/kinetic/shape.vwf.yaml | 4 +- .../vwf.example.com/kinetic/stage.vwf.yaml | 2 + .../mil-sym/unitGroup.vwf.yaml | 2 + 11 files changed, 165 insertions(+), 104 deletions(-) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index c6aab4bdf..5feacb696 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -100,6 +100,102 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], return vwfEventData; } + function attachMouseEvents( node ) { + + var mouseDown = false; + + node.kineticObj.on( "mousemove", function( evt ) { + var eData = processEvent( evt, node, false ); + self.kernel.fireEvent( node.ID, 'pointerMove', eData.eventData ); + } ); + + node.kineticObj.on( "mouseout", function( evt ) { + var eData = processEvent( evt, node, false ); + self.kernel.fireEvent( node.ID, 'pointerOut', eData.eventData ); + } ); + + node.kineticObj.on( "mouseenter", function( evt ) { + var eData = processEvent( evt, node, false ); + self.kernel.fireEvent( node.ID, 'pointerEnter', eData.eventData ); + } ); + + node.kineticObj.on( "mouseleave", function( evt ) { + var eData = processEvent( evt, node, false ); + self.kernel.fireEvent( node.ID, 'pointerLeave', eData.eventData ); + } ); + + node.kineticObj.on( "mousedown", function( evt ) { + var eData = processEvent( evt, node, false ); + mouseDown = true; + self.kernel.fireEvent( node.ID, 'pointerDown', eData.eventData ); + } ); + + node.kineticObj.on( "mouseup", function( evt ) { + var eData = processEvent( evt, node, false ); + mouseDown = false; + self.kernel.fireEvent( node.ID, 'pointerUp', eData.eventData ); + if ( node.kineticObj.mouseDragging ) { + self.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); + node.kineticObj.mouseDragging = false; + } + } ); + + node.kineticObj.on( "click", function( evt ) { + var eData = processEvent( evt, node, false ); + self.kernel.fireEvent( node.ID, 'pointerClick', eData.eventData ); + } ); + + node.kineticObj.on( "dblclick", function( evt ) { + var eData = processEvent( evt, node, false ); + self.kernel.fireEvent( node.ID, 'pointerDoubleClick', eData.eventData ); + } ); + + node.kineticObj.on( "dragstart", function( evt ) { + var eData = processEvent( evt, node, false ); + self.kernel.fireEvent( node.ID, 'dragStart', eData.eventData ); + node.kineticObj.mouseDragging = true; + } ); + + node.kineticObj.on( "dragmove", function( evt ) { + var eData = processEvent( evt, node, false ); + self.kernel.fireEvent( node.ID, 'dragMove', eData.eventData ); + } ); + + } + + function attachTouchEvents( node ) { + + var TOUCH_EVENT = true; + + node.kineticObj.on( "touchstart", function( evt ) { + var eData = processEvent( evt, node, false ); + self.kernel.fireEvent( node.ID, 'touchStart', eData.eventData ); + } ); + + node.kineticObj.on( "touchmove", function( evt ) { + var eData = processEvent( evt, node, false ); + self.kernel.fireEvent( node.ID, 'touchMove', eData.eventData ); + } ); + + node.kineticObj.on( "touchend", function( evt ) { + var eData = processEvent( evt, node, false ); + self.kernel.fireEvent( node.ID, 'touchEnd', eData.eventData ); + } ); + + node.kineticObj.on( "tap", function( evt ) { + var eData = processEvent( evt, node, false ); + self.kernel.fireEvent( node.ID, 'tap', eData.eventData ); + } ); + + node.kineticObj.on( "dbltap", function( evt ) { + var eData = processEvent( evt, node, false ); + self.kernel.fireEvent( node.ID, 'doubleTap', eData.eventData ); + } ); + + } + + + return view.load( module, { initialize: function( options ) { @@ -156,107 +252,11 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], return; } - if ( node.kineticObj ) { - - var mouseDown = false; - - var TOUCH_EVENT = true; - - node.kineticObj.on( "mousemove", function( evt ) { - var eData = processEvent( evt, node, false ); - //self.kernel.dispatchEvent( node.ID, 'pointerMove', eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'pointerMove', eData.eventData ); - } ); - - node.kineticObj.on( "mouseout", function( evt ) { - var eData = processEvent( evt, node, false ); - self.kernel.fireEvent( node.ID, 'pointerOut', eData.eventData ); - } ); - - node.kineticObj.on( "mouseenter", function( evt ) { - var eData = processEvent( evt, node, false ); - //self.kernel.dispatchEvent( node.ID, 'pointerEnter', eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'pointerEnter', eData.eventData ); - } ); - - node.kineticObj.on( "mouseleave", function( evt ) { - var eData = processEvent( evt, node, false ); - // self.kernel.dispatchEvent( node.ID, 'pointerLeave', eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'pointerLeave', eData.eventData ); - } ); - - node.kineticObj.on( "mousedown", function( evt ) { - var eData = processEvent( evt, node, false ); - mouseDown = true; - //self.kernel.dispatchEvent( node.ID, 'pointerDown', eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'pointerDown', eData.eventData ); - } ); - - node.kineticObj.on( "mouseup", function( evt ) { - var eData = processEvent( evt, node, false ); - mouseDown = false; - //self.kernel.dispatchEvent( node.ID, 'pointerUp', eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'pointerUp', eData.eventData ); - if ( node.kineticObj.mouseDragging ) { - self.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); - node.kineticObj.mouseDragging = false; - } - } ); - - node.kineticObj.on( "click", function( evt ) { - var eData = processEvent( evt, node, false ); - //self.kernel.dispatchEvent( node.ID, 'pointerClick', eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'pointerClick', eData.eventData ); - } ); - - node.kineticObj.on( "dblclick", function( evt ) { - var eData = processEvent( evt, node, false ); - //self.kernel.dispatchEvent( node.ID, 'pointerDoubleClick', eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'pointerDoubleClick', eData.eventData ); - } ); - - node.kineticObj.on( "touchstart", function( evt ) { - var eData = processEvent( evt, node, false ); - //self.kernel.dispatchEvent( node.ID, "touchStart", eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'touchStart', eData.eventData ); - } ); - - node.kineticObj.on( "touchmove", function( evt ) { - var eData = processEvent( evt, node, false ); - //self.kernel.dispatchEvent( node.ID, "touchMove", eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'touchMove', eData.eventData ); - } ); - - node.kineticObj.on( "touchend", function( evt ) { - var eData = processEvent( evt, node, false ); - //self.kernel.dispatchEvent( node.ID, "touchEnd", eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'touchEnd', eData.eventData ); - } ); - - node.kineticObj.on( "tap", function( evt ) { - var eData = processEvent( evt, node, false ); - //self.kernel.dispatchEvent( node.ID, "tap", eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'tap', eData.eventData ); - } ); - - node.kineticObj.on( "dbltap", function( evt ) { - var eData = processEvent( evt, node, false ); - //self.kernel.dispatchEvent( node.ID, "dragStart", eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'doubleTap', eData.eventData ); - } ); - - node.kineticObj.on( "dragstart", function( evt ) { - var eData = processEvent( evt, node, false ); - //self.kernel.dispatchEvent( node.ID, "dragStart", eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'dragStart', eData.eventData ); - node.kineticObj.mouseDragging = true; - } ); - - node.kineticObj.on( "dragmove", function( evt ) { - var eData = processEvent( evt, node, false ); - //self.kernel.dispatchEvent( node.ID, "dragMove", eData.eventData, eData.eventNodeData ); - self.kernel.fireEvent( node.ID, 'dragMove', eData.eventData ); - } ); + if ( node.kineticObj ) { + + // Attach the mouse and/or touch events based on property settings + vwf_view.kernel.getProperty( childID, "supportMouseEvents" ); + vwf_view.kernel.getProperty( childID, "supportTouchEvents" ); // I couldn't get this to work, so instead I keep track of mouseDragging separately // in dragstart and mouseup (Eric - 11/18/14) @@ -305,6 +305,18 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var kineticObj = node.kineticObj; switch ( propertyName ) { + case "supportMouseEvents": + if ( propertyValue === true ) { + attachMouseEvents( node ); + } + break; + + case "supportTouchEvents": + if ( propertyValue === true ) { + attachTouchEvents( node ); + } + break; + case "enableEvents": var mouseDown = false; var touch = false; @@ -397,6 +409,33 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], }, + gotProperty: function( nodeID, propertyName, propertyValue ) { + + var node = this.state.nodes[ nodeID ]; + + // If we don't have a record of this node, it is not a kinetic node, and we ignore it + if ( !( node && node.kineticObj ) ) { + return; + } + + switch ( propertyName ) { + case "supportMouseEvents": + if ( propertyValue === true ) { + attachMouseEvents( node ); + } + break; + + case "supportTouchEvents": + if ( propertyValue === true ) { + attachTouchEvents( node ); + } + break; + + default: + break; + } + }, + firedEvent: function( nodeID, eventName ) { if ( eventName == "draggingFromView" ) { var clientThatSatProperty = self.kernel.client(); diff --git a/support/proxy/vwf.example.com/kinetic/container.vwf.yaml b/support/proxy/vwf.example.com/kinetic/container.vwf.yaml index 7d3faf4b9..346e5f65e 100644 --- a/support/proxy/vwf.example.com/kinetic/container.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/container.vwf.yaml @@ -4,6 +4,8 @@ extends: http://vwf.example.com/kinetic/node.vwf properties: clipFunc: + supportMouseEvents: false + supportTouchEvents: false method: deleteChildNode: scripts: diff --git a/support/proxy/vwf.example.com/kinetic/drawingGroup.vwf.yaml b/support/proxy/vwf.example.com/kinetic/drawingGroup.vwf.yaml index 0c0d31322..f71bc8fe4 100644 --- a/support/proxy/vwf.example.com/kinetic/drawingGroup.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/drawingGroup.vwf.yaml @@ -1,4 +1,7 @@ # http://kineticjs.com/docs/Kinetic.Group.html --- -extends: http://vwf.example.com/kinetic/group.vwf \ No newline at end of file +extends: http://vwf.example.com/kinetic/group.vwf +properties: + supportMouseEvents: false + supportTouchEvents: false diff --git a/support/proxy/vwf.example.com/kinetic/fastLayer.vwf.yaml b/support/proxy/vwf.example.com/kinetic/fastLayer.vwf.yaml index e0e54ad73..276bfcd80 100644 --- a/support/proxy/vwf.example.com/kinetic/fastLayer.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/fastLayer.vwf.yaml @@ -4,3 +4,5 @@ extends: http://vwf.example.com/kinetic/container.vwf properties: clearBeforeDraw: + supportMouseEvents: false + supportTouchEvents: false diff --git a/support/proxy/vwf.example.com/kinetic/group.vwf.yaml b/support/proxy/vwf.example.com/kinetic/group.vwf.yaml index 27847bf7b..e0af7f460 100644 --- a/support/proxy/vwf.example.com/kinetic/group.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/group.vwf.yaml @@ -1,4 +1,7 @@ # http://kineticjs.com/docs/Kinetic.Group.html --- -extends: http://vwf.example.com/kinetic/container.vwf \ No newline at end of file +extends: http://vwf.example.com/kinetic/container.vwf +properties: + supportMouseEvents: false + supportTouchEvents: false diff --git a/support/proxy/vwf.example.com/kinetic/layer.vwf.yaml b/support/proxy/vwf.example.com/kinetic/layer.vwf.yaml index 19a8bd98c..fe0484536 100644 --- a/support/proxy/vwf.example.com/kinetic/layer.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/layer.vwf.yaml @@ -4,3 +4,5 @@ extends: http://vwf.example.com/kinetic/container.vwf properties: clearBeforeDraw: + supportMouseEvents: false + supportTouchEvents: false diff --git a/support/proxy/vwf.example.com/kinetic/line.vwf.yaml b/support/proxy/vwf.example.com/kinetic/line.vwf.yaml index 585ed9ddb..736da89a9 100644 --- a/support/proxy/vwf.example.com/kinetic/line.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/line.vwf.yaml @@ -8,3 +8,5 @@ properties: closed: false stroke: "#000000" strokeWidth: 1 + supportMouseEvents: true + supportTouchEvents: true diff --git a/support/proxy/vwf.example.com/kinetic/node.vwf.yaml b/support/proxy/vwf.example.com/kinetic/node.vwf.yaml index 80cf9dde9..53a6688c4 100644 --- a/support/proxy/vwf.example.com/kinetic/node.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/node.vwf.yaml @@ -31,6 +31,8 @@ properties: absoluteOpacity: absoluteZIndex: uniqueInView: + supportMouseEvents: + supportTouchEvents: dragProperty: "position" methods: toggleVisibility: diff --git a/support/proxy/vwf.example.com/kinetic/shape.vwf.yaml b/support/proxy/vwf.example.com/kinetic/shape.vwf.yaml index 1c500544f..e7ed88303 100644 --- a/support/proxy/vwf.example.com/kinetic/shape.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/shape.vwf.yaml @@ -61,4 +61,6 @@ properties: dash: dashEnabled: x: 0 - y: 0 \ No newline at end of file + y: 0 + supportMouseEvents: true + supportTouchEvents: true diff --git a/support/proxy/vwf.example.com/kinetic/stage.vwf.yaml b/support/proxy/vwf.example.com/kinetic/stage.vwf.yaml index cb57aac51..4a8f4f640 100644 --- a/support/proxy/vwf.example.com/kinetic/stage.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/stage.vwf.yaml @@ -4,6 +4,8 @@ extends: http://vwf.example.com/kinetic/container.vwf properties: container: + supportMouseEvents: true + supportTouchEvents: true enableEvents: events: pointerDown: diff --git a/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml b/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml index 51f5e0eb6..47b8c2741 100755 --- a/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml +++ b/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml @@ -1,6 +1,8 @@ --- extends: http://vwf.example.com/kinetic/group.vwf properties: + supportMouseEvents: true + supportTouchEvents: true mapPosition: set: | From d9ce196d778d2ce627315ac000fee5446f6f0b6b Mon Sep 17 00:00:00 2001 From: youngca Date: Tue, 21 Apr 2015 15:44:09 -0400 Subject: [PATCH 006/644] Double check to ensure the mouse and touch events are only added once per object. --- support/client/lib/vwf/view/kineticjs.js | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 5feacb696..932da460c 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -258,14 +258,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], vwf_view.kernel.getProperty( childID, "supportMouseEvents" ); vwf_view.kernel.getProperty( childID, "supportTouchEvents" ); - // I couldn't get this to work, so instead I keep track of mouseDragging separately - // in dragstart and mouseup (Eric - 11/18/14) - // node.kineticObj.on( "dragend", function( evt ) { - // var eData = processEvent( evt, node, false ); - // //self.kernel.dispatchEvent( node.ID, "dragEnd", eData.eventData, eData.eventNodeData ); - // self.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); - // } ); - } }, @@ -412,28 +404,35 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], gotProperty: function( nodeID, propertyName, propertyValue ) { var node = this.state.nodes[ nodeID ]; + var returnVal = false; // If we don't have a record of this node, it is not a kinetic node, and we ignore it if ( !( node && node.kineticObj ) ) { - return; + return returnVal; } switch ( propertyName ) { case "supportMouseEvents": - if ( propertyValue === true ) { + if ( ( propertyValue === true ) && ( node.mouseEventsAdded === undefined ) ) { attachMouseEvents( node ); + node.mouseEventsAdded = true; + returnVal = node.mouseEventsAdded; } break; case "supportTouchEvents": - if ( propertyValue === true ) { + if ( ( propertyValue === true ) && ( node.touchEventsAdded === undefined ) ) { attachTouchEvents( node ); + node.touchEventsAdded = true; + returnVal = node.touchEventsAdded; } break; default: break; - } + } + + return returnVal; }, firedEvent: function( nodeID, eventName ) { From 07fda3ce87c58146099ad4902cd4a147448ef0c8 Mon Sep 17 00:00:00 2001 From: youngca Date: Tue, 21 Apr 2015 15:45:51 -0400 Subject: [PATCH 007/644] Rename the return variable to something more obvious. --- support/client/lib/vwf/view/kineticjs.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 932da460c..6b64a403d 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -404,11 +404,11 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], gotProperty: function( nodeID, propertyName, propertyValue ) { var node = this.state.nodes[ nodeID ]; - var returnVal = false; + var eventsAdded = false; // If we don't have a record of this node, it is not a kinetic node, and we ignore it if ( !( node && node.kineticObj ) ) { - return returnVal; + return eventsAdded; } switch ( propertyName ) { @@ -416,7 +416,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], if ( ( propertyValue === true ) && ( node.mouseEventsAdded === undefined ) ) { attachMouseEvents( node ); node.mouseEventsAdded = true; - returnVal = node.mouseEventsAdded; + eventsAdded = node.mouseEventsAdded; } break; @@ -424,7 +424,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], if ( ( propertyValue === true ) && ( node.touchEventsAdded === undefined ) ) { attachTouchEvents( node ); node.touchEventsAdded = true; - returnVal = node.touchEventsAdded; + eventsAdded = node.touchEventsAdded; } break; @@ -432,7 +432,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], break; } - return returnVal; + return eventsAdded; }, firedEvent: function( nodeID, eventName ) { From 45b217b7650381e600ff9f8d20ae0fd9f8630510 Mon Sep 17 00:00:00 2001 From: youngca Date: Wed, 22 Apr 2015 09:54:21 -0400 Subject: [PATCH 008/644] Propagate the status of attached mouse and touch events in kinetic nodes. Add a property to the kinetic node, set it to false in the model and update it in the view when the events are attached. --- support/client/lib/vwf/model/kineticjs.js | 4 +++- support/client/lib/vwf/view/kineticjs.js | 12 ++++++------ support/proxy/vwf.example.com/kinetic/node.vwf.yaml | 2 ++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index dd7f3bdaf..f83abf892 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -39,7 +39,9 @@ define( [ "module", "prototypes": undefined, "kineticObj": undefined, "stage": undefined, - "uniqueInView": false + "uniqueInView": false, + "hasMouseEvents": false, + "hasTouchEvents": false }; }, isKineticClass: function( prototypes, classID ) { diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 6b64a403d..30dfb4b4f 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -413,18 +413,18 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], switch ( propertyName ) { case "supportMouseEvents": - if ( ( propertyValue === true ) && ( node.mouseEventsAdded === undefined ) ) { + if ( ( propertyValue === true ) && ( !node.hasMouseEvents ) ) { attachMouseEvents( node ); - node.mouseEventsAdded = true; - eventsAdded = node.mouseEventsAdded; + node.hasMouseEvents = true; + eventsAdded = node.hasMouseEvents; } break; case "supportTouchEvents": - if ( ( propertyValue === true ) && ( node.touchEventsAdded === undefined ) ) { + if ( ( propertyValue === true ) && ( !node.hasTouchEvents ) ) { attachTouchEvents( node ); - node.touchEventsAdded = true; - eventsAdded = node.touchEventsAdded; + node.hasMouseEvents = true; + eventsAdded = node.hasMouseEvents; } break; diff --git a/support/proxy/vwf.example.com/kinetic/node.vwf.yaml b/support/proxy/vwf.example.com/kinetic/node.vwf.yaml index 53a6688c4..809ef60af 100644 --- a/support/proxy/vwf.example.com/kinetic/node.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/node.vwf.yaml @@ -33,6 +33,8 @@ properties: uniqueInView: supportMouseEvents: supportTouchEvents: + hasMouseEvents: false + hasTouchEvents: false dragProperty: "position" methods: toggleVisibility: From ce8e3f1175e0c7a074ff3ef4f523f553495b10b1 Mon Sep 17 00:00:00 2001 From: youngca Date: Fri, 24 Apr 2015 16:07:49 -0400 Subject: [PATCH 009/644] Mouse and touch event addition only when needed per class. Turn off listening by default - object will not listen to mouse and touch events until listening is turned on. Register when mouse and touch events have been added to the object. Also, mil-sym symbols support roles in creation requests. --- support/client/lib/vwf/model/kineticjs.js | 8 +++++++ support/client/lib/vwf/view/kineticjs.js | 4 ++-- support/client/lib/vwf/view/mil-sym.js | 6 ++++- .../kinetic/baseLayer.vwf.yaml | 4 ++++ .../proxy/vwf.example.com/kinetic/drawing.js | 5 +++++ .../kinetic/fastLayer.vwf.yaml | 2 ++ .../vwf.example.com/kinetic/layer.vwf.yaml | 2 ++ support/proxy/vwf.example.com/kinetic/node.js | 22 +++++++++++++++++++ .../vwf.example.com/kinetic/node.vwf.yaml | 2 ++ .../vwf.example.com/mil-sym/unitGroup.js | 3 +++ 10 files changed, 55 insertions(+), 3 deletions(-) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index f83abf892..8088f51bd 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -885,6 +885,10 @@ define( [ "module", kineticObj.clearBeforeDraw( Boolean( propertyValue ) ); break; + case "hitGraphEnabled": + kineticObj.hitGraphEnabled( Boolean(propertyValue) ); + break; + default: value = undefined; break; @@ -1362,6 +1366,10 @@ define( [ "module", value = kineticObj.listening(); break; + case "isListening": + value = kineticObj.isListening(); + break; + case "opacity": value = kineticObj.opacity(); break; diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 30dfb4b4f..68dddbb55 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -423,8 +423,8 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], case "supportTouchEvents": if ( ( propertyValue === true ) && ( !node.hasTouchEvents ) ) { attachTouchEvents( node ); - node.hasMouseEvents = true; - eventsAdded = node.hasMouseEvents; + node.hasTouchEvents = true; + eventsAdded = node.hasTouchEvents; } break; diff --git a/support/client/lib/vwf/view/mil-sym.js b/support/client/lib/vwf/view/mil-sym.js index 69d2298ed..453eb012e 100644 --- a/support/client/lib/vwf/view/mil-sym.js +++ b/support/client/lib/vwf/view/mil-sym.js @@ -300,7 +300,11 @@ define( [ "module", "vwf/view", "mil-sym/cws" ], function( module, view, cws ) { switch ( options.request ) { case "addQuickUnit": unitEvent = "quickUnitAdded"; - self.kernel.fireEvent( appID, unitEvent, [ options.unitID, updatedUnit ] ); + if ( options.role ) { + self.kernel.fireEvent( appID, unitEvent, [ options.role, options.unitID, updatedUnit ] ); + } else { + self.kernel.fireEvent( appID, unitEvent, [ '', options.unitID, updatedUnit ] ); + } break; case "addFavoriteUnit": unitEvent = "favoriteUnitAdded"; diff --git a/support/proxy/vwf.example.com/kinetic/baseLayer.vwf.yaml b/support/proxy/vwf.example.com/kinetic/baseLayer.vwf.yaml index a6a136e5d..41c740ca1 100644 --- a/support/proxy/vwf.example.com/kinetic/baseLayer.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/baseLayer.vwf.yaml @@ -4,3 +4,7 @@ extends: http://vwf.example.com/kinetic/container.vwf properties: clearBeforeDraw: + supportMouseEvents: false + supportTouchEvents: false + hitGraphEnabled: false + listening: false diff --git a/support/proxy/vwf.example.com/kinetic/drawing.js b/support/proxy/vwf.example.com/kinetic/drawing.js index e9fc28b9b..843e29de8 100644 --- a/support/proxy/vwf.example.com/kinetic/drawing.js +++ b/support/proxy/vwf.example.com/kinetic/drawing.js @@ -187,6 +187,7 @@ this.down = function( eventData, nodeData, touch ) { var getDefaultProperties = function( drawingMode, groupParent, eventPoint ) { var retObj = { "visible": 'inherit', + "listening": 'inherit', "opacity": userState.drawing_opacity, "z-index": 4 }; @@ -236,6 +237,7 @@ this.down = function( eventData, nodeData, touch ) { "extends": groupExtends, "properties": { "visible": false, + "listening": false, "position": eventPointDown }, "children": {} @@ -374,6 +376,9 @@ this.update = function( eventData, nodeData, upEvent ) { if ( drawingObject.visible !== userState.drawing_visible ) { drawingObject.visible = userState.drawing_visible; } + if ( drawingObject.listening !== userState.drawing_listening ) { + drawingObject.listening = userState.drawing_listening; + } var diffX = eventPoint[ 0 ] - privateState.initialDownPoint[ 0 ]; var diffY = eventPoint[ 1 ] - privateState.initialDownPoint[ 1 ]; var pos = [ privateState.initialDownPoint[ 0 ], privateState.initialDownPoint[ 1 ] ]; diff --git a/support/proxy/vwf.example.com/kinetic/fastLayer.vwf.yaml b/support/proxy/vwf.example.com/kinetic/fastLayer.vwf.yaml index 276bfcd80..84b3cf565 100644 --- a/support/proxy/vwf.example.com/kinetic/fastLayer.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/fastLayer.vwf.yaml @@ -6,3 +6,5 @@ properties: clearBeforeDraw: supportMouseEvents: false supportTouchEvents: false + hitGraphEnabled: false + listening: false diff --git a/support/proxy/vwf.example.com/kinetic/layer.vwf.yaml b/support/proxy/vwf.example.com/kinetic/layer.vwf.yaml index fe0484536..a18748111 100644 --- a/support/proxy/vwf.example.com/kinetic/layer.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/layer.vwf.yaml @@ -6,3 +6,5 @@ properties: clearBeforeDraw: supportMouseEvents: false supportTouchEvents: false + hitGraphEnabled: false + listening: false diff --git a/support/proxy/vwf.example.com/kinetic/node.js b/support/proxy/vwf.example.com/kinetic/node.js index 078556749..ac7636cc0 100644 --- a/support/proxy/vwf.example.com/kinetic/node.js +++ b/support/proxy/vwf.example.com/kinetic/node.js @@ -1,5 +1,6 @@ this.initialize = function() { this.previousVisible = undefined; + this.previousListening = undefined; } this.toggleVisibility = function() { @@ -23,4 +24,25 @@ this.toggleVisibility = function() { } +this.toggleListening = function() { + + // isListening will take care of 'inherit', and + // trace up through the scene graph to determine + // if the current state is listening or not + if ( this.isListening ) { + this.listening = this.previousListening ? this.previousListening : false; + } else { + this.listening = this.previousListening ? this.previousListening : true; + } + + var listen = this.listening; + + if ( listen === 'inherit' ) { + this.previousListening = 'inherit'; + } else { + this.previousListening = undefined; + } + +} + //@ sourceURL=kinetic_node.js \ No newline at end of file diff --git a/support/proxy/vwf.example.com/kinetic/node.vwf.yaml b/support/proxy/vwf.example.com/kinetic/node.vwf.yaml index 809ef60af..e26686357 100644 --- a/support/proxy/vwf.example.com/kinetic/node.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/node.vwf.yaml @@ -10,6 +10,7 @@ properties: visible: isVisible: listening: + isListening: id: name: opacity: @@ -38,6 +39,7 @@ properties: dragProperty: "position" methods: toggleVisibility: + toggleListening: events: pointerMove: pointerOut: diff --git a/support/proxy/vwf.example.com/mil-sym/unitGroup.js b/support/proxy/vwf.example.com/mil-sym/unitGroup.js index 5e682c424..6caff8a24 100755 --- a/support/proxy/vwf.example.com/mil-sym/unitGroup.js +++ b/support/proxy/vwf.example.com/mil-sym/unitGroup.js @@ -95,6 +95,7 @@ this.updateThreatShape = function() { "x": 20, "y": 20, "visible": visible, + "listening": false, "width": 40, "height": 40, "opacity": 0.3, @@ -113,6 +114,7 @@ this.updateThreatShape = function() { "x": 16, "y": 16, "visible": visible, + "listening": false, "radius": 32, "opacity": 0.3, "fill": color, @@ -130,6 +132,7 @@ this.updateThreatShape = function() { "x": 16, "y": 16, "visible": visible, + "listening": false, "width": 40, "height": 40, "angle": 40, From dcf21c770e425ae4be47387edde484fcdb135f0d Mon Sep 17 00:00:00 2001 From: Scott Haynes Date: Tue, 10 Mar 2015 20:21:45 -0400 Subject: [PATCH 010/644] Initial check in of removing uniqueInView --- support/client/lib/vwf/model/kineticjs.js | 1237 +++++++---------- support/client/lib/vwf/view/kineticjs.js | 408 ++++-- .../proxy/vwf.example.com/kinetic/drawing.js | 55 +- .../vwf.example.com/kinetic/node.vwf.yaml | 1 - 4 files changed, 809 insertions(+), 892 deletions(-) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index 8088f51bd..0b529836a 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -6,7 +6,7 @@ define( [ "module", "vwf/utility/color" ], function( module, model, utility, color ) { - var self; + var modelDriver; return model.load( module, { @@ -16,17 +16,18 @@ define( [ "module", initialize: function( options ) { - self = this; + modelDriver = this; this.arguments = Array.prototype.slice.call( arguments ); this.options = ( options !== undefined ) ? options : {}; this.state = { - nodes: {}, - stages: {}, - prototypes: {}, - createLocalNode: function( nodeID, childID, childExtendsID, childImplementsIDs, + "nodes": {}, + "draggingNodes": {}, + "stages": {}, + "prototypes": {}, + "createLocalNode": function( nodeID, childID, childExtendsID, childImplementsIDs, childSource, childType, childIndex, childName, callback ) { return { "parentID": nodeID, @@ -39,12 +40,12 @@ define( [ "module", "prototypes": undefined, "kineticObj": undefined, "stage": undefined, - "uniqueInView": false, + "uniqueInView": false "hasMouseEvents": false, "hasTouchEvents": false - }; + "model": {} }; }, - isKineticClass: function( prototypes, classID ) { + "isKineticClass": function( prototypes, classID ) { if ( prototypes ) { for ( var i = 0; i < prototypes.length; i++ ) { if ( prototypes[ i ] === classID ) { @@ -55,7 +56,7 @@ define( [ "module", } return false; }, - isKineticComponent: function( prototypes ) { + "isKineticComponent": function( prototypes ) { var found = false; if ( prototypes ) { for ( var i = 0; i < prototypes.length && !found; i++ ) { @@ -63,253 +64,101 @@ define( [ "module", } } return found; - } - }; - - // turns on logger debugger console messages - this.debug = { - "creation": false, - "native": false, - "initializing": false, - "parenting": false, - "deleting": false, - "properties": false, - "setting": false, - "getting": false, - "methods": false, - "events": false, - "prototypes": false - }; - }, + "setProperty": function( kineticObj, propertyName, propertyValue ) { + var value = undefined; + value = this.setNodeProperty( kineticObj, propertyName, propertyValue ); - // == Model API ============================================================================ - - // -- creatingNode ------------------------------------------------------------------------ - - creatingNode: function( nodeID, childID, childExtendsID, childImplementsIDs, - childSource, childType, childIndex, childName, callback ) { - - var appID = this.kernel.application(); + if ( value === undefined ) { + value = this.setShapeProperty( kineticObj, propertyName, propertyValue ); + } - if ( this.debug.creation ) { - this.logger.infox( "creatingNode", nodeID, childID, childExtendsID, childImplementsIDs, childSource, childType, childIndex, childName ); + if ( value === undefined ) { + value = this.setContainerProperty( kineticObj, propertyName, propertyValue ); } - // If the node being created is a prototype, construct it and add it to the array of prototypes, - // and then return - var prototypeID = utility.ifPrototypeGetId( appID, this.state.prototypes, nodeID, childID ); - if ( prototypeID !== undefined ) { - - if ( this.debug.prototypes ) { - this.logger.infox( "prototype: ", prototypeID ); + if ( value === undefined && kineticObj instanceof Kinetic.Arc ) { + value = this.setArcProperty( kineticObj, propertyName, propertyValue ); } - this.state.prototypes[ prototypeID ] = { - parentID: nodeID, - ID: childID, - extendsID: childExtendsID, - implementsID: childImplementsIDs, - source: childSource, - type: childType, - name: childName - }; - return; + if ( value === undefined && + ( kineticObj instanceof Kinetic.BaseLayer || + kineticObj instanceof Kinetic.FastLayer || + kineticObj instanceof Kinetic.Layer + ) ) { + value = this.setLayerProperty( kineticObj, propertyName, propertyValue ); } - var protos = getPrototypes( this.kernel, childExtendsID ); + if ( value === undefined && kineticObj instanceof Kinetic.Canvas ) { + value = this.setCanvasProperty( kineticObj, propertyName, propertyValue ); + } - var node; + if ( value === undefined && kineticObj instanceof Kinetic.Circle ) { + value = this.setCircleProperty( kineticObj, propertyName, propertyValue ); + } - if ( this.state.isKineticComponent( protos ) ) { + if ( value === undefined && kineticObj instanceof Kinetic.Ellipse ) { + value = this.setEllipseProperty( kineticObj, propertyName, propertyValue ) + } - if ( this.debug.native ) { - this.logger.infox( "creatingNode", nodeID, childID, childExtendsID, childImplementsIDs, childSource, childType, childIndex, childName ); - } - - // Create the local copy of the node properties - if ( this.state.nodes[ childID ] === undefined ){ - this.state.nodes[ childID ] = this.state.createLocalNode( nodeID, childID, childExtendsID, childImplementsIDs, - childSource, childType, childIndex, childName, callback ); + if ( value === undefined && kineticObj instanceof Kinetic.Image ) { + value = this.setImageProperty( kineticObj, propertyName, propertyValue ); } - node = this.state.nodes[ childID ]; - - node.prototypes = protos; - - node.kineticObj = createKineticObject( node ); - - // If the kineticObj was created, attach it to the parent kineticObj, if it is a - // kinetic container - // (if a kinteticObj is created asynchronously ... like an Image, it will be - // undefined here, but will be added to its parent in the appropriate callback) - addNodeToHierarchy( node ); + if ( value === undefined && kineticObj instanceof Kinetic.Line ) { + value = this.setLineProperty( kineticObj, propertyName, propertyValue ); + } + if ( value === undefined && kineticObj instanceof Kinetic.Path ) { + value = this.setPathProperty( kineticObj, propertyName, propertyValue ); } - - }, - - // initializingNode: function( nodeID, childID, childExtendsID, childImplementsIDs, - // childSource, childType, childIndex, childName ) { - - // if ( this.debug.initializing ) { - // this.logger.infox( "initializingNode", nodeID, childID, childExtendsID, childImplementsIDs, childSource, childType, childName ); - // } - - // }, - - // -- deletingNode ------------------------------------------------------------------------- - - deletingNode: function( nodeID ) { - - if ( this.debug.deleting ) { - this.logger.infox( "deletingNode", nodeID ); + if ( value === undefined && kineticObj instanceof Kinetic.Rect ) { + value = this.setRectProperty( kineticObj, propertyName, propertyValue ); } - if ( this.state.nodes[ nodeID ] !== undefined ) { - - var node = this.state.nodes[ nodeID ]; - if ( node.kineticObj !== undefined ) { - // removes and destroys object - node.kineticObj.destroy(); - node.kineticObj = undefined; - } - - delete this.state.nodes[ nodeID ]; + if ( value === undefined && kineticObj instanceof Kinetic.RegularPolygon ) { + value = this.setRegularPolygonProperty( kineticObj, propertyName, propertyValue ); } - }, - - // -- addingChild ------------------------------------------------------------------------ - - // addingChild: function( nodeID, childID, childName ) { - // if ( this.debug.parenting ) { - // this.logger.infox( "addingChild", nodeID, childID, childName ); - // } - // }, - - - // -- movingChild ------------------------------------------------------------------------ - - movingChild: function( nodeID, childID, childName ) { - - if ( this.debug.parenting ) { - this.logger.infox( "movingChild", nodeID, childID, childName ); + if ( value === undefined && kineticObj instanceof Kinetic.Ring ) { + value = this.setRingProperty( kineticObj, propertyName, propertyValue ); } - - if ( this.state.nodes[ childID ] !== undefined ) { - if ( this.state.nodes[ nodeID ] !== undefined ) { - var parentNode = this.state.nodes[ nodeID ]; - - if ( isContainerDefinition( parentNode.prototypes ) && parentNode.kineticObj ) { - - var node = this.state.nodes[ childID ]; - if ( node.kineticObj !== undefined ) { - // removes object only - node.kineticObj.remove(); - parentNode.kineticObj.add( node.kineticObj ); - } + if ( value === undefined && kineticObj instanceof Kinetic.Sprite ) { + value = this.setSpriteProperty( kineticObj, propertyName, propertyValue ); } - } - } - - }, - - - // -- removingChild ------------------------------------------------------------------------ - - // removingChild: function( nodeID, childID, childName ) { - // if ( this.debug.parenting ) { - // this.logger.infox( "removingChild", nodeID, childID, childName ); - // } - // }, - - // -- creatingProperty --------------------------------------------------------------------- - - creatingProperty: function( nodeID, propertyName, propertyValue ) { - - var value = undefined; - if ( this.debug.properties ) { - this.logger.infox( "C === creatingProperty ", nodeID, propertyName, propertyValue ); + if ( value === undefined && kineticObj instanceof Kinetic.Star ) { + value = this.setStarProperty( kineticObj, propertyName, propertyValue ); } - var node = this.state.nodes[ nodeID ]; - if ( node !== undefined ) { - value = this.settingProperty( nodeID, propertyName, propertyValue ); + if ( value === undefined && kineticObj instanceof Kinetic.Text ) { + value = this.setTextProperty( kineticObj, propertyName, propertyValue ); } - return value; - }, - - // -- initializingProperty ----------------------------------------------------------------- - - initializingProperty: function( nodeID, propertyName, propertyValue ) { - - var value = undefined; - - if ( this.debug.properties ) { - this.logger.infox( " I === initializingProperty ", nodeID, propertyName, propertyValue ); + if ( value === undefined && kineticObj instanceof Kinetic.TextPath ) { + value = this.setTextPathProperty( kineticObj, propertyName, propertyValue ); } - var node = this.state.nodes[ nodeID ]; - if ( node !== undefined ) { - value = this.settingProperty( nodeID, propertyName, propertyValue ); + if ( value === undefined && kineticObj instanceof Kinetic.Wedge ) { + value = this.setWedgeProperty( kineticObj, propertyName, propertyValue ); } - - return value; - + return value; }, - // -- settingProperty ---------------------------------------------------------------------- + "setNodeProperty": function( kineticObj, propertyName, propertyValue ) { - settingProperty: function( nodeID, propertyName, propertyValue ) { + var value = propertyValue; - if ( this.debug.properties || this.debug.setting ) { - this.logger.infox( " S === settingProperty ", nodeID, propertyName, propertyValue ); - } - var node = this.state.nodes[ nodeID ]; - var imageObj; - var value = undefined; - if ( node && node.kineticObj && utility.validObject( propertyValue ) ) { - - var kineticObj = node.kineticObj; - - if ( isNodeDefinition( node.prototypes ) ) { - - // 'id' will be set to the nodeID - value = propertyValue; - switch ( propertyName ) { case "x": - kineticObj.modelX = Number( propertyValue ); - - // Update the view - though this would be more appropriate to do in the - // view driver's satProperty, it is important that it be updated - // atomically with the model so there is no risk that "ticked" will - // discover the descrepancy between model and view values and assume - // that the user has dragged the node via kinetic (thus triggering it to - // set the model value from the old view value) - if ( !node.uniqueInView ) { - kineticObj.x( kineticObj.modelX ); - } + kineticObj.x( Number( propertyValue ) ); break; case "y": - kineticObj.modelY = Number( propertyValue ); - - // Update the view - though this would be more appropriate to do in the - // view driver's satProperty, it is important that it be updated - // atomically with the model so there is no risk that "ticked" will - // discover the descrepancy between model and view values and assume - // that the user has dragged the node via kinetic (thus triggering it to - // set the model value from the old view value) - if ( !node.uniqueInView ) { - kineticObj.y( Number( kineticObj.modelY ) ); - } + kineticObj.y( Number( propertyValue ) ); break; case "width": @@ -400,40 +249,25 @@ define( [ "module", case "position": if ( propertyValue instanceof Array ) { - kineticObj.modelX = Number( propertyValue[ 0 ] ); - kineticObj.modelY = Number( propertyValue[ 1 ] ); + kineticObj.setPosition( { + x: Number( propertyValue[ 0 ] ), + y: Number( propertyValue[ 1 ] ) + } ); } else { - kineticObj.modelX = Number( propertyValue.x ); - kineticObj.modelY = Number( propertyValue.y ); - } - - // Update the view - though this would be more appropriate to do in the - // view driver's satProperty, it is important that it be updated - // atomically with the model so there is no risk that "ticked" will - // discover the descrepancy between model and view values and assume - // that the user has dragged the node via kinetic (thus triggering it to - // set the model value from the old view value) - - // If the node is being dragged by this client, then its view has - // already updated, and we risk updating it with a stale value. - // Therefore, if the view has told us to ignore the next update, we will - // do that. Otherwise, update the view value. - if ( node.viewIgnoreNextPositionUpdate ) { - node.viewIgnoreNextPositionUpdate = false; - } else if ( !node.uniqueInView ) { kineticObj.setPosition( { - x: kineticObj.modelX, - y: kineticObj.modelY + x: propertyValue.x, + y: propertyValue.y } ); } break; + case "absolutePosition": - // Store the current absolute position because we are about to tamper - // with the view value to get kinetic to compute the new model values - // for us. If uniqueInView is true, we should not change the view - // value, so we will need to put this one back. - var oldAbsolutePosition = kineticObj.getAbsolutePosition(); + // // Store the current absolute position because we are about to tamper + // // with the view value to get kinetic to compute the new model values + // // for us. If uniqueInView is true, we should not change the view + // // value, so we will need to put this one back. + // var oldAbsolutePosition = kineticObj.getAbsolutePosition(); // Compute new modelX and modelY values if ( propertyValue instanceof Array ) { @@ -447,61 +281,60 @@ define( [ "module", "y": Number( propertyValue.y ) }); } - kineticObj.modelX = kineticObj.x(); - kineticObj.modelY = kineticObj.y(); - - // If each user has a unique view value, setting the model value should - // not change the view value, so we set the original view value back now - // that we are done using it to calculate the new model value. - if ( node.uniqueInView ) { - kineticObj.setAbsolutePosition( oldAbsolutePosition ); - } - break; - - case "uniqueInView": - node.uniqueInView = Boolean( propertyValue ); - - // If we no longer have unique views, all view positions should be set - // to the model value - // Note: though this would be more appropriate to do in the view - // driver's satProperty, it is important that it be updated atomically - // with the model so there is no risk that "ticked" will discover the - // descrepancy between model and view values and assume that the user - // has dragged the node via kinetic (thus triggering it to set the model - // value from the old view value) - if ( !node.uniqueInView ) { - kineticObj.x( kineticObj.modelX ); - kineticObj.y( kineticObj.modelY ); - } - break; + // kineticObj.modelX = kineticObj.x(); + // kineticObj.modelY = kineticObj.y(); + + // // If each user has a unique view value, setting the model value should + // // not change the view value, so we set the original view value back now + // // that we are done using it to calculate the new model value. + // if ( node.uniqueInView ) { + // kineticObj.setAbsolutePosition( oldAbsolutePosition ); + // } + break; + + // case "uniqueInView": + // node.uniqueInView = Boolean( propertyValue ); + + // // If we no longer have unique views, all view positions should be set + // // to the model value + // // Note: though this would be more appropriate to do in the view + // // driver's satProperty, it is important that it be updated atomically + // // with the model so there is no risk that "ticked" will discover the + // // descrepancy between model and view values and assume that the user + // // has dragged the node via kinetic (thus triggering it to set the model + // // value from the old view value) + // if ( !node.uniqueInView ) { + // kineticObj.x( kineticObj.modelX ); + // kineticObj.y( kineticObj.modelY ); + // } + // break; case "dragBoundFunc": var functionString = propertyValue; if ( !utility.isString( functionString ) ) { - this.logger.errorx( "settingProperty", + modelDriver.logger.errorx( "settingProperty", "The value of dragBoundFunc should be a string of the " + "function to be used." ); break; } - node.kineticObj.dragBoundFunc( eval( "(" + functionString + ")" ) ); + kineticObj.dragBoundFunc( eval( "(" + functionString + ")" ) ); break; case "transform": case "absoluteTransform": case "absoluteOpacity": case "absoluteZIndex": - this.logger.errorx( "settingProperty", "Cannot set property ", - propertyName ); + modelDriver.logger.errorx( "settingProperty", "Cannot set property ", propertyName ); value = undefined; + default: value = undefined; break; } - } - - if ( value === undefined && isShapeDefinition( node.prototypes ) ) { - - value = propertyValue; + return value; + }, + "setShapeProperty": function( kineticObj, propertyName, propertyValue ) { + var value = propertyValue; switch ( propertyName ) { @@ -519,11 +352,11 @@ define( [ "module", case "fillGreen": kineticObj.fillGreen( Number( propertyValue ) ); break; - + case "fillBlue": kineticObj.fillGreen( Number( propertyValue ) ); break; - + case "fillAlpha": kineticObj.fillAlpha( parseFloat( propertyValue ) ); break; @@ -550,7 +383,7 @@ define( [ "module", case "fillPatternY": kineticObj.fillPatternY( Number( propertyValue ) ); break; - + case "fillPatternOffset": if ( propertyValue instanceof Array ) { kineticObj.fillPatternOffset( { "x": Number( propertyValue[ 0 ] ), "y": Number( propertyValue[ 1 ] ) }); @@ -598,7 +431,7 @@ define( [ "module", break; default: - this.logger.warnx( "incorrect value for fillPatternRepeat: " + propertyValue ); + modelDriver.logger.warnx( "incorrect value for fillPatternRepeat: " + propertyValue ); break; } break; @@ -699,7 +532,7 @@ define( [ "module", break; default: - this.logger.warnx( "incorrect value for fillPriority: " + propertyValue ); + modelDriver.logger.warnx( "incorrect value for fillPriority: " + propertyValue ); break; } break; @@ -749,7 +582,7 @@ define( [ "module", break; default: - this.logger.warnx( "incorrect value for lineJoin: " + propertyValue ); + modelDriver.logger.warnx( "incorrect value for lineJoin: " + propertyValue ); break; } break; @@ -764,7 +597,7 @@ define( [ "module", break; default: - this.logger.warnx( "incorrect value for lineCap: " + propertyValue ); + modelDriver.logger.warnx( "incorrect value for lineCap: " + propertyValue ); break; } break; @@ -830,23 +663,11 @@ define( [ "module", default: value = undefined; break; - } - } - - if ( value === undefined && isContainerDefinition( node.prototypes ) ) { - value = propertyValue; - - switch ( propertyName ) { - - case "clipFunc": - default: - value = undefined; - break; - } - } - - if ( value === undefined && kineticObj instanceof Kinetic.Arc ) { - value = propertyValue; + } + return value; + }, + "setArcProperty": function( kineticObj, propertyName, propertyValue ) { + var value = propertyValue; switch ( propertyName ) { @@ -870,14 +691,11 @@ define( [ "module", value = undefined; break; } - } - if ( value === undefined && - ( kineticObj instanceof Kinetic.BaseLayer || - kineticObj instanceof Kinetic.FastLayer || - kineticObj instanceof Kinetic.Layer - ) ) { - value = propertyValue; + return value; + }, + "setCanvasProperty": function( kineticObj, propertyName, propertyValue ) { + var value = propertyValue; switch ( propertyName ) { @@ -889,17 +707,6 @@ define( [ "module", kineticObj.hitGraphEnabled( Boolean(propertyValue) ); break; - default: - value = undefined; - break; - } - } - - if ( value === undefined && kineticObj instanceof Kinetic.Canvas ) { - value = propertyValue; - - switch ( propertyName ) { - case "width": kineticObj.setWidth( Number( propertyValue ) ); break; @@ -916,33 +723,61 @@ define( [ "module", value = undefined; break; } - } + return value; + }, + "setContainerProperty": function( kineticObj, propertyName, propertyValue ) { + var value = propertyValue; - if ( value === undefined && kineticObj instanceof Kinetic.Circle ) { - value = propertyValue; + switch ( propertyName ) { + case "clipFunc": + default: + value = undefined; + break; + } + + return value; + }, + "setLayerProperty": function( kineticObj, propertyName, propertyValue ) { + var value = propertyValue; + switch ( propertyName ) { - case "radius": - kineticObj.radius( Number( propertyValue ) ); + case "clearBeforeDraw": + kineticObj.clearBeforeDraw( Boolean( propertyValue ) ); break; default: value = undefined; break; - } - } + } + return value; + }, + "setCircleProperty": function( kineticObj, propertyName, propertyValue ) { + var value = propertyValue; - if ( value === undefined && kineticObj instanceof Kinetic.Ellipse ) { - value = propertyValue; - switch ( propertyName ) { case "radius": - if ( propertyValue instanceof Array ) { - kineticObj.radius( { "x": Number( propertyValue[ 0 ] ), "y": Number( propertyValue[ 1 ] ) }); - } else { + kineticObj.radius( Number( propertyValue ) ); + break; + + default: + value = undefined; + break; + } + return value; + }, + "setEllipseProperty": function( kineticObj, propertyName, propertyValue ) { + var value = propertyValue; + + switch ( propertyName ) { + + case "radius": + if ( propertyValue instanceof Array ) { + kineticObj.radius( { "x": Number( propertyValue[ 0 ] ), "y": Number( propertyValue[ 1 ] ) }); + } else { kineticObj.radius( { "x": Number( propertyValue.x ), "y": Number( propertyValue.y ) }); } break; @@ -951,16 +786,17 @@ define( [ "module", value = undefined; break; } - } - if ( value === undefined && kineticObj instanceof Kinetic.Image ) { - value = propertyValue; - + return value; + }, + "setImageProperty": function( kineticObj, propertyName, propertyValue ) { + var value = propertyValue; + switch ( propertyName ) { case "image": if ( utility.validObject( propertyValue ) ) { - loadImage( node, propertyValue ); + loadImage( kineticObj, propertyValue ); } break; @@ -982,18 +818,19 @@ define( [ "module", break; case "scaleOnLoad": - node.scaleOnLoad = Boolean( propertyValue ); + //node.scaleOnLoad = Boolean( propertyValue ); break; default: value = undefined; break; } - } - if ( value === undefined && kineticObj instanceof Kinetic.Line ) { - value = propertyValue; - + return value; + }, + "setLineProperty": function( kineticObj, propertyName, propertyValue ) { + var value = propertyValue; + switch ( propertyName ) { case "points": @@ -1012,11 +849,12 @@ define( [ "module", value = undefined; break; } - } - if ( value === undefined && kineticObj instanceof Kinetic.Path ) { - value = propertyValue; - + return value; + }, + "setPathProperty": function( kineticObj, propertyName, propertyValue ) { + var value = propertyValue; + switch ( propertyName ) { case "data": @@ -1027,11 +865,12 @@ define( [ "module", value = undefined; break; } - } - if ( value === undefined && kineticObj instanceof Kinetic.Rect ) { - value = propertyValue; - + return value; + }, + "setRectProperty": function( kineticObj, propertyName, propertyValue ) { + var value = propertyValue; + switch ( propertyName ) { case "cornerRadius": @@ -1042,11 +881,12 @@ define( [ "module", value = undefined; break; } - } - if ( value === undefined && kineticObj instanceof Kinetic.RegularPolygon ) { - value = propertyValue; - + return value; + }, + "setRegularPolygonProperty": function( kineticObj, propertyName, propertyValue ) { + var value = propertyValue; + switch ( propertyName ) { case "sides": @@ -1061,11 +901,12 @@ define( [ "module", value = undefined; break; } - } - - if ( value === undefined && kineticObj instanceof Kinetic.Ring ) { - value = propertyValue; - + + return value; + }, + "setRingProperty": function( kineticObj, propertyName, propertyValue ) { + var value = propertyValue; + switch ( propertyName ) { case "innerRadius": @@ -1080,11 +921,12 @@ define( [ "module", value = undefined; break; } - } - - if ( value === undefined && kineticObj instanceof Kinetic.Sprite ) { - value = propertyValue; - + + return value; + }, + "setSpriteProperty": function( kineticObj, propertyName, propertyValue ) { + var value = propertyValue; + switch ( propertyName ) { case "animation": @@ -1101,23 +943,24 @@ define( [ "module", case "image": if ( utility.validObject( propertyValue ) ) { - loadImage( node, propertyValue ); + loadImage( kineticObj, propertyValue ); } break; case "scaleOnLoad": - node.scaleOnLoad = Boolean( propertyValue ); + //node.scaleOnLoad = Boolean( propertyValue ); break; default: value = undefined; break; } - } - if ( value === undefined && kineticObj instanceof Kinetic.Star ) { - value = propertyValue; - + return value; + }, + "setStarProperty": function( kineticObj, propertyName, propertyValue ) { + var value = propertyValue; + switch ( propertyName ) { case "numPoints": @@ -1135,13 +978,12 @@ define( [ "module", default: value = undefined; break; - } - } - + } + return value; + }, + "setTextProperty": function( kineticObj, propertyName, propertyValue ) { + var value = propertyValue; - if ( value === undefined && kineticObj instanceof Kinetic.Text ) { - value = propertyValue; - switch ( propertyName ) { case "fontFamily": @@ -1162,7 +1004,7 @@ define( [ "module", break; default: - this.logger.warnx( "incorrect value for fontStyle: " + propertyValue ); + modelDriver.logger.warnx( "incorrect value for fontStyle: " + propertyValue ); break; } break; @@ -1176,7 +1018,7 @@ define( [ "module", break; default: - this.logger.warnx( "incorrect value for fontVariant: " + propertyValue ); + modelDriver.logger.warnx( "incorrect value for fontVariant: " + propertyValue ); break; } break; @@ -1195,7 +1037,7 @@ define( [ "module", break; default: - this.logger.warnx( "incorrect value for align: " + propertyValue ); + modelDriver.logger.warnx( "incorrect value for align: " + propertyValue ); break; } break; @@ -1226,7 +1068,7 @@ define( [ "module", break; default: - this.logger.warnx( "incorrect value for wrap: " + propertyValue ); + modelDriver.logger.warnx( "incorrect value for wrap: " + propertyValue ); break; } break; @@ -1235,11 +1077,12 @@ define( [ "module", value = undefined; break; } - } - if ( value === undefined && kineticObj instanceof Kinetic.TextPath ) { - value = propertyValue; - + return value; + }, + "setTextPathProperty": function( kineticObj, propertyName, propertyValue ) { + var value = propertyValue; + switch ( propertyName ) { case "fontFamily": @@ -1260,7 +1103,7 @@ define( [ "module", break; default: - this.logger.warnx( "incorrect value for fontStyle: " + propertyValue ); + modelDriver.logger.warnx( "incorrect value for fontStyle: " + propertyValue ); break; } break; @@ -1274,7 +1117,7 @@ define( [ "module", break; default: - this.logger.warnx( "incorrect value for fontVariant: " + propertyValue ); + modelDriver.logger.warnx( "incorrect value for fontVariant: " + propertyValue ); break; } break; @@ -1291,11 +1134,12 @@ define( [ "module", value = undefined; break; } - } - if ( value === undefined && kineticObj instanceof Kinetic.Wedge ) { - value = propertyValue; - + return value; + }, + "setWedgeProperty": function( kineticObj, propertyName, propertyValue ) { + var value = propertyValue; + switch ( propertyName ) { case "angle": @@ -1313,28 +1157,11 @@ define( [ "module", default: value = undefined; break; - } - } - - } + } return value; }, - - // -- gettingProperty ---------------------------------------------------------------------- - - gettingProperty: function( nodeID, propertyName, propertyValue ) { - - if ( this.debug.properties || this.debug.getting ) { - this.logger.infox( " G === gettingProperty ", nodeID, propertyName ); - } - - var node = this.state.nodes[nodeID]; + "getProperty": function( kineticObj, propertyName ) { var value = undefined; - if ( node && node.kineticObj ) { - var kineticObj = node.kineticObj; - - - if ( isNodeDefinition( node.prototypes ) ) { switch ( propertyName ) { @@ -1422,7 +1249,7 @@ define( [ "module", break; case "dragBoundFunc": - var dragBoundFunc = node.kineticObj.dragBoundFunc(); + var dragBoundFunc = kineticObj.dragBoundFunc(); value = dragBoundFunc ? dragBoundFunc.toString() : undefined; break; @@ -1443,34 +1270,16 @@ define( [ "module", case "transform": value = kineticObj.getTransform().m; - value[ 4 ] = kineticObj.modelX || 0; - value[ 5 ] = kineticObj.modelY || 0; + //value[ 4 ] = kineticObj.modelX || 0; + //value[ 5 ] = kineticObj.modelY || 0; break; case "absolutePosition": - if ( !node.uniqueInView ) { value = kineticObj.getAbsolutePosition(); - } else { - // TODO: Since we are allowing the view to drag objects independent - // of the model, we can't be sure that kinetic has the proper - // model value. Therefore, we need to compute the math - // ourselves. - this.logger.errorx( "gettingProperty", "getter for ", - "absolutePosition when uniqueInView is not implemented" ); - } break; case "absoluteTransform": - if ( !node.uniqueInView ) { value = kineticObj.getAbsoluteTransform(); - } else { - // TODO: Since we are allowing the view to drag objects independent - // of the model, we can't be sure that kinetic has the proper - // model value. Therefore, we need to compute the math - // ourselves. - this.logger.errorx( "gettingProperty", "getter for ", - "absoluteTransform when uniqueInView is not implemented" ); - } break; case "absoluteOpacity": @@ -1481,265 +1290,8 @@ define( [ "module", value = kineticObj.getAbsoluteZIndex(); break; - case "uniqueInView": - value = node.uniqueInView; - break; - } - } - - if ( value === undefined && isShapeDefinition( node.prototypes ) ) { - - var img = undefined; - - switch ( propertyName ) { - - case "fill": - value = kineticObj.fill(); - break; - - case "fillRed": - value = kineticObj.fillRed(); - break; - - case "fillGreen": - value = kineticObj.fillGreen(); - break; - - case "fillBlue": - value = kineticObj.fillGreen(); - break; - - case "fillAlpha": - value = kineticObj.fillAlpha(); - break; - - case "fillPatternImage": - img = kineticObj.fillPatternImage(); - if ( img ){ - value = img.src; - } - break; - - case "fillPatternX": - value = kineticObj.fillPatternX(); - break; - - case "fillPatternY": - value = kineticObj.fillPatternY(); - break; - - case "fillPatternOffset": - value = kineticObj.fillPatternOffset(); - break; - - case "fillPatternOffsetX": - value = kineticObj.fillPatternOffsetX(); - break; - - case "fillPatternOffsetY": - value = kineticObj.fillPatternOffsetY(); - break; - - case "fillPatternScale": - value = kineticObj.fillPatternScale(); - break; - - case "fillPatternScaleX": - value = kineticObj.fillPatternScaleX(); - break; - - case "fillPatternScaleY": - value = kineticObj.fillPatternScaleY(); - break; - - case "fillPatternRotation": - value = kineticObj.fillPatternRotation(); - break; - - case "fillPatternRepeat": - value = kineticObj.fillPatternRepeat(); - break; - - case "fillLinearGradientStartPoint": - value = kineticObj.fillLinearGradientStartPoint(); - break; - - case "fillLinearGradientStartPointX": - value = kineticObj.fillLinearGradientStartPointX(); - break; - - case "fillLinearGradientStartPointY": - value = kineticObj.fillLinearGradientStartPointY(); - break; - - case "fillLinearGradientEndPoint": - value = kineticObj.fillLinearGradientEndPoint(); - break; - - case "fillLinearGradientEndPointX": - value = kineticObj.fillLinearGradientEndPointX(); - break; - - case "fillLinearGradientEndPointY": - value = kineticObj.fillLinearGradientEndPointY(); - break; - - case "fillLinearGradientColorStops": - value = kineticObj.fillLinearGradientColorStops(); - break; - - case "fillRadialGradientStartPoint": - value = kineticObj.fillRadialGradientStartPoint(); - break; - case "fillRadialGradientStartPointX": - value = kineticObj.fillRadialGradientStartPointX(); - break; - - case "fillRadialGradientStartPointY": - value = kineticObj.fillRadialGradientStartPointX(); - break; - - case "fillRadialGradientEndPoint": - value = kineticObj.fillRadialGradientEndPoint(); - break; - - case "fillRadialGradientEndPointX": - value = kineticObj.fillRadialGradientEndPointX(); - break; - - case "fillRadialGradientEndPointY": - value = kineticObj.fillRadialGradientEndPointY(); - break; - - case "fillRadialGradientStartRadius": - value = kineticObj.fillRadialGradientStartRadius(); - break; - - case "fillRadialGradientEndRadius": - value = kineticObj.fillRadialGradientEndRadius(); - break; - - case "fillRadialGradientColorStops": - value = kineticObj.fillRadialGradientColorStops(); - break; - - case "fillEnabled": - value = kineticObj.fillEnabled(); - break; - - case "fillPriority": - value = kineticObj.fillPriority(); - break; - - case "stroke": - value = kineticObj.stroke(); - break; - - case "strokeRed": - value = kineticObj.strokeRed(); - break; - - case "strokeGreen": - value = kineticObj.strokeGreen(); - break; - - case "strokeBlue": - value = kineticObj.strokeBlue(); - break; - - case "strokeAlpha": - value = kineticObj.strokeAlpha(); - break; - - case "strokeWidth": - value = kineticObj.strokeWidth(); - break; - - case "strokeScaleEnabled": - value = kineticObj.strokeScaleEnabled(); - break; - - case "strokeEnabled": - value = kineticObj.strokeEnabled(); - break; - - case "lineJoin": - value = kineticObj.lineJoin(); - break; - - case "lineCap": - value = kineticObj.lineCap(); - break; - - case "shadowColor": - value = kineticObj.shadowColor(); - - break; - - case "shadowRed": - value = kineticObj.shadowRed(); - break; - - case "shadowGreen": - value = kineticObj.shadowGreen(); - break; - - case "shadowBlue": - value = kineticObj.shadowBlue(); - break; - - case "shadowBlue": - value = kineticObj.shadowBlue(); - break; - - case "shadowBlur": - value = kineticObj.shadowBlur(); - break; - - case "shadowOffset": - value = kineticObj.shadowOffset(); - break; - - case "shadowOffsetX": - value = kineticObj.shadowOffsetX(); - break; - - case "shadowOffsetY": - value = kineticObj.shadowOffsetY(); - break; - - case "shadowOpacity": - value = kineticObj.shadowOpacity(); - break; - - case "shadowEnabled": - value = kineticObj.shadowEnabled(); - break; - - case "dash": - value = kineticObj.dash(); - break; - - case "dashEnabled": - value = kineticObj.dashEnabled(); - break; - - default: - value = undefined; - break; - } - } - - if ( value === undefined && isContainerDefinition( node.prototypes ) ) { - - switch ( propertyName ) { - - case "clipFunc": - break; - } - } // this is causing the editor to cause a infinite loop @@ -1847,7 +1399,7 @@ define( [ "module", break; case "scaleOnLoad": - value = node.scaleOnLoad; + //value = node.scaleOnLoad; break; } @@ -1944,7 +1496,7 @@ define( [ "module", break; case "scaleOnLoad": - value = node.scaleOnLoad; + //value = node.scaleOnLoad; break; } } @@ -2066,6 +1618,245 @@ define( [ "module", } } + return value; + } + }; + + // turns on logger debugger console messages + this.debug = { + "creation": false, + "native": false, + "initializing": false, + "parenting": false, + "deleting": false, + "properties": false, + "setting": false, + "getting": false, + "methods": false, + "events": false, + "prototypes": false + }; + + }, + + + // == Model API ============================================================================ + + // -- creatingNode ------------------------------------------------------------------------ + + creatingNode: function( nodeID, childID, childExtendsID, childImplementsIDs, + childSource, childType, childIndex, childName, callback ) { + + var appID = this.kernel.application(); + + if ( this.debug.creation ) { + this.logger.infox( "creatingNode", nodeID, childID, childExtendsID, childImplementsIDs, childSource, childType, childIndex, childName ); + } + + // If the node being created is a prototype, construct it and add it to the array of prototypes, + // and then return + var prototypeID = utility.ifPrototypeGetId( appID, this.state.prototypes, nodeID, childID ); + if ( prototypeID !== undefined ) { + + if ( this.debug.prototypes ) { + this.logger.infox( "prototype: ", prototypeID ); + } + + this.state.prototypes[ prototypeID ] = { + parentID: nodeID, + ID: childID, + extendsID: childExtendsID, + implementsID: childImplementsIDs, + source: childSource, + type: childType, + name: childName + }; + return; + } + + var protos = getPrototypes( this.kernel, childExtendsID ); + + var node; + + if ( this.state.isKineticComponent( protos ) ) { + + if ( this.debug.native ) { + this.logger.infox( "creatingNode", nodeID, childID, childExtendsID, childImplementsIDs, childSource, childType, childIndex, childName ); + } + + // Create the local copy of the node properties + if ( this.state.nodes[ childID ] === undefined ){ + this.state.nodes[ childID ] = this.state.createLocalNode( nodeID, childID, childExtendsID, childImplementsIDs, + childSource, childType, childIndex, childName, callback ); + } + + node = this.state.nodes[ childID ]; + + node.prototypes = protos; + + node.kineticObj = createKineticObject( node ); + + // if ( node.kineticObj instanceof Kinetic.Stage ) { + // node.model.scale = { "value": 1, "type": "static" }; + // node.model.scaleX = { "value": 1, "type": "static" }; + // node.model.scaleY = { "value": 1, "type": "static" }; + // node.model.x = { "value": 0, "type": "static" }; + // node.model.y = { "value": 0, "type": "static" }; + // node.model.position = { "value": [ 0, 0 ], "type": "static" }; + // node.model.absolutePosition = { "value": [ 0, 0 ], "type": "static" }; + // node.model.absoluteTransform = { "value": [ 1, 0, 0, 1 ], "type": "static" }; + // } + + // If the kineticObj was created, attach it to the parent kineticObj, if it is a + // kinetic container + // (if a kineticObj is created asynchronously ... like an Image, it will be + // undefined here, but will be added to its parent in the appropriate callback) + addNodeToHierarchy( node ); + + } + + }, + + // initializingNode: function( nodeID, childID, childExtendsID, childImplementsIDs, + // childSource, childType, childIndex, childName ) { + + // if ( this.debug.initializing ) { + // this.logger.infox( "initializingNode", nodeID, childID, childExtendsID, childImplementsIDs, childSource, childType, childName ); + // } + + + // }, + + // -- deletingNode ------------------------------------------------------------------------- + + deletingNode: function( nodeID ) { + + if ( this.debug.deleting ) { + this.logger.infox( "deletingNode", nodeID ); + } + + if ( this.state.nodes[ nodeID ] !== undefined ) { + + var node = this.state.nodes[ nodeID ]; + if ( node.kineticObj !== undefined ) { + // removes and destroys object + node.kineticObj.destroy(); + node.kineticObj = undefined; + } + + delete this.state.nodes[ nodeID ]; + } + + }, + + // -- addingChild ------------------------------------------------------------------------ + + // addingChild: function( nodeID, childID, childName ) { + // if ( this.debug.parenting ) { + // this.logger.infox( "addingChild", nodeID, childID, childName ); + // } + // }, + + + // -- movingChild ------------------------------------------------------------------------ + + movingChild: function( nodeID, childID, childName ) { + + if ( this.debug.parenting ) { + this.logger.infox( "movingChild", nodeID, childID, childName ); + } + + if ( this.state.nodes[ childID ] !== undefined ) { + + if ( this.state.nodes[ nodeID ] !== undefined ) { + var parentNode = this.state.nodes[ nodeID ]; + + if ( isContainerDefinition( parentNode.prototypes ) && parentNode.kineticObj ) { + + var node = this.state.nodes[ childID ]; + if ( node.kineticObj !== undefined ) { + // removes object only + node.kineticObj.remove(); + parentNode.kineticObj.add( node.kineticObj ); + } + } + } + } + + }, + + + // -- removingChild ------------------------------------------------------------------------ + + // removingChild: function( nodeID, childID, childName ) { + // if ( this.debug.parenting ) { + // this.logger.infox( "removingChild", nodeID, childID, childName ); + // } + // }, + + // -- creatingProperty --------------------------------------------------------------------- + + creatingProperty: function( nodeID, propertyName, propertyValue ) { + + if ( this.debug.properties ) { + this.logger.infox( "C === creatingProperty ", nodeID, propertyName, propertyValue ); + } + return this.settingProperty( nodeID, propertyName, propertyValue );; + }, + + // -- initializingProperty ----------------------------------------------------------------- + + initializingProperty: function( nodeID, propertyName, propertyValue ) { + + if ( this.debug.properties ) { + this.logger.infox( " I === initializingProperty ", nodeID, propertyName, propertyValue ); + } + return this.settingProperty( nodeID, propertyName, propertyValue );; + + }, + // -- settingProperty ---------------------------------------------------------------------- + + settingProperty: function( nodeID, propertyName, propertyValue ) { + + if ( this.debug.properties || this.debug.setting ) { + this.logger.infox( " S === settingProperty ", nodeID, propertyName, propertyValue ); + } + var node = this.state.nodes[ nodeID ]; + var imageObj; + var value = undefined; + if ( node && node.kineticObj && utility.validObject( propertyValue ) ) { + + if ( node.model[ propertyName ] !== undefined ) { + if ( this.kernel.client() === this.kernel.moniker() ) { + //node.model[ propertyName ] = propertyValue; + value = this.state.setProperty( node.kineticObj, propertyName, propertyValue ); + } + } else { + value = this.state.setProperty( node.kineticObj, propertyName, propertyValue ); + } + + } + return value; + }, + + // -- gettingProperty ---------------------------------------------------------------------- + + gettingProperty: function( nodeID, propertyName, propertyValue ) { + + if ( this.debug.properties || this.debug.getting ) { + this.logger.infox( " G === gettingProperty ", nodeID, propertyName ); + } + + var node = this.state.nodes[nodeID]; + var value = undefined; + if ( node && node.kineticObj ) { + var kineticObj = node.kineticObj; + + if ( node.model[ propertyName ] ) { + value = node.model[ propertyName ].value; + } else { + value = this.state.getProperty( kineticObj, propertyName ); + } } if ( value !== undefined ) { propertyValue = value; @@ -2113,21 +1904,21 @@ define( [ "module", var protos = node.prototypes; var kineticObj = undefined; - if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/arc.vwf" ) ) { + if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/arc.vwf" ) ) { kineticObj = new Kinetic.Arc( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/baseLayer.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/baseLayer.vwf" ) ) { kineticObj = new Kinetic.BaseLayer( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/canvas.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/canvas.vwf" ) ) { kineticObj = new Kinetic.Canvas( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/circle.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/circle.vwf" ) ) { kineticObj = new Kinetic.Circle( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/ellipse.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/ellipse.vwf" ) ) { kineticObj = new Kinetic.Ellipse( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/fastLayer.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/fastLayer.vwf" ) ) { kineticObj = new Kinetic.FastLayer( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/group.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/group.vwf" ) ) { kineticObj = new Kinetic.Group( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/image.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/image.vwf" ) ) { var imageObj = new Image(); node.scaleOnLoad = false; kineticObj = new Kinetic.Image( { @@ -2136,19 +1927,19 @@ define( [ "module", if ( node.source !== undefined ) { imageObj.src = node.source; } - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/layer.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/layer.vwf" ) ) { kineticObj = new Kinetic.Layer( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/line.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/line.vwf" ) ) { kineticObj = new Kinetic.Line( config || { "points": [] } ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/path.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/path.vwf" ) ) { kineticObj = new Kinetic.Path( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/rect.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/rect.vwf" ) ) { kineticObj = new Kinetic.Rect( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/regularPolygon.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/regularPolygon.vwf" ) ) { kineticObj = new Kinetic.RegularPolygon( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/ring.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/ring.vwf" ) ) { kineticObj = new Kinetic.Ring( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/sprite.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/sprite.vwf" ) ) { var imageObj = new Image(); node.scaleOnLoad = false; kineticObj = new Kinetic.Sprite( { @@ -2157,7 +1948,7 @@ define( [ "module", if ( node.source !== undefined ) { imageObj.src = node.source; } - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/stage.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/stage.vwf" ) ) { var stageWidth = ( window && window.innerWidth ) ? window.innerWidth : 800; var stageHeight = ( window && window.innerHeight ) ? window.innerHeight : 600; var stageContainer = ( config && config.container ) || 'vwf-root'; @@ -2169,20 +1960,20 @@ define( [ "module", "height": stageHeight }; kineticObj = new Kinetic.Stage( stageDef ); - self.state.stages[ node.ID ] = kineticObj; - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/star.vwf" ) ) { + modelDriver.state.stages[ node.ID ] = kineticObj; + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/star.vwf" ) ) { kineticObj = new Kinetic.Star( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/text.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/text.vwf" ) ) { kineticObj = new Kinetic.Text( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/textPath.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/textPath.vwf" ) ) { kineticObj = new Kinetic.TextPath( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/wedge.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/wedge.vwf" ) ) { kineticObj = new Kinetic.Wedge( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/shape.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/shape.vwf" ) ) { kineticObj = new Kinetic.Shape( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/container.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/container.vwf" ) ) { kineticObj = new Kinetic.Container( config || {} ); - } else if ( self.state.isKineticClass( protos, "http://vwf.example.com/kinetic/node.vwf" ) ) { + } else if ( modelDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/node.vwf" ) ) { kineticObj = new Kinetic.Node( config || {} ); } @@ -2206,8 +1997,8 @@ define( [ "module", function addNodeToHierarchy( node ) { if ( node.kineticObj ) { - if ( self.state.nodes[ node.parentID ] !== undefined ) { - var parent = self.state.nodes[ node.parentID ]; + if ( modelDriver.state.nodes[ node.parentID ] !== undefined ) { + var parent = modelDriver.state.nodes[ node.parentID ]; if ( parent.kineticObj && isContainerDefinition( parent.prototypes ) ) { if ( parent.children === undefined ) { @@ -2281,9 +2072,8 @@ define( [ "module", return found; } - function loadImage( node, url ) { - if ( node && node.kineticObj ) { - var kineticObj = node.kineticObj; + function loadImage( kineticObj, url ) { + var imageObj = kineticObj.image(); var validImage = ( imageObj !== undefined ); var width = kineticObj.width(); @@ -2305,16 +2095,17 @@ define( [ "module", kineticObj.scale( { "x": height / imageObj.height ,"y": height / imageObj.height } ); } } - self.kernel.fireEvent( node.ID, "imageLoaded", [ url ] ); + modelDriver.kernel.fireEvent( node.ID, "imageLoaded", [ url ] ); } imageObj.onerror = function() { - self.logger.errorx( "loadImage", "Invalid image url:", url ); + modelDriver.logger.errorx( "loadImage", "Invalid image url:", url ); imageObj.src = oldSrc; - self.kernel.fireEvent( node.ID, "imageLoadError", [ url ] ); + modelDriver.kernel.fireEvent( node.ID, "imageLoadError", [ url ] ); } var oldSrc = imageObj.src; imageObj.src = url; - } + } + }); diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 68dddbb55..dac2e71f8 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -3,162 +3,140 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], function( module, view, $, utility, color ) { - var self; + var viewDriver; var stageContainer; var stageWidth = 800; var stageHeight = 600; - function processEvent( e, node, propagate ) { - var returnData = { eventData: undefined, eventNodeData: undefined }; - - if ( !propagate ) { - // For the "dragend" event, kinetic sometimes sends us an event object that doesn't - // have all the expected functions and properties attached - e.evt.stopPropagation && e.evt.stopPropagation(); - } - - var eventPosition; - var isTouchEvent = ( e.evt instanceof TouchEvent ); - if ( isTouchEvent ) { - eventPosition = e.evt.changedTouches[ 0 ]; - } else { - eventPosition = e.evt; - } - - var stage = node && node.stage; - returnData.eventData = [ convertBrowserEventDataToVwf( eventPosition, stage ) ]; - - var eventDataElement = returnData.eventData[ 0 ]; - eventDataElement.button = e.evt.button; - eventDataElement.timeStamp = e.evt.timeStamp; - eventDataElement.shiftKey = e.evt.shiftKey; - eventDataElement.ctrlKey = e.evt.ctrlKey; - eventDataElement.altKey = e.evt.altKey; - eventDataElement.metaKey = e.evt.metaKey; - - if ( isTouchEvent ) { - returnData.eventData[ 0 ].touches = []; - for ( var i = 0; i < e.evt.touches.length; i++ ) { - returnData.eventData[ 0 ].touches[ i ] = convertBrowserEventDataToVwf( - e.evt.touches[ i ], - stage - ); - } - } - - if ( propagate ) { + function attachMouseEvents( node ) { - var stageId = stage && stage.getId(); - var pointerPickID = e.targetNode ? e.targetNode.getId() : stageId; + initialize: function( options ) { + + viewDriver = this; - returnData.eventNodeData = { "": [ { - pickID: pointerPickID, - } ] }; + this.arguments = Array.prototype.slice.call( arguments ); - if ( self && self.state.nodes[ pointerPickID ] ) { - var childID = pointerPickID; - var child = self.state.nodes[ childID ]; - var parentID = child.parentID; - var parent = self.state.nodes[ child.parentID ]; - while ( child ) { + this.options = options || {}; - returnData.eventNodeData[ childID ] = [ { - pickID: pointerPickID, - } ]; + if ( window && window.innerWidth ) { + stageWidth = window.innerWidth - 20; + } + if ( window && window.innerHeight ) { + stageHeight = window.innerHeight - 20; + } - childID = parentID; - child = self.state.nodes[ childID ]; - parentID = child ? child.parentID : undefined; - parent = parentID ? self.state.nodes[ child.parentID ] : undefined; + stageContainer = this.options.container || 'vwf-root'; + stageWidth = this.options.width || stageWidth; + stageHeight = this.options.height || stageHeight; + }, - } + createdNode: function( nodeID, childID, childExtendsID, childImplementsIDs, + childSource, childType, childIndex, childName, callback ) { + + var node = this.state.nodes[ childID ]; + + // If the "nodes" object does not have this object in it, it must not be one that + // this driver cares about + if ( !node ) { + return; } - } - return returnData; - } + var protos = node.prototypes; + if ( viewDriver.state.isKineticClass( protos, [ "kinetic", "stage", "vwf" ] ) ) { + var stage = this.state.stage = node.kineticObj; + } + + }, - function convertBrowserEventDataToVwf( browserEventData, stage ) { - var vwfEventData = { - "location": [ browserEventData.x, browserEventData.y ], - "stageRelative": [ browserEventData.pageX, browserEventData.pageY ], - "client": [ browserEventData.clientX, browserEventData.clientY ], - "screen": [ browserEventData.screenX, browserEventData.screenY ], - "layer": [ browserEventData.layerX, browserEventData.layerY ], - "page": [ browserEventData.pageX, browserEventData.pageY ], - "offset": [ browserEventData.offsetX, browserEventData.offsetY ], - "movement": [ browserEventData.webkitMovementX, browserEventData.webkitMovementY ] - }; + initializedNode: function( nodeID, childID, childExtendsID, childImplementsIDs, + childSource, childType, childIndex, childName, callback ) { + + var node = this.state.nodes[ childID ]; + + // If the "nodes" object does not have this object in it, it must not be one that + // this driver cares about + if ( !node ) { - if ( stage ) { - vwfEventData.stage = [ stage.x(), stage.y() ]; - vwfEventData.stageRelative = [ - ( browserEventData.pageX - stage.x() ) / stage.scaleX(), - ( browserEventData.pageY - stage.y() ) / stage.scaleY() - ]; - } - return vwfEventData; - } + //var stage = this.state.stages[ childID ]; + //renderScene( stage ); + return; + } - function attachMouseEvents( node ) { + if ( node.kineticObj ) { var mouseDown = false; node.kineticObj.on( "mousemove", function( evt ) { var eData = processEvent( evt, node, false ); - self.kernel.fireEvent( node.ID, 'pointerMove', eData.eventData ); + //viewDriver.kernel.dispatchEvent( node.ID, 'pointerMove', eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'pointerMove', eData.eventData ); } ); node.kineticObj.on( "mouseout", function( evt ) { var eData = processEvent( evt, node, false ); - self.kernel.fireEvent( node.ID, 'pointerOut', eData.eventData ); + viewDriver.kernel.fireEvent( node.ID, 'pointerOut', eData.eventData ); } ); node.kineticObj.on( "mouseenter", function( evt ) { var eData = processEvent( evt, node, false ); - self.kernel.fireEvent( node.ID, 'pointerEnter', eData.eventData ); + //viewDriver.kernel.dispatchEvent( node.ID, 'pointerEnter', eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'pointerEnter', eData.eventData ); } ); node.kineticObj.on( "mouseleave", function( evt ) { var eData = processEvent( evt, node, false ); - self.kernel.fireEvent( node.ID, 'pointerLeave', eData.eventData ); + // viewDriver.kernel.dispatchEvent( node.ID, 'pointerLeave', eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'pointerLeave', eData.eventData ); } ); node.kineticObj.on( "mousedown", function( evt ) { var eData = processEvent( evt, node, false ); mouseDown = true; - self.kernel.fireEvent( node.ID, 'pointerDown', eData.eventData ); + //viewDriver.kernel.dispatchEvent( node.ID, 'pointerDown', eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'pointerDown', eData.eventData ); } ); node.kineticObj.on( "mouseup", function( evt ) { var eData = processEvent( evt, node, false ); mouseDown = false; - self.kernel.fireEvent( node.ID, 'pointerUp', eData.eventData ); - if ( node.kineticObj.mouseDragging ) { - self.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); - node.kineticObj.mouseDragging = false; + //viewDriver.kernel.dispatchEvent( node.ID, 'pointerUp', eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'pointerUp', eData.eventData ); + + viewDriver.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); + setViewProperty( node.ID, "x" ); + setViewProperty( node.ID, "y" ); + + if ( viewDriver.state.draggingNodes[ node.ID ] !== undefined ) { + //var x = viewDriver.state.getModelProperty( node.ID, "x" ); + //var y = viewDriver.state.getModelProperty( node.ID, "y" ); + delete viewDriver.state.draggingNodes[ node.ID ]; + //viewDriver.state.setModelProperty( node.ID, "x", x ); + //viewDriver.state.setModelProperty( node.ID, "y", y ); } + } ); node.kineticObj.on( "click", function( evt ) { var eData = processEvent( evt, node, false ); - self.kernel.fireEvent( node.ID, 'pointerClick', eData.eventData ); + //viewDriver.kernel.dispatchEvent( node.ID, 'pointerClick', eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'pointerClick', eData.eventData ); } ); node.kineticObj.on( "dblclick", function( evt ) { var eData = processEvent( evt, node, false ); - self.kernel.fireEvent( node.ID, 'pointerDoubleClick', eData.eventData ); + //viewDriver.kernel.dispatchEvent( node.ID, 'pointerDoubleClick', eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'pointerDoubleClick', eData.eventData ); } ); node.kineticObj.on( "dragstart", function( evt ) { var eData = processEvent( evt, node, false ); - self.kernel.fireEvent( node.ID, 'dragStart', eData.eventData ); + viewDriver.kernel.fireEvent( node.ID, 'dragStart', eData.eventData ); node.kineticObj.mouseDragging = true; } ); node.kineticObj.on( "dragmove", function( evt ) { var eData = processEvent( evt, node, false ); - self.kernel.fireEvent( node.ID, 'dragMove', eData.eventData ); + viewDriver.kernel.fireEvent( node.ID, 'dragMove', eData.eventData ); } ); } @@ -169,32 +147,58 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], node.kineticObj.on( "touchstart", function( evt ) { var eData = processEvent( evt, node, false ); - self.kernel.fireEvent( node.ID, 'touchStart', eData.eventData ); + //viewDriver.kernel.dispatchEvent( node.ID, "touchStart", eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'touchStart', eData.eventData ); } ); node.kineticObj.on( "touchmove", function( evt ) { var eData = processEvent( evt, node, false ); - self.kernel.fireEvent( node.ID, 'touchMove', eData.eventData ); + //viewDriver.kernel.dispatchEvent( node.ID, "touchMove", eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'touchMove', eData.eventData ); } ); node.kineticObj.on( "touchend", function( evt ) { var eData = processEvent( evt, node, false ); - self.kernel.fireEvent( node.ID, 'touchEnd', eData.eventData ); + //viewDriver.kernel.dispatchEvent( node.ID, "touchEnd", eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'touchEnd', eData.eventData ); } ); node.kineticObj.on( "tap", function( evt ) { var eData = processEvent( evt, node, false ); - self.kernel.fireEvent( node.ID, 'tap', eData.eventData ); + //viewDriver.kernel.dispatchEvent( node.ID, "tap", eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'tap', eData.eventData ); } ); node.kineticObj.on( "dbltap", function( evt ) { var eData = processEvent( evt, node, false ); - self.kernel.fireEvent( node.ID, 'doubleTap', eData.eventData ); + //viewDriver.kernel.dispatchEvent( node.ID, "dragStart", eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'doubleTap', eData.eventData ); } ); - } - - + node.kineticObj.on( "dragstart", function( evt ) { + var eData = processEvent( evt, node, false ); + //viewDriver.kernel.dispatchEvent( node.ID, "dragStart", eData.eventData, eData.eventNodeData ); + + viewDriver.kernel.fireEvent( node.ID, 'dragStart', eData.eventData ); + setViewProperty( node.ID, "x", viewDriver.state.getProperty( node.ID, "x" ) ); + setViewProperty( node.ID, "y", viewDriver.state.getProperty( node.ID, "y" ) ); + + viewDriver.state.draggingNodes[ node.ID ] = true; + } ); + + node.kineticObj.on( "dragmove", function( evt ) { + var eData = processEvent( evt, node, false ); + //viewDriver.kernel.dispatchEvent( node.ID, "dragMove", eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'dragMove', eData.eventData ); + } ); + + // I couldn't get this to work, so instead I keep track of mouseDragging separately + // in dragstart and mouseup (Eric - 11/18/14) + // node.kineticObj.on( "dragend", function( evt ) { + // var eData = processEvent( evt, node, false ); + // //viewDriver.kernel.dispatchEvent( node.ID, "dragEnd", eData.eventData, eData.eventNodeData ); + // viewDriver.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); + // } ); return view.load( module, { @@ -318,7 +322,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var timer = new Date(); var protos = node.prototypes; - if ( self.state.isKineticClass( protos, [ "kinetic", "stage", "vwf" ] ) ) { + if ( viewDriver.state.isKineticClass( protos, [ "kinetic", "stage", "vwf" ] ) ) { var stage = kineticObj; var TOUCH_EVENT = true; @@ -339,28 +343,28 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], mouseDownId = ( node !== undefined ) ? node.getId() : stage.getId(); mouseDown = true; mouseDownTime = timer.getTime(); - var eData = processEvent( evt, self.state.nodes[ mouseDownId ], true ); // false might be more corret here + var eData = processEvent( evt, viewDriver.state.nodes[ mouseDownId ], true ); // false might be more corret here - self.kernel.dispatchEvent( mouseDownId, 'pointerDown', eData.eventData, eData.eventNodeData ); + viewDriver.kernel.dispatchEvent( mouseDownId, 'pointerDown', eData.eventData, eData.eventNodeData ); }); stage.on( 'contentMousemove', function( evt ) { var node = evt.targetNode; - var eData = processEvent( evt, self.state.nodes[ mouseDownId ], true ); // false might be more corret here + var eData = processEvent( evt, viewDriver.state.nodes[ mouseDownId ], true ); // false might be more corret here - self.kernel.dispatchEvent( mouseDownId ? mouseDownId : stage.getId(), 'pointerMove', eData.eventData, eData.eventNodeData ); + viewDriver.kernel.dispatchEvent( mouseDownId ? mouseDownId : stage.getId(), 'pointerMove', eData.eventData, eData.eventNodeData ); }); stage.on( 'contentMouseup', function( evt ) { var node = evt.targetNode; mouseDown = false; - var eData = processEvent( evt, self.state.nodes[ mouseDownId ], true ); // false might be more corret here + var eData = processEvent( evt, viewDriver.state.nodes[ mouseDownId ], true ); // false might be more corret here if ( timer.getTime() - mouseDownTime < 700.0 ) { - self.kernel.dispatchEvent( mouseDownId, 'pointerClick', eData.eventData, eData.eventNodeData ); + viewDriver.kernel.dispatchEvent( mouseDownId, 'pointerClick', eData.eventData, eData.eventNodeData ); } - self.kernel.dispatchEvent( mouseDownId ? mouseDownId : stage.getId(), 'pointerUp', eData.eventData, eData.eventNodeData ); + viewDriver.kernel.dispatchEvent( mouseDownId ? mouseDownId : stage.getId(), 'pointerUp', eData.eventData, eData.eventNodeData ); mouseDownTime = null; mouseDownId = null; @@ -380,27 +384,41 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } break; case "scale": - if ( !node.uniqueInView ) { + if ( node.model.scale !== undefined ) { kineticObj.scale( { - "x": kineticObj.modelScaleX, - "y": kineticObj.modelScaleY + "x": node.model.scale.x, + "y": node.model.scale.y } ); } break; case "scaleX": - if ( !node.uniqueInView ) { - kineticObj.scaleX( kineticObj.modelScaleX ); + if ( node.model.scaleX !== undefined ) { + kineticObj.scaleX( node.model.scaleX ); } break; case "scaleY": - if ( !node.uniqueInView ) { - kineticObj.scaleY( kineticObj.modelScaleY ); + if ( node.model.scaleX !== undefined ) { + kineticObj.scaleY( node.model.scaleX ); } break; } }, + calledMethod: function( nodeID, methodName, methodParameters, methodValue ) { + + if ( this.kernel.client() === this.kernel.moniker() ) { + var prop, value, t; + switch ( methodName ) { + + case "setViewProperty": + prop = methodParameters[ 0 ]; + value = methodParameters[ 1 ]; + t = methodParameters.length > 1 ? methodParameters[ 2 ] : "dynamic"; + + setViewProperty( nodeID, prop, value, t ); + break; + gotProperty: function( nodeID, propertyName, propertyValue ) { var node = this.state.nodes[ nodeID ]; @@ -451,42 +469,54 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], node.viewIgnoreNextPositionUpdate = true; } } + }, + // firedEvent: function( nodeID, eventName ) { + // }, + ticked: function( vwfTime ) { - var nodeIDs = Object.keys( this.state.nodes ); + update( vwfTime ); + } + + + } ); + + function update( vwfTime ) { + + // switch to update, when the tickless branch is merged to development + var nodeIDs = Object.keys( viewDriver.state.draggingNodes ); + for ( var i = 0; i < nodeIDs.length; i++ ) { + var nodeID = nodeIDs[ i ]; - var node = this.state.nodes[ nodeID ]; + var node = viewDriver.state.draggingNodes[ nodeID ]; // If users can drag this node and all clients should stay synchronized, we must // pull the new node position out of kinetic and update the model with it - if ( node.kineticObj.draggable() && !node.uniqueInView ) { + if ( node.kineticObj.draggable() && node.model.x !== undefined && node.model.y !== undefined ) { var kineticX = node.kineticObj.x(); var kineticY = node.kineticObj.y(); // If the position of this node has changes since it's last model value, set the // model property with the new value - if ( ( node.kineticObj.modelX !== kineticX ) || - ( node.kineticObj.modelY !== kineticY ) ) { + if ( ( node.model.x !== kineticX ) || + ( node.model.y !== kineticY ) ) { // Fire this event to notify the model that kinetic has already updated the // view and it doesn't need to (if the model set the value, it would risk // having the model set the view back to an old value, which results in // jitter while the user is dragging the node) - vwf_view.kernel.fireEvent( nodeID, "draggingFromView" ); - vwf_view.kernel.setProperty( nodeID, "position", [ kineticX, kineticY ] ); + viewDriver.kernel.fireEvent( nodeID, "draggingFromView" ); + viewDriver.kernel.setProperty( nodeID, "position", [ kineticX, kineticY ] ); } } } - for ( var id in self.state.stages ){ - renderScene( self.state.stages[ id ] ); + + for ( var id in viewDriver.state.stages ){ + renderScene( viewDriver.state.stages[ id ] ); } - } - - - } ); function renderScene( stage ) { //window.requestAnimationFrame( renderScene( stage ) ); @@ -495,5 +525,119 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } } + function processEvent( e, node, propagate ) { + var returnData = { eventData: undefined, eventNodeData: undefined }; + + if ( !propagate ) { + // For the "dragend" event, kinetic sometimes sends us an event object that doesn't + // have all the expected functions and properties attached + e.evt.stopPropagation && e.evt.stopPropagation(); + } + + var eventPosition; + var isTouchEvent = ( e.evt instanceof TouchEvent ); + if ( isTouchEvent ) { + eventPosition = e.evt.changedTouches[ 0 ]; + } else { + eventPosition = e.evt; + } + + var stage = node && node.stage; + returnData.eventData = [ convertBrowserEventDataToVwf( eventPosition, stage ) ]; + + var eventDataElement = returnData.eventData[ 0 ]; + eventDataElement.button = e.evt.button; + eventDataElement.timeStamp = e.evt.timeStamp; + eventDataElement.shiftKey = e.evt.shiftKey; + eventDataElement.ctrlKey = e.evt.ctrlKey; + eventDataElement.altKey = e.evt.altKey; + eventDataElement.metaKey = e.evt.metaKey; + + if ( isTouchEvent ) { + returnData.eventData[ 0 ].touches = []; + for ( var i = 0; i < e.evt.touches.length; i++ ) { + returnData.eventData[ 0 ].touches[ i ] = convertBrowserEventDataToVwf( + e.evt.touches[ i ], + stage + ); + } + } + + if ( propagate ) { + + var stageId = stage && stage.getId(); + var pointerPickID = e.targetNode ? e.targetNode.getId() : stageId; + + returnData.eventNodeData = { "": [ { + pickID: pointerPickID, + } ] }; + + if ( viewDriver && viewDriver.state.nodes[ pointerPickID ] ) { + var childID = pointerPickID; + var child = viewDriver.state.nodes[ childID ]; + var parentID = child.parentID; + var parent = viewDriver.state.nodes[ child.parentID ]; + while ( child ) { + + returnData.eventNodeData[ childID ] = [ { + pickID: pointerPickID, + } ]; + + childID = parentID; + child = viewDriver.state.nodes[ childID ]; + parentID = child ? child.parentID : undefined; + parent = parentID ? viewDriver.state.nodes[ child.parentID ] : undefined; + + } + } + } + + return returnData; + } + + function convertBrowserEventDataToVwf( browserEventData, stage ) { + var vwfEventData = { + "location": [ browserEventData.x, browserEventData.y ], + "stageRelative": [ browserEventData.pageX, browserEventData.pageY ], + "client": [ browserEventData.clientX, browserEventData.clientY ], + "screen": [ browserEventData.screenX, browserEventData.screenY ], + "layer": [ browserEventData.layerX, browserEventData.layerY ], + "page": [ browserEventData.pageX, browserEventData.pageY ], + "offset": [ browserEventData.offsetX, browserEventData.offsetY ], + "movement": [ browserEventData.webkitMovementX, browserEventData.webkitMovementY ] + }; + + if ( stage ) { + vwfEventData.stage = [ stage.x(), stage.y() ]; + vwfEventData.stageRelative = [ + ( browserEventData.pageX - stage.x() ) / stage.scaleX(), + ( browserEventData.pageY - stage.y() ) / stage.scaleY() + ]; + } + return vwfEventData; + } + + function setViewProperty( id, propertyName, propertyValue, type ) { + + //console.info( "setViewProperty( "+id+", "+propertyName+", "+propertyValue+", "+type+" )" ); + node = viewDriver.state.nodes[ id ]; + if ( node && node.kineticObj ) { + if ( utility.validObject( propertyValue ) ) { + if ( node.model[ propertyName ] === undefined ) { + node.model[ propertyName ] = { + "value": viewDriver.state.getProperty( node.kineticObj, propertyName ), + "type": type + }; + } + viewDriver.state.setProperty( node.kineticObj, propertyName, propertyValue ); + } else { + var modelValue = node.model[ propertyName ].value; + if ( modelValue !== undefined ) { + delete node.model[ propertyName ]; + viewDriver.state.setProperty( node.kineticObj, propertyName, modelValue ); + } + } + } + } }); \ No newline at end of file diff --git a/support/proxy/vwf.example.com/kinetic/drawing.js b/support/proxy/vwf.example.com/kinetic/drawing.js index 843e29de8..60ec15f09 100644 --- a/support/proxy/vwf.example.com/kinetic/drawing.js +++ b/support/proxy/vwf.example.com/kinetic/drawing.js @@ -21,20 +21,21 @@ this.clientWatch = function() { }; -// this.isValid = function( obj ) { -// var objType = ( {} ).toString.call( obj ).match( /\s([a-zA-Z]+)/ )[ 1 ].toLowerCase(); -// return ( objType != 'null' && objType != 'undefined' ); -// }; +this.isValid = function( obj ) { + -this.clientJoin = function( moniker ) { - function isValid( obj ) { var objType = ( {} ).toString.call( obj ).match( /\s([a-zA-Z]+)/ )[ 1 ].toLowerCase(); return ( objType != 'null' && objType != 'undefined' ); - }; +}; + +this.clientJoin = function( moniker ) { + if ( this.id === "http://vwf.example.com/kinetic/drawing.vwf" ){ + return; + } // mirrors the initial state of the toolbar - if ( !isValid( this.drawing_clients ) ) { + if ( !this.isValid( this.drawing_clients ) ) { this.drawing_clients = {}; } if ( this.drawing_clients[ moniker ] === undefined ) { @@ -50,7 +51,7 @@ this.clientJoin = function( moniker ) { "angle": 30 }; } - this.drawing_clients = this.drawing_clients; + //this.drawing_clients = this.drawing_clients; }; @@ -82,15 +83,10 @@ this.setUpPrivate = function( moniker ) { this.setClientUIState = function( stateObj ) { - function isValid( obj ) { - var objType = ( {} ).toString.call( obj ).match( /\s([a-zA-Z]+)/ )[ 1 ].toLowerCase(); - return ( objType != 'null' && objType != 'undefined' ); - }; - //console.info( "setClientUIState " + JSON.stringify( stateObj ) ); if ( stateObj !== undefined ) { - if ( !isValid( this.drawing_clients ) || - !isValid( this.drawing_clients[ this.client ] ) ) { + if ( !this.isValid( this.drawing_clients ) || + !this.isValid( this.drawing_clients[ this.client ] ) ) { this.clientJoin( this.client ); } var clients = this.drawing_clients; @@ -104,16 +100,12 @@ this.setClientUIState = function( stateObj ) { this.down = function( eventData, nodeData, touch ) { - function isValid( obj ) { - var objType = ( {} ).toString.call( obj ).match( /\s([a-zA-Z]+)/ )[ 1 ].toLowerCase(); - return ( objType != 'null' && objType != 'undefined' ); - }; - if ( !isValid( this.drawing_clients ) || - !isValid( this.drawing_clients[ this.client ] ) ) { + if ( !this.isValid( this.drawing_clients ) || + !this.isValid( this.drawing_clients[ this.client ] ) ) { this.clientJoin( this.client ); } - if ( !isValid( this.drawing_private ) || - !isValid( this.drawing_private[ this.client ] ) ) { + if ( !this.isValid( this.drawing_private ) || + !this.isValid( this.drawing_private[ this.client ] ) ) { this.setUpPrivate( this.client ); } @@ -290,13 +282,9 @@ this.down = function( eventData, nodeData, touch ) { this.move = function( eventData, nodeData, touch ) { - function isValid( obj ) { - var objType = ( {} ).toString.call( obj ).match( /\s([a-zA-Z]+)/ )[ 1 ].toLowerCase(); - return ( objType != 'null' && objType != 'undefined' ); - }; - if ( !isValid( this.drawing_clients ) || - !isValid( this.drawing_clients[ this.client ] ) ) { + if ( !this.isValid( this.drawing_clients ) || + !this.isValid( this.drawing_clients[ this.client ] ) ) { this.clientJoin( this.client ); } if ( this.drawing_private === undefined || @@ -353,15 +341,10 @@ this.up = function( eventData, nodeData, touch ) { }; this.update = function( eventData, nodeData, upEvent ) { - - function isValid( obj ) { - var objType = ( {} ).toString.call( obj ).match( /\s([a-zA-Z]+)/ )[ 1 ].toLowerCase(); - return ( objType != 'null' && objType != 'undefined' ); - }; if ( this.drawing_private === undefined || this.drawing_private[ this.client ] === undefined || - !isValid( this.drawing_clients ) ) { + !this.isValid( this.drawing_clients ) ) { return; } diff --git a/support/proxy/vwf.example.com/kinetic/node.vwf.yaml b/support/proxy/vwf.example.com/kinetic/node.vwf.yaml index e26686357..e02622624 100644 --- a/support/proxy/vwf.example.com/kinetic/node.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/node.vwf.yaml @@ -31,7 +31,6 @@ properties: absoluteTransform: absoluteOpacity: absoluteZIndex: - uniqueInView: supportMouseEvents: supportTouchEvents: hasMouseEvents: false From b551cfa5489adf749334ef480b88f629bce034a6 Mon Sep 17 00:00:00 2001 From: youngca Date: Wed, 13 May 2015 09:51:04 -0400 Subject: [PATCH 011/644] Rebased kinetic-view on development. Some bug fixes implemented to correct referencing node properly. --- support/client/lib/vwf/model/kineticjs.js | 736 +++++++++--------- support/client/lib/vwf/view/kineticjs.js | 258 +++--- .../proxy/vwf.example.com/kinetic/drawing.js | 7 +- .../vwf.example.com/kinetic/drawing.vwf.yaml | 2 +- 4 files changed, 487 insertions(+), 516 deletions(-) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index 0b529836a..906460ed8 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -40,9 +40,9 @@ define( [ "module", "prototypes": undefined, "kineticObj": undefined, "stage": undefined, - "uniqueInView": false + //"uniqueInView": false, "hasMouseEvents": false, - "hasTouchEvents": false + "hasTouchEvents": false, "model": {} }; }, "isKineticClass": function( prototypes, classID ) { @@ -64,10 +64,14 @@ define( [ "module", } } return found; - }, + }, "setProperty": function( kineticObj, propertyName, propertyValue ) { var value = undefined; + if ( !kineticObj ) { + return value; + } + value = this.setNodeProperty( kineticObj, propertyName, propertyValue ); if ( value === undefined ) { @@ -76,11 +80,11 @@ define( [ "module", if ( value === undefined ) { value = this.setContainerProperty( kineticObj, propertyName, propertyValue ); - } + } if ( value === undefined && kineticObj instanceof Kinetic.Arc ) { value = this.setArcProperty( kineticObj, propertyName, propertyValue ); - } + } if ( value === undefined && ( kineticObj instanceof Kinetic.BaseLayer || @@ -88,7 +92,7 @@ define( [ "module", kineticObj instanceof Kinetic.Layer ) ) { value = this.setLayerProperty( kineticObj, propertyName, propertyValue ); - } + } if ( value === undefined && kineticObj instanceof Kinetic.Canvas ) { value = this.setCanvasProperty( kineticObj, propertyName, propertyValue ); @@ -104,27 +108,27 @@ define( [ "module", if ( value === undefined && kineticObj instanceof Kinetic.Image ) { value = this.setImageProperty( kineticObj, propertyName, propertyValue ); - } + } if ( value === undefined && kineticObj instanceof Kinetic.Line ) { value = this.setLineProperty( kineticObj, propertyName, propertyValue ); - } + } if ( value === undefined && kineticObj instanceof Kinetic.Path ) { value = this.setPathProperty( kineticObj, propertyName, propertyValue ); - } + } if ( value === undefined && kineticObj instanceof Kinetic.Rect ) { value = this.setRectProperty( kineticObj, propertyName, propertyValue ); - } + } if ( value === undefined && kineticObj instanceof Kinetic.RegularPolygon ) { value = this.setRegularPolygonProperty( kineticObj, propertyName, propertyValue ); - } + } if ( value === undefined && kineticObj instanceof Kinetic.Ring ) { value = this.setRingProperty( kineticObj, propertyName, propertyValue ); - } + } if ( value === undefined && kineticObj instanceof Kinetic.Sprite ) { value = this.setSpriteProperty( kineticObj, propertyName, propertyValue ); @@ -132,21 +136,21 @@ define( [ "module", if ( value === undefined && kineticObj instanceof Kinetic.Star ) { value = this.setStarProperty( kineticObj, propertyName, propertyValue ); - } + } if ( value === undefined && kineticObj instanceof Kinetic.Text ) { value = this.setTextProperty( kineticObj, propertyName, propertyValue ); - } + } if ( value === undefined && kineticObj instanceof Kinetic.TextPath ) { value = this.setTextPathProperty( kineticObj, propertyName, propertyValue ); - } + } if ( value === undefined && kineticObj instanceof Kinetic.Wedge ) { value = this.setWedgeProperty( kineticObj, propertyName, propertyValue ); - } + } return value; - }, + }, "setNodeProperty": function( kineticObj, propertyName, propertyValue ) { var value = propertyValue; @@ -1158,468 +1162,470 @@ define( [ "module", value = undefined; break; } - return value; - }, + return value; + }, "getProperty": function( kineticObj, propertyName ) { - var value = undefined; - - switch ( propertyName ) { + var value = undefined; + if ( !kineticObj ) { + return value; + } - case "x": - value = kineticObj.modelX || 0; - break; + //if ( value === undefined ) { - case "y": - value = kineticObj.modelY || 0; - break; + switch ( propertyName ) { - case "width": - value = kineticObj.width(); - break; + case "x": + value = kineticObj.x() || 0; + break; - case "height": - value = kineticObj.height(); - break; + case "y": + value = kineticObj.y() || 0; + break; - case "visible": - value = kineticObj.visible(); - break; + case "width": + value = kineticObj.width(); + break; - case "isVisible": - value = kineticObj.isVisible(); - break; + case "height": + value = kineticObj.height(); + break; - case "listening": - value = kineticObj.listening(); - break; - - case "isListening": - value = kineticObj.isListening(); - break; - - case "opacity": - value = kineticObj.opacity(); - break; + case "visible": + value = kineticObj.visible(); + break; - case "scale": - value = kineticObj.scale(); - break; + case "isVisible": + value = kineticObj.isVisible(); + break; - case "scaleX": - value = kineticObj.scaleX(); - break; + case "listening": + value = kineticObj.listening(); + break; + + case "isListening": + value = kineticObj.isListening(); + break; + + case "opacity": + value = kineticObj.opacity(); + break; - case "scaleY": - value = kineticObj.scaleY(); - break; + case "scale": + value = kineticObj.scale(); + break; - case "rotation": - value = kineticObj.rotation(); - break; + case "scaleX": + value = kineticObj.scaleX(); + break; - // check code, not in docs - case "offset": - value = kineticObj.offset(); - break; + case "scaleY": + value = kineticObj.scaleY(); + break; - // check code, not in docs - case "offsetX": - value = kineticObj.offsetX(); - break; + case "rotation": + value = kineticObj.rotation(); + break; - case "offsetY": - value = kineticObj.offsetY(); - break; + // check code, not in docs + case "offset": + value = kineticObj.offset(); + break; - case "draggable": - // Return the model value that we have stored separately, - // not the value that is directly in the kinetic object - // because a user's view might have changed that for only - // that user - value = kineticObj.isDraggable; - break; + // check code, not in docs + case "offsetX": + value = kineticObj.offsetX(); + break; - // check code, not in docs - case "dragDistance": - value = kineticObj.dragDistance(); - break; + case "offsetY": + value = kineticObj.offsetY(); + break; - case "zIndex": - value = kineticObj.getZIndex(); - break; + case "draggable": + // Return the model value that we have stored separately, + // not the value that is directly in the kinetic object + // because a user's view might have changed that for only + // that user + value = kineticObj.isDraggable; + break; - case "dragBoundFunc": - var dragBoundFunc = kineticObj.dragBoundFunc(); - value = dragBoundFunc ? dragBoundFunc.toString() : undefined; - break; + // check code, not in docs + case "dragDistance": + value = kineticObj.dragDistance(); + break; - case "id": - value = kineticObj.getId(); - break + case "zIndex": + value = kineticObj.getZIndex(); + break; - case "name": - value = kineticObj.getName(); - break; - - case "position": - value = { - x: kineticObj.modelX || 0, - y: kineticObj.modelY || 0 - }; - break; + case "dragBoundFunc": + var dragBoundFunc = kineticObj.dragBoundFunc(); + value = dragBoundFunc ? dragBoundFunc.toString() : undefined; + break; - case "transform": - value = kineticObj.getTransform().m; - //value[ 4 ] = kineticObj.modelX || 0; - //value[ 5 ] = kineticObj.modelY || 0; - break; + case "id": + value = kineticObj.getId(); + break - case "absolutePosition": - value = kineticObj.getAbsolutePosition(); - break; + case "name": + value = kineticObj.getName(); + break; + + case "position": + value = { + x: kineticObj.x() || 0, + y: kineticObj.y() || 0 + }; + break; - case "absoluteTransform": - value = kineticObj.getAbsoluteTransform(); - break; + case "transform": + value = kineticObj.getTransform().m; + break; - case "absoluteOpacity": - value = kineticObj.getAbsoluteOpacity(); - break; + case "absolutePosition": + value = kineticObj.getAbsolutePosition(); + break; - case "absoluteZIndex": - value = kineticObj.getAbsoluteZIndex(); - break; + case "absoluteTransform": + value = kineticObj.getAbsoluteTransform(); + break; - } + case "absoluteOpacity": + value = kineticObj.getAbsoluteOpacity(); + break; + case "absoluteZIndex": + value = kineticObj.getAbsoluteZIndex(); + break; + } + //} - // this is causing the editor to cause a infinite loop - // need to understand why, but no time now + // this is causing the editor to cause a infinite loop + // need to understand why, but no time now - // if ( value === undefined && kineticObj instanceof Kinetic.Stage ) { - - // switch ( propertyName ) { + // if ( value === undefined && kineticObj instanceof Kinetic.Stage ) { - // case "container": - // value = kineticObj.getAttr( 'container' ); - // break; - // } - // } + // switch ( propertyName ) { + + // case "container": + // value = kineticObj.getAttr( 'container' ); + // break; + // } + // } - if ( value === undefined && kineticObj instanceof Kinetic.Arc ) { - - switch ( propertyName ) { + if ( value === undefined && kineticObj instanceof Kinetic.Arc ) { - case "angle": - value = kineticObj.angle(); - break; + switch ( propertyName ) { + + case "angle": + value = kineticObj.angle(); + break; - case "innerRadius": - value = kineticObj.innerRadius(); - break; + case "innerRadius": + value = kineticObj.innerRadius(); + break; - case "outerRadius": - value = kineticObj.outerRadius(); - break; + case "outerRadius": + value = kineticObj.outerRadius(); + break; - case "clockwise": - value = kineticObj.clockwise(); - break; + case "clockwise": + value = kineticObj.clockwise(); + break; + } } - } - if ( value === undefined && - ( kineticObj instanceof Kinetic.BaseLayer || - kineticObj instanceof Kinetic.FastLayer || - kineticObj instanceof Kinetic.Layer - ) ) { - - switch ( propertyName ) { + if ( value === undefined && + ( kineticObj instanceof Kinetic.BaseLayer || + kineticObj instanceof Kinetic.FastLayer || + kineticObj instanceof Kinetic.Layer + ) ) { + + switch ( propertyName ) { - case "clearBeforeDraw": - value = kineticObj.clearBeforeDraw(); - break; - } - } + case "clearBeforeDraw": + value = kineticObj.clearBeforeDraw(); + break; + } + } - if ( value === undefined && kineticObj instanceof Kinetic.Canvas ) { - - switch ( propertyName ) { + if ( value === undefined && kineticObj instanceof Kinetic.Canvas ) { + + switch ( propertyName ) { - case width: - value = kineticObj.getWidth(); - break; + case width: + value = kineticObj.getWidth(); + break; - case height: - value = kineticObj.getHeight(); - break; + case height: + value = kineticObj.getHeight(); + break; - case pixelRatio: - value = kineticObj.getPixelRatio(); - break; - } - } + case pixelRatio: + value = kineticObj.getPixelRatio(); + break; + } + } - if ( value === undefined && kineticObj instanceof Kinetic.Circle ) { - - switch ( propertyName ) { + if ( value === undefined && kineticObj instanceof Kinetic.Circle ) { + + switch ( propertyName ) { - case "radius": - value = kineticObj.radius(); - break; + case "radius": + value = kineticObj.radius(); + break; - } - } + } + } - if ( value === undefined && kineticObj instanceof Kinetic.Ellipse ) { - - switch ( propertyName ) { + if ( value === undefined && kineticObj instanceof Kinetic.Ellipse ) { + + switch ( propertyName ) { - case "radius": - value = kineticObj.radius(); - break; - } - } + case "radius": + value = kineticObj.radius(); + break; + } + } - if ( value === undefined && kineticObj instanceof Kinetic.Image ) { - - switch ( propertyName ) { + if ( value === undefined && kineticObj instanceof Kinetic.Image ) { + + switch ( propertyName ) { - case "image": - var imageObj = kineticObj.image(); - if ( imageObj !== undefined ) { - value = imageObj.src; - } - break; + case "image": + var imageObj = kineticObj.image(); + if ( imageObj !== undefined ) { + value = imageObj.src; + } + break; - case "crop": - value = kineticObj.crop(); - break; + case "crop": + value = kineticObj.crop(); + break; - case "scaleOnLoad": - //value = node.scaleOnLoad; - break; - - } - } + case "scaleOnLoad": + //value = node.scaleOnLoad; + break; + + } + } - if ( value === undefined && kineticObj instanceof Kinetic.Line ) { - - switch ( propertyName ) { + if ( value === undefined && kineticObj instanceof Kinetic.Line ) { - case "points": - value = kineticObj.points(); - break; + switch ( propertyName ) { + + case "points": + value = kineticObj.points(); + break; - case "tension": - value = kineticObj.tension(); - break; + case "tension": + value = kineticObj.tension(); + break; - case "closed": - value = kineticObj.closed(); - break; + case "closed": + value = kineticObj.closed(); + break; + } } - } - if ( value === undefined && kineticObj instanceof Kinetic.Path ) { - - switch ( propertyName ) { + if ( value === undefined && kineticObj instanceof Kinetic.Path ) { - case "data": - value = kineticObj.data(); - break; + switch ( propertyName ) { + + case "data": + value = kineticObj.data(); + break; + } } - } - if ( value === undefined && kineticObj instanceof Kinetic.Rect ) { - - switch ( propertyName ) { + if ( value === undefined && kineticObj instanceof Kinetic.Rect ) { - case "cornerRadius": - value = kineticObj.cornerRadius(); - break; + switch ( propertyName ) { + + case "cornerRadius": + value = kineticObj.cornerRadius(); + break; + } } - } - if ( value === undefined && kineticObj instanceof Kinetic.RegularPolygon ) { - - switch ( propertyName ) { + if ( value === undefined && kineticObj instanceof Kinetic.RegularPolygon ) { - case "sides": - value = kineticObj.sides(); - break; + switch ( propertyName ) { + + case "sides": + value = kineticObj.sides(); + break; - case "radius": - value = kineticObj.radius(); - break; + case "radius": + value = kineticObj.radius(); + break; + } } - } - - if ( value === undefined && kineticObj instanceof Kinetic.Ring ) { - - switch ( propertyName ) { + + if ( value === undefined && kineticObj instanceof Kinetic.Ring ) { - case "innerRadius": - value = kineticObj.innerRadius(); - break; + switch ( propertyName ) { + + case "innerRadius": + value = kineticObj.innerRadius(); + break; - case "outerRadius": - value = kineticObj.outerRadius(); - break; + case "outerRadius": + value = kineticObj.outerRadius(); + break; + } } - } - - if ( value === undefined && kineticObj instanceof Kinetic.Sprite ) { - switch ( propertyName ) { + if ( value === undefined && kineticObj instanceof Kinetic.Sprite ) { - case "animation": - value = kineticObj.animation(); - break; + switch ( propertyName ) { + + case "animation": + value = kineticObj.animation(); + break; - case "animations": - value = JSON.stringify( kineticObj.animations() ); - break; + case "animations": + value = JSON.stringify( kineticObj.animations() ); + break; - case "frameIndex": - value = kineticObj.frameIndex(); - break; + case "frameIndex": + value = kineticObj.frameIndex(); + break; - case "image": - var imageObj = kineticObj.image(); - if ( imageObj !== undefined ) { - value = imageObj.src; - } - break; + case "image": + var imageObj = kineticObj.image(); + if ( imageObj !== undefined ) { + value = imageObj.src; + } + break; - case "scaleOnLoad": - //value = node.scaleOnLoad; - break; + case "scaleOnLoad": + //value = node.scaleOnLoad; + break; + } } - } - if ( value === undefined && kineticObj instanceof Kinetic.Star ) { - - switch ( propertyName ) { + if ( value === undefined && kineticObj instanceof Kinetic.Star ) { - case "numPoints": - value = kineticObj.animation(); - break; + switch ( propertyName ) { + + case "numPoints": + value = kineticObj.animation(); + break; - case "innerRadius": - value = kineticObj.innerRadius(); - break; + case "innerRadius": + value = kineticObj.innerRadius(); + break; - case "outerRadius": - value = kineticObj.outerRadius(); - break; + case "outerRadius": + value = kineticObj.outerRadius(); + break; + } } - } - if ( value === undefined && kineticObj instanceof Kinetic.Text ) { - - switch ( propertyName ) { + if ( value === undefined && kineticObj instanceof Kinetic.Text ) { - case "fontFamily": - value = kineticObj.fontFamily(); - break; + switch ( propertyName ) { + + case "fontFamily": + value = kineticObj.fontFamily(); + break; - case "fontSize": - value = kineticObj.fontSize(); - break; + case "fontSize": + value = kineticObj.fontSize(); + break; - case "fontStyle": - value = kineticObj.fontStyle(); - break; + case "fontStyle": + value = kineticObj.fontStyle(); + break; - case "fontVariant": - value = kineticObj.fontVariant(); - break; + case "fontVariant": + value = kineticObj.fontVariant(); + break; - case "text": - value = kineticObj.text(); - break; + case "text": + value = kineticObj.text(); + break; - case "align": - value = kineticObj.align(); - break; + case "align": + value = kineticObj.align(); + break; - case "padding": - value = kineticObj.padding(); - break; + case "padding": + value = kineticObj.padding(); + break; - case "width": - value = kineticObj.width(); - break; + case "width": + value = kineticObj.width(); + break; - case "height": - value = kineticObj.height(); - break; + case "height": + value = kineticObj.height(); + break; - case "lineHeight": - value = kineticObj.lineHeight(); - break; + case "lineHeight": + value = kineticObj.lineHeight(); + break; - case "wrap": - value = kineticObj.wrap(); - break; + case "wrap": + value = kineticObj.wrap(); + break; + } } - } - if ( value === undefined && kineticObj instanceof Kinetic.TextPath ) { - - switch ( propertyName ) { + if ( value === undefined && kineticObj instanceof Kinetic.TextPath ) { - case "fontFamily": - value = kineticObj.fontFamily(); - break; + switch ( propertyName ) { + + case "fontFamily": + value = kineticObj.fontFamily(); + break; - case "fontSize": - value = kineticObj.fontSize(); - break; + case "fontSize": + value = kineticObj.fontSize(); + break; - case "fontStyle": - value = kineticObj.fontStyle(); - break; + case "fontStyle": + value = kineticObj.fontStyle(); + break; - case "fontVariant": - value = kineticObj.fontVariant(); - break; + case "fontVariant": + value = kineticObj.fontVariant(); + break; - case "text": - value = kineticObj.text(); - break; + case "text": + value = kineticObj.text(); + break; - case "data": - value = kineticObj.data(); - break; + case "data": + value = kineticObj.data(); + break; + } } - } - if ( value === undefined && kineticObj instanceof Kinetic.Wedge ) { - - switch ( propertyName ) { + if ( value === undefined && kineticObj instanceof Kinetic.Wedge ) { - case "angle": - value = kineticObj.angle(); - break; + switch ( propertyName ) { + + case "angle": + value = kineticObj.angle(); + break; - case "radius": - value = kineticObj.radius(); - break; + case "radius": + value = kineticObj.radius(); + break; - case "clockwise": - kineticObj.clockwise(); - break; + case "clockwise": + kineticObj.clockwise(); + break; + } } - } return value; - } + } }; // turns on logger debugger console messages diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index dac2e71f8..b72cffb82 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -10,134 +10,120 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], function attachMouseEvents( node ) { - initialize: function( options ) { - - viewDriver = this; - - this.arguments = Array.prototype.slice.call( arguments ); - - this.options = options || {}; - - if ( window && window.innerWidth ) { - stageWidth = window.innerWidth - 20; - } - if ( window && window.innerHeight ) { - stageHeight = window.innerHeight - 20; - } - - stageContainer = this.options.container || 'vwf-root'; - stageWidth = this.options.width || stageWidth; - stageHeight = this.options.height || stageHeight; - }, - - createdNode: function( nodeID, childID, childExtendsID, childImplementsIDs, - childSource, childType, childIndex, childName, callback ) { - - var node = this.state.nodes[ childID ]; - - // If the "nodes" object does not have this object in it, it must not be one that - // this driver cares about - if ( !node ) { - return; - } - - var protos = node.prototypes; - if ( viewDriver.state.isKineticClass( protos, [ "kinetic", "stage", "vwf" ] ) ) { - var stage = this.state.stage = node.kineticObj; - } - - }, - - initializedNode: function( nodeID, childID, childExtendsID, childImplementsIDs, - childSource, childType, childIndex, childName, callback ) { - - var node = this.state.nodes[ childID ]; - - // If the "nodes" object does not have this object in it, it must not be one that - // this driver cares about - if ( !node ) { - - //var stage = this.state.stages[ childID ]; - //renderScene( stage ); - return; - } - - if ( node.kineticObj ) { - var mouseDown = false; node.kineticObj.on( "mousemove", function( evt ) { var eData = processEvent( evt, node, false ); - //viewDriver.kernel.dispatchEvent( node.ID, 'pointerMove', eData.eventData, eData.eventNodeData ); - viewDriver.kernel.fireEvent( node.ID, 'pointerMove', eData.eventData ); + //viewDriver.kernel.dispatchEvent( node.ID, 'pointerMove', eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'pointerMove', eData.eventData ); } ); node.kineticObj.on( "mouseout", function( evt ) { var eData = processEvent( evt, node, false ); - viewDriver.kernel.fireEvent( node.ID, 'pointerOut', eData.eventData ); + viewDriver.kernel.fireEvent( node.ID, 'pointerOut', eData.eventData ); } ); node.kineticObj.on( "mouseenter", function( evt ) { var eData = processEvent( evt, node, false ); - //viewDriver.kernel.dispatchEvent( node.ID, 'pointerEnter', eData.eventData, eData.eventNodeData ); - viewDriver.kernel.fireEvent( node.ID, 'pointerEnter', eData.eventData ); + //viewDriver.kernel.dispatchEvent( node.ID, 'pointerEnter', eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'pointerEnter', eData.eventData ); } ); node.kineticObj.on( "mouseleave", function( evt ) { var eData = processEvent( evt, node, false ); - // viewDriver.kernel.dispatchEvent( node.ID, 'pointerLeave', eData.eventData, eData.eventNodeData ); - viewDriver.kernel.fireEvent( node.ID, 'pointerLeave', eData.eventData ); + // viewDriver.kernel.dispatchEvent( node.ID, 'pointerLeave', eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'pointerLeave', eData.eventData ); } ); node.kineticObj.on( "mousedown", function( evt ) { var eData = processEvent( evt, node, false ); mouseDown = true; - //viewDriver.kernel.dispatchEvent( node.ID, 'pointerDown', eData.eventData, eData.eventNodeData ); - viewDriver.kernel.fireEvent( node.ID, 'pointerDown', eData.eventData ); + //viewDriver.kernel.dispatchEvent( node.ID, 'pointerDown', eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'pointerDown', eData.eventData ); } ); node.kineticObj.on( "mouseup", function( evt ) { var eData = processEvent( evt, node, false ); mouseDown = false; - //viewDriver.kernel.dispatchEvent( node.ID, 'pointerUp', eData.eventData, eData.eventNodeData ); - viewDriver.kernel.fireEvent( node.ID, 'pointerUp', eData.eventData ); - - viewDriver.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); - setViewProperty( node.ID, "x" ); - setViewProperty( node.ID, "y" ); - - if ( viewDriver.state.draggingNodes[ node.ID ] !== undefined ) { - //var x = viewDriver.state.getModelProperty( node.ID, "x" ); - //var y = viewDriver.state.getModelProperty( node.ID, "y" ); - delete viewDriver.state.draggingNodes[ node.ID ]; - //viewDriver.state.setModelProperty( node.ID, "x", x ); - //viewDriver.state.setModelProperty( node.ID, "y", y ); + //viewDriver.kernel.dispatchEvent( node.ID, 'pointerUp', eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'pointerUp', eData.eventData ); + + if ( node.kineticObj.mouseDragging ) { + viewDriver.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); + node.kineticObj.mouseDragging = false; + + //setViewProperty( node.ID, "x", eData.eventData.stageRelative.x ); + //setViewProperty( node.ID, "y", eData.eventData.stageRelative.y ); + + if ( viewDriver.state.draggingNodes[ node.ID ] !== undefined ) { + //var x = viewDriver.state.getModelProperty( node.ID, "x" ); + //var y = viewDriver.state.getModelProperty( node.ID, "y" ); + delete viewDriver.state.draggingNodes[ node.ID ]; + //viewDriver.state.setModelProperty( node.ID, "x", x ); + //viewDriver.state.setModelProperty( node.ID, "y", y ); + } } } ); node.kineticObj.on( "click", function( evt ) { var eData = processEvent( evt, node, false ); - //viewDriver.kernel.dispatchEvent( node.ID, 'pointerClick', eData.eventData, eData.eventNodeData ); - viewDriver.kernel.fireEvent( node.ID, 'pointerClick', eData.eventData ); + //viewDriver.kernel.dispatchEvent( node.ID, 'pointerClick', eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'pointerClick', eData.eventData ); } ); node.kineticObj.on( "dblclick", function( evt ) { var eData = processEvent( evt, node, false ); - //viewDriver.kernel.dispatchEvent( node.ID, 'pointerDoubleClick', eData.eventData, eData.eventNodeData ); - viewDriver.kernel.fireEvent( node.ID, 'pointerDoubleClick', eData.eventData ); + //viewDriver.kernel.dispatchEvent( node.ID, 'pointerDoubleClick', eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'pointerDoubleClick', eData.eventData ); } ); + /* node.kineticObj.on( "dragstart", function( evt ) { var eData = processEvent( evt, node, false ); viewDriver.kernel.fireEvent( node.ID, 'dragStart', eData.eventData ); node.kineticObj.mouseDragging = true; } ); + + + node.kineticObj.on( "dragmove", function( evt ) { + var eData = processEvent( evt, node, false ); + viewDriver.kernel.fireEvent( node.ID, 'dragMove', eData.eventData ); + } ); + */ + + node.kineticObj.on( "dragstart", function( evt ) { + var eData = processEvent( evt, node, false ); + //viewDriver.kernel.dispatchEvent( node.ID, "dragStart", eData.eventData, eData.eventNodeData ); + + viewDriver.kernel.fireEvent( node.ID, 'dragStart', eData.eventData ); + + //var xPos = viewDriver.state.getProperty( node.ID, "x" ); + //var yPos = viewDriver.state.getProperty( node.ID, "y" ); + var xPos = viewDriver.state.getProperty( node.kineticObj, "x" ); + var yPos = viewDriver.state.getProperty( node.kineticObj, "y" ); + setViewProperty( node.ID, "x", xPos ); + setViewProperty( node.ID, "y", yPos ); + + //viewDriver.state.draggingNodes[ node.ID ] = true; + viewDriver.state.draggingNodes[ node.ID ] = node; + node.kineticObj.mouseDragging = true; + } ); + node.kineticObj.on( "dragmove", function( evt ) { var eData = processEvent( evt, node, false ); + //viewDriver.kernel.dispatchEvent( node.ID, "dragMove", eData.eventData, eData.eventNodeData ); viewDriver.kernel.fireEvent( node.ID, 'dragMove', eData.eventData ); } ); + + // I couldn't get this to work, so instead I keep track of mouseDragging separately + // in dragstart and mouseup (Eric - 11/18/14) + // node.kineticObj.on( "dragend", function( evt ) { + // var eData = processEvent( evt, node, false ); + // //viewDriver.kernel.dispatchEvent( node.ID, "dragEnd", eData.eventData, eData.eventNodeData ); + // viewDriver.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); + // } ); } @@ -147,64 +133,40 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], node.kineticObj.on( "touchstart", function( evt ) { var eData = processEvent( evt, node, false ); - //viewDriver.kernel.dispatchEvent( node.ID, "touchStart", eData.eventData, eData.eventNodeData ); - viewDriver.kernel.fireEvent( node.ID, 'touchStart', eData.eventData ); + //viewDriver.kernel.dispatchEvent( node.ID, "touchStart", eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'touchStart', eData.eventData ); } ); node.kineticObj.on( "touchmove", function( evt ) { var eData = processEvent( evt, node, false ); - //viewDriver.kernel.dispatchEvent( node.ID, "touchMove", eData.eventData, eData.eventNodeData ); - viewDriver.kernel.fireEvent( node.ID, 'touchMove', eData.eventData ); + //viewDriver.kernel.dispatchEvent( node.ID, "touchMove", eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'touchMove', eData.eventData ); } ); node.kineticObj.on( "touchend", function( evt ) { var eData = processEvent( evt, node, false ); - //viewDriver.kernel.dispatchEvent( node.ID, "touchEnd", eData.eventData, eData.eventNodeData ); - viewDriver.kernel.fireEvent( node.ID, 'touchEnd', eData.eventData ); + //viewDriver.kernel.dispatchEvent( node.ID, "touchEnd", eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'touchEnd', eData.eventData ); } ); node.kineticObj.on( "tap", function( evt ) { var eData = processEvent( evt, node, false ); - //viewDriver.kernel.dispatchEvent( node.ID, "tap", eData.eventData, eData.eventNodeData ); - viewDriver.kernel.fireEvent( node.ID, 'tap', eData.eventData ); + //viewDriver.kernel.dispatchEvent( node.ID, "tap", eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'tap', eData.eventData ); } ); node.kineticObj.on( "dbltap", function( evt ) { var eData = processEvent( evt, node, false ); - //viewDriver.kernel.dispatchEvent( node.ID, "dragStart", eData.eventData, eData.eventNodeData ); - viewDriver.kernel.fireEvent( node.ID, 'doubleTap', eData.eventData ); + //viewDriver.kernel.dispatchEvent( node.ID, "dragStart", eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'doubleTap', eData.eventData ); } ); - - node.kineticObj.on( "dragstart", function( evt ) { - var eData = processEvent( evt, node, false ); - //viewDriver.kernel.dispatchEvent( node.ID, "dragStart", eData.eventData, eData.eventNodeData ); - - viewDriver.kernel.fireEvent( node.ID, 'dragStart', eData.eventData ); - setViewProperty( node.ID, "x", viewDriver.state.getProperty( node.ID, "x" ) ); - setViewProperty( node.ID, "y", viewDriver.state.getProperty( node.ID, "y" ) ); - - viewDriver.state.draggingNodes[ node.ID ] = true; - } ); - - node.kineticObj.on( "dragmove", function( evt ) { - var eData = processEvent( evt, node, false ); - //viewDriver.kernel.dispatchEvent( node.ID, "dragMove", eData.eventData, eData.eventNodeData ); - viewDriver.kernel.fireEvent( node.ID, 'dragMove', eData.eventData ); - } ); - - // I couldn't get this to work, so instead I keep track of mouseDragging separately - // in dragstart and mouseup (Eric - 11/18/14) - // node.kineticObj.on( "dragend", function( evt ) { - // var eData = processEvent( evt, node, false ); - // //viewDriver.kernel.dispatchEvent( node.ID, "dragEnd", eData.eventData, eData.eventNodeData ); - // viewDriver.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); - // } ); + } return view.load( module, { initialize: function( options ) { - self = this; + viewDriver = this; this.arguments = Array.prototype.slice.call( arguments ); @@ -234,15 +196,13 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } var protos = node.prototypes; - if ( self.state.isKineticClass( protos, [ "kinetic", "stage", "vwf" ] ) ) { - + if ( viewDriver.state.isKineticClass( protos, [ "kinetic", "stage", "vwf" ] ) ) { var stage = this.state.stage = node.kineticObj; - } }, - initializedNode: function( nodeID, childID, childExtendsID, childImplementsIDs, + initializedNode: function( nodeID, childID, childExtendsID, childImplementsIDs, childSource, childType, childIndex, childName, callback ) { var node = this.state.nodes[ childID ]; @@ -256,7 +216,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], return; } - if ( node.kineticObj ) { + if ( node.kineticObj ) { // Attach the mouse and/or touch events based on property settings vwf_view.kernel.getProperty( childID, "supportMouseEvents" ); @@ -418,6 +378,10 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], setViewProperty( nodeID, prop, value, t ); break; + } + } + + }, gotProperty: function( nodeID, propertyName, propertyValue ) { @@ -453,10 +417,11 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], return eventsAdded; }, + /* firedEvent: function( nodeID, eventName ) { if ( eventName == "draggingFromView" ) { var clientThatSatProperty = self.kernel.client(); - var me = self.kernel.moniker(); + var me = viewDriver.kernel.moniker(); // If the transform property was initially updated by this view.... if ( clientThatSatProperty == me ) { @@ -471,6 +436,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } }, + */ // firedEvent: function( nodeID, eventName ) { // }, @@ -487,36 +453,38 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // switch to update, when the tickless branch is merged to development var nodeIDs = Object.keys( viewDriver.state.draggingNodes ); - for ( var i = 0; i < nodeIDs.length; i++ ) { - - var nodeID = nodeIDs[ i ]; + for ( var i = 0; i < nodeIDs.length; i++ ) { + + var nodeID = nodeIDs[ i ]; var node = viewDriver.state.draggingNodes[ nodeID ]; - // If users can drag this node and all clients should stay synchronized, we must - // pull the new node position out of kinetic and update the model with it - if ( node.kineticObj.draggable() && node.model.x !== undefined && node.model.y !== undefined ) { - var kineticX = node.kineticObj.x(); - var kineticY = node.kineticObj.y(); - - // If the position of this node has changes since it's last model value, set the - // model property with the new value - if ( ( node.model.x !== kineticX ) || - ( node.model.y !== kineticY ) ) { - - // Fire this event to notify the model that kinetic has already updated the - // view and it doesn't need to (if the model set the value, it would risk - // having the model set the view back to an old value, which results in - // jitter while the user is dragging the node) - viewDriver.kernel.fireEvent( nodeID, "draggingFromView" ); - viewDriver.kernel.setProperty( nodeID, "position", [ kineticX, kineticY ] ); - } + + // If users can drag this node and all clients should stay synchronized, we must + // pull the new node position out of kinetic and update the model with it + if ( node.kineticObj.draggable() && ( node.model.x !== undefined ) && ( node.model.y !== undefined ) ) { + var kineticX = node.kineticObj.x(); + var kineticY = node.kineticObj.y(); + + // If the position of this node has changes since it's last model value, set the + // model property with the new value + if ( ( node.model.x.value !== kineticX ) || + ( node.model.y.value !== kineticY ) ) { + + // Fire this event to notify the model that kinetic has already updated the + // view and it doesn't need to (if the model set the value, it would risk + // having the model set the view back to an old value, which results in + // jitter while the user is dragging the node) + //viewDriver.kernel.kernel.fireEvent( nodeID, "draggingFromView" ); + viewDriver.kernel.kernel.setProperty( nodeID, "position", [ kineticX, kineticY ] ); } } + } + for ( var id in viewDriver.state.stages ){ renderScene( viewDriver.state.stages[ id ] ); - } - } + } + } function renderScene( stage ) { //window.requestAnimationFrame( renderScene( stage ) ); diff --git a/support/proxy/vwf.example.com/kinetic/drawing.js b/support/proxy/vwf.example.com/kinetic/drawing.js index 60ec15f09..786acd8bc 100644 --- a/support/proxy/vwf.example.com/kinetic/drawing.js +++ b/support/proxy/vwf.example.com/kinetic/drawing.js @@ -22,11 +22,8 @@ this.clientWatch = function() { }; this.isValid = function( obj ) { - - - - var objType = ( {} ).toString.call( obj ).match( /\s([a-zA-Z]+)/ )[ 1 ].toLowerCase(); - return ( objType != 'null' && objType != 'undefined' ); + var objType = ( {} ).toString.call( obj ).match( /\s([a-zA-Z]+)/ )[ 1 ].toLowerCase(); + return ( objType != 'null' && objType != 'undefined' ); }; this.clientJoin = function( moniker ) { diff --git a/support/proxy/vwf.example.com/kinetic/drawing.vwf.yaml b/support/proxy/vwf.example.com/kinetic/drawing.vwf.yaml index da3de0afb..5919fc277 100644 --- a/support/proxy/vwf.example.com/kinetic/drawing.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/drawing.vwf.yaml @@ -14,7 +14,7 @@ methods: clientLeave: setUpPrivate: setClientUIState: - #isValid: + isValid: getStageRelativePoint: events: pointerDown: From 80fb59478728708aa799be783c2e531699cc3382 Mon Sep 17 00:00:00 2001 From: youngca Date: Mon, 18 May 2015 14:15:51 -0400 Subject: [PATCH 012/644] Unit symbols can be dragged and reflect on each client. Visibility/listening/opacity unique-in-view values tested out ok. Still some issues to fix: 1. Late joiners don't get any graphics (lines or shapes), but do get unit symbols. 2. Unit symbol jumps back to creation position when activating threat area. 3. Sometimes dragging map or unit symbols can be a little jerky (especially on client that did not originate session). --- support/client/lib/vwf/model/kineticjs.js | 52 ++++++- support/client/lib/vwf/view/kineticjs.js | 127 ++++++++++++------ .../vwf.example.com/kinetic/node.vwf.yaml | 2 + 3 files changed, 135 insertions(+), 46 deletions(-) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index 906460ed8..074e0604b 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -66,6 +66,9 @@ define( [ "module", return found; }, "setProperty": function( kineticObj, propertyName, propertyValue ) { + + console.info( "setProperty("+propertyName+", "+ propertyValue+")" ); + var value = undefined; if ( !kineticObj ) { @@ -1636,7 +1639,7 @@ define( [ "module", "parenting": false, "deleting": false, "properties": false, - "setting": false, + "setting": true, "getting": false, "methods": false, "events": false, @@ -1832,13 +1835,50 @@ define( [ "module", var value = undefined; if ( node && node.kineticObj && utility.validObject( propertyValue ) ) { - if ( node.model[ propertyName ] !== undefined ) { + if ( node.model[ propertyName ] === undefined ) { + this.logger.infox( " - model value does not exist " ); + // Not unique-in-view + value = this.state.setProperty( node.kineticObj, propertyName, propertyValue ); + + if ( propertyName === "position" ) { + node.model[ propertyName ] = + { + "value": propertyValue, + "isStatic": false + }; + } + //} else if ( !node.model[ propertyName ].isStatic ) { + // Not unique-in-view + // value = this.state.setProperty( node.kineticObj, propertyName, node.model[ propertyName ].value ); + + } else { + if ( propertyName === "position" ) { + + node.model[ propertyName ].value = propertyValue; + + if ( node.model[ propertyName ].ignoreNextPositionUpdate ) { + this.logger.infox( " - ignore position update this time " ); + node.model[ propertyName ].ignoreNextPositionUpdate = false; + } else if ( !node.model[ propertyName ].isStatic ) { + this.logger.infox( " - set position to model value " ); + value = this.state.setProperty( node.kineticObj, propertyName, node.model[ propertyName ].value ); + } + + } else if ( !node.model[ propertyName ].isStatic ) { + this.logger.infox( " - not unique in view, update property " ); + value = this.state.setProperty( node.kineticObj, propertyName, node.model[ propertyName ].value ); + } else { + this.logger.infox( " - unique in view, update model only " ); + node.model[ propertyName ].value = propertyValue; + } + /* if ( this.kernel.client() === this.kernel.moniker() ) { - //node.model[ propertyName ] = propertyValue; + node.model[ propertyName ].value = propertyValue; value = this.state.setProperty( node.kineticObj, propertyName, propertyValue ); - } - } else { - value = this.state.setProperty( node.kineticObj, propertyName, propertyValue ); + } else { + node.model[ propertyName ].value = propertyValue; + } + */ } } diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index b72cffb82..a37172101 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -103,8 +103,10 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var xPos = viewDriver.state.getProperty( node.kineticObj, "x" ); var yPos = viewDriver.state.getProperty( node.kineticObj, "y" ); - setViewProperty( node.ID, "x", xPos ); - setViewProperty( node.ID, "y", yPos ); + //setViewProperty( node.ID, "position", [ xPos, yPos ] ); + ////setViewProperty( node.ID, "x", xPos ); + ////setViewProperty( node.ID, "y", yPos ); + console.info( "dragstart( "+node.ID+", x: "+xPos+", y: "+yPos+" )" ); //viewDriver.state.draggingNodes[ node.ID ] = true; viewDriver.state.draggingNodes[ node.ID ] = node; @@ -115,15 +117,34 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var eData = processEvent( evt, node, false ); //viewDriver.kernel.dispatchEvent( node.ID, "dragMove", eData.eventData, eData.eventNodeData ); viewDriver.kernel.fireEvent( node.ID, 'dragMove', eData.eventData ); + + if ( node.kineticObj.mouseDragging ) { + var xPos = viewDriver.state.getProperty( node.kineticObj, "x" ); + var yPos = viewDriver.state.getProperty( node.kineticObj, "y" ); + //setViewProperty( node.ID, "position", [ xPos, yPos ] ); + ////setViewProperty( node.ID, "x", xPos ); + ////setViewProperty( node.ID, "y", yPos ); + } + } ); // I couldn't get this to work, so instead I keep track of mouseDragging separately // in dragstart and mouseup (Eric - 11/18/14) - // node.kineticObj.on( "dragend", function( evt ) { - // var eData = processEvent( evt, node, false ); - // //viewDriver.kernel.dispatchEvent( node.ID, "dragEnd", eData.eventData, eData.eventNodeData ); - // viewDriver.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); - // } ); + node.kineticObj.on( "dragend", function( evt ) { + var eData = processEvent( evt, node, false ); + //viewDriver.kernel.dispatchEvent( node.ID, "dragEnd", eData.eventData, eData.eventNodeData ); + viewDriver.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); + + node.kineticObj.mouseDragging = false; + if ( viewDriver.state.draggingNodes[ node.ID ] !== undefined ) { + //var x = viewDriver.state.getModelProperty( node.ID, "x" ); + //var y = viewDriver.state.getModelProperty( node.ID, "y" ); + delete viewDriver.state.draggingNodes[ node.ID ]; + //viewDriver.state.setModelProperty( node.ID, "x", x ); + //viewDriver.state.setModelProperty( node.ID, "y", y ); + } + + } ); } @@ -219,8 +240,10 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], if ( node.kineticObj ) { // Attach the mouse and/or touch events based on property settings - vwf_view.kernel.getProperty( childID, "supportMouseEvents" ); - vwf_view.kernel.getProperty( childID, "supportTouchEvents" ); + //vwf_view.kernel.getProperty( childID, "supportMouseEvents" ); + //vwf_view.kernel.getProperty( childID, "supportTouchEvents" ); + viewDriver.kernel.getProperty( childID, "supportMouseEvents" ); + viewDriver.kernel.getProperty( childID, "supportTouchEvents" ); } @@ -374,9 +397,9 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], case "setViewProperty": prop = methodParameters[ 0 ]; value = methodParameters[ 1 ]; - t = methodParameters.length > 1 ? methodParameters[ 2 ] : "dynamic"; + var isStatic = methodParameters.length > 1 ? methodParameters[ 2 ] : false ; - setViewProperty( nodeID, prop, value, t ); + setViewProperty( nodeID, prop, value, isStatic ); break; } } @@ -417,26 +440,22 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], return eventsAdded; }, - /* firedEvent: function( nodeID, eventName ) { if ( eventName == "draggingFromView" ) { - var clientThatSatProperty = self.kernel.client(); - var me = viewDriver.kernel.moniker(); // If the transform property was initially updated by this view.... - if ( clientThatSatProperty == me ) { + if ( self.kernel.client() === viewDriver.kernel.moniker() ) { // Tell the model not to update the view on the next position update because // kinetic has already done so // (this event is fired right before this driver sets the model property, so we // can be sure that the very next set of the position property is from us) var node = this.state.nodes[ nodeID ]; - node.viewIgnoreNextPositionUpdate = true; + node.model.position.viewIgnoreNextPositionUpdate = true; } } }, - */ // firedEvent: function( nodeID, eventName ) { // }, @@ -458,24 +477,38 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var nodeID = nodeIDs[ i ]; var node = viewDriver.state.draggingNodes[ nodeID ]; - // If users can drag this node and all clients should stay synchronized, we must // pull the new node position out of kinetic and update the model with it - if ( node.kineticObj.draggable() && ( node.model.x !== undefined ) && ( node.model.y !== undefined ) ) { - var kineticX = node.kineticObj.x(); - var kineticY = node.kineticObj.y(); - - // If the position of this node has changes since it's last model value, set the - // model property with the new value - if ( ( node.model.x.value !== kineticX ) || - ( node.model.y.value !== kineticY ) ) { - - // Fire this event to notify the model that kinetic has already updated the - // view and it doesn't need to (if the model set the value, it would risk - // having the model set the view back to an old value, which results in - // jitter while the user is dragging the node) - //viewDriver.kernel.kernel.fireEvent( nodeID, "draggingFromView" ); - viewDriver.kernel.kernel.setProperty( nodeID, "position", [ kineticX, kineticY ] ); + if ( node.kineticObj ) { + console.info( "update( Node: "+nodeID+" )" ); + if ( node.kineticObj.draggable() && node.model && node.model.position && !node.model.position.isStatic ) { + //( ( node.model.y !== undefined ) && !( node.model.y.isStatic ) ) ) { + var kineticX = node.kineticObj.x(); + var kineticY = node.kineticObj.y(); + + // If the position of this node has changed since its last model value, set the + // model property with the new value + if ( ( node.model.position.value[0] !== kineticX ) || + ( node.model.position.value[1] !== kineticY ) ) { + console.info( "- "+nodeID+", model position: "+node.model.position.value.x+", "+node.model.position.value.y+", kinetic position: "+kineticX+", "+kineticY ); + + // Fire this event to notify the model that kinetic has already updated the + // view and it doesn't need to (if the model set the value, it would risk + // having the model set the view back to an old value, which results in + // jitter while the user is dragging the node) + viewDriver.kernel.fireEvent( nodeID, "draggingFromView" ); + viewDriver.kernel.setProperty( nodeID, "position", [ kineticX, kineticY ] ); + //viewDriver.kernel.setProperty( nodeID, "position", [ kineticX, kineticY ] ); + console.info( "setProperty( "+nodeID+", position: kineticX: "+kineticX+", kineticY: "+kineticY+" )" ); + + // Tell the model not to update the view on the next position update because + // kinetic has already done so + // (this event is fired right before this driver sets the model property, so we + // can be sure that the very next set of the position property is from us) + //if ( viewDriver.kernel.client() === viewDriver.kernel.moniker() ) { + // node.model.position.ignoreNextPositionUpdate = true; + //} + } } } @@ -585,27 +618,41 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], return vwfEventData; } - function setViewProperty( id, propertyName, propertyValue, type ) { + function setViewProperty( id, propertyName, propertyValue, isStatic ) { - //console.info( "setViewProperty( "+id+", "+propertyName+", "+propertyValue+", "+type+" )" ); + console.info( "setViewProperty( "+id+", "+propertyName+", "+propertyValue+", "+isStatic+" )" ); node = viewDriver.state.nodes[ id ]; if ( node && node.kineticObj ) { if ( utility.validObject( propertyValue ) ) { if ( node.model[ propertyName ] === undefined ) { + console.info( "- store property "+propertyName+" model value: "+viewDriver.state.getProperty( node.kineticObj, propertyName )+", isStatic: "+isStatic ); node.model[ propertyName ] = { - "value": viewDriver.state.getProperty( node.kineticObj, propertyName ), - "type": type + "value": viewDriver.state.getProperty( node.kineticObj, propertyName ), + "isStatic": ( ( isStatic === undefined ) ? false : isStatic ) }; + } else if ( node.model[propertyName].isStatic ) { + node.model[ propertyName ].value = propertyValue; } - viewDriver.state.setProperty( node.kineticObj, propertyName, propertyValue ); + viewDriver.state.setProperty( node.kineticObj, propertyName, propertyValue ); + console.info( "- set kineticObject property: "+propertyName+" to: "+propertyValue ); } else { var modelValue = node.model[ propertyName ].value; if ( modelValue !== undefined ) { - delete node.model[ propertyName ]; + //delete node.model[ propertyName ]; viewDriver.state.setProperty( node.kineticObj, propertyName, modelValue ); + console.info( "- deletes node.model and set kineticObject property: "+propertyName+" to: "+modelValue ); } } - } + } + + /* + if ( this.kernel.client() === this.kernel.moniker() ) { + node.model[ propertyName ].value = propertyValue; + value = this.state.setProperty( node.kineticObj, propertyName, propertyValue ); + } else { + node.model[ propertyName ].value = propertyValue; + } + */ } }); \ No newline at end of file diff --git a/support/proxy/vwf.example.com/kinetic/node.vwf.yaml b/support/proxy/vwf.example.com/kinetic/node.vwf.yaml index e02622624..31ac03488 100644 --- a/support/proxy/vwf.example.com/kinetic/node.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/node.vwf.yaml @@ -31,6 +31,8 @@ properties: absoluteTransform: absoluteOpacity: absoluteZIndex: + modelX: + modelY: supportMouseEvents: supportTouchEvents: hasMouseEvents: false From 442b467a3e6fade7bfafa318bdc43bf6eac1b820 Mon Sep 17 00:00:00 2001 From: youngca Date: Thu, 28 May 2015 14:20:03 -0400 Subject: [PATCH 013/644] Ensure that drawings (lines and shapes) show up on late-joiners. Make sure that stroke and fill data doesn't get lost. --- support/client/lib/vwf/model/kineticjs.js | 26 +++++++++++++------ .../proxy/vwf.example.com/kinetic/drawing.js | 12 ++++----- .../vwf.example.com/kinetic/node.vwf.yaml | 1 + 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index 074e0604b..8b03ac29a 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -77,11 +77,11 @@ define( [ "module", value = this.setNodeProperty( kineticObj, propertyName, propertyValue ); - if ( value === undefined ) { + if ( value === undefined && ( kineticObj.nodeType === "Shape" ) ) { value = this.setShapeProperty( kineticObj, propertyName, propertyValue ); } - if ( value === undefined ) { + if ( value === undefined && kineticObj instanceof Kinetic.Container ) { value = this.setContainerProperty( kineticObj, propertyName, propertyValue ); } @@ -1840,12 +1840,21 @@ define( [ "module", // Not unique-in-view value = this.state.setProperty( node.kineticObj, propertyName, propertyValue ); - if ( propertyName === "position" ) { - node.model[ propertyName ] = - { - "value": propertyValue, - "isStatic": false - }; + switch ( propertyName ) { + case "position": + case "stroke": + case "strokeWidth": + case "fill": + case "radius": + node.model[ propertyName ] = + { + "value": propertyValue, + "isStatic": false + }; + break; + + default: + break; } //} else if ( !node.model[ propertyName ].isStatic ) { // Not unique-in-view @@ -1866,6 +1875,7 @@ define( [ "module", } else if ( !node.model[ propertyName ].isStatic ) { this.logger.infox( " - not unique in view, update property " ); + node.model[ propertyName ].value = propertyValue; value = this.state.setProperty( node.kineticObj, propertyName, node.model[ propertyName ].value ); } else { this.logger.infox( " - unique in view, update model only " ); diff --git a/support/proxy/vwf.example.com/kinetic/drawing.js b/support/proxy/vwf.example.com/kinetic/drawing.js index 786acd8bc..731466d64 100644 --- a/support/proxy/vwf.example.com/kinetic/drawing.js +++ b/support/proxy/vwf.example.com/kinetic/drawing.js @@ -27,9 +27,9 @@ this.isValid = function( obj ) { }; this.clientJoin = function( moniker ) { - if ( this.id === "http://vwf.example.com/kinetic/drawing.vwf" ){ - return; - } + //if ( this.id === "http://vwf.example.com/kinetic/drawing.vwf" ){ + // return; + //} // mirrors the initial state of the toolbar if ( !this.isValid( this.drawing_clients ) ) { @@ -48,7 +48,7 @@ this.clientJoin = function( moniker ) { "angle": 30 }; } - //this.drawing_clients = this.drawing_clients; + this.drawing_clients = this.drawing_clients; }; @@ -429,7 +429,7 @@ this.update = function( eventData, nodeData, upEvent ) { var posY = eventPoint[ 1 ] - drawingObject.y; if ( isFirstStrokeOfNewLine ) { - if ( Math.abs( posX ) + Math.abs( posY ) > 0 ) { + if ( ( Math.abs( posX ) + Math.abs( posY ) ) > 0 ) { drawingObject.points = [ 0, 0, posX, posY ]; } else { pointAccepted = false; @@ -440,7 +440,7 @@ this.update = function( eventData, nodeData, upEvent ) { posY - privateState.previousPoint[ 1 ] ]; - if ( Math.abs( dragDiff[0] ) + Math.abs( dragDiff[1] ) > 0 ) { + if ( ( Math.abs( dragDiff[0] ) + Math.abs( dragDiff[1] ) ) > 0 ) { drawingObject.points.push( posX ); drawingObject.points.push( posY ); } else { diff --git a/support/proxy/vwf.example.com/kinetic/node.vwf.yaml b/support/proxy/vwf.example.com/kinetic/node.vwf.yaml index 31ac03488..83048d328 100644 --- a/support/proxy/vwf.example.com/kinetic/node.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/node.vwf.yaml @@ -9,6 +9,7 @@ properties: height: visible: isVisible: + isGloballyVisible: false listening: isListening: id: From 0eaafe667453da1be78c6be999d83ee92e43e003 Mon Sep 17 00:00:00 2001 From: youngca Date: Tue, 23 Jun 2015 13:42:45 -0400 Subject: [PATCH 014/644] Clean up console info messages and references to the old "uniqueInView" property. --- support/client/lib/vwf/model/kineticjs.js | 34 ++++++----------------- support/client/lib/vwf/view/kineticjs.js | 16 +++++------ support/client/lib/vwf/view/mil-sym.js | 6 ++-- 3 files changed, 19 insertions(+), 37 deletions(-) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index 8b03ac29a..a66fd102b 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -40,7 +40,6 @@ define( [ "module", "prototypes": undefined, "kineticObj": undefined, "stage": undefined, - //"uniqueInView": false, "hasMouseEvents": false, "hasTouchEvents": false, "model": {} }; @@ -67,7 +66,7 @@ define( [ "module", }, "setProperty": function( kineticObj, propertyName, propertyValue ) { - console.info( "setProperty("+propertyName+", "+ propertyValue+")" ); + //console.info( "setProperty("+propertyName+", "+ propertyValue+")" ); var value = undefined; @@ -299,23 +298,6 @@ define( [ "module", // } break; - // case "uniqueInView": - // node.uniqueInView = Boolean( propertyValue ); - - // // If we no longer have unique views, all view positions should be set - // // to the model value - // // Note: though this would be more appropriate to do in the view - // // driver's satProperty, it is important that it be updated atomically - // // with the model so there is no risk that "ticked" will discover the - // // descrepancy between model and view values and assume that the user - // // has dragged the node via kinetic (thus triggering it to set the model - // // value from the old view value) - // if ( !node.uniqueInView ) { - // kineticObj.x( kineticObj.modelX ); - // kineticObj.y( kineticObj.modelY ); - // } - // break; - case "dragBoundFunc": var functionString = propertyValue; if ( !utility.isString( functionString ) ) { @@ -1639,7 +1621,7 @@ define( [ "module", "parenting": false, "deleting": false, "properties": false, - "setting": true, + "setting": false, "getting": false, "methods": false, "events": false, @@ -1836,7 +1818,7 @@ define( [ "module", if ( node && node.kineticObj && utility.validObject( propertyValue ) ) { if ( node.model[ propertyName ] === undefined ) { - this.logger.infox( " - model value does not exist " ); + //this.logger.infox( " - model value does not exist " ); // Not unique-in-view value = this.state.setProperty( node.kineticObj, propertyName, propertyValue ); @@ -1866,20 +1848,20 @@ define( [ "module", node.model[ propertyName ].value = propertyValue; if ( node.model[ propertyName ].ignoreNextPositionUpdate ) { - this.logger.infox( " - ignore position update this time " ); + //this.logger.infox( " - ignore position update this time " ); node.model[ propertyName ].ignoreNextPositionUpdate = false; } else if ( !node.model[ propertyName ].isStatic ) { - this.logger.infox( " - set position to model value " ); + //this.logger.infox( " - set position to model value " ); value = this.state.setProperty( node.kineticObj, propertyName, node.model[ propertyName ].value ); } } else if ( !node.model[ propertyName ].isStatic ) { - this.logger.infox( " - not unique in view, update property " ); + //this.logger.infox( " - not unique in view, update property " ); node.model[ propertyName ].value = propertyValue; value = this.state.setProperty( node.kineticObj, propertyName, node.model[ propertyName ].value ); } else { - this.logger.infox( " - unique in view, update model only " ); - node.model[ propertyName ].value = propertyValue; + //this.logger.infox( " - unique in view, update model only " ); + node.model[ propertyName ].value = propertyValue; } /* if ( this.kernel.client() === this.kernel.moniker() ) { diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index a37172101..c1c22030b 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -106,7 +106,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], //setViewProperty( node.ID, "position", [ xPos, yPos ] ); ////setViewProperty( node.ID, "x", xPos ); ////setViewProperty( node.ID, "y", yPos ); - console.info( "dragstart( "+node.ID+", x: "+xPos+", y: "+yPos+" )" ); + //console.info( "dragstart( "+node.ID+", x: "+xPos+", y: "+yPos+" )" ); //viewDriver.state.draggingNodes[ node.ID ] = true; viewDriver.state.draggingNodes[ node.ID ] = node; @@ -480,7 +480,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // If users can drag this node and all clients should stay synchronized, we must // pull the new node position out of kinetic and update the model with it if ( node.kineticObj ) { - console.info( "update( Node: "+nodeID+" )" ); + //console.info( "update( Node: "+nodeID+" )" ); if ( node.kineticObj.draggable() && node.model && node.model.position && !node.model.position.isStatic ) { //( ( node.model.y !== undefined ) && !( node.model.y.isStatic ) ) ) { var kineticX = node.kineticObj.x(); @@ -490,7 +490,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // model property with the new value if ( ( node.model.position.value[0] !== kineticX ) || ( node.model.position.value[1] !== kineticY ) ) { - console.info( "- "+nodeID+", model position: "+node.model.position.value.x+", "+node.model.position.value.y+", kinetic position: "+kineticX+", "+kineticY ); + //console.info( "- "+nodeID+", model position: "+node.model.position.value.x+", "+node.model.position.value.y+", kinetic position: "+kineticX+", "+kineticY ); // Fire this event to notify the model that kinetic has already updated the // view and it doesn't need to (if the model set the value, it would risk @@ -499,7 +499,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], viewDriver.kernel.fireEvent( nodeID, "draggingFromView" ); viewDriver.kernel.setProperty( nodeID, "position", [ kineticX, kineticY ] ); //viewDriver.kernel.setProperty( nodeID, "position", [ kineticX, kineticY ] ); - console.info( "setProperty( "+nodeID+", position: kineticX: "+kineticX+", kineticY: "+kineticY+" )" ); + //console.info( "setProperty( "+nodeID+", position: kineticX: "+kineticX+", kineticY: "+kineticY+" )" ); // Tell the model not to update the view on the next position update because // kinetic has already done so @@ -620,12 +620,12 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], function setViewProperty( id, propertyName, propertyValue, isStatic ) { - console.info( "setViewProperty( "+id+", "+propertyName+", "+propertyValue+", "+isStatic+" )" ); + //console.info( "setViewProperty( "+id+", "+propertyName+", "+propertyValue+", "+isStatic+" )" ); node = viewDriver.state.nodes[ id ]; if ( node && node.kineticObj ) { if ( utility.validObject( propertyValue ) ) { if ( node.model[ propertyName ] === undefined ) { - console.info( "- store property "+propertyName+" model value: "+viewDriver.state.getProperty( node.kineticObj, propertyName )+", isStatic: "+isStatic ); + //console.info( "- store property "+propertyName+" model value: "+viewDriver.state.getProperty( node.kineticObj, propertyName )+", isStatic: "+isStatic ); node.model[ propertyName ] = { "value": viewDriver.state.getProperty( node.kineticObj, propertyName ), "isStatic": ( ( isStatic === undefined ) ? false : isStatic ) @@ -634,13 +634,13 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], node.model[ propertyName ].value = propertyValue; } viewDriver.state.setProperty( node.kineticObj, propertyName, propertyValue ); - console.info( "- set kineticObject property: "+propertyName+" to: "+propertyValue ); + //console.info( "- set kineticObject property: "+propertyName+" to: "+propertyValue ); } else { var modelValue = node.model[ propertyName ].value; if ( modelValue !== undefined ) { //delete node.model[ propertyName ]; viewDriver.state.setProperty( node.kineticObj, propertyName, modelValue ); - console.info( "- deletes node.model and set kineticObject property: "+propertyName+" to: "+modelValue ); + //console.info( "- deletes node.model and set kineticObject property: "+propertyName+" to: "+modelValue ); } } } diff --git a/support/client/lib/vwf/view/mil-sym.js b/support/client/lib/vwf/view/mil-sym.js index 453eb012e..c3d0c2fed 100644 --- a/support/client/lib/vwf/view/mil-sym.js +++ b/support/client/lib/vwf/view/mil-sym.js @@ -223,7 +223,7 @@ define( [ "module", "vwf/view", "mil-sym/cws" ], function( module, view, cws ) { var symUtil = renderer.utilities.SymbolUtilities; var modifiers = {}; - self.logger.info(" Mil-SymJS SymbolID before echelon and affiliation: " + symbolID ); + //self.logger.info(" Mil-SymJS SymbolID before echelon and affiliation: " + symbolID ); if ( cws ) { updatedUnit = unit; @@ -233,9 +233,9 @@ define( [ "module", "vwf/view", "mil-sym/cws" ], function( module, view, cws ) { // Add echelon if ( echelonID != undefined ) { - self.logger.info(" Mil-SymJS Adding Echelon: " + echelonID ); + //self.logger.info(" Mil-SymJS Adding Echelon: " + echelonID ); updatedUnit.symbolID = cws.addEchelonToSymbolId( updatedUnit.symbolID, echelonID ); - self.logger.info(" Mil-SymJS SymbolID after echelon and affiliation: " + updatedUnit.symbolID ); + //self.logger.info(" Mil-SymJS SymbolID after echelon and affiliation: " + updatedUnit.symbolID ); } // Add modifiers From 94dc606bbd7c1ad4fadc770a2776c5ffc8e45b75 Mon Sep 17 00:00:00 2001 From: youngca Date: Fri, 26 Jun 2015 08:48:34 -0400 Subject: [PATCH 015/644] Check to see if the isStatic setting changed if the model object exists for a property. Fixes an issue where clients 2, 3, 4,... would drag each other's maps. --- support/client/lib/vwf/view/kineticjs.js | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index c1c22030b..adc331339 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -444,7 +444,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], if ( eventName == "draggingFromView" ) { // If the transform property was initially updated by this view.... - if ( self.kernel.client() === viewDriver.kernel.moniker() ) { + if ( self.kernel.client() === self.kernel.moniker() ) { // Tell the model not to update the view on the next position update because // kinetic has already done so @@ -630,29 +630,22 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], "value": viewDriver.state.getProperty( node.kineticObj, propertyName ), "isStatic": ( ( isStatic === undefined ) ? false : isStatic ) }; - } else if ( node.model[propertyName].isStatic ) { - node.model[ propertyName ].value = propertyValue; + } else if ( node.model[propertyName].isStatic !== isStatic ) { + node.model[propertyName].isStatic = ( ( isStatic === undefined ) ? false : isStatic ); + } + if ( node.model[propertyName].isStatic ) { + node.model[ propertyName ].value = propertyValue; } viewDriver.state.setProperty( node.kineticObj, propertyName, propertyValue ); //console.info( "- set kineticObject property: "+propertyName+" to: "+propertyValue ); } else { var modelValue = node.model[ propertyName ].value; if ( modelValue !== undefined ) { - //delete node.model[ propertyName ]; viewDriver.state.setProperty( node.kineticObj, propertyName, modelValue ); //console.info( "- deletes node.model and set kineticObject property: "+propertyName+" to: "+modelValue ); } } } - - /* - if ( this.kernel.client() === this.kernel.moniker() ) { - node.model[ propertyName ].value = propertyValue; - value = this.state.setProperty( node.kineticObj, propertyName, propertyValue ); - } else { - node.model[ propertyName ].value = propertyValue; - } - */ } }); \ No newline at end of file From 1e98543e5a0388dd98d443d302b7fd4b7757f412 Mon Sep 17 00:00:00 2001 From: youngca Date: Mon, 29 Jun 2015 10:23:42 -0400 Subject: [PATCH 016/644] Prevent the kinetic model from defaulting the stage position to isStatic to false. The model was overriding the stage's position "isStatic" flag when new clients joined, so stage position changes were being treated as global changes, not local changes. This is more or less a patch prior to the demo of ITDG 1.5. A more correct solution is forthcoming. --- support/client/lib/vwf/model/kineticjs.js | 14 ++++++++------ support/client/lib/vwf/view/kineticjs.js | 13 +++++-------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index a66fd102b..e40d7f3ba 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -156,7 +156,7 @@ define( [ "module", "setNodeProperty": function( kineticObj, propertyName, propertyValue ) { var value = propertyValue; - + switch ( propertyName ) { case "x": @@ -1828,11 +1828,13 @@ define( [ "module", case "strokeWidth": case "fill": case "radius": - node.model[ propertyName ] = - { - "value": propertyValue, - "isStatic": false - }; + if ( node.kineticObj.nodeType !== "Stage" ) { + node.model[ propertyName ] = + { + "value": propertyValue, + "isStatic": false + }; + } break; default: diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index adc331339..3b19a384b 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -619,9 +619,8 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } function setViewProperty( id, propertyName, propertyValue, isStatic ) { - //console.info( "setViewProperty( "+id+", "+propertyName+", "+propertyValue+", "+isStatic+" )" ); - node = viewDriver.state.nodes[ id ]; + var node = viewDriver.state.nodes[ id ]; if ( node && node.kineticObj ) { if ( utility.validObject( propertyValue ) ) { if ( node.model[ propertyName ] === undefined ) { @@ -630,19 +629,17 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], "value": viewDriver.state.getProperty( node.kineticObj, propertyName ), "isStatic": ( ( isStatic === undefined ) ? false : isStatic ) }; - } else if ( node.model[propertyName].isStatic !== isStatic ) { - node.model[propertyName].isStatic = ( ( isStatic === undefined ) ? false : isStatic ); - } - if ( node.model[propertyName].isStatic ) { - node.model[ propertyName ].value = propertyValue; + } else if ( node.model[propertyName].isStatic ) { + node.model[ propertyName ].value = propertyValue; } viewDriver.state.setProperty( node.kineticObj, propertyName, propertyValue ); //console.info( "- set kineticObject property: "+propertyName+" to: "+propertyValue ); } else { var modelValue = node.model[ propertyName ].value; if ( modelValue !== undefined ) { + //delete node.model[ propertyName ]; viewDriver.state.setProperty( node.kineticObj, propertyName, modelValue ); - //console.info( "- deletes node.model and set kineticObject property: "+propertyName+" to: "+modelValue ); + console.info( "- deletes node.model and set kineticObject property: "+propertyName+" to: "+modelValue ); } } } From 7d00c1b00a24bc6a023448eb9b74ef8311d92b60 Mon Sep 17 00:00:00 2001 From: youngca Date: Wed, 8 Jul 2015 14:25:11 -0400 Subject: [PATCH 017/644] Clean up tabs in the map drag fix. --- support/client/lib/vwf/model/kineticjs.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index e40d7f3ba..e5607d06a 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -1828,13 +1828,13 @@ define( [ "module", case "strokeWidth": case "fill": case "radius": - if ( node.kineticObj.nodeType !== "Stage" ) { - node.model[ propertyName ] = - { - "value": propertyValue, - "isStatic": false - }; - } + if ( node.kineticObj.nodeType !== "Stage" ) { + node.model[ propertyName ] = + { + "value": propertyValue, + "isStatic": false + }; + } break; default: From beb8fd5466dace1402b70c509abf9051a6c90eeb Mon Sep 17 00:00:00 2001 From: youngca Date: Wed, 8 Jul 2015 14:26:29 -0400 Subject: [PATCH 018/644] Handle the video formats that jPlayer natively supports. --- support/client/lib/vwf/model/jPlayer.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/support/client/lib/vwf/model/jPlayer.js b/support/client/lib/vwf/model/jPlayer.js index 6debc886e..7324de2f0 100644 --- a/support/client/lib/vwf/model/jPlayer.js +++ b/support/client/lib/vwf/model/jPlayer.js @@ -397,6 +397,18 @@ define( [ mediaObject = { wav: url }; + } else if ( url.search( "data:audio/mp4" ) === 0 ) { + mediaObject = { + m4a: url + }; + } else if ( url.search( "data:audio/ogg" ) === 0 ) { + mediaObject = { + oga: url + }; + } else if ( url.search( "data:audio/webm" ) === 0 ) { + mediaObject = { + webma: url + }; } else { modelDriver.logger.errorx( "setUrl", "Unsupported sound type for '", url, "'" ); @@ -408,6 +420,16 @@ define( [ m4v: url, poster: node.posterImageUrl }; + } else if ( url.search( "data:video/ogg" ) === 0 ) { + mediaObject = { + ogv: url, + poster: node.posterImageUrl + }; + } else if ( url.search( "data:video/webm" ) === 0 ) { + mediaObject = { + webmv: url, + poster: node.posterImageUrl + }; } else { modelDriver.logger.errorx( "setUrl", "Unsupported video type for '", url, "'" ); From 7acc60c3b6e721965164d3cbb1e13e418bb75ec3 Mon Sep 17 00:00:00 2001 From: youngca Date: Mon, 13 Jul 2015 14:16:28 -0400 Subject: [PATCH 019/644] Fix error where drawingGroups (inserted images, text and arrows) were not responding to erase. --- support/proxy/vwf.example.com/kinetic/drawing.js | 3 +-- support/proxy/vwf.example.com/kinetic/drawingGroup.vwf.yaml | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/support/proxy/vwf.example.com/kinetic/drawing.js b/support/proxy/vwf.example.com/kinetic/drawing.js index 731466d64..abadea8e3 100644 --- a/support/proxy/vwf.example.com/kinetic/drawing.js +++ b/support/proxy/vwf.example.com/kinetic/drawing.js @@ -188,7 +188,6 @@ this.down = function( eventData, nodeData, touch ) { retObj.opacity = 1.0; retObj.scaleOnLoad = true; break; - default: retObj.fill = userState.drawing_color; break; @@ -226,7 +225,7 @@ this.down = function( eventData, nodeData, touch ) { "extends": groupExtends, "properties": { "visible": false, - "listening": false, + "listening": "inherit", "position": eventPointDown }, "children": {} diff --git a/support/proxy/vwf.example.com/kinetic/drawingGroup.vwf.yaml b/support/proxy/vwf.example.com/kinetic/drawingGroup.vwf.yaml index f71bc8fe4..9941b6a96 100644 --- a/support/proxy/vwf.example.com/kinetic/drawingGroup.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/drawingGroup.vwf.yaml @@ -3,5 +3,5 @@ --- extends: http://vwf.example.com/kinetic/group.vwf properties: - supportMouseEvents: false - supportTouchEvents: false + supportMouseEvents: true + supportTouchEvents: true From 0d9f91dfaf5e744d11e2527edce5acc0ccfda002 Mon Sep 17 00:00:00 2001 From: youngca Date: Tue, 21 Jul 2015 18:14:35 -0400 Subject: [PATCH 020/644] Add echelon as a modifier so the user can set the echelon after a unit symbol has been placed (ITDG). --- support/proxy/vwf.example.com/mil-sym/modifier.vwf.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/support/proxy/vwf.example.com/mil-sym/modifier.vwf.yaml b/support/proxy/vwf.example.com/mil-sym/modifier.vwf.yaml index 291852360..c1986ecee 100755 --- a/support/proxy/vwf.example.com/mil-sym/modifier.vwf.yaml +++ b/support/proxy/vwf.example.com/mil-sym/modifier.vwf.yaml @@ -5,6 +5,7 @@ properties: icon: true keepUnitRatio: symbologyStandard: + echelon: quantity: additionalInfo1: additionalInfo2: From 092baaa68344821089eab4ba1e4c9cbbbe37a80e Mon Sep 17 00:00:00 2001 From: youngca Date: Tue, 21 Jul 2015 18:16:38 -0400 Subject: [PATCH 021/644] Add modifier mapper for echelon so it is recognized. --- support/client/lib/mil-sym/cws.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/support/client/lib/mil-sym/cws.js b/support/client/lib/mil-sym/cws.js index 4802f3255..059a5223d 100644 --- a/support/client/lib/mil-sym/cws.js +++ b/support/client/lib/mil-sym/cws.js @@ -4874,6 +4874,9 @@ define( function(){ }, "aliasModifiers": { + "echelon": { modifier: "B_ECHELON", + type: "ModifiersUnits", + valueType: "Text" }, "quantity": { modifier: "C_QUANTITY", type: "ModifiersUnits", valueType: "Number" }, From 9e80673b248c27ccb1b08e5e09a9ca1515e3a252 Mon Sep 17 00:00:00 2001 From: youngca Date: Wed, 22 Jul 2015 11:03:32 -0400 Subject: [PATCH 022/644] Support for keeping the unit symbol at the same map location when changing modifiers. Attempt to fix an issue with the icon snapping back to its original placement position if the symbol's modifiers were changed after it had been dragged to a new location. --- support/proxy/vwf.example.com/mil-sym/unitGroup.js | 10 ++++++++++ .../proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml | 8 +++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/support/proxy/vwf.example.com/mil-sym/unitGroup.js b/support/proxy/vwf.example.com/mil-sym/unitGroup.js index 6caff8a24..76d4d5fe1 100755 --- a/support/proxy/vwf.example.com/mil-sym/unitGroup.js +++ b/support/proxy/vwf.example.com/mil-sym/unitGroup.js @@ -159,4 +159,14 @@ this.updateThreatShape = function() { } +this.setAbsoluteMapPosition = function( mapPosition ) { + if ( mapPosition !== undefined ) { + this.mapPosition = mapPosition; + this.position = { + "x": this.mapPosition.x, + "y": this.mapPosition.y + }; + } +} + //@ sourceURL=unitGroup.js \ No newline at end of file diff --git a/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml b/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml index 47b8c2741..0e5b3249e 100755 --- a/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml +++ b/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml @@ -6,15 +6,17 @@ properties: mapPosition: set: | + debugger; if ( value !== undefined ) { + //this.mapPosition = { "x": value.x, "y": value.y }; this.mapPosition = value; if ( this.icon && this.icon.symbolCenter ) { this.position = { - "x": this.mapPosition.x - this.icon.symbolCenter.x, - "y": this.mapPosition.y - this.icon.symbolCenter.y + "x": ( this.mapPosition.absolute ? this.mapPosition.x : this.mapPosition.x - this.icon.symbolCenter.x ), + "y": ( this.mapPosition.absolute ? this.mapPosition.y : this.mapPosition.y - this.icon.symbolCenter.y ) }; } else { - this.position = value; + this.position = { "x": value.x, "y": value.y }; } } value: { "x": 0, "y": 0 } From c296449f7c637cbe7a4056d978a6eec25c245961 Mon Sep 17 00:00:00 2001 From: youngca Date: Mon, 31 Aug 2015 16:53:33 -0400 Subject: [PATCH 023/644] Remove debugger statement. --- support/client/lib/vwf/view/kineticjs.js | 4 ++-- support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 3b19a384b..e735bb284 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -5,8 +5,8 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var viewDriver; var stageContainer; - var stageWidth = 800; - var stageHeight = 600; + var stageWidth = ( window && window.innerWidth ) ? window.innerWidth : 800; + var stageHeight = ( window && window.innerHeight ) ? window.innerHeight : 600; function attachMouseEvents( node ) { diff --git a/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml b/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml index 0e5b3249e..bc15d4659 100755 --- a/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml +++ b/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml @@ -6,7 +6,6 @@ properties: mapPosition: set: | - debugger; if ( value !== undefined ) { //this.mapPosition = { "x": value.x, "y": value.y }; this.mapPosition = value; From fc8b6802763cafcdfdbfc8545b3dc1b5f5d52f82 Mon Sep 17 00:00:00 2001 From: youngca Date: Mon, 2 Nov 2015 14:43:28 -0500 Subject: [PATCH 024/644] First attempt at moving drawing functionality from model to view. Twofold: draw live with the user so he sees what he's doing and reduce network traffic. --- support/client/lib/vwf/model/kineticjs.js | 144 ++-- support/client/lib/vwf/view/kineticjs.js | 768 +++++++++++++++++- .../proxy/vwf.example.com/kinetic/drawing.js | 6 + .../vwf.example.com/kinetic/drawing.vwf.yaml | 1 + 4 files changed, 837 insertions(+), 82 deletions(-) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index e5607d06a..1acacc94d 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -1684,25 +1684,30 @@ define( [ "module", node = this.state.nodes[ childID ]; node.prototypes = protos; - - node.kineticObj = createKineticObject( node ); - - // if ( node.kineticObj instanceof Kinetic.Stage ) { - // node.model.scale = { "value": 1, "type": "static" }; - // node.model.scaleX = { "value": 1, "type": "static" }; - // node.model.scaleY = { "value": 1, "type": "static" }; - // node.model.x = { "value": 0, "type": "static" }; - // node.model.y = { "value": 0, "type": "static" }; - // node.model.position = { "value": [ 0, 0 ], "type": "static" }; - // node.model.absolutePosition = { "value": [ 0, 0 ], "type": "static" }; - // node.model.absoluteTransform = { "value": [ 1, 0, 0, 1 ], "type": "static" }; - // } - - // If the kineticObj was created, attach it to the parent kineticObj, if it is a - // kinetic container - // (if a kineticObj is created asynchronously ... like an Image, it will be - // undefined here, but will be added to its parent in the appropriate callback) - addNodeToHierarchy( node ); + + var creatingClient = this.kernel.client(); + var thisClient = this.kernel.moniker(); + + if ( !this.kernel.client() || ( this.kernel.client() === this.kernel.moniker() ) ) { + node.kineticObj = createKineticObject( node ); + + // if ( node.kineticObj instanceof Kinetic.Stage ) { + // node.model.scale = { "value": 1, "type": "static" }; + // node.model.scaleX = { "value": 1, "type": "static" }; + // node.model.scaleY = { "value": 1, "type": "static" }; + // node.model.x = { "value": 0, "type": "static" }; + // node.model.y = { "value": 0, "type": "static" }; + // node.model.position = { "value": [ 0, 0 ], "type": "static" }; + // node.model.absolutePosition = { "value": [ 0, 0 ], "type": "static" }; + // node.model.absoluteTransform = { "value": [ 1, 0, 0, 1 ], "type": "static" }; + // } + + // If the kineticObj was created, attach it to the parent kineticObj, if it is a + // kinetic container + // (if a kineticObj is created asynchronously ... like an Image, it will be + // undefined here, but will be added to its parent in the appropriate callback) + addNodeToHierarchy( node ); + } } @@ -1815,64 +1820,67 @@ define( [ "module", var node = this.state.nodes[ nodeID ]; var imageObj; var value = undefined; - if ( node && node.kineticObj && utility.validObject( propertyValue ) ) { + if ( node && utility.validObject( propertyValue ) ) { + if ( node.kineticObj ) { + if ( node.model[ propertyName ] === undefined ) { + //this.logger.infox( " - model value does not exist " ); + // Not unique-in-view + value = this.state.setProperty( node.kineticObj, propertyName, propertyValue ); - if ( node.model[ propertyName ] === undefined ) { - //this.logger.infox( " - model value does not exist " ); - // Not unique-in-view - value = this.state.setProperty( node.kineticObj, propertyName, propertyValue ); + switch ( propertyName ) { + case "position": + case "stroke": + case "strokeWidth": + case "fill": + case "radius": + if ( node.kineticObj.nodeType !== "Stage" ) { + node.model[ propertyName ] = + { + "value": propertyValue, + "isStatic": false + }; + } + break; - switch ( propertyName ) { - case "position": - case "stroke": - case "strokeWidth": - case "fill": - case "radius": - if ( node.kineticObj.nodeType !== "Stage" ) { - node.model[ propertyName ] = - { - "value": propertyValue, - "isStatic": false - }; - } - break; + default: + break; + } + //} else if ( !node.model[ propertyName ].isStatic ) { + // Not unique-in-view + // value = this.state.setProperty( node.kineticObj, propertyName, node.model[ propertyName ].value ); - default: - break; - } - //} else if ( !node.model[ propertyName ].isStatic ) { - // Not unique-in-view - // value = this.state.setProperty( node.kineticObj, propertyName, node.model[ propertyName ].value ); + } else { + if ( propertyName === "position" ) { - } else { - if ( propertyName === "position" ) { + node.model[ propertyName ].value = propertyValue; - node.model[ propertyName ].value = propertyValue; + if ( node.model[ propertyName ].ignoreNextPositionUpdate ) { + //this.logger.infox( " - ignore position update this time " ); + node.model[ propertyName ].ignoreNextPositionUpdate = false; + } else if ( !node.model[ propertyName ].isStatic ) { + //this.logger.infox( " - set position to model value " ); + value = this.state.setProperty( node.kineticObj, propertyName, node.model[ propertyName ].value ); + } - if ( node.model[ propertyName ].ignoreNextPositionUpdate ) { - //this.logger.infox( " - ignore position update this time " ); - node.model[ propertyName ].ignoreNextPositionUpdate = false; } else if ( !node.model[ propertyName ].isStatic ) { - //this.logger.infox( " - set position to model value " ); - value = this.state.setProperty( node.kineticObj, propertyName, node.model[ propertyName ].value ); + //this.logger.infox( " - not unique in view, update property " ); + node.model[ propertyName ].value = propertyValue; + value = this.state.setProperty( node.kineticObj, propertyName, node.model[ propertyName ].value ); + } else { + //this.logger.infox( " - unique in view, update model only " ); + node.model[ propertyName ].value = propertyValue; } - - } else if ( !node.model[ propertyName ].isStatic ) { - //this.logger.infox( " - not unique in view, update property " ); - node.model[ propertyName ].value = propertyValue; - value = this.state.setProperty( node.kineticObj, propertyName, node.model[ propertyName ].value ); - } else { - //this.logger.infox( " - unique in view, update model only " ); - node.model[ propertyName ].value = propertyValue; - } - /* - if ( this.kernel.client() === this.kernel.moniker() ) { - node.model[ propertyName ].value = propertyValue; - value = this.state.setProperty( node.kineticObj, propertyName, propertyValue ); - } else { - node.model[ propertyName ].value = propertyValue; + /* + if ( this.kernel.client() === this.kernel.moniker() ) { + node.model[ propertyName ].value = propertyValue; + value = this.state.setProperty( node.kineticObj, propertyName, propertyValue ); + } else { + node.model[ propertyName ].value = propertyValue; + } + */ } - */ + } else { + node.model[ propertyName ] = propertyValue; } } diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index e735bb284..3725257d1 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -7,6 +7,21 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var stageContainer; var stageWidth = ( window && window.innerWidth ) ? window.innerWidth : 800; var stageHeight = ( window && window.innerHeight ) ? window.innerHeight : 600; + var drawing_private = {}; + var drawing_client = { + "drawing_mode": 'none', + "drawing_visible": 'inherit', + "drawing_color": 'black', + "drawing_width": 4, + "drawing_parentPath": '/', + "drawing_parentID": undefined, + "drawing_opacity": 1.0, + "nameIndex": 1, + "fontSize": 16, + "angle": 30 + }; + var drawing_index = 0; + var private_node = undefined; function attachMouseEvents( node ) { @@ -155,19 +170,22 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], node.kineticObj.on( "touchstart", function( evt ) { var eData = processEvent( evt, node, false ); //viewDriver.kernel.dispatchEvent( node.ID, "touchStart", eData.eventData, eData.eventNodeData ); - viewDriver.kernel.fireEvent( node.ID, 'touchStart', eData.eventData ); + //viewDriver.kernel.fireEvent( node.ID, 'touchStart', eData.eventData ); + drawDown( node.ID, eData.eventData[0], node, false ); } ); node.kineticObj.on( "touchmove", function( evt ) { var eData = processEvent( evt, node, false ); //viewDriver.kernel.dispatchEvent( node.ID, "touchMove", eData.eventData, eData.eventNodeData ); - viewDriver.kernel.fireEvent( node.ID, 'touchMove', eData.eventData ); + //viewDriver.kernel.fireEvent( node.ID, 'touchMove', eData.eventData ); + drawMove( node.ID, eData.eventData[0], node, false ); } ); node.kineticObj.on( "touchend", function( evt ) { var eData = processEvent( evt, node, false ); //viewDriver.kernel.dispatchEvent( node.ID, "touchEnd", eData.eventData, eData.eventNodeData ); - viewDriver.kernel.fireEvent( node.ID, 'touchEnd', eData.eventData ); + //viewDriver.kernel.fireEvent( node.ID, 'touchEnd', eData.eventData ); + drawUp( node.ID, eData.eventData[0], node, true ); } ); node.kineticObj.on( "tap", function( evt ) { @@ -401,6 +419,10 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], setViewProperty( nodeID, prop, value, isStatic ); break; + + case "setClientUIState": + setClientUIState( methodParameters[0] ); + break; } } @@ -440,19 +462,44 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], return eventsAdded; }, - firedEvent: function( nodeID, eventName ) { - if ( eventName == "draggingFromView" ) { + firedEvent: function( nodeID, eventName, eventData ) { + switch ( eventName ) { - // If the transform property was initially updated by this view.... - if ( self.kernel.client() === self.kernel.moniker() ) { + case "draggingFromView": - // Tell the model not to update the view on the next position update because - // kinetic has already done so - // (this event is fired right before this driver sets the model property, so we - // can be sure that the very next set of the position property is from us) - var node = this.state.nodes[ nodeID ]; - node.model.position.viewIgnoreNextPositionUpdate = true; - } + // If the transform property was initially updated by this view.... + if ( self.kernel.client() === self.kernel.moniker() ) { + + // Tell the model not to update the view on the next position update because + // kinetic has already done so + // (this event is fired right before this driver sets the model property, so we + // can be sure that the very next set of the position property is from us) + var node = this.state.nodes[ nodeID ]; + node.model.position.viewIgnoreNextPositionUpdate = true; + } + break; + + case "privateDrawingUpdated": + // User is actively drawing on the local client + // make sure the drawing is displayed as the user draws it. + if ( self.kernel.client() === self.kernel.moniker() ) { + var node = this.state.nodes[ eventData[0] ]; + if ( node ) { + var kineticObj = node.kineticObj; + if ( kineticObj ) { + //kineticObj.drawScene(); + kineticObj.draw(); + } + } + /* + for ( var id in viewDriver.state.stages ){ + viewDriver.state.stages[ id ].drawScene(); + } */ + } + break; + + default: + break; } }, @@ -645,4 +692,697 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } } + setUpPrivate = function() { + + if ( drawing_private === undefined ) { + drawing_private = {}; + } + if ( drawing_private === undefined ) { + drawing_private = { + "drawingObject": null, + "initialDownPoint": [ -1, -1 ], + "previousPoint": [ -1, -1 ], + "mouseDown": false + }; + } + + }; + + function drawDown( nodeID, eventData, nodeData, touch ) { + + var node = viewDriver.state.nodes[ nodeID ]; + + //if ( !isValid( node.drawing_clients ) || + // !isValid( node.drawing_clients[ node.client ] ) ) { + // node.clientJoin( node.client ); + //} + if ( !isValid( drawing_private ) ) { + setUpPrivate(); + } + + var userState = drawing_client; + var privateState = drawing_private; + var drawingMode = userState.drawing_mode; + + if ( privateState.drawingObject || drawingMode === 'none' ) { + return; + } + + var compExtends = undefined; + var groupExtends = undefined; + var section = "shapes"; + + if ( drawingMode === "freeDraw" ) { + section = "lines"; + } + + switch ( drawingMode ) { + + case "arc": + case "circle": + case "ellipse": + case "regularPolygon": + case "rect": + case "ring": + case "star": + case "wedge": + compExtends = [ "http://vwf.example.com/kinetic/", drawingMode, ".vwf" ].join(''); + break; + + case "sprite": + case "text": + case "image": + groupExtends = "http://vwf.example.com/kinetic/drawingGroup.vwf"; + compExtends = { + "border": "http://vwf.example.com/kinetic/line.vwf", + "content": [ "http://vwf.example.com/kinetic/", drawingMode, ".vwf" ].join('') + }; + break; + + case "arrow": + groupExtends = "http://vwf.example.com/kinetic/drawingGroup.vwf"; + compExtends = { + "line": "http://vwf.example.com/kinetic/line.vwf", + "head": "http://vwf.example.com/kinetic/regularPolygon.vwf" + }; + break; + + case "thickArrow": + groupExtends = "http://vwf.example.com/kinetic/drawingGroup.vwf"; + compExtends = { + "line": "http://vwf.example.com/kinetic/line.vwf", + "head": "http://vwf.example.com/kinetic/regularPolygon.vwf" + }; + break; + + case "borderRect": + case "line": + case "freeDraw": + compExtends = "http://vwf.example.com/kinetic/line.vwf"; + break; + + case 'none': + default: + break; + + } + + var getDefaultProperties = function( drawingMode, groupParent, eventPoint ) { + var retObj = { + "visible": 'inherit', + "listening": 'inherit', + "opacity": userState.drawing_opacity, + "z-index": 4 + }; + + switch( drawingMode ) { + case "sprite": + //case "text": + case "image": + retObj.opacity = 1.0; + retObj.scaleOnLoad = true; + break; + default: + retObj.fill = userState.drawing_color; + break; + } + + if ( groupParent ) { + retObj.x = 0; + retObj.y = 0; + retObj.position = [ 0, 0 ]; + } else { + retObj.x = eventPoint[ 0 ]; + retObj.y = eventPoint[ 1 ]; + retObj.position = eventPoint; + } + + return retObj; + }; + + var eventPointDown = eventData.stageRelative; + if ( groupExtends !== undefined ) { + + privateState.initialDownPoint = eventPointDown; + //var parentPath = userState.drawing_parentPath + section ; + var parentPath = userState.drawing_parentID; + //var parentNode = viewDriver.state.nodes[ parentPath ]; + var section = findSection( parentPath, section ); + var parent = section ? section : node; + //var parents = this.find( parentPath ); + + // find was failing 9/2/14, and the code below + // was a backup, going to leave this in until we feel good + // about the issues we saw are no longer a problem + //if ( parents === undefined ) { + // parents = [ node.findChild( this, parentPath.split( '/' ) ) ]; + //} + + //var parent = viewDriver.state.nodes[ parentPath ] ? viewDriver.state.nodes[ parentPath ] : node; + + //var parent = parents.length > 0 ? parents[ 0 ] : this; + var groupDef = { + "extends": groupExtends, + "properties": { + "visible": false, + "listening": "inherit", + "position": eventPointDown + }, + "children": {} + }; + + for ( var def in compExtends ) { + groupDef.children[ def ] = { + "extends": compExtends[ def ], + "properties": getDefaultProperties( drawingMode, true, eventPointDown ) + } + } + + var self = this; + var selfMoniker = node.client; + var name = drawingMode + drawing_index; + drawing_index = drawing_index + 1; + + //parent.children.create( name, groupDef, function( child ) { + // drawing_private.drawingObject = child; + //} ); + private_node = createLocalKineticNode( section.ID, childID, groupDef, [], undefined, undefined, name ); + drawing_private.drawingObject = private_node.kineticObject; + + + } else if ( compExtends !== undefined ) { + + privateState.initialDownPoint = eventPointDown; + //var parentPath = userState.drawing_parentPath + section; + //var parents = node.find( parentPath ); + //var parents = this.find( parentPath ); + //var parents = viewDriver.state.nodes.find( parentPath ); + + // find was failing 9/2/14, and the code below + // was a backup, going to leave this in until we feel good + // about the issues we saw are no longer a problem + //if ( parents === undefined ) { + // parents = [ node.findChild( this, parentPath.split( '/' ) ) ]; + //} + + //var parent = parents.length > 0 ? parents[ 0 ] : this; + var parentPath = userState.drawing_parentID; + //var parentNode = viewDriver.state.nodes[ parentPath ]; + var section = findSection( parentPath, section ); + var parent = section ? section : node; + //var parents = this.find( parentPath ); + + // find was failing 9/2/14, and the code below + // was a backup, going to leave this in until we feel good + // about the issues we saw are no longer a problem + //if ( parents === undefined ) { + // parents = [ node.findChild( this, parentPath.split( '/' ) ) ]; + //} + + //var parent = viewDriver.state.nodes[ parentPath ] ? viewDriver.state.nodes[ parentPath ] : node; + + var shapeDef = { + "extends": compExtends, + "properties": getDefaultProperties( drawingMode, false, eventPointDown ) + }; + + var self = this; + var selfMoniker = node.client; + var name = drawingMode + drawing_index; + drawing_index = drawing_index + 1; + var childID = section.ID + ":" + name; + //drawing_private.drawingObject = createLocalKineticNode( section.ID, childID, shapeDef, [], undefined, undefined, name ); + private_node = createLocalKineticNode( section.ID, childID, shapeDef, [], undefined, undefined, name ); + drawing_private.drawingObject = private_node.kineticObject; + //parent.children.create( name, shapeDef, function( child ) { + // drawing_private.drawingObject = child; + //} ); + + } + }; + + function drawMove( nodeID, eventData, nodeData, touch ) { + + var node = viewDriver.state.nodes[ nodeID ]; + + //if ( !isValid( node.drawing_clients ) || + // !isValid( node.drawing_clients[ node.client ] ) ) { + // node.clientJoin( node.client ); + //} + if ( drawing_private === undefined ) { + setUpPrivate( ); + } + + var userState = drawing_client; + if ( userState.drawing_mode === 'none' ) { + return; + } + + drawUpdate( drawing_private.drawingObject.ID, eventData, nodeData, false ); + }; + + function drawUp( nodeID, eventData, nodeData, touch ) { + + var node = viewDriver.state.nodes[ nodeID ]; + + if ( drawing_private !== undefined && + drawing_private.drawingObject ) { + var drawingObject = drawing_private.drawingObject; + drawUpdate( drawing_private.drawingObject.ID, eventData, nodeData, true ); + + node.drawingObjectCreated( drawingObject.id ); + + var userState = drawing_client; + if ( node.moniker === node.client ) { + + switch( userState.drawing_mode ) { + + case "text": + node.textCreated( drawingObject.content.id ); + break; + + case "sprite": + case "image": + node.imageCreated( drawingObject.content.id ); + break; + + } + } + + switch( userState.drawing_mode ) { + + case "text": + case "sprite": + case "image": + drawingObject.border.visible = false; + break; + + } + + drawing_private.drawingObject = null; + } + }; + + function drawUpdate( nodeID, eventData, nodeData, upEvent ) { + + var node = viewDriver.state.nodes[ nodeID ]; + + if ( drawing_private === undefined || + !isValid( drawing_client ) ) { + return; + } + + if ( drawing_private.drawingObject && !upEvent ) { + + var eventPoint = eventData.stageRelative; + var userState = drawing_client; + var privateState = drawing_private; + var drawingObject = privateState.drawingObject; + var pointAccepted = true; + + if ( drawingObject.visible !== userState.drawing_visible ) { + drawingObject.visible = userState.drawing_visible; + } + if ( drawingObject.listening !== userState.drawing_listening ) { + drawingObject.listening = userState.drawing_listening; + } + var diffX = eventPoint[ 0 ] - privateState.initialDownPoint[ 0 ]; + var diffY = eventPoint[ 1 ] - privateState.initialDownPoint[ 1 ]; + var pos = [ privateState.initialDownPoint[ 0 ], privateState.initialDownPoint[ 1 ] ]; + var width = diffX; + var height = diffY; + var dist = Math.sqrt( ( diffX * diffX ) + ( diffY * diffY ) ); + + //console.info( "== "+userState.drawing_mode +" ==" ); + //console.info( "== pos: " + pos + " diffX: " + diffX + " diffY: " + diffY ); + + // this keeps the pos as the top left corner for the + // rectangular objects + switch ( userState.drawing_mode ) { + + case "line": + case "arrow": + case "thickArrow": + case "freeDraw": + break; + + default: + if ( diffX < 0 ) { + pos[ 0 ] += diffX; + width = Math.abs( diffX ); + } + if ( diffY < 0 ) { + pos[ 1 ] += diffY; + height = Math.abs( diffY ); + } + drawingObject.position = pos; + drawingObject.width = width; + drawingObject.height = height; + break; + } + + //console.info( "== pos: " + pos + " diffX: " + diffX + " diffY: " + diffY ); + + switch ( userState.drawing_mode ) { + + case "arc": + drawingObject.angle = userState.angle ? userState.angle : 30; + if ( dist > node.drawing_width ) { + drawingObject.innerRadius = dist - node.drawing_width; + drawingObject.outerRadius = dist; + } + break; + + case "ellipse": + drawingObject.radius = { "x": width * 0.5, "y": height * 0.5 }; + break; + + case "circle": + drawingObject.radius = dist; + break; + + case "line": + drawingObject.stroke = userState.drawing_color; + drawingObject.strokeWidth = userState.drawing_width; + drawingObject.points = [ 0, 0, diffX, diffY ]; + break; + + case "freeDraw": + //debugger; + drawingObject.stroke = userState.drawing_color; + drawingObject.strokeWidth = userState.drawing_width; + + if ( drawingObject.points === undefined ) { + drawingObject[ "points" ] = []; + } + + var isFirstStrokeOfNewLine = ( drawingObject.points.length === 0 ); + + console.info( "VIEW: Event point: [ " + eventPoint[0] + ", " + eventPoint[1] + " ], Drawing object x, y: [ " + drawingObject.x() + ", " + drawingObject.y() + " ]"); + + var posX = eventPoint[ 0 ] - drawingObject.x(); + var posY = eventPoint[ 1 ] - drawingObject.y(); + + if ( isFirstStrokeOfNewLine ) { + if ( ( Math.abs( posX ) + Math.abs( posY ) ) > 0 ) { + drawingObject.points = [ 0, 0, posX, posY ]; + } else { + pointAccepted = false; + } + } else { + var dragDiff = [ + posX - privateState.previousPoint[ 0 ], + posY - privateState.previousPoint[ 1 ] + ]; + + if ( ( Math.abs( dragDiff[0] ) + Math.abs( dragDiff[1] ) ) > 0 ) { + drawingObject.points.push( posX ); + drawingObject.points.push( posY ); + } else { + pointAccepted = false; + } + } + break; + + case "regularPolygon": + // needs defining + break; + + case "ring": + if ( dist > userState.drawing_width ) { + drawingObject.innerRadius = dist - userState.drawing_width; + drawingObject.outerRadius = dist; + } + break; + + case "star": + drawingObject.points = 5; + drawingObject.innerRadius = dist * 80; + drawingObject.outerRadius = dist; + break; + + case "wedge": + // needs defining + drawingObject.angle = userState.angle ? userState.angle : 30; + drawingObject.radius = dist; + drawingObject.clockwise = false; + break; + + case "borderRect": + drawingObject.stroke = userState.drawing_color; + drawingObject.strokeWidth = userState.drawing_width; + drawingObject.points = [ 0, 0, width, 0, width, height, 0, height, 0, 0 ]; + break; + + case "arrow": + drawingObject.x = drawingObject.position[ 0 ]; + drawingObject.y = drawingObject.position[ 1 ]; + + drawingObject.line.stroke = userState.drawing_color; + drawingObject.line.strokeWidth = userState.drawing_width; + drawingObject.line.position = [ 0, 0 ]; + + drawingObject.head.sides = 3; + drawingObject.head.radius = userState.drawing_width * 3; + + var endPoint = goog.vec.Vec2.createFloat32FromValues( 0, 0 ); + var relativeXDiff = eventPoint[ 0 ] - drawingObject.x; + var relativeYDiff = eventPoint[ 1 ] - drawingObject.y; + var headOffset = ( userState.drawing_width * 3 ) * Math.sin( Math.PI / 6 ); + var dir = goog.vec.Vec2.createFloat32FromValues( relativeXDiff, relativeYDiff ); + var len = goog.vec.Vec2.distance( goog.vec.Vec2.createFloat32FromValues( 0, 0 ), dir ); + goog.vec.Vec2.normalize( dir, dir ); + + drawingObject.head.rotation = Math.atan2( dir[1], dir[0] ) * ( 180 / Math.PI ) - 30; + goog.vec.Vec2.scale( dir, len - ( userState.drawing_width * 3 ), endPoint ); + drawingObject.head.position = [ endPoint[0], endPoint[1] ]; + goog.vec.Vec2.scale( dir, len - ( ( userState.drawing_width * 3 ) + headOffset ), endPoint ); + drawingObject.line.points = [ 0, 0, endPoint[0], endPoint[1] ]; + break; + + case "thickArrow": + drawingObject.x = drawingObject.position[ 0 ]; + drawingObject.y = drawingObject.position[ 1 ]; + + drawingObject.line.stroke = userState.drawing_color; + drawingObject.line.strokeWidth = userState.drawing_width * 8; + drawingObject.line.position = [ 0, 0 ]; + + drawingObject.head.sides = 3; + drawingObject.head.radius = userState.drawing_width * 8; + + var endPoint = goog.vec.Vec2.createFloat32FromValues( 0, 0 ); + var relativeXDiff = eventPoint[ 0 ] - drawingObject.x; + var relativeYDiff = eventPoint[ 1 ] - drawingObject.y; + var headOffset = ( userState.drawing_width * 8 ) * Math.sin( Math.PI / 6 ); + var dir = goog.vec.Vec2.createFloat32FromValues( relativeXDiff, relativeYDiff ); + var len = goog.vec.Vec2.distance( goog.vec.Vec2.createFloat32FromValues( 0, 0 ), dir ); + goog.vec.Vec2.normalize( dir, dir ); + + drawingObject.head.rotation = Math.atan2( dir[1], dir[0] ) * ( 180 / Math.PI ) - 30; + goog.vec.Vec2.scale( dir, len - ( userState.drawing_width * 8 ), endPoint ); + drawingObject.head.position = [ endPoint[0], endPoint[1] ]; + goog.vec.Vec2.scale( dir, len - ( ( userState.drawing_width * 8 ) + headOffset ), endPoint ); + drawingObject.line.points = [ 0, 0, endPoint[0], endPoint[1] ]; + break; + + case "sprite": + case "image": + drawingObject.border.stroke = userState.drawing_color; + drawingObject.border.strokeWidth = 4; + drawingObject.border.points = [ 0, 0, width, 0, width, height, 0, height, 0, 0 ]; + drawingObject.content.width = width; + drawingObject.content.height = height; + break; + + case "text": + drawingObject.border.stroke = userState.drawing_color; + drawingObject.border.strokeWidth = 4; + drawingObject.border.points = [ 0, 0, width, 0, width, height, 0, height, 0, 0 ]; + drawingObject.content.fontSize = userState.fontSize ? userState.fontSize : 16; + break; + + case "rect": + default: + break; + + } + + if ( pointAccepted ) { + privateState.previousPoint = eventPoint; + // Update the view to keep pace with user input + //console.info( drawingObject.id + " updated, sending update event." ); + //node.privateDrawingUpdated( drawingObject.id ); + if ( drawingObject ) { + drawingObject.drawScene(); + } + } + + } + }; + + function isValid( obj ) { + var objType = ( {} ).toString.call( obj ).match( /\s([a-zA-Z]+)/ )[ 1 ].toLowerCase(); + return ( objType != 'null' && objType != 'undefined' ); + }; + + function setClientUIState( stateObj ) { + + //console.info( "setClientUIState " + JSON.stringify( stateObj ) ); + if ( stateObj !== undefined ) { + //if ( !isValid( drawing_client ) ) { + // clientJoin( this.client ); + //} + //var clients = drawing_client; + var userState = drawing_client; + for ( var property in stateObj ) { + userState[ property ] = stateObj[ property ]; + } + //drawing_client = clients; + } + }; + + this.findChild = function( parent, names ) { + if ( names.length > 0 ) { + var childName = names.shift(); + while ( childName === "" ) { + childName = names.shift(); + } + if ( parent.children[ childName ] ) { + if ( names.length === 0 ) { + return parent.children[ childName ]; + } else { + return this.findChild( parent.children[ childName ], names ); + } + } + else { + return undefined; + } + } + return undefined; + } + + function findSection( parentID, name ) { + var parent = viewDriver.state.nodes[ parentID ]; + + if ( parent && parent.children ) { + for ( var i = 0; i < parent.children.length; i++ ) { + if ( parent.children[ i ].indexOf( name, parentID.length ) >= 0 ) { + var childID = parent.children[ i ]; + var child = viewDriver.state.nodes[ childID ]; + return child; + } + } + } + + return undefined; + } + + function createLocalKineticNode( parentID, drawingID, objDef, implementsID, source, type, name ) { + + var extendsID = objDef[ "extends" ]; + //var protos = getPrototypes( viewDriver.kernel, extendsID ); + + var node = viewDriver.state.createLocalNode( parentID, drawingID, extendsID, implementsID, source, type, drawing_index, name ); + node.prototypes = []; + node.prototypes.push( extendsID ); + + var kineticObj = createKineticObject( node, objDef.properties ); + node.kineticObject = kineticObj; + + return node; + } + + function createKineticObject( node, config ) { + var protos = node.prototypes; + var kineticObj = undefined; + + if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/arc.vwf" ) ) { + kineticObj = new Kinetic.Arc( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/baseLayer.vwf" ) ) { + kineticObj = new Kinetic.BaseLayer( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/canvas.vwf" ) ) { + kineticObj = new Kinetic.Canvas( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/circle.vwf" ) ) { + kineticObj = new Kinetic.Circle( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/ellipse.vwf" ) ) { + kineticObj = new Kinetic.Ellipse( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/fastLayer.vwf" ) ) { + kineticObj = new Kinetic.FastLayer( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/group.vwf" ) ) { + kineticObj = new Kinetic.Group( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/image.vwf" ) ) { + var imageObj = new Image(); + node.scaleOnLoad = false; + kineticObj = new Kinetic.Image( { + image: imageObj + } ); + if ( node.source !== undefined ) { + imageObj.src = node.source; + } + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/layer.vwf" ) ) { + kineticObj = new Kinetic.Layer( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/line.vwf" ) ) { + kineticObj = new Kinetic.Line( config || { "points": [] } ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/path.vwf" ) ) { + kineticObj = new Kinetic.Path( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/rect.vwf" ) ) { + kineticObj = new Kinetic.Rect( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/regularPolygon.vwf" ) ) { + kineticObj = new Kinetic.RegularPolygon( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/ring.vwf" ) ) { + kineticObj = new Kinetic.Ring( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/sprite.vwf" ) ) { + var imageObj = new Image(); + node.scaleOnLoad = false; + kineticObj = new Kinetic.Sprite( { + image: imageObj + } ); + if ( node.source !== undefined ) { + imageObj.src = node.source; + } + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/stage.vwf" ) ) { + var stageWidth = ( window && window.innerWidth ) ? window.innerWidth : 800; + var stageHeight = ( window && window.innerHeight ) ? window.innerHeight : 600; + var stageContainer = ( config && config.container ) || 'vwf-root'; + var stageWidth = ( config && config.width ) || stageWidth; + var stageHeight = ( config && config.height ) || stageHeight; + var stageDef = { + "container": stageContainer, + "width": stageWidth, + "height": stageHeight + }; + kineticObj = new Kinetic.Stage( stageDef ); + viewDriver.state.stages[ node.ID ] = kineticObj; + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/star.vwf" ) ) { + kineticObj = new Kinetic.Star( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/text.vwf" ) ) { + kineticObj = new Kinetic.Text( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/textPath.vwf" ) ) { + kineticObj = new Kinetic.TextPath( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/wedge.vwf" ) ) { + kineticObj = new Kinetic.Wedge( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/shape.vwf" ) ) { + kineticObj = new Kinetic.Shape( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/container.vwf" ) ) { + kineticObj = new Kinetic.Container( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/node.vwf" ) ) { + kineticObj = new Kinetic.Node( config || {} ); + } + + return kineticObj; + } + + function getPrototypes( kernel, extendsID ) { + var prototypes = []; + var id = extendsID; + + while ( id !== undefined ) { + prototypes.push( id ); + id = kernel.prototype( id ); + } + + return prototypes; + } + }); \ No newline at end of file diff --git a/support/proxy/vwf.example.com/kinetic/drawing.js b/support/proxy/vwf.example.com/kinetic/drawing.js index abadea8e3..f489d0fd4 100644 --- a/support/proxy/vwf.example.com/kinetic/drawing.js +++ b/support/proxy/vwf.example.com/kinetic/drawing.js @@ -420,10 +420,13 @@ this.update = function( eventData, nodeData, upEvent ) { break; case "freeDraw": + //debugger; drawingObject.stroke = userState.drawing_color; drawingObject.strokeWidth = userState.drawing_width; var isFirstStrokeOfNewLine = ( drawingObject.points.length === 0 ); + + console.info( "MODEL: Event point: [ " + eventPoint[0] + ", " + eventPoint[1] + " ], Drawing object x, y: [ " + drawingObject.x + ", " + drawingObject.y + " ]"); var posX = eventPoint[ 0 ] - drawingObject.x; var posY = eventPoint[ 1 ] - drawingObject.y; @@ -554,6 +557,9 @@ this.update = function( eventData, nodeData, upEvent ) { if ( pointAccepted ) { privateState.previousPoint = eventPoint; + // Update the view to keep pace with user input + //console.info( drawingObject.id + " updated, sending update event." ); + this.privateDrawingUpdated( drawingObject.id ); } } diff --git a/support/proxy/vwf.example.com/kinetic/drawing.vwf.yaml b/support/proxy/vwf.example.com/kinetic/drawing.vwf.yaml index 5919fc277..7f207da02 100644 --- a/support/proxy/vwf.example.com/kinetic/drawing.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/drawing.vwf.yaml @@ -27,5 +27,6 @@ events: textCreated: imageCreated: findChild: + privateDrawingUpdated: scripts: - source: "http://vwf.example.com/kinetic/drawing.js" From 63dd77852f45ab62d168ad076f20b546d3ca2cc5 Mon Sep 17 00:00:00 2001 From: Scott Haynes Date: Tue, 3 Nov 2015 09:07:19 -0500 Subject: [PATCH 025/644] Attempts to move the drawing into the view --- support/client/lib/vwf/view/kineticjs.js | 56 +++++++++++++++++++++--- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 3725257d1..4b1569960 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -9,7 +9,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var stageHeight = ( window && window.innerHeight ) ? window.innerHeight : 600; var drawing_private = {}; var drawing_client = { - "drawing_mode": 'none', + "drawing_mode": 'freeDraw', "drawing_visible": 'inherit', "drawing_color": 'black', "drawing_width": 4, @@ -30,7 +30,8 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], node.kineticObj.on( "mousemove", function( evt ) { var eData = processEvent( evt, node, false ); //viewDriver.kernel.dispatchEvent( node.ID, 'pointerMove', eData.eventData, eData.eventNodeData ); - viewDriver.kernel.fireEvent( node.ID, 'pointerMove', eData.eventData ); + //viewDriver.kernel.fireEvent( node.ID, 'pointerMove', eData.eventData ); + drawMove( node.ID, eData.eventData[0], node, false ); } ); node.kineticObj.on( "mouseout", function( evt ) { @@ -54,14 +55,17 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var eData = processEvent( evt, node, false ); mouseDown = true; //viewDriver.kernel.dispatchEvent( node.ID, 'pointerDown', eData.eventData, eData.eventNodeData ); - viewDriver.kernel.fireEvent( node.ID, 'pointerDown', eData.eventData ); + //viewDriver.kernel.fireEvent( node.ID, 'pointerDown', eData.eventData ); + + drawDown( node.ID, eData.eventData[0], node, false ); } ); node.kineticObj.on( "mouseup", function( evt ) { var eData = processEvent( evt, node, false ); mouseDown = false; //viewDriver.kernel.dispatchEvent( node.ID, 'pointerUp', eData.eventData, eData.eventNodeData ); - viewDriver.kernel.fireEvent( node.ID, 'pointerUp', eData.eventData ); + //viewDriver.kernel.fireEvent( node.ID, 'pointerUp', eData.eventData ); + drawUp( node.ID, eData.eventData[0], node, true ); if ( node.kineticObj.mouseDragging ) { viewDriver.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); @@ -93,7 +97,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], viewDriver.kernel.fireEvent( node.ID, 'pointerDoubleClick', eData.eventData ); } ); - /* + /*draw node.kineticObj.on( "dragstart", function( evt ) { var eData = processEvent( evt, node, false ); viewDriver.kernel.fireEvent( node.ID, 'dragStart', eData.eventData ); @@ -402,12 +406,20 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], kineticObj.scaleY( node.model.scaleX ); } break; + + case "activeLayerID": + if ( this.kernel.client() === this.kernel.moniker() ) { + drawing_client.drawing_parentID = propertyValue; + } + break; } }, calledMethod: function( nodeID, methodName, methodParameters, methodValue ) { + console.info( "methodName = " + methodName ); + if ( this.kernel.client() === this.kernel.moniker() ) { var prop, value, t; switch ( methodName ) { @@ -423,6 +435,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], case "setClientUIState": setClientUIState( methodParameters[0] ); break; + } } @@ -921,6 +934,35 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } }; + function addNodeToHierarchy( node ) { + + console.info( "addNodeToHierarchy ID: " + node.ID + " parentID: " + node.parentID ); + + if ( node.kineticObj ) { + + debugger; + + if ( modelDriver.state.nodes[ node.parentID ] !== undefined ) { + var parent = modelDriver.state.nodes[ node.parentID ]; + if ( parent.kineticObj && isContainerDefinition( parent.prototypes ) ) { + + if ( parent.children === undefined ) { + parent.children = []; + } + parent.children.push( node.ID ); + //console.info( "Adding child: " + childID + " to " + nodeID ); + parent.kineticObj.add( node.kineticObj ); + } + } + node.kineticObj.setId( node.ID ); + node.kineticObj.name( node.name ); + + node.stage = findStage( node.kineticObj ); + } + + } + + function drawMove( nodeID, eventData, nodeData, touch ) { var node = viewDriver.state.nodes[ nodeID ]; @@ -1283,6 +1325,8 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var extendsID = objDef[ "extends" ]; //var protos = getPrototypes( viewDriver.kernel, extendsID ); + console.info( "createLocalKineticNode" ); + var node = viewDriver.state.createLocalNode( parentID, drawingID, extendsID, implementsID, source, type, drawing_index, name ); node.prototypes = []; node.prototypes.push( extendsID ); @@ -1290,6 +1334,8 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var kineticObj = createKineticObject( node, objDef.properties ); node.kineticObject = kineticObj; + addNodeToHierarchy( node ); + return node; } From 9b04d0ac30bfc6eab6c814e2c8b15fc3dc319a10 Mon Sep 17 00:00:00 2001 From: David Easter Date: Tue, 10 Nov 2015 14:06:42 -0500 Subject: [PATCH 026/644] npm shrinkwrap --- npm-shrinkwrap.json | 485 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 404 insertions(+), 81 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index ce3b268cd..ad91b34ef 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -2,13 +2,400 @@ "name": "vwf", "version": "0.0.0", "dependencies": { + "async": { + "version": "0.2.10", + "from": "async@0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz" + }, "crypto": { "version": "0.0.3", - "from": "crypto@0.0.x" + "from": "crypto@>=0.0.0 <0.1.0", + "resolved": "https://registry.npmjs.org/crypto/-/crypto-0.0.3.tgz" + }, + "express": { + "version": "4.13.3", + "from": "express@>=4.13.3 <5.0.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.13.3.tgz", + "dependencies": { + "accepts": { + "version": "1.2.13", + "from": "accepts@>=1.2.12 <1.3.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.2.13.tgz", + "dependencies": { + "mime-types": { + "version": "2.1.7", + "from": "mime-types@>=2.1.7 <2.2.0", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.7.tgz", + "dependencies": { + "mime-db": { + "version": "1.19.0", + "from": "mime-db@>=1.19.0 <1.20.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.19.0.tgz" + } + } + }, + "negotiator": { + "version": "0.5.3", + "from": "negotiator@0.5.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.5.3.tgz" + } + } + }, + "array-flatten": { + "version": "1.1.1", + "from": "array-flatten@1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" + }, + "content-disposition": { + "version": "0.5.0", + "from": "content-disposition@0.5.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.0.tgz" + }, + "content-type": { + "version": "1.0.1", + "from": "content-type@>=1.0.1 <1.1.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.1.tgz" + }, + "cookie": { + "version": "0.1.3", + "from": "cookie@0.1.3", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.3.tgz" + }, + "cookie-signature": { + "version": "1.0.6", + "from": "cookie-signature@1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" + }, + "debug": { + "version": "2.2.0", + "from": "debug@>=2.2.0 <2.3.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "dependencies": { + "ms": { + "version": "0.7.1", + "from": "ms@0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz" + } + } + }, + "depd": { + "version": "1.0.1", + "from": "depd@>=1.0.1 <1.1.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.0.1.tgz" + }, + "escape-html": { + "version": "1.0.2", + "from": "escape-html@1.0.2", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.2.tgz" + }, + "etag": { + "version": "1.7.0", + "from": "etag@>=1.7.0 <1.8.0", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.7.0.tgz" + }, + "finalhandler": { + "version": "0.4.0", + "from": "finalhandler@0.4.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.4.0.tgz", + "dependencies": { + "unpipe": { + "version": "1.0.0", + "from": "unpipe@1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" + } + } + }, + "fresh": { + "version": "0.3.0", + "from": "fresh@0.3.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.3.0.tgz" + }, + "merge-descriptors": { + "version": "1.0.0", + "from": "merge-descriptors@1.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.0.tgz" + }, + "methods": { + "version": "1.1.1", + "from": "methods@>=1.1.1 <1.2.0", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.1.tgz" + }, + "on-finished": { + "version": "2.3.0", + "from": "on-finished@>=2.3.0 <2.4.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "dependencies": { + "ee-first": { + "version": "1.1.1", + "from": "ee-first@1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" + } + } + }, + "parseurl": { + "version": "1.3.0", + "from": "parseurl@>=1.3.0 <1.4.0", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.0.tgz" + }, + "path-to-regexp": { + "version": "0.1.7", + "from": "path-to-regexp@0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" + }, + "proxy-addr": { + "version": "1.0.8", + "from": "proxy-addr@>=1.0.8 <1.1.0", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.0.8.tgz", + "dependencies": { + "forwarded": { + "version": "0.1.0", + "from": "forwarded@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.0.tgz" + }, + "ipaddr.js": { + "version": "1.0.1", + "from": "ipaddr.js@1.0.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.0.1.tgz" + } + } + }, + "qs": { + "version": "4.0.0", + "from": "qs@4.0.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-4.0.0.tgz" + }, + "range-parser": { + "version": "1.0.3", + "from": "range-parser@>=1.0.2 <1.1.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.3.tgz" + }, + "send": { + "version": "0.13.0", + "from": "send@0.13.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.13.0.tgz", + "dependencies": { + "destroy": { + "version": "1.0.3", + "from": "destroy@1.0.3", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.3.tgz" + }, + "http-errors": { + "version": "1.3.1", + "from": "http-errors@>=1.3.1 <1.4.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", + "dependencies": { + "inherits": { + "version": "2.0.1", + "from": "inherits@>=2.0.1 <2.1.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + } + } + }, + "mime": { + "version": "1.3.4", + "from": "mime@1.3.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz" + }, + "ms": { + "version": "0.7.1", + "from": "ms@0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz" + }, + "statuses": { + "version": "1.2.1", + "from": "statuses@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.2.1.tgz" + } + } + }, + "serve-static": { + "version": "1.10.0", + "from": "serve-static@>=1.10.0 <1.11.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.10.0.tgz" + }, + "type-is": { + "version": "1.6.9", + "from": "type-is@>=1.6.6 <1.7.0", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.9.tgz", + "dependencies": { + "media-typer": { + "version": "0.3.0", + "from": "media-typer@0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" + }, + "mime-types": { + "version": "2.1.7", + "from": "mime-types@>=2.1.7 <2.2.0", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.7.tgz", + "dependencies": { + "mime-db": { + "version": "1.19.0", + "from": "mime-db@>=1.19.0 <1.20.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.19.0.tgz" + } + } + } + } + }, + "utils-merge": { + "version": "1.0.0", + "from": "utils-merge@1.0.0", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz" + }, + "vary": { + "version": "1.0.1", + "from": "vary@>=1.0.1 <1.1.0", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.0.1.tgz" + } + } + }, + "fs-extra": { + "version": "0.8.1", + "from": "fs-extra@>=0.8.0 <0.9.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.8.1.tgz", + "dependencies": { + "ncp": { + "version": "0.4.2", + "from": "ncp@>=0.4.2 <0.5.0", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-0.4.2.tgz" + }, + "mkdirp": { + "version": "0.3.5", + "from": "mkdirp@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz" + }, + "jsonfile": { + "version": "1.1.1", + "from": "jsonfile@>=1.1.0 <1.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-1.1.1.tgz" + }, + "rimraf": { + "version": "2.2.8", + "from": "rimraf@>=2.2.0 <2.3.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz" + } + } + }, + "glob": { + "version": "5.0.15", + "from": "glob@>=5.0.15 <6.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "dependencies": { + "inflight": { + "version": "1.0.4", + "from": "inflight@>=1.0.4 <2.0.0", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.1", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + } + } + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "minimatch": { + "version": "3.0.0", + "from": "minimatch@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.0.tgz", + "dependencies": { + "brace-expansion": { + "version": "1.1.1", + "from": "brace-expansion@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.1.tgz", + "dependencies": { + "balanced-match": { + "version": "0.2.1", + "from": "balanced-match@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.1.tgz" + }, + "concat-map": { + "version": "0.0.1", + "from": "concat-map@0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + } + } + } + } + }, + "once": { + "version": "1.3.2", + "from": "once@>=1.3.0 <2.0.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.1", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + } + } + }, + "path-is-absolute": { + "version": "1.0.0", + "from": "path-is-absolute@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz" + } + } + }, + "js-yaml": { + "version": "2.1.3", + "from": "js-yaml@>=2.1.0 <2.2.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-2.1.3.tgz", + "dependencies": { + "argparse": { + "version": "0.1.16", + "from": "argparse@>=0.1.11 <0.2.0", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.16.tgz", + "dependencies": { + "underscore": { + "version": "1.7.0", + "from": "underscore@>=1.7.0 <1.8.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz" + }, + "underscore.string": { + "version": "2.4.0", + "from": "underscore.string@>=2.4.0 <2.5.0", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz" + } + } + }, + "esprima": { + "version": "1.0.4", + "from": "esprima@>=1.0.2 <1.1.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz" + } + } + }, + "mime": { + "version": "1.2.11", + "from": "mime@>=1.2.0 <1.3.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz" + }, + "optimist": { + "version": "0.6.1", + "from": "optimist@0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "dependencies": { + "wordwrap": { + "version": "0.0.3", + "from": "wordwrap@>=0.0.2 <0.1.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz" + }, + "minimist": { + "version": "0.0.10", + "from": "minimist@>=0.0.1 <0.1.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz" + } + } }, "socket.io": { - "version": "0.9.16", - "from": "socket.io@0.9.x", + "version": "0.9.17", + "from": "socket.io@0.9.17", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-0.9.17.tgz", "dependencies": { "socket.io-client": { "version": "0.9.16", @@ -21,25 +408,29 @@ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-1.2.5.tgz" }, "ws": { - "version": "0.4.31", - "from": "ws@0.4.x", + "version": "0.4.32", + "from": "ws@>=0.4.0 <0.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-0.4.32.tgz", "dependencies": { "commander": { - "version": "0.6.1", - "from": "commander@~0.6.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz" + "version": "2.1.0", + "from": "commander@>=2.1.0 <2.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz" }, "nan": { - "version": "0.3.2", - "from": "nan@~0.3.0" + "version": "1.0.0", + "from": "nan@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-1.0.0.tgz" }, "tinycolor": { "version": "0.0.1", - "from": "tinycolor@0.x" + "from": "tinycolor@>=0.0.0 <1.0.0", + "resolved": "https://registry.npmjs.org/tinycolor/-/tinycolor-0.0.1.tgz" }, "options": { - "version": "0.0.5", - "from": "options@>=0.0.5" + "version": "0.0.6", + "from": "options@>=0.0.5", + "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz" } } }, @@ -78,74 +469,6 @@ "resolved": "https://registry.npmjs.org/redis/-/redis-0.7.3.tgz" } } - }, - "async": { - "version": "0.2.9", - "from": "async@0.2.x" - }, - "mime": { - "version": "1.2.11", - "from": "mime@1.2.x" - }, - "js-yaml": { - "version": "2.1.3", - "from": "js-yaml@2.1.x", - "dependencies": { - "argparse": { - "version": "0.1.15", - "from": "argparse@~ 0.1.11", - "dependencies": { - "underscore": { - "version": "1.4.4", - "from": "underscore@~1.4.3" - }, - "underscore.string": { - "version": "2.3.3", - "from": "underscore.string@~2.3.1" - } - } - }, - "esprima": { - "version": "1.0.4", - "from": "esprima@~ 1.0.2" - } - } - }, - "optimist": { - "version": "0.6.0", - "from": "optimist@0.6.x", - "dependencies": { - "wordwrap": { - "version": "0.0.2", - "from": "wordwrap@~0.0.2" - }, - "minimist": { - "version": "0.0.5", - "from": "minimist@~0.0.1" - } - } - }, - "fs-extra": { - "version": "0.8.1", - "from": "fs-extra@0.8.x", - "dependencies": { - "ncp": { - "version": "0.4.2", - "from": "ncp@~0.4.2" - }, - "mkdirp": { - "version": "0.3.5", - "from": "mkdirp@0.3.x" - }, - "jsonfile": { - "version": "1.1.1", - "from": "jsonfile@~1.1.0" - }, - "rimraf": { - "version": "2.2.5", - "from": "rimraf@~2.2.0" - } - } } } } From fca2d52f9c9e3541f47b1840288f9d4596d69b58 Mon Sep 17 00:00:00 2001 From: youngca Date: Fri, 27 Nov 2015 18:34:14 -0500 Subject: [PATCH 027/644] Client-side (view-based) drawing is working for non-group objects. Need to propagate to model. --- support/client/lib/vwf/model/kineticjs.js | 33 +++ support/client/lib/vwf/view/kineticjs.js | 343 +++++++++++++++------- 2 files changed, 271 insertions(+), 105 deletions(-) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index 1acacc94d..ad73040db 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -1922,6 +1922,14 @@ define( [ "module", if ( this.debug.methods ) { this.logger.infox( " M === callingMethod ", nodeID, methodName ); } + + switch( methodName ) { + case "propagateKineticNode": + if ( methodParameters.length > 0 ) { + propagateKineticNode( methodParameters[0] ); + } + break; + } }, // -- executing ------------------------------------------------------------------------------ @@ -2042,6 +2050,31 @@ define( [ "module", } + function propagateKineticNode( nodeObj ) { + //if ( modelDriver.state.isKineticComponent( nodeObj.prototypes ) ) { + + //if ( modelDriver.debug.native ) { + // modelDriver.logger.infox( "propagateKineticNode", nodeObj.parentID, nodeObj.ID, nodeObj.extendsID, nodeObj.implementsIDs, nodeObj.source, nodeObj.type, undefined, nodeObj.name ); + //} + + // Create the local copy of the node properties + if ( modelDriver.state.nodes[ nodeObj.ID ] === undefined ){ + modelDriver.state.nodes[ nodeObj.ID ] = + modelDriver.state.createLocalNode( nodeObj.parentID, nodeObj.ID, nodeObj.extendsID, nodeObj.implementsIDs, + nodeObj.source, nodeObj.type, undefined, nodeObj.name, null ); + } + + // Add the kinetic object to the node properties + node = modelDriver.state.nodes[ nodeObj.ID ]; + + node.prototypes = nodeObj.prototypes; + node.kineticObj = nodeObj.kineticObj; + + // Add the node to the hierarchy + addNodeToHierarchy( node ); + //} + } + function addNodeToHierarchy( node ) { if ( node.kineticObj ) { diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 4b1569960..87f01951c 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -9,7 +9,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var stageHeight = ( window && window.innerHeight ) ? window.innerHeight : 600; var drawing_private = {}; var drawing_client = { - "drawing_mode": 'freeDraw', + "drawing_mode": 'none', "drawing_visible": 'inherit', "drawing_color": 'black', "drawing_width": 4, @@ -18,10 +18,13 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], "drawing_opacity": 1.0, "nameIndex": 1, "fontSize": 16, - "angle": 30 + "angle": 30, + "lineCap": 'round' }; var drawing_index = 0; var private_node = undefined; + var activelyDrawing = false; + var clearBeforeDraw = false; function attachMouseEvents( node ) { @@ -31,7 +34,20 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var eData = processEvent( evt, node, false ); //viewDriver.kernel.dispatchEvent( node.ID, 'pointerMove', eData.eventData, eData.eventNodeData ); //viewDriver.kernel.fireEvent( node.ID, 'pointerMove', eData.eventData ); - drawMove( node.ID, eData.eventData[0], node, false ); + //activelyDrawing = mouseDown; + + //var userState = drawing_client; + //if ( userState[ "drawing_mode" ] && ( userState[ "drawing_mode" ] !== "none" ) ) { + //activelyDrawing = true; + // drawMove( node.ID, eData.eventData[0], node, false ); + //} + drawMove( node.ID, eData.eventData[0], node, false ); + + var userState = drawing_client; + if ( userState[ "drawing_mode" ] && ( userState[ "drawing_mode" ] !== "none" ) ) { + activelyDrawing = true; + } + } ); node.kineticObj.on( "mouseout", function( evt ) { @@ -57,16 +73,38 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], //viewDriver.kernel.dispatchEvent( node.ID, 'pointerDown', eData.eventData, eData.eventNodeData ); //viewDriver.kernel.fireEvent( node.ID, 'pointerDown', eData.eventData ); - drawDown( node.ID, eData.eventData[0], node, false ); + var userState = drawing_client; + //if ( userState[ "drawing_mode" ] && ( userState[ "drawing_mode" ] !== "none" ) ) { + // activelyDrawing = true; + // console.info( "VIEW: drawDown" ); + // drawDown( node.ID, eData.eventData[0], node, false ); + //} + drawDown( node.ID, eData.eventData[0], node, false ); + + var userState = drawing_client; + if ( userState[ "drawing_mode" ] && ( userState[ "drawing_mode" ] !== "none" ) ) { + activelyDrawing = true; + } + } ); node.kineticObj.on( "mouseup", function( evt ) { var eData = processEvent( evt, node, false ); mouseDown = false; + //viewDriver.kernel.dispatchEvent( node.ID, 'pointerUp', eData.eventData, eData.eventNodeData ); //viewDriver.kernel.fireEvent( node.ID, 'pointerUp', eData.eventData ); drawUp( node.ID, eData.eventData[0], node, true ); + activelyDrawing = false; + + //var userState = drawing_client; + //if ( activelyDrawing ) { + // console.info( "VIEW: drawUp" ); + // drawUp( node.ID, eData.eventData[0], node, true ); + //} + //activelyDrawing = false; + if ( node.kineticObj.mouseDragging ) { viewDriver.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); node.kineticObj.mouseDragging = false; @@ -176,6 +214,12 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], //viewDriver.kernel.dispatchEvent( node.ID, "touchStart", eData.eventData, eData.eventNodeData ); //viewDriver.kernel.fireEvent( node.ID, 'touchStart', eData.eventData ); drawDown( node.ID, eData.eventData[0], node, false ); + + var userState = drawing_client; + if ( userState[ "drawing_mode" ] && ( userState[ "drawing_mode" ] !== "none" ) ) { + activelyDrawing = true; + } + } ); node.kineticObj.on( "touchmove", function( evt ) { @@ -183,6 +227,12 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], //viewDriver.kernel.dispatchEvent( node.ID, "touchMove", eData.eventData, eData.eventNodeData ); //viewDriver.kernel.fireEvent( node.ID, 'touchMove', eData.eventData ); drawMove( node.ID, eData.eventData[0], node, false ); + + var userState = drawing_client; + if ( userState[ "drawing_mode" ] && ( userState[ "drawing_mode" ] !== "none" ) ) { + activelyDrawing = true; + } + } ); node.kineticObj.on( "touchend", function( evt ) { @@ -190,6 +240,8 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], //viewDriver.kernel.dispatchEvent( node.ID, "touchEnd", eData.eventData, eData.eventNodeData ); //viewDriver.kernel.fireEvent( node.ID, 'touchEnd', eData.eventData ); drawUp( node.ID, eData.eventData[0], node, true ); + + activelyDrawing = false; } ); node.kineticObj.on( "tap", function( evt ) { @@ -499,9 +551,9 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var node = this.state.nodes[ eventData[0] ]; if ( node ) { var kineticObj = node.kineticObj; - if ( kineticObj ) { + if ( kineticObj && activelyDrawing ) { //kineticObj.drawScene(); - kineticObj.draw(); + //kineticObj.draw(); } } /* @@ -581,7 +633,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], function renderScene( stage ) { //window.requestAnimationFrame( renderScene( stage ) ); - if ( stage !== undefined ) { + if ( stage !== undefined && !activelyDrawing ) { stage.batchDraw(); } } @@ -707,9 +759,9 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], setUpPrivate = function() { - if ( drawing_private === undefined ) { - drawing_private = {}; - } + //if ( drawing_private === undefined ) { + // drawing_private = {}; + //} if ( drawing_private === undefined ) { drawing_private = { "drawingObject": null, @@ -880,39 +932,17 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // drawing_private.drawingObject = child; //} ); private_node = createLocalKineticNode( section.ID, childID, groupDef, [], undefined, undefined, name ); - drawing_private.drawingObject = private_node.kineticObject; + drawing_private.drawingObject = private_node.kineticObj; + drawUpdate( drawing_private.drawingObject.ID, eventData, nodeData, false ); } else if ( compExtends !== undefined ) { privateState.initialDownPoint = eventPointDown; - //var parentPath = userState.drawing_parentPath + section; - //var parents = node.find( parentPath ); - //var parents = this.find( parentPath ); - //var parents = viewDriver.state.nodes.find( parentPath ); - - // find was failing 9/2/14, and the code below - // was a backup, going to leave this in until we feel good - // about the issues we saw are no longer a problem - //if ( parents === undefined ) { - // parents = [ node.findChild( this, parentPath.split( '/' ) ) ]; - //} - - //var parent = parents.length > 0 ? parents[ 0 ] : this; var parentPath = userState.drawing_parentID; //var parentNode = viewDriver.state.nodes[ parentPath ]; var section = findSection( parentPath, section ); var parent = section ? section : node; - //var parents = this.find( parentPath ); - - // find was failing 9/2/14, and the code below - // was a backup, going to leave this in until we feel good - // about the issues we saw are no longer a problem - //if ( parents === undefined ) { - // parents = [ node.findChild( this, parentPath.split( '/' ) ) ]; - //} - - //var parent = viewDriver.state.nodes[ parentPath ] ? viewDriver.state.nodes[ parentPath ] : node; var shapeDef = { "extends": compExtends, @@ -924,12 +954,9 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var name = drawingMode + drawing_index; drawing_index = drawing_index + 1; var childID = section.ID + ":" + name; - //drawing_private.drawingObject = createLocalKineticNode( section.ID, childID, shapeDef, [], undefined, undefined, name ); private_node = createLocalKineticNode( section.ID, childID, shapeDef, [], undefined, undefined, name ); - drawing_private.drawingObject = private_node.kineticObject; - //parent.children.create( name, shapeDef, function( child ) { - // drawing_private.drawingObject = child; - //} ); + drawing_private.drawingObject = private_node.kineticObj; + drawUpdate( drawing_private.drawingObject.ID, eventData, nodeData, false ); } }; @@ -940,10 +967,10 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], if ( node.kineticObj ) { - debugger; + //debugger; - if ( modelDriver.state.nodes[ node.parentID ] !== undefined ) { - var parent = modelDriver.state.nodes[ node.parentID ]; + if ( viewDriver.state.nodes[ node.parentID ] !== undefined ) { + var parent = viewDriver.state.nodes[ node.parentID ]; if ( parent.kineticObj && isContainerDefinition( parent.prototypes ) ) { if ( parent.children === undefined ) { @@ -980,7 +1007,9 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], return; } - drawUpdate( drawing_private.drawingObject.ID, eventData, nodeData, false ); + if ( drawing_private.drawingObject ) { + drawUpdate( drawing_private.drawingObject.ID, eventData, nodeData, false ); + } }; function drawUp( nodeID, eventData, nodeData, touch ) { @@ -992,7 +1021,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var drawingObject = drawing_private.drawingObject; drawUpdate( drawing_private.drawingObject.ID, eventData, nodeData, true ); - node.drawingObjectCreated( drawingObject.id ); + //node.drawingObjectCreated( drawingObject.id ); var userState = drawing_client; if ( node.moniker === node.client ) { @@ -1021,7 +1050,8 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } - drawing_private.drawingObject = null; + propagateNodeToModel(); + //drawing_private.drawingObject = null; } }; @@ -1055,9 +1085,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var height = diffY; var dist = Math.sqrt( ( diffX * diffX ) + ( diffY * diffY ) ); - //console.info( "== "+userState.drawing_mode +" ==" ); - //console.info( "== pos: " + pos + " diffX: " + diffX + " diffY: " + diffY ); - // this keeps the pos as the top left corner for the // rectangular objects switch ( userState.drawing_mode ) { @@ -1066,6 +1093,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], case "arrow": case "thickArrow": case "freeDraw": + case "borderRect": break; default: @@ -1083,54 +1111,59 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], break; } - //console.info( "== pos: " + pos + " diffX: " + diffX + " diffY: " + diffY ); - switch ( userState.drawing_mode ) { case "arc": drawingObject.angle = userState.angle ? userState.angle : 30; if ( dist > node.drawing_width ) { - drawingObject.innerRadius = dist - node.drawing_width; - drawingObject.outerRadius = dist; + drawingObject.innerRadius( dist - node.drawing_width ); + drawingObject.outerRadius( dist ); } + clearBeforeDraw = true; break; case "ellipse": - drawingObject.radius = { "x": width * 0.5, "y": height * 0.5 }; + drawingObject.radius( { "x": width * 0.5, "y": height * 0.5 } ); + clearBeforeDraw = true; break; case "circle": - drawingObject.radius = dist; + drawingObject.radius( dist ); + clearBeforeDraw = true; break; case "line": - drawingObject.stroke = userState.drawing_color; - drawingObject.strokeWidth = userState.drawing_width; - drawingObject.points = [ 0, 0, diffX, diffY ]; + drawingObject.stroke( userState.drawing_color ); + drawingObject.strokeWidth( userState.drawing_width ); + drawingObject.points( [ 0, 0, diffX, diffY ] ); + drawingObject.lineCap( "round" ); + clearBeforeDraw = true; break; case "freeDraw": - //debugger; - drawingObject.stroke = userState.drawing_color; - drawingObject.strokeWidth = userState.drawing_width; - - if ( drawingObject.points === undefined ) { - drawingObject[ "points" ] = []; + drawingObject.stroke( userState.drawing_color ); + drawingObject.strokeWidth( userState.drawing_width ); + drawingObject.lineCap( "round" ); + drawingObject.lineJoin( "round" ); + var points = drawingObject.points(); + var isFirstStrokeOfNewLine = false; + + if ( drawingObject.points() === undefined ) { + points = [ 0, 0, diffX, diffY ]; + isFirstStrokeOfNewLine = true; } - var isFirstStrokeOfNewLine = ( drawingObject.points.length === 0 ); - - console.info( "VIEW: Event point: [ " + eventPoint[0] + ", " + eventPoint[1] + " ], Drawing object x, y: [ " + drawingObject.x() + ", " + drawingObject.y() + " ]"); - var posX = eventPoint[ 0 ] - drawingObject.x(); var posY = eventPoint[ 1 ] - drawingObject.y(); if ( isFirstStrokeOfNewLine ) { if ( ( Math.abs( posX ) + Math.abs( posY ) ) > 0 ) { - drawingObject.points = [ 0, 0, posX, posY ]; + points = [ 0, 0, posX, posY ]; + privateState[ "previousPoint" ] = [ posX, posY ]; } else { pointAccepted = false; } + privateState.previousPoint = [ posX, posY ]; } else { var dragDiff = [ posX - privateState.previousPoint[ 0 ], @@ -1138,12 +1171,17 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], ]; if ( ( Math.abs( dragDiff[0] ) + Math.abs( dragDiff[1] ) ) > 0 ) { - drawingObject.points.push( posX ); - drawingObject.points.push( posY ); + points.push( posX ); + points.push( posY ); + privateState.previousPoint = [ posX, posY ]; } else { pointAccepted = false; } + } + points.push( posX ); + points.push( posY ); + drawingObject.points( points ); break; case "regularPolygon": @@ -1152,40 +1190,46 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], case "ring": if ( dist > userState.drawing_width ) { - drawingObject.innerRadius = dist - userState.drawing_width; - drawingObject.outerRadius = dist; + drawingObject.innerRadius( dist - userState.drawing_width ); + drawingObject.outerRadius( dist ); + clearBeforeDraw = true; } break; case "star": - drawingObject.points = 5; - drawingObject.innerRadius = dist * 80; - drawingObject.outerRadius = dist; + drawingObject.points( 5 ); + drawingObject.innerRadius( dist * 80 ); + drawingObject.outerRadius( dist ); + clearBeforeDraw = true; break; case "wedge": // needs defining - drawingObject.angle = userState.angle ? userState.angle : 30; - drawingObject.radius = dist; - drawingObject.clockwise = false; + drawingObject.angle( userState.angle ? userState.angle : 30 ); + drawingObject.radius( dist ); + drawingObject.clockwise( false ); + clearBeforeDraw = true; break; case "borderRect": - drawingObject.stroke = userState.drawing_color; - drawingObject.strokeWidth = userState.drawing_width; - drawingObject.points = [ 0, 0, width, 0, width, height, 0, height, 0, 0 ]; + drawingObject.stroke( userState.drawing_color ); + drawingObject.strokeWidth( userState.drawing_width ); + drawingObject.points( [ 0, 0, width, 0, width, height, 0, height, 0, 0 ] ); + drawingObject.lineCap( "round" ); + drawingObject.lineJoin( "round" ); + clearBeforeDraw = true; break; case "arrow": - drawingObject.x = drawingObject.position[ 0 ]; - drawingObject.y = drawingObject.position[ 1 ]; + drawingObject.x( drawingObject.position[ 0 ] ); + drawingObject.y( drawingObject.position[ 1 ] ); - drawingObject.line.stroke = userState.drawing_color; - drawingObject.line.strokeWidth = userState.drawing_width; - drawingObject.line.position = [ 0, 0 ]; + drawingObject.line.stroke( userState.drawing_color ); + drawingObject.line.strokeWidth( userState.drawing_width ); + drawingObject.line.position( [ 0, 0 ] ); - drawingObject.head.sides = 3; - drawingObject.head.radius = userState.drawing_width * 3; + drawingObject.head.sides( 3 ); + drawingObject.head.radius( userState.drawing_width * 3 ); var endPoint = goog.vec.Vec2.createFloat32FromValues( 0, 0 ); var relativeXDiff = eventPoint[ 0 ] - drawingObject.x; @@ -1195,11 +1239,12 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var len = goog.vec.Vec2.distance( goog.vec.Vec2.createFloat32FromValues( 0, 0 ), dir ); goog.vec.Vec2.normalize( dir, dir ); - drawingObject.head.rotation = Math.atan2( dir[1], dir[0] ) * ( 180 / Math.PI ) - 30; + drawingObject.head.rotation( Math.atan2( dir[1], dir[0] ) * ( 180 / Math.PI ) - 30 ); goog.vec.Vec2.scale( dir, len - ( userState.drawing_width * 3 ), endPoint ); - drawingObject.head.position = [ endPoint[0], endPoint[1] ]; + drawingObject.head.position( [ endPoint[0], endPoint[1] ] ); goog.vec.Vec2.scale( dir, len - ( ( userState.drawing_width * 3 ) + headOffset ), endPoint ); - drawingObject.line.points = [ 0, 0, endPoint[0], endPoint[1] ]; + drawingObject.line.points( [ 0, 0, endPoint[0], endPoint[1] ] ); + clearBeforeDraw = true; break; case "thickArrow": @@ -1230,33 +1275,59 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], case "sprite": case "image": - drawingObject.border.stroke = userState.drawing_color; - drawingObject.border.strokeWidth = 4; - drawingObject.border.points = [ 0, 0, width, 0, width, height, 0, height, 0, 0 ]; - drawingObject.content.width = width; - drawingObject.content.height = height; + drawingObject.border.stroke( userState.drawing_color ); + drawingObject.border.strokeWidth( 4 ); + drawingObject.border.points( [ 0, 0, width, 0, width, height, 0, height, 0, 0 ] ); + drawingObject.content.width( width ); + drawingObject.content.height( height ); + clearBeforeDraw = true; break; case "text": - drawingObject.border.stroke = userState.drawing_color; - drawingObject.border.strokeWidth = 4; - drawingObject.border.points = [ 0, 0, width, 0, width, height, 0, height, 0, 0 ]; - drawingObject.content.fontSize = userState.fontSize ? userState.fontSize : 16; + drawingObject.border.stroke( userState.drawing_color ); + drawingObject.border.strokeWidth( 4 ); + drawingObject.border.points( [ 0, 0, width, 0, width, height, 0, height, 0, 0 ] ); + drawingObject.content.fontSize( userState.fontSize ? userState.fontSize : 16 ); + clearBeforeDraw = true; break; case "rect": + drawingObject.x( pos[ 0 ] ); + drawingObject.y( pos[ 1 ] ); + drawingObject.stroke( userState.drawing_color ); + drawingObject.strokeWidth( userState.drawing_width ); + drawingObject.fill( userState.drawing_color ); + drawingObject.size( { "width": width, "height": height} ); + drawingObject.lineCap( "round" ); + drawingObject.lineJoin( "round" ); + clearBeforeDraw = true; + break; + default: break; } if ( pointAccepted ) { - privateState.previousPoint = eventPoint; + //privateState.previousPoint = eventPoint; // Update the view to keep pace with user input //console.info( drawingObject.id + " updated, sending update event." ); //node.privateDrawingUpdated( drawingObject.id ); - if ( drawingObject ) { - drawingObject.drawScene(); + if ( drawingObject && activelyDrawing ) { + console.info( "VIEW: draw object " ); + if ( clearBeforeDraw ) { + // Draw the full layer + var layer = findLayer( drawingObject ); + if ( layer ) { + layer.draw(); + } else { + // Should never happen - object should always be a descendent of a layer + drawingObject.draw(); + } + clearBeforeDraw = false; + } else { + drawingObject.draw(); + } } } @@ -1284,7 +1355,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } }; - this.findChild = function( parent, names ) { + function findChild( parent, names ) { if ( names.length > 0 ) { var childName = names.shift(); while ( childName === "" ) { @@ -1332,7 +1403,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], node.prototypes.push( extendsID ); var kineticObj = createKineticObject( node, objDef.properties ); - node.kineticObject = kineticObj; + node.kineticObj = kineticObj; addNodeToHierarchy( node ); @@ -1431,4 +1502,66 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], return prototypes; } + function isContainerDefinition( prototypes ) { + var found = false; + if ( prototypes ) { + for ( var i = 0; i < prototypes.length && !found; i++ ) { + found = ( prototypes[i] == "http://vwf.example.com/kinetic/container.vwf" ); + } + } + return found; + } + + function findStage( kineticObj ) { + + var stage = undefined + var parent = kineticObj; + while ( parent !== undefined && stage === undefined ) { + if ( parent.nodeType === "Stage" ) { + stage = parent; + } + parent = parent.parent; + } + return stage; + + } + + function findLayer( kineticObj ) { + + var layer = undefined + var parent = kineticObj; + while ( parent !== undefined && layer === undefined ) { + if ( parent.nodeType === "Layer" ) { + layer = parent; + } + parent = parent.parent; + } + return layer; + + } + + function propagateNodeToModel() { + + // Send data about this node so the global node can be created and propagated + //viewDriver.kernel.callMethod( private_node.parentID, "propagateKineticNode", [ appID, private_node ] ); + var appID = viewDriver.kernel.kernel.application(); + + viewDriver.kernel.kernel.callMethod( appID, "propagateKineticNode", [ private_node ] ); + + viewDriver.kernel.kernel.createNode( private_node.extendsID, undefined, private_node.ID, null ); + + + // Delete the private node - we no longer need it + drawing_private = {}; + //delete private_node; + private_node = undefined; + + //callMethod(); + + //kineticNode = private_node.kineticObj; + + + } + + }); \ No newline at end of file From 0c1acc6075ad734158ffcf9345ac870c035725b7 Mon Sep 17 00:00:00 2001 From: youngca Date: Wed, 9 Dec 2015 15:58:10 -0500 Subject: [PATCH 028/644] Add support for line styles, fills. Consolidate filled/unfilled drawing shapes and streamline shapes. Consolidate circles/rings into a single shape with fill options. Consolidate rectangles/border rectangles into a single shape with fill options. Add polygon shape, using free draw with closed=true. Change arrow from a grouped two-part object to a closed outline rotated to an orientation. Remove image border object and just set the stroke to do an outline of the image while drawing out. Support text. TO DO: Image still doesn't fully work. --- support/client/lib/vwf/model/kineticjs.js | 67 ++-- support/client/lib/vwf/view/kineticjs.js | 379 ++++++++++++------ .../mil-sym/unitGroup.vwf.yaml | 1 + 3 files changed, 301 insertions(+), 146 deletions(-) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index ad73040db..82e325822 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -2153,40 +2153,57 @@ define( [ "module", return found; } + function isSymbolDefinition( prototypes ) { + var found = false; + if ( prototypes ) { + for ( var i = 0; i < prototypes.length && !found; i++ ) { + found = ( prototypes[i] == "http://vwf.example.com/mil-sym/unitIcon.vwf" ); + } + } + return found; + } + function loadImage( kineticObj, url ) { - var imageObj = kineticObj.image(); - var validImage = ( imageObj !== undefined ); - var width = kineticObj.width(); - var height = kineticObj.height(); - + var imageObj = kineticObj.image(); + var validImage = ( imageObj !== undefined ); + var width = kineticObj.width(); + var height = kineticObj.height(); + var nodeID = kineticObj.id(); + var node = modelDriver.state.nodes[ nodeID ]; + + if ( isSymbolDefinition( node.prototypes ) ) { + kineticObj.setZIndex( 16 ); + } + + if ( !validImage ) { + imageObj = new Image(); + } + + imageObj.onload = function() { if ( !validImage ) { - imageObj = new Image(); + kineticObj.image( imageObj ); } + if ( node.scaleOnLoad ) { - imageObj.onload = function() { - if ( !validImage ) { - kineticObj.image( imageObj ); - } - if ( node.scaleOnLoad ) { - - if ( width > height ) { - kineticObj.scale( { "x": width / imageObj.width ,"y": width / imageObj.width } ); - } else { - kineticObj.scale( { "x": height / imageObj.height ,"y": height / imageObj.height } ); - } + if ( width > height ) { + kineticObj.scale( { "x": width / imageObj.width ,"y": width / imageObj.width } ); + } else { + kineticObj.scale( { "x": height / imageObj.height ,"y": height / imageObj.height } ); } - modelDriver.kernel.fireEvent( node.ID, "imageLoaded", [ url ] ); } - imageObj.onerror = function() { + //modelDriver.kernel.fireEvent( node.ID, "imageLoaded", [ url ] ); + modelDriver.kernel.fireEvent( nodeID, "imageLoaded", [ url ] ); + } + imageObj.onerror = function() { modelDriver.logger.errorx( "loadImage", "Invalid image url:", url ); imageObj.src = oldSrc; - modelDriver.kernel.fireEvent( node.ID, "imageLoadError", [ url ] ); - } - var oldSrc = imageObj.src; - imageObj.src = url; - - + //modelDriver.kernel.fireEvent( node.ID, "imageLoadError", [ url ] ); + modelDriver.kernel.fireEvent( nodeID, "imageLoadError", [ url ] ); + } + + var oldSrc = imageObj.src; + imageObj.src = url; } }); diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 87f01951c..9ef3f19ca 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -19,7 +19,11 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], "nameIndex": 1, "fontSize": 16, "angle": 30, - "lineCap": 'round' + "lineCap": 'round', + "lineJoin": 'round', + "dashLineStyle": null, + "fillStyle": null, + "zIndex": 4 }; var drawing_index = 0; var private_node = undefined; @@ -351,6 +355,9 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var node = this.state.nodes[ nodeID ]; + console.info( "kineticjs(view) satProperty. propertyName: " + propertyName + ", propertyValue: " + propertyValue + ", nodeID: " + nodeID ); + + // If we don't have a record of this node, it is not a kinetic node, and we ignore it if ( !( node && node.kineticObj ) ) { return; @@ -464,6 +471,18 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], drawing_client.drawing_parentID = propertyValue; } break; + + case "text": + if ( drawing_private !== undefined && drawing_private.drawingObject ) { + var drawingObject = drawing_private.drawingObject; + if ( drawingObject.content.id() === nodeID ) { + drawingObject.content.text( propertyValue ); + drawObject( drawingObject, true ); + propagateNodeToModel(); + } + } + break; + } }, @@ -488,6 +507,22 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], setClientUIState( methodParameters[0] ); break; + case "setKineticProperty": + if ( private_node && private_node.kineticObj ) { + var propertyName = methodParameters[ 1 ]; + var propertyValue = methodParameters[ 2 ]; + setKineticProperty( private_node.kineticObj, propertyName, propertyValue ); + } + /* + var kineticNode = viewDriver.state.nodes[ methodParameters[0] ]; + var propertyName = methodParameters[ 1 ]; + var propetyValue = methodParameters[ 2 ]; + if ( kineticNode && kineticNode.kineticObj ) { + setKineticProperty( kineticNode.kineticObj, propertyName, propertyValue ); + } + */ + break; + } } @@ -563,6 +598,17 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } break; + case "textValueUpdated": + if ( drawing_private !== undefined && drawing_private.drawingObject ) { + var drawingObject = drawing_private.drawingObject; + if ( drawingObject.content.id() === eventData[0] ) { + drawingObject.content.text( eventData[1] ); + drawObject( drawingObject, true ); + propagateNodeToModel(); + } + } + break; + default: break; } @@ -815,34 +861,30 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], break; case "sprite": - case "text": case "image": + /* groupExtends = "http://vwf.example.com/kinetic/drawingGroup.vwf"; compExtends = { "border": "http://vwf.example.com/kinetic/line.vwf", - "content": [ "http://vwf.example.com/kinetic/", drawingMode, ".vwf" ].join('') - }; + "content": [ "http://vwf.example.com/kinetic/", drawingMode, ".vwf" ].join('') + };*/ + compExtends = [ "http://vwf.example.com/kinetic/", drawingMode, ".vwf" ].join('') break; - case "arrow": - groupExtends = "http://vwf.example.com/kinetic/drawingGroup.vwf"; - compExtends = { - "line": "http://vwf.example.com/kinetic/line.vwf", - "head": "http://vwf.example.com/kinetic/regularPolygon.vwf" - }; - break; - - case "thickArrow": + case "text": groupExtends = "http://vwf.example.com/kinetic/drawingGroup.vwf"; compExtends = { - "line": "http://vwf.example.com/kinetic/line.vwf", - "head": "http://vwf.example.com/kinetic/regularPolygon.vwf" + "border": "http://vwf.example.com/kinetic/rect.vwf", + "content": [ "http://vwf.example.com/kinetic/", drawingMode, ".vwf" ].join('') }; break; - case "borderRect": - case "line": case "freeDraw": + case "polygon": + case "line": + case "borderRect": + case "arrow": + case "thickArrow": compExtends = "http://vwf.example.com/kinetic/line.vwf"; break; @@ -857,12 +899,12 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], "visible": 'inherit', "listening": 'inherit', "opacity": userState.drawing_opacity, - "z-index": 4 + "index": 4 }; switch( drawingMode ) { case "sprite": - //case "text": + case "text": case "image": retObj.opacity = 1.0; retObj.scaleOnLoad = true; @@ -909,30 +951,46 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var groupDef = { "extends": groupExtends, "properties": { - "visible": false, + "visible": "inherit", "listening": "inherit", "position": eventPointDown }, "children": {} }; + var self = this; + var selfMoniker = node.client; + var name = drawingMode + drawing_index; + drawing_index = drawing_index + 1; + var childID = section.ID + ":" + name; + + private_node = createLocalKineticNode( section.ID, childID, groupDef, [], undefined, undefined, name ); + drawing_private.drawingObject = private_node.kineticObj; + + // Define the component objects of this group object for ( var def in compExtends ) { groupDef.children[ def ] = { "extends": compExtends[ def ], - "properties": getDefaultProperties( drawingMode, true, eventPointDown ) - } + "properties": getDefaultProperties( drawingMode, false, eventPointDown ) + } + var compID = childID + ":" + def; + var compChild = createLocalKineticNode( childID, compID, groupDef.children[ def ], [], undefined, undefined, def ); + drawing_private.drawingObject[ def ] = compChild.kineticObj; + drawing_private.drawingObject.children.push( drawing_private.drawingObject[ def ] ); + //drawing_private.children.push( compID ); } - var self = this; - var selfMoniker = node.client; - var name = drawingMode + drawing_index; - drawing_index = drawing_index + 1; + //var self = this; + //var selfMoniker = node.client; + //var name = drawingMode + drawing_index; + //drawing_index = drawing_index + 1; + //var childID = section.ID + ":" + name; //parent.children.create( name, groupDef, function( child ) { // drawing_private.drawingObject = child; //} ); - private_node = createLocalKineticNode( section.ID, childID, groupDef, [], undefined, undefined, name ); - drawing_private.drawingObject = private_node.kineticObj; + //private_node = createLocalKineticNode( section.ID, childID, groupDef, [], undefined, undefined, name ); + //drawing_private.drawingObject = private_node.kineticObj; drawUpdate( drawing_private.drawingObject.ID, eventData, nodeData, false ); @@ -1015,43 +1073,77 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], function drawUp( nodeID, eventData, nodeData, touch ) { var node = viewDriver.state.nodes[ nodeID ]; + var appID = viewDriver.kernel.application(); + var drawAndPropagate = false; if ( drawing_private !== undefined && drawing_private.drawingObject ) { var drawingObject = drawing_private.drawingObject; - drawUpdate( drawing_private.drawingObject.ID, eventData, nodeData, true ); + drawUpdate( drawingObject.ID, eventData, nodeData, true ); //node.drawingObjectCreated( drawingObject.id ); + viewDriver.kernel.fireEvent( appID, 'drawingObjectCreated', [ drawingObject.id() ] ); var userState = drawing_client; - if ( node.moniker === node.client ) { - - switch( userState.drawing_mode ) { - - case "text": - node.textCreated( drawingObject.content.id ); - break; - - case "sprite": - case "image": - node.imageCreated( drawingObject.content.id ); - break; - - } - } + drawingObject.setZIndex( userState.zIndex ); switch( userState.drawing_mode ) { case "text": + drawingObject.border.visible( false ); + viewDriver.kernel.fireEvent( appID, 'textCreated', [ drawingObject.content.id() ] ); + break; + case "sprite": case "image": - drawingObject.border.visible = false; + //drawingObject.border.visible( false ); + drawingObject.stroke( null ); + viewDriver.kernel.fireEvent( appID, 'imageCreated', [ drawingObject.id() ] ); + drawAndPropagate = true; break; + case "line": + drawAndPropagate = true; + break; + + case "freeDraw": + case "polygon": + case "circle": + case "ellipse": + case "rect": + case "arrow": + case "thickArrow": + drawingObject.dash( userState.dashLineStyle ); + switch ( userState.fillStyle ) { + case 'noFill': + drawingObject.fill( null ); + break; + + case 'solidFill': + case 'transparentFill': + var colorRGB = Kinetic.Util.getRGB( userState.drawing_color ); + var alpha = ( userState.fillStyle === 'transparentFill' ? 0.5 : 1.0 ); + drawingObject.fillRed( colorRGB.r ); + drawingObject.fillGreen( colorRGB.g ); + drawingObject.fillBlue( colorRGB.b ); + drawingObject.fillAlpha( alpha ); + break; + + default: + break; + } + drawAndPropagate = true; + break; + + default: + break; } - propagateNodeToModel(); - //drawing_private.drawingObject = null; + if ( drawAndPropagate ) { + drawObject( drawingObject, true ); + propagateNodeToModel(); + //drawing_private.drawingObject = null; + } } }; @@ -1084,6 +1176,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var width = diffX; var height = diffY; var dist = Math.sqrt( ( diffX * diffX ) + ( diffY * diffY ) ); + var angleDeg = Math.atan2( diffY, diffX ) * 180.0 / Math.PI; // this keeps the pos as the top left corner for the // rectangular objects @@ -1093,6 +1186,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], case "arrow": case "thickArrow": case "freeDraw": + case "polygon": case "borderRect": break; @@ -1105,9 +1199,9 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], pos[ 1 ] += diffY; height = Math.abs( diffY ); } - drawingObject.position = pos; - drawingObject.width = width; - drawingObject.height = height; + drawingObject.position( privateState.initialDownPoint ); + drawingObject.width( width ); + drawingObject.height( height ); break; } @@ -1124,11 +1218,17 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], case "ellipse": drawingObject.radius( { "x": width * 0.5, "y": height * 0.5 } ); + drawingObject.stroke( userState.drawing_color ); + drawingObject.strokeWidth( userState.drawing_width ); + drawingObject.fill( null ); clearBeforeDraw = true; break; case "circle": drawingObject.radius( dist ); + drawingObject.stroke( userState.drawing_color ); + drawingObject.strokeWidth( userState.drawing_width ); + drawingObject.fill( null ); clearBeforeDraw = true; break; @@ -1136,15 +1236,17 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], drawingObject.stroke( userState.drawing_color ); drawingObject.strokeWidth( userState.drawing_width ); drawingObject.points( [ 0, 0, diffX, diffY ] ); - drawingObject.lineCap( "round" ); + drawingObject.lineCap( userState.lineCap ); + drawingObject.dash( userState.dashLineStyle ); clearBeforeDraw = true; break; case "freeDraw": + case "polygon": drawingObject.stroke( userState.drawing_color ); drawingObject.strokeWidth( userState.drawing_width ); - drawingObject.lineCap( "round" ); - drawingObject.lineJoin( "round" ); + drawingObject.lineCap( userState.lineCap ); + drawingObject.lineJoin( userState.lineJoin ); var points = drawingObject.points(); var isFirstStrokeOfNewLine = false; @@ -1182,6 +1284,12 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], points.push( posX ); points.push( posY ); drawingObject.points( points ); + + if ( userState.drawing_mode === 'polygon' ) { + drawingObject.closed( true ); + drawingObject.fill( null ); + clearBeforeDraw = true; + } break; case "regularPolygon": @@ -1215,79 +1323,74 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], drawingObject.stroke( userState.drawing_color ); drawingObject.strokeWidth( userState.drawing_width ); drawingObject.points( [ 0, 0, width, 0, width, height, 0, height, 0, 0 ] ); - drawingObject.lineCap( "round" ); - drawingObject.lineJoin( "round" ); + drawingObject.lineCap( userState.lineCap ); + drawingObject.lineJoin( userState.lineJoin ); + drawingObject.dash( userState.dashLineStyle ); clearBeforeDraw = true; break; case "arrow": + case "thickArrow": + var arrowWidthMult = ( userState.drawing_mode === 'arrow' ? 3 : 8 ); + drawingObject.x( drawingObject.position[ 0 ] ); drawingObject.y( drawingObject.position[ 1 ] ); - drawingObject.line.stroke( userState.drawing_color ); - drawingObject.line.strokeWidth( userState.drawing_width ); - drawingObject.line.position( [ 0, 0 ] ); - - drawingObject.head.sides( 3 ); - drawingObject.head.radius( userState.drawing_width * 3 ); - - var endPoint = goog.vec.Vec2.createFloat32FromValues( 0, 0 ); - var relativeXDiff = eventPoint[ 0 ] - drawingObject.x; - var relativeYDiff = eventPoint[ 1 ] - drawingObject.y; - var headOffset = ( userState.drawing_width * 3 ) * Math.sin( Math.PI / 6 ); - var dir = goog.vec.Vec2.createFloat32FromValues( relativeXDiff, relativeYDiff ); - var len = goog.vec.Vec2.distance( goog.vec.Vec2.createFloat32FromValues( 0, 0 ), dir ); - goog.vec.Vec2.normalize( dir, dir ); - - drawingObject.head.rotation( Math.atan2( dir[1], dir[0] ) * ( 180 / Math.PI ) - 30 ); - goog.vec.Vec2.scale( dir, len - ( userState.drawing_width * 3 ), endPoint ); - drawingObject.head.position( [ endPoint[0], endPoint[1] ] ); - goog.vec.Vec2.scale( dir, len - ( ( userState.drawing_width * 3 ) + headOffset ), endPoint ); - drawingObject.line.points( [ 0, 0, endPoint[0], endPoint[1] ] ); + drawingObject.stroke( userState.drawing_color ); + drawingObject.strokeWidth( userState.drawing_width ); + drawingObject.lineCap( userState.lineCap ); + drawingObject.lineJoin( userState.lineJoin ); + drawingObject.dash( null ); + drawingObject.fill( null ); + drawingObject.position( [ 0, 0 ] ); + drawingObject.closed( true ); + var arrowThickness = userState.drawing_width * arrowWidthMult; + var headWidth = userState.drawing_width * arrowWidthMult * 2; + var headLength = userState.drawing_width * arrowWidthMult * 2; + var arrowLength = dist; + var arrowShaft = arrowLength - headLength; + var arrowPts = [ 0, 0, 0, arrowThickness, arrowShaft, arrowThickness, arrowShaft, headWidth, arrowLength, 0, arrowShaft, (-1 * headWidth), arrowShaft, (-1 * arrowThickness), 0, (-1 * arrowThickness) ]; + drawingObject.points( arrowPts ); + drawingObject.rotation( angleDeg ); clearBeforeDraw = true; break; - case "thickArrow": - drawingObject.x = drawingObject.position[ 0 ]; - drawingObject.y = drawingObject.position[ 1 ]; - - drawingObject.line.stroke = userState.drawing_color; - drawingObject.line.strokeWidth = userState.drawing_width * 8; - drawingObject.line.position = [ 0, 0 ]; - - drawingObject.head.sides = 3; - drawingObject.head.radius = userState.drawing_width * 8; - - var endPoint = goog.vec.Vec2.createFloat32FromValues( 0, 0 ); - var relativeXDiff = eventPoint[ 0 ] - drawingObject.x; - var relativeYDiff = eventPoint[ 1 ] - drawingObject.y; - var headOffset = ( userState.drawing_width * 8 ) * Math.sin( Math.PI / 6 ); - var dir = goog.vec.Vec2.createFloat32FromValues( relativeXDiff, relativeYDiff ); - var len = goog.vec.Vec2.distance( goog.vec.Vec2.createFloat32FromValues( 0, 0 ), dir ); - goog.vec.Vec2.normalize( dir, dir ); - - drawingObject.head.rotation = Math.atan2( dir[1], dir[0] ) * ( 180 / Math.PI ) - 30; - goog.vec.Vec2.scale( dir, len - ( userState.drawing_width * 8 ), endPoint ); - drawingObject.head.position = [ endPoint[0], endPoint[1] ]; - goog.vec.Vec2.scale( dir, len - ( ( userState.drawing_width * 8 ) + headOffset ), endPoint ); - drawingObject.line.points = [ 0, 0, endPoint[0], endPoint[1] ]; - break; - case "sprite": case "image": + /* drawingObject.border.stroke( userState.drawing_color ); - drawingObject.border.strokeWidth( 4 ); + drawingObject.border.strokeWidth( 2 ); drawingObject.border.points( [ 0, 0, width, 0, width, height, 0, height, 0, 0 ] ); + drawingObject.border.lineCap( userState.lineCap ); + drawingObject.border.lineJoin( userState.lineJoin ); + drawingObject.border.dash( [ 2, 5 ] ); drawingObject.content.width( width ); drawingObject.content.height( height ); + */ + drawingObject.x( pos[ 0 ] ); + drawingObject.y( pos[ 1 ] ); + drawingObject.stroke( userState.drawing_color ); + drawingObject.strokeWidth( 2 ); + //drawingObject.points( [ 0, 0, width, 0, width, height, 0, height, 0, 0 ] ); + drawingObject.lineCap( userState.lineCap ); + drawingObject.lineJoin( userState.lineJoin ); + drawingObject.dash( [ 2, 5 ] ); + drawingObject.width( width ); + drawingObject.height( height ); clearBeforeDraw = true; break; case "text": drawingObject.border.stroke( userState.drawing_color ); - drawingObject.border.strokeWidth( 4 ); - drawingObject.border.points( [ 0, 0, width, 0, width, height, 0, height, 0, 0 ] ); + drawingObject.border.strokeWidth( 2 ); + drawingObject.border.width( width ); + drawingObject.border.height( height ); + drawingObject.border.lineCap( userState.lineCap ); + drawingObject.border.lineJoin( userState.lineJoin ); + drawingObject.border.dash( [ 2, 5 ] ); + drawingObject.border.fill( null ); drawingObject.content.fontSize( userState.fontSize ? userState.fontSize : 16 ); + drawingObject.content.fontStyle( 'bold' ); clearBeforeDraw = true; break; @@ -1296,10 +1399,10 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], drawingObject.y( pos[ 1 ] ); drawingObject.stroke( userState.drawing_color ); drawingObject.strokeWidth( userState.drawing_width ); - drawingObject.fill( userState.drawing_color ); + drawingObject.fill( null ); drawingObject.size( { "width": width, "height": height} ); - drawingObject.lineCap( "round" ); - drawingObject.lineJoin( "round" ); + drawingObject.lineCap( userState.lineCap ); + drawingObject.lineJoin( userState.lineJoin ); clearBeforeDraw = true; break; @@ -1314,20 +1417,9 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], //console.info( drawingObject.id + " updated, sending update event." ); //node.privateDrawingUpdated( drawingObject.id ); if ( drawingObject && activelyDrawing ) { - console.info( "VIEW: draw object " ); - if ( clearBeforeDraw ) { - // Draw the full layer - var layer = findLayer( drawingObject ); - if ( layer ) { - layer.draw(); - } else { - // Should never happen - object should always be a descendent of a layer - drawingObject.draw(); - } - clearBeforeDraw = false; - } else { - drawingObject.draw(); - } + //console.info( "VIEW: draw object " ); + drawObject( drawingObject, clearBeforeDraw ); + clearBeforeDraw = false; } } @@ -1428,6 +1520,8 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], kineticObj = new Kinetic.FastLayer( config || {} ); } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/group.vwf" ) ) { kineticObj = new Kinetic.Group( config || {} ); + } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/drawingGroup.vwf" ) ) { + kineticObj = new Kinetic.Group( config || {} ); } else if ( viewDriver.state.isKineticClass( protos, "http://vwf.example.com/kinetic/image.vwf" ) ) { var imageObj = new Image(); node.scaleOnLoad = false; @@ -1552,6 +1646,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // Delete the private node - we no longer need it + drawing_private.drawingObject = null; drawing_private = {}; //delete private_node; private_node = undefined; @@ -1563,5 +1658,47 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } + function drawObject( kineticObject, clearBefore ) { + + if ( clearBefore ) { + // Draw the full layer + var layer = findLayer( kineticObject ); + if ( layer ) { + layer.draw(); + } else { + // Should never happen - object should always be a descendent of a layer + kineticObject.draw(); + } + } else { + kineticObject.draw(); + } + } + + function setKineticProperty( kineticObj, propertyName, propertyValue ) { + + var userState = drawing_client; + + switch ( propertyName ) { + + case "text": + kineticObj.content.text( propertyValue ); + //kineticObj.content.stroke( userState.drawing_color ); + kineticObj.content.fill( userState.drawing_color ); + drawObject( kineticObj, true ); + propagateNodeToModel(); + break; + + case "image": + kineticObj.image( propertyValue ); + break; + + default: + break; + + } + + } + + }); \ No newline at end of file diff --git a/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml b/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml index bc15d4659..2c91c30b2 100755 --- a/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml +++ b/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml @@ -3,6 +3,7 @@ extends: http://vwf.example.com/kinetic/group.vwf properties: supportMouseEvents: true supportTouchEvents: true + index: 8 mapPosition: set: | From 34d9e30764da2c5818e901c8759b9edc9fb63fce Mon Sep 17 00:00:00 2001 From: youngca Date: Tue, 15 Dec 2015 08:21:36 -0500 Subject: [PATCH 029/644] Add support for tapHold and swipe gestures in the kinetic view. --- support/client/lib/vwf/model/kineticjs.js | 2 +- support/client/lib/vwf/view/kineticjs.js | 239 +++++++++++++++++- .../vwf.example.com/mil-sym/unitGroup.js | 2 + .../mil-sym/unitGroup.vwf.yaml | 1 + .../vwf.example.com/mil-sym/unitIcon.vwf.yaml | 2 + 5 files changed, 239 insertions(+), 7 deletions(-) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index 82e325822..78cc8f11c 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -2173,7 +2173,7 @@ define( [ "module", var node = modelDriver.state.nodes[ nodeID ]; if ( isSymbolDefinition( node.prototypes ) ) { - kineticObj.setZIndex( 16 ); + kineticObj.setZIndex( 100 ); } if ( !validImage ) { diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 9ef3f19ca..8811de0af 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -30,12 +30,156 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var activelyDrawing = false; var clearBeforeDraw = false; + // Object implements tapHold behavior (kineticJS doesn't have a built-in one) + var tapHold = { + "node": null, + "initialPosition": [ 0, 0], + "timeout": 1500, // timeout in milliseconds + "moveThreshold": 64, // Square of the threshold + "timerId": null, + "protoFilter": null, + "isListening": false, + "start": function( node, position ) { + if ( this.isListening && !this.node && this.matchesProtoFilter( node.prototypes ) ) { + this.node = node; + this.initialPosition = position.client; + this.timerId = setTimeout( function(){ fireTapHold(); }, this.timeout ); + } + }, + "moved": function( node, position ) { + if ( node === this.node ) { + console.info( " tapHold moved for node: " + this.node.ID + " at position: [ " + position.client[0] + ", " + position.client[1] + " ], timerId = " + this.timerId ); + if ( this.timerId ) { + var deltaPos = [ ( position.client[0] - this.initialPosition[0] ), + ( position.client[1] - this.initialPosition[1] ) ]; + var distanceSquared = ( ( deltaPos[0] * deltaPos[0] ) + ( deltaPos[1] * deltaPos[1] ) ); + if ( distanceSquared > this.moveThreshold ) { + this.cancel(); + } + } + } + }, + "cancel": function() { + if ( this.timerId ) { + console.info( " Cancel tapHold for node: " + this.node.ID ); + clearTimeout( this.timerId ); + } + this.node = null; + this.initialPosition = [ 0, 0 ]; + this.timerId = null; + }, + "matchesProtoFilter": function( prototypes ) { + var found = false; + if ( this.protoFilter ) { + if ( prototypes ) { + var kIndex; + for ( var i = 0; i < prototypes.length && !found; i++ ) { + for ( var j = 0; j < this.protoFilter.length && !found; j++ ) { + found = ( prototypes[ i ] === this.protoFilter[ j ] ); + } + } + } + } else { + found = true; // Not filtering anything + } + return found; + }, + "registerForTapHoldEvents": function( protoFilters ) { + console.info( " Registering for tapHold events for: "); + for ( var i = 0; i < protoFilters.length; i++ ) { + console.info( i + ". " + protoFilters[i] ); + } + this.protoFilter = protoFilters; + }, + "listenForTapHold": function( listen ) { + this.isListening = listen; + if ( !listen ) { + tapHold.cancel(); + } + } + + }; + + function fireTapHold() { + if ( tapHold.node ) { + console.info( " tapHold event firing for node: " + tapHold.node.ID ); + viewDriver.kernel.fireEvent( tapHold.node.ID, 'tapHold', [ tapHold.initialPosition ] ); + tapHold.cancel(); + } + } + + var swipe = { + "protoFilter": null, + "isListening": false, + "parentFilter": null, + "touchStartIsTap": null, + "swipedAcross": function( node, isTouchStart, eventData ) { + if ( this.isListening && this.isSwipe( node ) ) { + console.info( " swiped across node: " + node.ID ); + if ( isTouchStart && this.touchStartIsTap ) { + viewDriver.kernel.fireEvent( node.ID, 'tap', eventData ); + } else { + viewDriver.kernel.fireEvent( node.ID, 'swipe', [ ] ); + } + } + }, + "isSwipe": function( node ) { + var found = false; + var prototypes = node.prototypes; + if ( this.parentFilter && ( !isChildOf( node.kineticObj, this.parentFilter ) ) ) { + return found; + } + if ( this.protoFilter ) { + if ( prototypes ) { + var kIndex; + for ( var i = 0; i < prototypes.length && !found; i++ ) { + for ( var j = 0; j < this.protoFilter.length && !found; j++ ) { + found = ( prototypes[ i ] === this.protoFilter[ j ] ); + } + } + } + } else { + found = true; // Not filtering anything + } + return found; + }, + "registerForSwipeEvents": function( protoFilters ) { + console.info( " Registering for swipe events for: "); + for ( var i = 0; i < protoFilters.length; i++ ) { + console.info( i + ". " + protoFilters[i] ); + } + this.protoFilter = protoFilters; + }, + "listenForSwipes": function( params ) { + this.isListening = params.listen; + this.parentFilter = params[ "parent" ]; + this.touchStartIsTap = params[ "touchStartIsTap" ]; + } + }; + + // Find the parent of the kinetic node + function findParent( kineticNode, protoID ) { + + if ( kineticNode !== undefined ) { + if ( kineticNode.prototypeID === protoID ) + return kineticNode; + else + return findParent( _kineticComponents[ kineticNode.parentID ], protoID ); + } + return undefined; + } + + // Attach handlers for mouse events function attachMouseEvents( node ) { var mouseDown = false; node.kineticObj.on( "mousemove", function( evt ) { var eData = processEvent( evt, node, false ); + + // Cancel tapHold event (if any) + tapHold.cancel(); + //viewDriver.kernel.dispatchEvent( node.ID, 'pointerMove', eData.eventData, eData.eventNodeData ); //viewDriver.kernel.fireEvent( node.ID, 'pointerMove', eData.eventData ); //activelyDrawing = mouseDown; @@ -62,21 +206,33 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], node.kineticObj.on( "mouseenter", function( evt ) { var eData = processEvent( evt, node, false ); //viewDriver.kernel.dispatchEvent( node.ID, 'pointerEnter', eData.eventData, eData.eventNodeData ); - viewDriver.kernel.fireEvent( node.ID, 'pointerEnter', eData.eventData ); + //if ( mouseDown ) { + swipe.swipedAcross( node ); + //} + //viewDriver.kernel.fireEvent( node.ID, 'pointerEnter', eData.eventData ); } ); node.kineticObj.on( "mouseleave", function( evt ) { var eData = processEvent( evt, node, false ); // viewDriver.kernel.dispatchEvent( node.ID, 'pointerLeave', eData.eventData, eData.eventNodeData ); - viewDriver.kernel.fireEvent( node.ID, 'pointerLeave', eData.eventData ); + //if ( mouseDown ) { + swipe.swipedAcross( node ); + //} + //viewDriver.kernel.fireEvent( node.ID, 'pointerLeave', eData.eventData ); } ); node.kineticObj.on( "mousedown", function( evt ) { var eData = processEvent( evt, node, false ); + + // Cancel tapHold event (if any) + tapHold.cancel(); + + // Track mouseDown so we know we're holding the button during a move/drag mouseDown = true; //viewDriver.kernel.dispatchEvent( node.ID, 'pointerDown', eData.eventData, eData.eventNodeData ); //viewDriver.kernel.fireEvent( node.ID, 'pointerDown', eData.eventData ); + // Process drawing (if actively drawing) var userState = drawing_client; //if ( userState[ "drawing_mode" ] && ( userState[ "drawing_mode" ] !== "none" ) ) { // activelyDrawing = true; @@ -96,6 +252,9 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var eData = processEvent( evt, node, false ); mouseDown = false; + // Cancel tapHold event (if any) + tapHold.cancel(); + //viewDriver.kernel.dispatchEvent( node.ID, 'pointerUp', eData.eventData, eData.eventNodeData ); //viewDriver.kernel.fireEvent( node.ID, 'pointerUp', eData.eventData ); drawUp( node.ID, eData.eventData[0], node, true ); @@ -129,12 +288,20 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], node.kineticObj.on( "click", function( evt ) { var eData = processEvent( evt, node, false ); + + // Cancel tapHold event (if any) + tapHold.cancel(); + //viewDriver.kernel.dispatchEvent( node.ID, 'pointerClick', eData.eventData, eData.eventNodeData ); viewDriver.kernel.fireEvent( node.ID, 'pointerClick', eData.eventData ); } ); node.kineticObj.on( "dblclick", function( evt ) { var eData = processEvent( evt, node, false ); + + // Cancel tapHold event (if any) + tapHold.cancel(); + //viewDriver.kernel.dispatchEvent( node.ID, 'pointerDoubleClick', eData.eventData, eData.eventNodeData ); viewDriver.kernel.fireEvent( node.ID, 'pointerDoubleClick', eData.eventData ); } ); @@ -172,10 +339,15 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], //viewDriver.state.draggingNodes[ node.ID ] = true; viewDriver.state.draggingNodes[ node.ID ] = node; node.kineticObj.mouseDragging = true; + + swipe.swipedAcross( node ); + } ); node.kineticObj.on( "dragmove", function( evt ) { var eData = processEvent( evt, node, false ); + + tapHold.moved( node, eData.eventData[0] ); //viewDriver.kernel.dispatchEvent( node.ID, "dragMove", eData.eventData, eData.eventNodeData ); viewDriver.kernel.fireEvent( node.ID, 'dragMove', eData.eventData ); @@ -193,6 +365,8 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // in dragstart and mouseup (Eric - 11/18/14) node.kineticObj.on( "dragend", function( evt ) { var eData = processEvent( evt, node, false ); + + //tapHold.cancel(); //viewDriver.kernel.dispatchEvent( node.ID, "dragEnd", eData.eventData, eData.eventNodeData ); viewDriver.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); @@ -209,12 +383,17 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } + // Attach handlers for touch events function attachTouchEvents( node ) { var TOUCH_EVENT = true; node.kineticObj.on( "touchstart", function( evt ) { var eData = processEvent( evt, node, false ); + + // Start tapHold + tapHold.start( node, eData.eventData[0].touches[0] ); + //viewDriver.kernel.dispatchEvent( node.ID, "touchStart", eData.eventData, eData.eventNodeData ); //viewDriver.kernel.fireEvent( node.ID, 'touchStart', eData.eventData ); drawDown( node.ID, eData.eventData[0], node, false ); @@ -224,10 +403,16 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], activelyDrawing = true; } + swipe.swipedAcross( node, true, eData.eventData ); + } ); node.kineticObj.on( "touchmove", function( evt ) { var eData = processEvent( evt, node, false ); + + // If tapHold started, check that we haven't moved too much + tapHold.moved( node, eData.eventData[0].touches[0] ); + //viewDriver.kernel.dispatchEvent( node.ID, "touchMove", eData.eventData, eData.eventNodeData ); //viewDriver.kernel.fireEvent( node.ID, 'touchMove', eData.eventData ); drawMove( node.ID, eData.eventData[0], node, false ); @@ -237,10 +422,15 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], activelyDrawing = true; } + //swipe.swipedAcross( node ); } ); node.kineticObj.on( "touchend", function( evt ) { var eData = processEvent( evt, node, false ); + + // Cancel tapHold event (if any) + tapHold.cancel(); + //viewDriver.kernel.dispatchEvent( node.ID, "touchEnd", eData.eventData, eData.eventNodeData ); //viewDriver.kernel.fireEvent( node.ID, 'touchEnd', eData.eventData ); drawUp( node.ID, eData.eventData[0], node, true ); @@ -250,12 +440,20 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], node.kineticObj.on( "tap", function( evt ) { var eData = processEvent( evt, node, false ); + + // Cancel tapHold event (if any) + tapHold.cancel(); + //viewDriver.kernel.dispatchEvent( node.ID, "tap", eData.eventData, eData.eventNodeData ); viewDriver.kernel.fireEvent( node.ID, 'tap', eData.eventData ); } ); node.kineticObj.on( "dbltap", function( evt ) { var eData = processEvent( evt, node, false ); + + // Cancel tapHold event (if any) + tapHold.cancel(); + //viewDriver.kernel.dispatchEvent( node.ID, "dragStart", eData.eventData, eData.eventNodeData ); viewDriver.kernel.fireEvent( node.ID, 'doubleTap', eData.eventData ); } ); @@ -355,7 +553,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var node = this.state.nodes[ nodeID ]; - console.info( "kineticjs(view) satProperty. propertyName: " + propertyName + ", propertyValue: " + propertyValue + ", nodeID: " + nodeID ); + //console.info( "kineticjs(view) satProperty. propertyName: " + propertyName + ", propertyValue: " + propertyValue + ", nodeID: " + nodeID ); // If we don't have a record of this node, it is not a kinetic node, and we ignore it @@ -523,6 +721,22 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], */ break; + case "registerForTapHoldEvents": + tapHold.registerForTapHoldEvents( methodParameters ); + break; + + case "listenForTapHold": + tapHold.listenForTapHold( methodParameters[0] ); + break; + + case "registerForSwipeEvents": + swipe.registerForSwipeEvents( methodParameters ); + break; + + case "listenForSwipes": + swipe.listenForSwipes( methodParameters[0] ); + break; + } } @@ -575,7 +789,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // (this event is fired right before this driver sets the model property, so we // can be sure that the very next set of the position property is from us) var node = this.state.nodes[ nodeID ]; - node.model.position.viewIgnoreNextPositionUpdate = true; + node.model.position.ignoreNextPositionUpdate = true; } break; @@ -1608,7 +1822,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], function findStage( kineticObj ) { - var stage = undefined + var stage = undefined; var parent = kineticObj; while ( parent !== undefined && stage === undefined ) { if ( parent.nodeType === "Stage" ) { @@ -1622,7 +1836,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], function findLayer( kineticObj ) { - var layer = undefined + var layer = undefined; var parent = kineticObj; while ( parent !== undefined && layer === undefined ) { if ( parent.nodeType === "Layer" ) { @@ -1634,6 +1848,19 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } + function isChildOf( kineticObj, parentID ) { + + var foundParent = false; + var parent = kineticObj; + while ( parent !== undefined && !foundParent ) { + if ( parent.id() === parentID ) { + foundParent = true; + } + parent = parent.parent; + } + return foundParent; + } + function propagateNodeToModel() { // Send data about this node so the global node can be created and propagated diff --git a/support/proxy/vwf.example.com/mil-sym/unitGroup.js b/support/proxy/vwf.example.com/mil-sym/unitGroup.js index 76d4d5fe1..f934fbe70 100755 --- a/support/proxy/vwf.example.com/mil-sym/unitGroup.js +++ b/support/proxy/vwf.example.com/mil-sym/unitGroup.js @@ -45,6 +45,8 @@ this.initialize = function() { this.handleRender = function( img, iconSize, symbolCenter, symbolBounds ){ + this.zIndex = 20; + if ( this.threatArea ) { this.threatArea.position = this.icon.symbolCenter; } diff --git a/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml b/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml index 2c91c30b2..e9035dd90 100755 --- a/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml +++ b/support/proxy/vwf.example.com/mil-sym/unitGroup.vwf.yaml @@ -4,6 +4,7 @@ properties: supportMouseEvents: true supportTouchEvents: true index: 8 + zIndex: 8 mapPosition: set: | diff --git a/support/proxy/vwf.example.com/mil-sym/unitIcon.vwf.yaml b/support/proxy/vwf.example.com/mil-sym/unitIcon.vwf.yaml index 001ce9a20..750a88e1f 100755 --- a/support/proxy/vwf.example.com/mil-sym/unitIcon.vwf.yaml +++ b/support/proxy/vwf.example.com/mil-sym/unitIcon.vwf.yaml @@ -25,6 +25,8 @@ properties: } value: { "x": 16, "y": 16 } + zIndex: 20 + events: imageChanged: From 816881494a01528050ffabe76d8f9e9357b28e2d Mon Sep 17 00:00:00 2001 From: youngca Date: Tue, 15 Dec 2015 13:07:55 -0500 Subject: [PATCH 030/644] Add some comments to describe the node propagation. --- support/client/lib/vwf/view/kineticjs.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 8811de0af..0ee727adc 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -1355,8 +1355,9 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], if ( drawAndPropagate ) { drawObject( drawingObject, true ); + + // Create a node in the model so it gets replicated on all clients propagateNodeToModel(); - //drawing_private.drawingObject = null; } } }; @@ -1881,8 +1882,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], //callMethod(); //kineticNode = private_node.kineticObj; - - } function drawObject( kineticObject, clearBefore ) { From 2cdc32b3f0d06ceb6857972c0bca9f2efefa3768 Mon Sep 17 00:00:00 2001 From: youngca Date: Wed, 16 Dec 2015 13:26:48 -0500 Subject: [PATCH 031/644] Add function to bubble the unit symbols to the top for the active layer. --- support/client/lib/vwf/model/kineticjs.js | 23 +++++++++++++++++++ .../proxy/vwf.example.com/kinetic/drawing.js | 6 +++++ 2 files changed, 29 insertions(+) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index 78cc8f11c..fc1efc39c 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -1929,6 +1929,29 @@ define( [ "module", propagateKineticNode( methodParameters[0] ); } break; + case "moveToTop": + case "moveToBottom": + var node = this.state.nodes[ nodeID ]; + if ( node ) { + if ( node.kineticObj ) { + node.kineticObj.moveToTop(); + if ( ( methodParameters.length > 0 ) && ( node.kineticObj.children.length > 0 ) ) { + // Search for children with these names and elevate them to top + for ( var i = 0; i < methodParameters.length; i++ ) { + for ( var j = 0; j < node.kineticObj.children.length; j++ ) { + if ( node.kineticObj.children[ j ] && ( node.kineticObj.children[ j ].name() === methodParameters[ i ] ) ) { + if ( methodName === "moveToTop" ) { + node.kineticObj.children[ j ].moveToTop(); + } else { + node.kineticObj.children[ j ].moveToBottom(); + } + } + } + } + } + } + } + break; } }, diff --git a/support/proxy/vwf.example.com/kinetic/drawing.js b/support/proxy/vwf.example.com/kinetic/drawing.js index f489d0fd4..6d0fde44c 100644 --- a/support/proxy/vwf.example.com/kinetic/drawing.js +++ b/support/proxy/vwf.example.com/kinetic/drawing.js @@ -5,6 +5,8 @@ this.initialize = function() { this.clientWatch = function() { + debugger; + var clients = this.find( "doc('http://vwf.example.com/clients.vwf')" )[0]; if ( clients !== undefined ) { @@ -27,6 +29,8 @@ this.isValid = function( obj ) { }; this.clientJoin = function( moniker ) { + + debugger; //if ( this.id === "http://vwf.example.com/kinetic/drawing.vwf" ){ // return; //} @@ -53,6 +57,8 @@ this.clientJoin = function( moniker ) { }; this.clientLeave = function( moniker ) { + debugger; + if ( this.drawing_clients[ moniker ] !== undefined ) { delete this.drawing_clients[ moniker ]; this.drawing_clients = this.drawing_clients; From aa50ea5ff061d87f617ad874b53fb43d8ca0f0b6 Mon Sep 17 00:00:00 2001 From: youngca Date: Wed, 16 Dec 2015 17:30:24 -0500 Subject: [PATCH 032/644] Add a kinetic node to the hierarchy if it is not already in the hierarchy. Also, only handle the moveToTop and moveToBottom functions for the local client. Each client may have a different activeLayer and we want the graphics within that activeLayer to pop for just that user. --- support/client/lib/vwf/model/kineticjs.js | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index fc1efc39c..0b75850d0 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -1688,7 +1688,8 @@ define( [ "module", var creatingClient = this.kernel.client(); var thisClient = this.kernel.moniker(); - if ( !this.kernel.client() || ( this.kernel.client() === this.kernel.moniker() ) ) { + //if ( !this.kernel.client() || ( this.kernel.client() === this.kernel.moniker() ) ) { + if ( !isNodeInHierarchy( node ) ) { node.kineticObj = createKineticObject( node ); // if ( node.kineticObj instanceof Kinetic.Stage ) { @@ -1932,7 +1933,7 @@ define( [ "module", case "moveToTop": case "moveToBottom": var node = this.state.nodes[ nodeID ]; - if ( node ) { + if ( node && ( this.kernel.client() === this.kernel.moniker() ) ) { if ( node.kineticObj ) { node.kineticObj.moveToTop(); if ( ( methodParameters.length > 0 ) && ( node.kineticObj.children.length > 0 ) ) { @@ -2121,6 +2122,21 @@ define( [ "module", } + function isNodeInHierarchy( node ) { + var foundNode = false; + + if ( modelDriver.state.nodes[ node.parentID ] ) { + var parent = modelDriver.state.nodes[ node.parentID ]; + if ( parent.children ) { + for ( var i = 0; i < parent.children.length && !foundNode; i++ ) { + foundNode = ( parent.children[ i ] === node.ID ); + } + } + } + + return foundNode; + } + function isStageDefinition( prototypes ) { var found = false; if ( prototypes ) { From 86bbf3e090d5516cf232f912813de124d0bb3f82 Mon Sep 17 00:00:00 2001 From: youngca Date: Thu, 17 Dec 2015 18:26:12 -0500 Subject: [PATCH 033/644] Throttle the rendering rate and support moving the parent node to the top/bottom. --- support/client/lib/vwf/model/kineticjs.js | 22 +++++---- support/client/lib/vwf/view/kineticjs.js | 47 +++++++++++++++---- .../proxy/vwf.example.com/kinetic/drawing.js | 4 -- 3 files changed, 52 insertions(+), 21 deletions(-) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index 0b75850d0..39d37e457 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -1933,19 +1933,23 @@ define( [ "module", case "moveToTop": case "moveToBottom": var node = this.state.nodes[ nodeID ]; + var toTop = ( methodName === "moveToTop" ); + var params = null; + if ( methodParameters.length > 0 ) { + params = methodParameters[0]; + } if ( node && ( this.kernel.client() === this.kernel.moniker() ) ) { if ( node.kineticObj ) { - node.kineticObj.moveToTop(); - if ( ( methodParameters.length > 0 ) && ( node.kineticObj.children.length > 0 ) ) { + if ( params && params[ "includeParent" ] && node.kineticObj.parent ) { + ( toTop ? node.kineticObj.parent.moveToTop() : node.kineticObj.parent.moveToBottom() ); + } + ( toTop ? node.kineticObj.moveToTop() : node.kineticObj.moveToBottom() ); + if ( params && ( params[ "orderChildren" ].length > 0 ) && ( node.kineticObj.children.length > 0 ) ) { // Search for children with these names and elevate them to top - for ( var i = 0; i < methodParameters.length; i++ ) { + for ( var i = 0; i < params.orderChildren.length; i++ ) { for ( var j = 0; j < node.kineticObj.children.length; j++ ) { - if ( node.kineticObj.children[ j ] && ( node.kineticObj.children[ j ].name() === methodParameters[ i ] ) ) { - if ( methodName === "moveToTop" ) { - node.kineticObj.children[ j ].moveToTop(); - } else { - node.kineticObj.children[ j ].moveToBottom(); - } + if ( node.kineticObj.children[ j ] && ( node.kineticObj.children[ j ].name() === params.orderChildren[ i ] ) ) { + ( toTop ? node.kineticObj.children[ j ].moveToTop() : node.kineticObj.children[ j ].moveToBottom() ); } } } diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 0ee727adc..6c4af8c5b 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -29,6 +29,9 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var private_node = undefined; var activelyDrawing = false; var clearBeforeDraw = false; + var lastRenderTime = 0; // last time whole scene was rendered + var renderTimeout = 100; // ms between renders + var dt = new Date(); // Object implements tapHold behavior (kineticJS doesn't have a built-in one) var tapHold = { @@ -192,8 +195,8 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], drawMove( node.ID, eData.eventData[0], node, false ); var userState = drawing_client; - if ( userState[ "drawing_mode" ] && ( userState[ "drawing_mode" ] !== "none" ) ) { - activelyDrawing = true; + if ( !userState[ "drawing_mode" ] || ( userState[ "drawing_mode" ] === "none" ) ) { + activelyDrawing = false; } } ); @@ -260,6 +263,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], drawUp( node.ID, eData.eventData[0], node, true ); activelyDrawing = false; + render( node.kineticObj, true ); //var userState = drawing_client; //if ( activelyDrawing ) { @@ -291,6 +295,8 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // Cancel tapHold event (if any) tapHold.cancel(); + activelyDrawing = false; + render( node.kineticObj, true ); //viewDriver.kernel.dispatchEvent( node.ID, 'pointerClick', eData.eventData, eData.eventNodeData ); viewDriver.kernel.fireEvent( node.ID, 'pointerClick', eData.eventData ); @@ -301,6 +307,8 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // Cancel tapHold event (if any) tapHold.cancel(); + activelyDrawing = false; + render( node.kineticObj, true ); //viewDriver.kernel.dispatchEvent( node.ID, 'pointerDoubleClick', eData.eventData, eData.eventNodeData ); viewDriver.kernel.fireEvent( node.ID, 'pointerDoubleClick', eData.eventData ); @@ -350,6 +358,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], tapHold.moved( node, eData.eventData[0] ); //viewDriver.kernel.dispatchEvent( node.ID, "dragMove", eData.eventData, eData.eventNodeData ); viewDriver.kernel.fireEvent( node.ID, 'dragMove', eData.eventData ); + activelyDrawing = false; if ( node.kineticObj.mouseDragging ) { var xPos = viewDriver.state.getProperty( node.kineticObj, "x" ); @@ -369,6 +378,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], //tapHold.cancel(); //viewDriver.kernel.dispatchEvent( node.ID, "dragEnd", eData.eventData, eData.eventNodeData ); viewDriver.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); + activelyDrawing = false; node.kineticObj.mouseDragging = false; if ( viewDriver.state.draggingNodes[ node.ID ] !== undefined ) { @@ -399,8 +409,8 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], drawDown( node.ID, eData.eventData[0], node, false ); var userState = drawing_client; - if ( userState[ "drawing_mode" ] && ( userState[ "drawing_mode" ] !== "none" ) ) { - activelyDrawing = true; + if ( !userState[ "drawing_mode" ] || ( userState[ "drawing_mode" ] === "none" ) ) { + activelyDrawing = false; } swipe.swipedAcross( node, true, eData.eventData ); @@ -436,6 +446,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], drawUp( node.ID, eData.eventData[0], node, true ); activelyDrawing = false; + render( node.kineticObj, true ); } ); node.kineticObj.on( "tap", function( evt ) { @@ -443,9 +454,11 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // Cancel tapHold event (if any) tapHold.cancel(); + activelyDrawing = false; //viewDriver.kernel.dispatchEvent( node.ID, "tap", eData.eventData, eData.eventNodeData ); viewDriver.kernel.fireEvent( node.ID, 'tap', eData.eventData ); + render( node.kineticObj, true ); } ); node.kineticObj.on( "dbltap", function( evt ) { @@ -453,9 +466,11 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // Cancel tapHold event (if any) tapHold.cancel(); + activelyDrawing = false; //viewDriver.kernel.dispatchEvent( node.ID, "dragStart", eData.eventData, eData.eventNodeData ); viewDriver.kernel.fireEvent( node.ID, 'doubleTap', eData.eventData ); + render( node.kineticObj, true ); } ); } @@ -495,6 +510,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var protos = node.prototypes; if ( viewDriver.state.isKineticClass( protos, [ "kinetic", "stage", "vwf" ] ) ) { var stage = this.state.stage = node.kineticObj; + render( node.kineticObj ); } }, @@ -521,13 +537,19 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], viewDriver.kernel.getProperty( childID, "supportMouseEvents" ); viewDriver.kernel.getProperty( childID, "supportTouchEvents" ); + render( node.kineticObj ); } }, // -- deletedNode ------------------------------------------------------------------------------ - //deletedNode: function( nodeID ) { }, + deletedNode: function( nodeID ) { + + for ( var id in viewDriver.state.stages ) { + renderScene( viewDriver.state.stages[ id ], true ); + } + }, // -- addedChild ------------------------------------------------------------------------------- @@ -891,10 +913,19 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } } - function renderScene( stage ) { + function renderScene( stage, force ) { //window.requestAnimationFrame( renderScene( stage ) ); - if ( stage !== undefined && !activelyDrawing ) { - stage.batchDraw(); + if ( stage && !activelyDrawing ) { + //stage.batchDraw(); + render( stage, force ); + } + } + + function render( kineticObj, force ) { + var now = Date.now(); + if ( kineticObj && ( ( ( now - lastRenderTime ) > renderTimeout ) || force ) ) { + kineticObj.draw(); + lastRenderTime = now; } } diff --git a/support/proxy/vwf.example.com/kinetic/drawing.js b/support/proxy/vwf.example.com/kinetic/drawing.js index 6d0fde44c..7f1a3ae02 100644 --- a/support/proxy/vwf.example.com/kinetic/drawing.js +++ b/support/proxy/vwf.example.com/kinetic/drawing.js @@ -5,8 +5,6 @@ this.initialize = function() { this.clientWatch = function() { - debugger; - var clients = this.find( "doc('http://vwf.example.com/clients.vwf')" )[0]; if ( clients !== undefined ) { @@ -30,7 +28,6 @@ this.isValid = function( obj ) { this.clientJoin = function( moniker ) { - debugger; //if ( this.id === "http://vwf.example.com/kinetic/drawing.vwf" ){ // return; //} @@ -57,7 +54,6 @@ this.clientJoin = function( moniker ) { }; this.clientLeave = function( moniker ) { - debugger; if ( this.drawing_clients[ moniker ] !== undefined ) { delete this.drawing_clients[ moniker ]; From 10136ec3e3427cf594802d491f7a67d053747b55 Mon Sep 17 00:00:00 2001 From: youngca Date: Mon, 21 Dec 2015 16:49:49 -0500 Subject: [PATCH 034/644] Destroy the kinetic object and remove it from the tree after propagating the node to the model. --- support/client/lib/vwf/view/kineticjs.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 6c4af8c5b..75fefa7eb 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -1905,14 +1905,12 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // Delete the private node - we no longer need it + // Remove the kinetic object from the tree and destroy the object + drawing_private.drawingObject.destroy(); drawing_private.drawingObject = null; drawing_private = {}; - //delete private_node; private_node = undefined; - //callMethod(); - - //kineticNode = private_node.kineticObj; } function drawObject( kineticObject, clearBefore ) { From 62fe6961dc774289cada12b21d7db7865289b854 Mon Sep 17 00:00:00 2001 From: youngca Date: Tue, 22 Dec 2015 12:24:22 -0500 Subject: [PATCH 035/644] Do a better job of handling node deletion. Also support setting component listening. --- support/client/lib/vwf/model/kineticjs.js | 23 +++++++++++++++++++++++ support/client/lib/vwf/view/kineticjs.js | 20 ++++++++++++++++++-- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index 39d37e457..a149bdd4a 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -1957,6 +1957,29 @@ define( [ "module", } } break; + case "childListening": + var node = this.state.nodes[ nodeID ]; + var params = null; + if ( methodParameters.length > 0 ) { + params = methodParameters[0]; + } + if ( node && ( this.kernel.client() === this.kernel.moniker() ) ) { + if ( node.kineticObj ) { + if ( params ) { + if ( ( params[ "children" ].length > 0 ) && ( node.kineticObj.children.length > 0 ) ) { + // Search for children with these names and set their listening values + for ( var i = 0; i < params.children.length; i++ ) { + for ( var j = 0; j < node.kineticObj.children.length; j++ ) { + if ( node.kineticObj.children[ j ] && ( node.kineticObj.children[ j ].name() === params.children[ i ] ) ) { + node.kineticObj.children[ j ].listening( params.listening ); + } + } + } + } + } + } + } + break; } }, diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 75fefa7eb..aeb370ed2 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -31,7 +31,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var clearBeforeDraw = false; var lastRenderTime = 0; // last time whole scene was rendered var renderTimeout = 100; // ms between renders - var dt = new Date(); // Object implements tapHold behavior (kineticJS doesn't have a built-in one) var tapHold = { @@ -545,7 +544,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // -- deletedNode ------------------------------------------------------------------------------ deletedNode: function( nodeID ) { - for ( var id in viewDriver.state.stages ) { renderScene( viewDriver.state.stages[ id ], true ); } @@ -1320,6 +1318,20 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var node = viewDriver.state.nodes[ nodeID ]; var appID = viewDriver.kernel.application(); var drawAndPropagate = false; + var debugOn = true; + + if ( debugOn ) { + console.info( ' ' ); + console.info( ' === Nodes listening and visibility states ===' ); + for(var key in viewDriver.state.nodes) { + var kNode = viewDriver.state.nodes[ key ]; + var listening = ( kNode.kineticObj.listening instanceof Function ? kNode.kineticObj.listening() : undefined ); + var visible = ( kNode.kineticObj.visible instanceof Function ? kNode.kineticObj.visible() : undefined ); + console.info( ' Node: ' + kNode.kineticObj.id() + ', listening: ' + listening + ', visibility: ' + visible ); + } + console.info( ' === End ===' ); + console.info( ' ' ); + } if ( drawing_private !== undefined && drawing_private.drawingObject ) { @@ -1906,10 +1918,14 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // Delete the private node - we no longer need it // Remove the kinetic object from the tree and destroy the object + var nodeID = drawing_private.drawingObject.id(); drawing_private.drawingObject.destroy(); drawing_private.drawingObject = null; drawing_private = {}; private_node = undefined; + if ( viewDriver.state.nodes[ nodeID ] ) { + delete viewDriver.state.nodes[ nodeID ]; + } } From a481443f1db92be31eec2c4e8ccfcdec4c76722b Mon Sep 17 00:00:00 2001 From: David Easter Date: Tue, 22 Dec 2015 12:22:39 -0500 Subject: [PATCH 036/644] Don't clear the arrow position now that arrows are not composite objects --- support/client/lib/vwf/view/kineticjs.js | 1 - 1 file changed, 1 deletion(-) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index aeb370ed2..e2a021d0f 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -1600,7 +1600,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], drawingObject.lineJoin( userState.lineJoin ); drawingObject.dash( null ); drawingObject.fill( null ); - drawingObject.position( [ 0, 0 ] ); drawingObject.closed( true ); var arrowThickness = userState.drawing_width * arrowWidthMult; var headWidth = userState.drawing_width * arrowWidthMult * 2; From a789849730c8a225c2758e989fefca06990afe01 Mon Sep 17 00:00:00 2001 From: youngca Date: Tue, 22 Dec 2015 16:14:00 -0500 Subject: [PATCH 037/644] Fix detection of a swipe across an object with mouse when button is held down. --- support/client/lib/vwf/view/kineticjs.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index e2a021d0f..a46dadf94 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -31,6 +31,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var clearBeforeDraw = false; var lastRenderTime = 0; // last time whole scene was rendered var renderTimeout = 100; // ms between renders + var mouseDown = false; // Object implements tapHold behavior (kineticJS doesn't have a built-in one) var tapHold = { @@ -174,8 +175,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // Attach handlers for mouse events function attachMouseEvents( node ) { - var mouseDown = false; - node.kineticObj.on( "mousemove", function( evt ) { var eData = processEvent( evt, node, false ); @@ -208,18 +207,18 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], node.kineticObj.on( "mouseenter", function( evt ) { var eData = processEvent( evt, node, false ); //viewDriver.kernel.dispatchEvent( node.ID, 'pointerEnter', eData.eventData, eData.eventNodeData ); - //if ( mouseDown ) { + if ( mouseDown ) { swipe.swipedAcross( node ); - //} + } //viewDriver.kernel.fireEvent( node.ID, 'pointerEnter', eData.eventData ); } ); node.kineticObj.on( "mouseleave", function( evt ) { var eData = processEvent( evt, node, false ); // viewDriver.kernel.dispatchEvent( node.ID, 'pointerLeave', eData.eventData, eData.eventNodeData ); - //if ( mouseDown ) { + if ( mouseDown ) { swipe.swipedAcross( node ); - //} + } //viewDriver.kernel.fireEvent( node.ID, 'pointerLeave', eData.eventData ); } ); From 4796a2d080f8e831c71a1b719381ef3bf09d73ac Mon Sep 17 00:00:00 2001 From: David Easter Date: Tue, 15 Dec 2015 19:15:12 -0500 Subject: [PATCH 038/644] Remove unused `privateDrawingUpdated` --- support/client/lib/vwf/view/kineticjs.js | 20 ------------------- .../proxy/vwf.example.com/kinetic/drawing.js | 3 --- .../vwf.example.com/kinetic/drawing.vwf.yaml | 1 - 3 files changed, 24 deletions(-) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index a46dadf94..dd9d576a6 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -812,25 +812,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } break; - case "privateDrawingUpdated": - // User is actively drawing on the local client - // make sure the drawing is displayed as the user draws it. - if ( self.kernel.client() === self.kernel.moniker() ) { - var node = this.state.nodes[ eventData[0] ]; - if ( node ) { - var kineticObj = node.kineticObj; - if ( kineticObj && activelyDrawing ) { - //kineticObj.drawScene(); - //kineticObj.draw(); - } - } - /* - for ( var id in viewDriver.state.stages ){ - viewDriver.state.stages[ id ].drawScene(); - } */ - } - break; - case "textValueUpdated": if ( drawing_private !== undefined && drawing_private.drawingObject ) { var drawingObject = drawing_private.drawingObject; @@ -1671,7 +1652,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], //privateState.previousPoint = eventPoint; // Update the view to keep pace with user input //console.info( drawingObject.id + " updated, sending update event." ); - //node.privateDrawingUpdated( drawingObject.id ); if ( drawingObject && activelyDrawing ) { //console.info( "VIEW: draw object " ); drawObject( drawingObject, clearBeforeDraw ); diff --git a/support/proxy/vwf.example.com/kinetic/drawing.js b/support/proxy/vwf.example.com/kinetic/drawing.js index 7f1a3ae02..fdaf8b4a4 100644 --- a/support/proxy/vwf.example.com/kinetic/drawing.js +++ b/support/proxy/vwf.example.com/kinetic/drawing.js @@ -559,9 +559,6 @@ this.update = function( eventData, nodeData, upEvent ) { if ( pointAccepted ) { privateState.previousPoint = eventPoint; - // Update the view to keep pace with user input - //console.info( drawingObject.id + " updated, sending update event." ); - this.privateDrawingUpdated( drawingObject.id ); } } diff --git a/support/proxy/vwf.example.com/kinetic/drawing.vwf.yaml b/support/proxy/vwf.example.com/kinetic/drawing.vwf.yaml index 7f207da02..5919fc277 100644 --- a/support/proxy/vwf.example.com/kinetic/drawing.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/drawing.vwf.yaml @@ -27,6 +27,5 @@ events: textCreated: imageCreated: findChild: - privateDrawingUpdated: scripts: - source: "http://vwf.example.com/kinetic/drawing.js" From be65d9faebf41290f6e0b318bd2d73d332f35fd4 Mon Sep 17 00:00:00 2001 From: David Easter Date: Thu, 17 Dec 2015 01:31:29 -0500 Subject: [PATCH 039/644] Remove `this.kernel.moniker` in model --- support/client/lib/vwf/model/kineticjs.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index a149bdd4a..df54a6c72 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -1685,9 +1685,6 @@ define( [ "module", node.prototypes = protos; - var creatingClient = this.kernel.client(); - var thisClient = this.kernel.moniker(); - //if ( !this.kernel.client() || ( this.kernel.client() === this.kernel.moniker() ) ) { if ( !isNodeInHierarchy( node ) ) { node.kineticObj = createKineticObject( node ); From 85baf6a4fe1c3c08c41e4041bfba060b27564176 Mon Sep 17 00:00:00 2001 From: David Easter Date: Thu, 17 Dec 2015 01:32:30 -0500 Subject: [PATCH 040/644] Initialize single per-client private data correctly --- support/client/lib/vwf/view/kineticjs.js | 39 ++++-------------------- 1 file changed, 6 insertions(+), 33 deletions(-) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index dd9d576a6..978859e53 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -7,7 +7,12 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var stageContainer; var stageWidth = ( window && window.innerWidth ) ? window.innerWidth : 800; var stageHeight = ( window && window.innerHeight ) ? window.innerHeight : 600; - var drawing_private = {}; + var drawing_private = { + "drawingObject": null, + "initialDownPoint": [ -1, -1 ], + "previousPoint": [ -1, -1 ], + "mouseDown": false + }; var drawing_client = { "drawing_mode": 'none', "drawing_visible": 'inherit', @@ -1026,34 +1031,10 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } } - setUpPrivate = function() { - - //if ( drawing_private === undefined ) { - // drawing_private = {}; - //} - if ( drawing_private === undefined ) { - drawing_private = { - "drawingObject": null, - "initialDownPoint": [ -1, -1 ], - "previousPoint": [ -1, -1 ], - "mouseDown": false - }; - } - - }; - function drawDown( nodeID, eventData, nodeData, touch ) { var node = viewDriver.state.nodes[ nodeID ]; - //if ( !isValid( node.drawing_clients ) || - // !isValid( node.drawing_clients[ node.client ] ) ) { - // node.clientJoin( node.client ); - //} - if ( !isValid( drawing_private ) ) { - setUpPrivate(); - } - var userState = drawing_client; var privateState = drawing_private; var drawingMode = userState.drawing_mode; @@ -1275,14 +1256,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var node = viewDriver.state.nodes[ nodeID ]; - //if ( !isValid( node.drawing_clients ) || - // !isValid( node.drawing_clients[ node.client ] ) ) { - // node.clientJoin( node.client ); - //} - if ( drawing_private === undefined ) { - setUpPrivate( ); - } - var userState = drawing_client; if ( userState.drawing_mode === 'none' ) { return; From 9ed94dee8273ebfb95b4a8741207ff5599e14227 Mon Sep 17 00:00:00 2001 From: David Easter Date: Mon, 21 Dec 2015 20:59:51 -0500 Subject: [PATCH 041/644] Remove `propagateKineticNode` --- support/client/lib/vwf/model/kineticjs.js | 30 ----------------------- support/client/lib/vwf/view/kineticjs.js | 9 ------- 2 files changed, 39 deletions(-) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index df54a6c72..d55d4513b 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -1922,11 +1922,6 @@ define( [ "module", } switch( methodName ) { - case "propagateKineticNode": - if ( methodParameters.length > 0 ) { - propagateKineticNode( methodParameters[0] ); - } - break; case "moveToTop": case "moveToBottom": var node = this.state.nodes[ nodeID ]; @@ -2098,31 +2093,6 @@ define( [ "module", } - function propagateKineticNode( nodeObj ) { - //if ( modelDriver.state.isKineticComponent( nodeObj.prototypes ) ) { - - //if ( modelDriver.debug.native ) { - // modelDriver.logger.infox( "propagateKineticNode", nodeObj.parentID, nodeObj.ID, nodeObj.extendsID, nodeObj.implementsIDs, nodeObj.source, nodeObj.type, undefined, nodeObj.name ); - //} - - // Create the local copy of the node properties - if ( modelDriver.state.nodes[ nodeObj.ID ] === undefined ){ - modelDriver.state.nodes[ nodeObj.ID ] = - modelDriver.state.createLocalNode( nodeObj.parentID, nodeObj.ID, nodeObj.extendsID, nodeObj.implementsIDs, - nodeObj.source, nodeObj.type, undefined, nodeObj.name, null ); - } - - // Add the kinetic object to the node properties - node = modelDriver.state.nodes[ nodeObj.ID ]; - - node.prototypes = nodeObj.prototypes; - node.kineticObj = nodeObj.kineticObj; - - // Add the node to the hierarchy - addNodeToHierarchy( node ); - //} - } - function addNodeToHierarchy( node ) { if ( node.kineticObj ) { diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 978859e53..4b8bc10b4 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -1858,15 +1858,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], function propagateNodeToModel() { - // Send data about this node so the global node can be created and propagated - //viewDriver.kernel.callMethod( private_node.parentID, "propagateKineticNode", [ appID, private_node ] ); - var appID = viewDriver.kernel.kernel.application(); - - viewDriver.kernel.kernel.callMethod( appID, "propagateKineticNode", [ private_node ] ); - - viewDriver.kernel.kernel.createNode( private_node.extendsID, undefined, private_node.ID, null ); - - // Delete the private node - we no longer need it // Remove the kinetic object from the tree and destroy the object var nodeID = drawing_private.drawingObject.id(); From 6b8237c42ed5c40d0e418c4070774400e1d23b7a Mon Sep 17 00:00:00 2001 From: David Easter Date: Sun, 20 Dec 2015 13:49:30 -0500 Subject: [PATCH 042/644] Locate the parent node; save the descriptor to complete the edit --- support/client/lib/vwf/view/kineticjs.js | 64 +++++++----------------- 1 file changed, 19 insertions(+), 45 deletions(-) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 4b8bc10b4..9172c16ce 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -9,6 +9,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var stageHeight = ( window && window.innerHeight ) ? window.innerHeight : 600; var drawing_private = { "drawingObject": null, + "drawingDef": null, "initialDownPoint": [ -1, -1 ], "previousPoint": [ -1, -1 ], "mouseDown": false @@ -1033,8 +1034,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], function drawDown( nodeID, eventData, nodeData, touch ) { - var node = viewDriver.state.nodes[ nodeID ]; - var userState = drawing_client; var privateState = drawing_private; var drawingMode = userState.drawing_mode; @@ -1045,10 +1044,10 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var compExtends = undefined; var groupExtends = undefined; - var section = "shapes"; + var section = "/shapes"; if ( drawingMode === "freeDraw" ) { - section = "lines"; + section = "/lines"; } switch ( drawingMode ) { @@ -1135,23 +1134,10 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], if ( groupExtends !== undefined ) { privateState.initialDownPoint = eventPointDown; - //var parentPath = userState.drawing_parentPath + section ; - var parentPath = userState.drawing_parentID; - //var parentNode = viewDriver.state.nodes[ parentPath ]; - var section = findSection( parentPath, section ); - var parent = section ? section : node; - //var parents = this.find( parentPath ); - - // find was failing 9/2/14, and the code below - // was a backup, going to leave this in until we feel good - // about the issues we saw are no longer a problem - //if ( parents === undefined ) { - // parents = [ node.findChild( this, parentPath.split( '/' ) ) ]; - //} + var parentPath = userState.drawing_parentPath + section ; + var parentIDs = viewDriver.kernel.find( viewDriver.kernel.application(), parentPath ); - //var parent = viewDriver.state.nodes[ parentPath ] ? viewDriver.state.nodes[ parentPath ] : node; - - //var parent = parents.length > 0 ? parents[ 0 ] : this; + var parentID = parentIDs.length > 0 ? parentIDs[ 0 ] : viewDriver.kernel.application(); var groupDef = { "extends": groupExtends, "properties": { @@ -1162,13 +1148,12 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], "children": {} }; - var self = this; - var selfMoniker = node.client; var name = drawingMode + drawing_index; drawing_index = drawing_index + 1; - var childID = section.ID + ":" + name; - private_node = createLocalKineticNode( section.ID, childID, groupDef, [], undefined, undefined, name ); + var childID = parentID + ":" + name; + + private_node = createLocalKineticNode( parentID, childID, groupDef, [], undefined, undefined, name ); drawing_private.drawingObject = private_node.kineticObj; // Define the component objects of this group object @@ -1181,43 +1166,32 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var compChild = createLocalKineticNode( childID, compID, groupDef.children[ def ], [], undefined, undefined, def ); drawing_private.drawingObject[ def ] = compChild.kineticObj; drawing_private.drawingObject.children.push( drawing_private.drawingObject[ def ] ); - //drawing_private.children.push( compID ); } - //var self = this; - //var selfMoniker = node.client; - //var name = drawingMode + drawing_index; - //drawing_index = drawing_index + 1; - //var childID = section.ID + ":" + name; - - //parent.children.create( name, groupDef, function( child ) { - // drawing_private.drawingObject = child; - //} ); - //private_node = createLocalKineticNode( section.ID, childID, groupDef, [], undefined, undefined, name ); - //drawing_private.drawingObject = private_node.kineticObj; - drawUpdate( drawing_private.drawingObject.ID, eventData, nodeData, false ); + drawing_private.drawingDef = groupDef; + drawUpdate( drawing_private.drawingObject.ID, eventData, nodeData, false ); } else if ( compExtends !== undefined ) { privateState.initialDownPoint = eventPointDown; - var parentPath = userState.drawing_parentID; - //var parentNode = viewDriver.state.nodes[ parentPath ]; - var section = findSection( parentPath, section ); - var parent = section ? section : node; + var parentPath = userState.drawing_parentPath + section; + var parentIDs = viewDriver.kernel.find( viewDriver.kernel.application(), parentPath ); + var parentID = parentIDs.length > 0 ? parentIDs[ 0 ] : viewDriver.kernel.application(); var shapeDef = { "extends": compExtends, "properties": getDefaultProperties( drawingMode, false, eventPointDown ) }; - var self = this; - var selfMoniker = node.client; var name = drawingMode + drawing_index; drawing_index = drawing_index + 1; - var childID = section.ID + ":" + name; - private_node = createLocalKineticNode( section.ID, childID, shapeDef, [], undefined, undefined, name ); + var childID = parentID + ":" + name ; + private_node = createLocalKineticNode( parentID, childID, shapeDef, [], undefined, undefined, name ); drawing_private.drawingObject = private_node.kineticObj; + + drawing_private.drawingDef = shapeDef; + drawUpdate( drawing_private.drawingObject.ID, eventData, nodeData, false ); } From 177672e3f08f3e1f33d4719fe3f00d60c17e941a Mon Sep 17 00:00:00 2001 From: David Easter Date: Mon, 21 Dec 2015 11:36:47 -0500 Subject: [PATCH 043/644] Create the node in the model after the edit --- support/client/lib/vwf/view/kineticjs.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 9172c16ce..64ea135f3 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -10,6 +10,8 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var drawing_private = { "drawingObject": null, "drawingDef": null, + "drawingParentID": undefined, + "drawingChildName": "", "initialDownPoint": [ -1, -1 ], "previousPoint": [ -1, -1 ], "mouseDown": false @@ -1168,7 +1170,10 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], drawing_private.drawingObject.children.push( drawing_private.drawingObject[ def ] ); } + // Save data to be used to create the node in the model drawing_private.drawingDef = groupDef; + drawing_private.drawingParentID = parentID; + drawing_private.drawingChildName = name; drawUpdate( drawing_private.drawingObject.ID, eventData, nodeData, false ); @@ -1190,7 +1195,10 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], private_node = createLocalKineticNode( parentID, childID, shapeDef, [], undefined, undefined, name ); drawing_private.drawingObject = private_node.kineticObj; + // Save data to be used to create the node in the model drawing_private.drawingDef = shapeDef; + drawing_private.drawingParentID = parentID; + drawing_private.drawingChildName = name; drawUpdate( drawing_private.drawingObject.ID, eventData, nodeData, false ); @@ -1832,6 +1840,10 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], function propagateNodeToModel() { + // Create the node in the model + viewDriver.kernel.createChild( drawing_private.drawingParentID, drawing_private.drawingChildName, drawing_private.drawingDef ); + + // Delete the private node - we no longer need it // Remove the kinetic object from the tree and destroy the object var nodeID = drawing_private.drawingObject.id(); From dccd34f0e2a309d890ade7086728d721269ee616 Mon Sep 17 00:00:00 2001 From: David Easter Date: Wed, 23 Dec 2015 14:30:35 -0500 Subject: [PATCH 044/644] Add an `attributes` property to expose all Kinetic attributes --- support/client/lib/vwf/model/kineticjs.js | 9 +++++++++ support/proxy/vwf.example.com/kinetic/node.vwf.yaml | 1 + 2 files changed, 10 insertions(+) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index d55d4513b..2e208f2a6 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -315,6 +315,11 @@ define( [ "module", case "absoluteZIndex": modelDriver.logger.errorx( "settingProperty", "Cannot set property ", propertyName ); value = undefined; + break; + + case "attributes": + kineticObj.setAttrs( propertyValue || {} ); + break; default: value = undefined; @@ -1282,6 +1287,10 @@ define( [ "module", value = kineticObj.getAbsoluteZIndex(); break; + case "attributes": + value = kineticObj.getAttrs(); + break; + } //} diff --git a/support/proxy/vwf.example.com/kinetic/node.vwf.yaml b/support/proxy/vwf.example.com/kinetic/node.vwf.yaml index 83048d328..67c8c6a4a 100644 --- a/support/proxy/vwf.example.com/kinetic/node.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/node.vwf.yaml @@ -39,6 +39,7 @@ properties: hasMouseEvents: false hasTouchEvents: false dragProperty: "position" + attributes: methods: toggleVisibility: toggleListening: From 9e5bbf37acb4874011fd5550c1fbd8f97a439e4f Mon Sep 17 00:00:00 2001 From: David Easter Date: Wed, 23 Dec 2015 16:45:40 -0500 Subject: [PATCH 045/644] Create the model node using complete Kinetic attributes Use attributes retrieved from the intermediate Kinetic object instead of building a parallel VWF descriptor. --- support/client/lib/vwf/view/kineticjs.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 64ea135f3..5f52f575b 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -1841,6 +1841,14 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], function propagateNodeToModel() { // Create the node in the model + + drawing_private.drawingDef.properties = { + "attributes": $.extend( {}, drawing_private.drawingObject.getAttrs() ) + }; + + delete drawing_private.drawingDef.properties.attributes.id; + delete drawing_private.drawingDef.properties.attributes.name; + viewDriver.kernel.createChild( drawing_private.drawingParentID, drawing_private.drawingChildName, drawing_private.drawingDef ); From 4e8bea0b247947618eecaea212429418663ef38e Mon Sep 17 00:00:00 2001 From: David Easter Date: Wed, 23 Dec 2015 19:25:03 -0500 Subject: [PATCH 046/644] Fix Circle conflict between radius and width/height --- support/client/lib/vwf/view/kineticjs.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 5f52f575b..920fd97c8 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -1849,6 +1849,13 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], delete drawing_private.drawingDef.properties.attributes.id; delete drawing_private.drawingDef.properties.attributes.name; + // Ensure that the radius is the last property since width or height will override radius if + // both are provided. + + var radius = drawing_private.drawingDef.properties.attributes.radius; + delete drawing_private.drawingDef.properties.attributes.radius; + drawing_private.drawingDef.properties.attributes.radius = radius; + viewDriver.kernel.createChild( drawing_private.drawingParentID, drawing_private.drawingChildName, drawing_private.drawingDef ); From 90d5d1c6a9b9e91ccd2204caf7451f367c9b2945 Mon Sep 17 00:00:00 2001 From: David Easter Date: Wed, 23 Dec 2015 21:28:04 -0500 Subject: [PATCH 047/644] Use Kinetic attributes on child nodes in composite objects --- support/client/lib/vwf/view/kineticjs.js | 46 +++++++++++++++++------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 920fd97c8..f7fe58f45 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -1840,21 +1840,20 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], function propagateNodeToModel() { - // Create the node in the model - - drawing_private.drawingDef.properties = { - "attributes": $.extend( {}, drawing_private.drawingObject.getAttrs() ) - }; + // Update the VWF node descriptor with attributes from the intermediate Kinetic nodes used + // while editing - delete drawing_private.drawingDef.properties.attributes.id; - delete drawing_private.drawingDef.properties.attributes.name; + updateVWFdescriptor( drawing_private.drawingDef, drawing_private.drawingObject ); - // Ensure that the radius is the last property since width or height will override radius if - // both are provided. + if ( drawing_private.drawingDef.children ) { + for ( var def in drawing_private.drawingDef.children ) { + if ( drawing_private.drawingObject[ def ] ) { + updateVWFdescriptor( drawing_private.drawingDef.children[ def ], drawing_private.drawingObject[ def ] ); + } + } + } - var radius = drawing_private.drawingDef.properties.attributes.radius; - delete drawing_private.drawingDef.properties.attributes.radius; - drawing_private.drawingDef.properties.attributes.radius = radius; + // Create the node in the model viewDriver.kernel.createChild( drawing_private.drawingParentID, drawing_private.drawingChildName, drawing_private.drawingDef ); @@ -1870,6 +1869,29 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], delete viewDriver.state.nodes[ nodeID ]; } + + // Set a VWF descriptor's `properties` to describe a Kinetic node using its attributes + + function updateVWFdescriptor( vwfDescriptor, kineticNode ) { + + var properties = vwfDescriptor.properties = { + "attributes": $.extend( {}, kineticNode.getAttrs() ) + }; + + // Remove attributes related to editing with the intermediate node. + + delete properties.attributes.id; + delete properties.attributes.name; + + // Ensure that `radius` is the last attribute since `width` or `height` will override + // `radius` if both are provided. + + var radius = properties.attributes.radius; + delete properties.attributes.radius; + properties.attributes.radius = radius; + + } + } function drawObject( kineticObject, clearBefore ) { From 885a8c1add9756eede414a4762d471e488747784 Mon Sep 17 00:00:00 2001 From: David Easter Date: Wed, 23 Dec 2015 23:44:32 -0500 Subject: [PATCH 048/644] Randomize object names to avoid collisions --- support/client/lib/vwf/view/kineticjs.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index f7fe58f45..eaace9ce6 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -33,7 +33,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], "fillStyle": null, "zIndex": 4 }; - var drawing_index = 0; var private_node = undefined; var activelyDrawing = false; var clearBeforeDraw = false; @@ -1150,8 +1149,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], "children": {} }; - var name = drawingMode + drawing_index; - drawing_index = drawing_index + 1; + var name = drawingMode + "-" + randomSuffix(); var childID = parentID + ":" + name; @@ -1189,8 +1187,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], "properties": getDefaultProperties( drawingMode, false, eventPointDown ) }; - var name = drawingMode + drawing_index; - drawing_index = drawing_index + 1; + var name = drawingMode + "-" + randomSuffix(); var childID = parentID + ":" + name ; private_node = createLocalKineticNode( parentID, childID, shapeDef, [], undefined, undefined, name ); drawing_private.drawingObject = private_node.kineticObj; @@ -1203,6 +1200,12 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], drawUpdate( drawing_private.drawingObject.ID, eventData, nodeData, false ); } + + // Return a hex string representing a random 32-bit integer. + + function randomSuffix() { + return ( "00000000" + Math.floor( Math.random() * 0x100000000 ).toString( 16 ) ).substr( -8 ); + } }; function addNodeToHierarchy( node ) { @@ -1681,7 +1684,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], console.info( "createLocalKineticNode" ); - var node = viewDriver.state.createLocalNode( parentID, drawingID, extendsID, implementsID, source, type, drawing_index, name ); + var node = viewDriver.state.createLocalNode( parentID, drawingID, extendsID, implementsID, source, type, null, name ); node.prototypes = []; node.prototypes.push( extendsID ); From ab3f8c2d04ac5b524c1feb5fedc04ca9164c62d3 Mon Sep 17 00:00:00 2001 From: youngca Date: Thu, 31 Dec 2015 01:38:33 -0500 Subject: [PATCH 049/644] Create and destroy a temporary border for a text object; create the text object when text is set. --- support/client/lib/vwf/view/kineticjs.js | 149 ++++++++++++++--------- 1 file changed, 92 insertions(+), 57 deletions(-) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index eaace9ce6..460714bd3 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -699,8 +699,8 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], case "text": if ( drawing_private !== undefined && drawing_private.drawingObject ) { var drawingObject = drawing_private.drawingObject; - if ( drawingObject.content.id() === nodeID ) { - drawingObject.content.text( propertyValue ); + if ( drawingObject.id() === nodeID ) { + drawingObject.text( propertyValue ); drawObject( drawingObject, true ); propagateNodeToModel(); } @@ -822,8 +822,8 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], case "textValueUpdated": if ( drawing_private !== undefined && drawing_private.drawingObject ) { var drawingObject = drawing_private.drawingObject; - if ( drawingObject.content.id() === eventData[0] ) { - drawingObject.content.text( eventData[1] ); + if ( drawingObject.id() === eventData[0] ) { + drawingObject.text( eventData[1] ); drawObject( drawingObject, true ); propagateNodeToModel(); } @@ -1076,11 +1076,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], break; case "text": - groupExtends = "http://vwf.example.com/kinetic/drawingGroup.vwf"; - compExtends = { - "border": "http://vwf.example.com/kinetic/rect.vwf", - "content": [ "http://vwf.example.com/kinetic/", drawingMode, ".vwf" ].join('') - }; + compExtends = "http://vwf.example.com/kinetic/rect.vwf"; break; case "freeDraw": @@ -1098,39 +1094,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } - var getDefaultProperties = function( drawingMode, groupParent, eventPoint ) { - var retObj = { - "visible": 'inherit', - "listening": 'inherit', - "opacity": userState.drawing_opacity, - "index": 4 - }; - - switch( drawingMode ) { - case "sprite": - case "text": - case "image": - retObj.opacity = 1.0; - retObj.scaleOnLoad = true; - break; - default: - retObj.fill = userState.drawing_color; - break; - } - - if ( groupParent ) { - retObj.x = 0; - retObj.y = 0; - retObj.position = [ 0, 0 ]; - } else { - retObj.x = eventPoint[ 0 ]; - retObj.y = eventPoint[ 1 ]; - retObj.position = eventPoint; - } - - return retObj; - }; - var eventPointDown = eventData.stageRelative; if ( groupExtends !== undefined ) { @@ -1285,8 +1248,9 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], switch( userState.drawing_mode ) { case "text": - drawingObject.border.visible( false ); - viewDriver.kernel.fireEvent( appID, 'textCreated', [ drawingObject.content.id() ] ); + //drawingObject.border.visible( false ); + //drawingObject.visible( false ); + viewDriver.kernel.fireEvent( appID, 'textCreated', [ drawingObject.id() ] ); break; case "sprite": @@ -1576,16 +1540,20 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], break; case "text": - drawingObject.border.stroke( userState.drawing_color ); - drawingObject.border.strokeWidth( 2 ); - drawingObject.border.width( width ); - drawingObject.border.height( height ); - drawingObject.border.lineCap( userState.lineCap ); - drawingObject.border.lineJoin( userState.lineJoin ); - drawingObject.border.dash( [ 2, 5 ] ); - drawingObject.border.fill( null ); - drawingObject.content.fontSize( userState.fontSize ? userState.fontSize : 16 ); - drawingObject.content.fontStyle( 'bold' ); + drawingObject.x( pos[ 0 ] ); + drawingObject.y( pos[ 1 ] ); + drawingObject.size( { "width": width, "height": height} ); + drawingObject.stroke( userState.drawing_color ); + drawingObject.strokeWidth( 2 ); + //drawingObject.border.width( width ); + //drawingObject.border.height( height ); + drawingObject.lineCap( userState.lineCap ); + drawingObject.lineJoin( userState.lineJoin ); + drawingObject.dash( [ 2, 5 ] ); + drawingObject.fill( null ); + //drawingObject.visible( true ); + //drawingObject.content.fontSize( userState.fontSize ? userState.fontSize : 16 ); + //drawingObject.content.fontStyle( 'bold' ); clearBeforeDraw = true; break; @@ -1920,10 +1888,13 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], switch ( propertyName ) { case "text": - kineticObj.content.text( propertyValue ); + createTextObject(); + drawing_private.drawingObject.fontSize( userState.fontSize ? userState.fontSize : 16 ); + drawing_private.drawingObject.fontStyle( 'bold' ); + drawing_private.drawingObject.text( propertyValue ); //kineticObj.content.stroke( userState.drawing_color ); - kineticObj.content.fill( userState.drawing_color ); - drawObject( kineticObj, true ); + drawing_private.drawingObject.fill( userState.drawing_color ); + drawObject( drawing_private.drawingObject, true ); propagateNodeToModel(); break; @@ -1938,6 +1909,70 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } + function getDefaultProperties( drawingMode, groupParent, eventPoint ) { + + var userState = drawing_client; + + var retObj = { + "visible": 'inherit', + "listening": 'inherit', + "opacity": userState.drawing_opacity, + "index": 4 + }; + switch( drawingMode ) { + case "sprite": + case "text": + case "image": + retObj.opacity = 1.0; + retObj.scaleOnLoad = true; + break; + default: + retObj.fill = userState.drawing_color; + break; + } + + if ( groupParent ) { + retObj.x = 0; + retObj.y = 0; + retObj.position = [ 0, 0 ]; + } else { + retObj.x = eventPoint[ 0 ]; + retObj.y = eventPoint[ 1 ]; + retObj.position = eventPoint; + } + + return retObj; + } + + function createTextObject() { + + // Get the location and dimensions from the border rectangle + var position = [ drawing_private.drawingObject.x(), drawing_private.drawingObject.y() ]; + var width = drawing_private.drawingObject.width(); + var height = drawing_private.drawingObject.height(); + var childID = drawing_private.drawingObject.id(); + var parentID = drawing_private.drawingObject.parent.id(); + var name = drawing_private.drawingObject.name(); + var compExtends = "http://vwf.example.com/kinetic/text.vwf"; + var shapeDef = { + "extends": compExtends, + "properties": getDefaultProperties( "text", false, position ) + }; + + // Delete the border rectangle + var nodeID = drawing_private.drawingObject.id(); + drawing_private.drawingObject.destroy(); + drawing_private.drawingObject = null; + drawing_private.drawingDef = shapeDef; + if ( viewDriver.state.nodes[ nodeID ] ) { + delete viewDriver.state.nodes[ nodeID ]; + } + + // Create the text object + private_node = createLocalKineticNode( parentID, childID, shapeDef, [], undefined, undefined, name ); + drawing_private.drawingObject = private_node.kineticObj; + + } }); \ No newline at end of file From c3a2cd8db6e95d9088f1742681c1a7043abe2b93 Mon Sep 17 00:00:00 2001 From: youngca Date: Sat, 2 Jan 2016 13:02:43 -0500 Subject: [PATCH 050/644] Don't create the text object if the user didn't enter any text. --- support/client/lib/vwf/view/kineticjs.js | 34 +++++++++++++++--------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 460714bd3..40787c11a 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -1888,15 +1888,16 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], switch ( propertyName ) { case "text": - createTextObject(); - drawing_private.drawingObject.fontSize( userState.fontSize ? userState.fontSize : 16 ); - drawing_private.drawingObject.fontStyle( 'bold' ); - drawing_private.drawingObject.text( propertyValue ); - //kineticObj.content.stroke( userState.drawing_color ); - drawing_private.drawingObject.fill( userState.drawing_color ); - drawObject( drawing_private.drawingObject, true ); - propagateNodeToModel(); - break; + if ( createTextObject( propertyValue ) ) { + drawing_private.drawingObject.fontSize( userState.fontSize ? userState.fontSize : 16 ); + drawing_private.drawingObject.fontStyle( 'bold' ); + drawing_private.drawingObject.text( propertyValue ); + //kineticObj.content.stroke( userState.drawing_color ); + drawing_private.drawingObject.fill( userState.drawing_color ); + drawObject( drawing_private.drawingObject, true ); + propagateNodeToModel(); + } + break; case "image": kineticObj.image( propertyValue ); @@ -1945,7 +1946,9 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], return retObj; } - function createTextObject() { + function createTextObject( textValue ) { + + var textCreated = false; // Get the location and dimensions from the border rectangle var position = [ drawing_private.drawingObject.x(), drawing_private.drawingObject.y() ]; @@ -1970,9 +1973,16 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } // Create the text object - private_node = createLocalKineticNode( parentID, childID, shapeDef, [], undefined, undefined, name ); - drawing_private.drawingObject = private_node.kineticObj; + if ( textValue && ( textValue !== "" ) ) { + private_node = createLocalKineticNode( parentID, childID, shapeDef, [], undefined, undefined, name ); + drawing_private.drawingObject = private_node.kineticObj; + textCreated = true; + } else { + drawing_private = {}; + private_node = undefined; + } + return textCreated; } }); \ No newline at end of file From 0690cf3796bc258a853c13721ac5b3a7cf8016e1 Mon Sep 17 00:00:00 2001 From: youngca Date: Mon, 4 Jan 2016 18:09:28 -0500 Subject: [PATCH 051/644] Implement kinetic image objects propagating from view to model. Fix bug in text propagation. --- support/client/lib/vwf/model/kineticjs.js | 13 +- support/client/lib/vwf/view/kineticjs.js | 188 +++++------------- .../vwf.example.com/kinetic/image.vwf.yaml | 2 +- 3 files changed, 65 insertions(+), 138 deletions(-) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index 2e208f2a6..0b7248b3d 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -318,7 +318,12 @@ define( [ "module", break; case "attributes": - kineticObj.setAttrs( propertyValue || {} ); + // Special case for images, don't overwrite a valid image with a bogus object + var attrs = propertyValue; + if ( ( kineticObj instanceof Kinetic.Image ) && ( kineticObj.image() instanceof Image ) && propertyValue.image && !( propertyValue.image instanceof Image ) ) { + attrs.image = kineticObj.image(); + } + kineticObj.setAttrs( attrs || {} ); break; default: @@ -2208,7 +2213,7 @@ define( [ "module", function loadImage( kineticObj, url ) { var imageObj = kineticObj.image(); - var validImage = ( imageObj !== undefined ); + var validImage = ( imageObj && ( imageObj !== undefined ) && ( imageObj instanceof Image ) ); var width = kineticObj.width(); var height = kineticObj.height(); var nodeID = kineticObj.id(); @@ -2245,7 +2250,9 @@ define( [ "module", } var oldSrc = imageObj.src; - imageObj.src = url; + if ( url !== oldSrc ) { + imageObj.src = url; + } } }); diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 40787c11a..12092c07d 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -14,7 +14,8 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], "drawingChildName": "", "initialDownPoint": [ -1, -1 ], "previousPoint": [ -1, -1 ], - "mouseDown": false + "mouseDown": false, + "imageDataURL": null }; var drawing_client = { "drawing_mode": 'none', @@ -188,15 +189,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // Cancel tapHold event (if any) tapHold.cancel(); - //viewDriver.kernel.dispatchEvent( node.ID, 'pointerMove', eData.eventData, eData.eventNodeData ); - //viewDriver.kernel.fireEvent( node.ID, 'pointerMove', eData.eventData ); - //activelyDrawing = mouseDown; - - //var userState = drawing_client; - //if ( userState[ "drawing_mode" ] && ( userState[ "drawing_mode" ] !== "none" ) ) { - //activelyDrawing = true; - // drawMove( node.ID, eData.eventData[0], node, false ); - //} drawMove( node.ID, eData.eventData[0], node, false ); var userState = drawing_client; @@ -213,20 +205,19 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], node.kineticObj.on( "mouseenter", function( evt ) { var eData = processEvent( evt, node, false ); - //viewDriver.kernel.dispatchEvent( node.ID, 'pointerEnter', eData.eventData, eData.eventNodeData ); + if ( mouseDown ) { swipe.swipedAcross( node ); } - //viewDriver.kernel.fireEvent( node.ID, 'pointerEnter', eData.eventData ); } ); node.kineticObj.on( "mouseleave", function( evt ) { var eData = processEvent( evt, node, false ); - // viewDriver.kernel.dispatchEvent( node.ID, 'pointerLeave', eData.eventData, eData.eventNodeData ); + if ( mouseDown ) { swipe.swipedAcross( node ); } - //viewDriver.kernel.fireEvent( node.ID, 'pointerLeave', eData.eventData ); + } ); node.kineticObj.on( "mousedown", function( evt ) { @@ -237,16 +228,10 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // Track mouseDown so we know we're holding the button during a move/drag mouseDown = true; - //viewDriver.kernel.dispatchEvent( node.ID, 'pointerDown', eData.eventData, eData.eventNodeData ); - //viewDriver.kernel.fireEvent( node.ID, 'pointerDown', eData.eventData ); // Process drawing (if actively drawing) var userState = drawing_client; - //if ( userState[ "drawing_mode" ] && ( userState[ "drawing_mode" ] !== "none" ) ) { - // activelyDrawing = true; - // console.info( "VIEW: drawDown" ); - // drawDown( node.ID, eData.eventData[0], node, false ); - //} + drawDown( node.ID, eData.eventData[0], node, false ); var userState = drawing_client; @@ -263,33 +248,17 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // Cancel tapHold event (if any) tapHold.cancel(); - //viewDriver.kernel.dispatchEvent( node.ID, 'pointerUp', eData.eventData, eData.eventNodeData ); - //viewDriver.kernel.fireEvent( node.ID, 'pointerUp', eData.eventData ); drawUp( node.ID, eData.eventData[0], node, true ); activelyDrawing = false; render( node.kineticObj, true ); - //var userState = drawing_client; - //if ( activelyDrawing ) { - // console.info( "VIEW: drawUp" ); - // drawUp( node.ID, eData.eventData[0], node, true ); - //} - //activelyDrawing = false; - if ( node.kineticObj.mouseDragging ) { viewDriver.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); node.kineticObj.mouseDragging = false; - //setViewProperty( node.ID, "x", eData.eventData.stageRelative.x ); - //setViewProperty( node.ID, "y", eData.eventData.stageRelative.y ); - if ( viewDriver.state.draggingNodes[ node.ID ] !== undefined ) { - //var x = viewDriver.state.getModelProperty( node.ID, "x" ); - //var y = viewDriver.state.getModelProperty( node.ID, "y" ); delete viewDriver.state.draggingNodes[ node.ID ]; - //viewDriver.state.setModelProperty( node.ID, "x", x ); - //viewDriver.state.setModelProperty( node.ID, "y", y ); } } @@ -303,7 +272,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], activelyDrawing = false; render( node.kineticObj, true ); - //viewDriver.kernel.dispatchEvent( node.ID, 'pointerClick', eData.eventData, eData.eventNodeData ); viewDriver.kernel.fireEvent( node.ID, 'pointerClick', eData.eventData ); } ); @@ -315,7 +283,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], activelyDrawing = false; render( node.kineticObj, true ); - //viewDriver.kernel.dispatchEvent( node.ID, 'pointerDoubleClick', eData.eventData, eData.eventNodeData ); viewDriver.kernel.fireEvent( node.ID, 'pointerDoubleClick', eData.eventData ); } ); @@ -335,21 +302,10 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], node.kineticObj.on( "dragstart", function( evt ) { var eData = processEvent( evt, node, false ); - //viewDriver.kernel.dispatchEvent( node.ID, "dragStart", eData.eventData, eData.eventNodeData ); - viewDriver.kernel.fireEvent( node.ID, 'dragStart', eData.eventData ); - //var xPos = viewDriver.state.getProperty( node.ID, "x" ); - //var yPos = viewDriver.state.getProperty( node.ID, "y" ); - var xPos = viewDriver.state.getProperty( node.kineticObj, "x" ); var yPos = viewDriver.state.getProperty( node.kineticObj, "y" ); - //setViewProperty( node.ID, "position", [ xPos, yPos ] ); - ////setViewProperty( node.ID, "x", xPos ); - ////setViewProperty( node.ID, "y", yPos ); - //console.info( "dragstart( "+node.ID+", x: "+xPos+", y: "+yPos+" )" ); - - //viewDriver.state.draggingNodes[ node.ID ] = true; viewDriver.state.draggingNodes[ node.ID ] = node; node.kineticObj.mouseDragging = true; @@ -361,37 +317,25 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var eData = processEvent( evt, node, false ); tapHold.moved( node, eData.eventData[0] ); - //viewDriver.kernel.dispatchEvent( node.ID, "dragMove", eData.eventData, eData.eventNodeData ); viewDriver.kernel.fireEvent( node.ID, 'dragMove', eData.eventData ); activelyDrawing = false; if ( node.kineticObj.mouseDragging ) { var xPos = viewDriver.state.getProperty( node.kineticObj, "x" ); var yPos = viewDriver.state.getProperty( node.kineticObj, "y" ); - //setViewProperty( node.ID, "position", [ xPos, yPos ] ); - ////setViewProperty( node.ID, "x", xPos ); - ////setViewProperty( node.ID, "y", yPos ); } } ); - // I couldn't get this to work, so instead I keep track of mouseDragging separately - // in dragstart and mouseup (Eric - 11/18/14) node.kineticObj.on( "dragend", function( evt ) { var eData = processEvent( evt, node, false ); - //tapHold.cancel(); - //viewDriver.kernel.dispatchEvent( node.ID, "dragEnd", eData.eventData, eData.eventNodeData ); viewDriver.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); activelyDrawing = false; node.kineticObj.mouseDragging = false; if ( viewDriver.state.draggingNodes[ node.ID ] !== undefined ) { - //var x = viewDriver.state.getModelProperty( node.ID, "x" ); - //var y = viewDriver.state.getModelProperty( node.ID, "y" ); delete viewDriver.state.draggingNodes[ node.ID ]; - //viewDriver.state.setModelProperty( node.ID, "x", x ); - //viewDriver.state.setModelProperty( node.ID, "y", y ); } } ); @@ -409,8 +353,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // Start tapHold tapHold.start( node, eData.eventData[0].touches[0] ); - //viewDriver.kernel.dispatchEvent( node.ID, "touchStart", eData.eventData, eData.eventNodeData ); - //viewDriver.kernel.fireEvent( node.ID, 'touchStart', eData.eventData ); drawDown( node.ID, eData.eventData[0], node, false ); var userState = drawing_client; @@ -428,8 +370,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // If tapHold started, check that we haven't moved too much tapHold.moved( node, eData.eventData[0].touches[0] ); - //viewDriver.kernel.dispatchEvent( node.ID, "touchMove", eData.eventData, eData.eventNodeData ); - //viewDriver.kernel.fireEvent( node.ID, 'touchMove', eData.eventData ); drawMove( node.ID, eData.eventData[0], node, false ); var userState = drawing_client; @@ -446,8 +386,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // Cancel tapHold event (if any) tapHold.cancel(); - //viewDriver.kernel.dispatchEvent( node.ID, "touchEnd", eData.eventData, eData.eventNodeData ); - //viewDriver.kernel.fireEvent( node.ID, 'touchEnd', eData.eventData ); drawUp( node.ID, eData.eventData[0], node, true ); activelyDrawing = false; @@ -737,14 +675,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var propertyValue = methodParameters[ 2 ]; setKineticProperty( private_node.kineticObj, propertyName, propertyValue ); } - /* - var kineticNode = viewDriver.state.nodes[ methodParameters[0] ]; - var propertyName = methodParameters[ 1 ]; - var propetyValue = methodParameters[ 2 ]; - if ( kineticNode && kineticNode.kineticObj ) { - setKineticProperty( kineticNode.kineticObj, propertyName, propertyValue ); - } - */ break; case "registerForTapHoldEvents": @@ -1025,7 +955,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } else { var modelValue = node.model[ propertyName ].value; if ( modelValue !== undefined ) { - //delete node.model[ propertyName ]; viewDriver.state.setProperty( node.kineticObj, propertyName, modelValue ); console.info( "- deletes node.model and set kineticObject property: "+propertyName+" to: "+modelValue ); } @@ -1066,12 +995,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], case "sprite": case "image": - /* - groupExtends = "http://vwf.example.com/kinetic/drawingGroup.vwf"; - compExtends = { - "border": "http://vwf.example.com/kinetic/line.vwf", - "content": [ "http://vwf.example.com/kinetic/", drawingMode, ".vwf" ].join('') - };*/ compExtends = [ "http://vwf.example.com/kinetic/", drawingMode, ".vwf" ].join('') break; @@ -1177,8 +1100,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], if ( node.kineticObj ) { - //debugger; - if ( viewDriver.state.nodes[ node.parentID ] !== undefined ) { var parent = viewDriver.state.nodes[ node.parentID ]; if ( parent.kineticObj && isContainerDefinition( parent.prototypes ) ) { @@ -1239,7 +1160,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var drawingObject = drawing_private.drawingObject; drawUpdate( drawingObject.ID, eventData, nodeData, true ); - //node.drawingObjectCreated( drawingObject.id ); viewDriver.kernel.fireEvent( appID, 'drawingObjectCreated', [ drawingObject.id() ] ); var userState = drawing_client; @@ -1248,17 +1168,14 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], switch( userState.drawing_mode ) { case "text": - //drawingObject.border.visible( false ); - //drawingObject.visible( false ); viewDriver.kernel.fireEvent( appID, 'textCreated', [ drawingObject.id() ] ); break; case "sprite": case "image": - //drawingObject.border.visible( false ); drawingObject.stroke( null ); viewDriver.kernel.fireEvent( appID, 'imageCreated', [ drawingObject.id() ] ); - drawAndPropagate = true; + drawAndPropagate = false; break; case "line": @@ -1516,26 +1433,16 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], case "sprite": case "image": - /* - drawingObject.border.stroke( userState.drawing_color ); - drawingObject.border.strokeWidth( 2 ); - drawingObject.border.points( [ 0, 0, width, 0, width, height, 0, height, 0, 0 ] ); - drawingObject.border.lineCap( userState.lineCap ); - drawingObject.border.lineJoin( userState.lineJoin ); - drawingObject.border.dash( [ 2, 5 ] ); - drawingObject.content.width( width ); - drawingObject.content.height( height ); - */ drawingObject.x( pos[ 0 ] ); drawingObject.y( pos[ 1 ] ); drawingObject.stroke( userState.drawing_color ); drawingObject.strokeWidth( 2 ); - //drawingObject.points( [ 0, 0, width, 0, width, height, 0, height, 0, 0 ] ); drawingObject.lineCap( userState.lineCap ); drawingObject.lineJoin( userState.lineJoin ); drawingObject.dash( [ 2, 5 ] ); drawingObject.width( width ); drawingObject.height( height ); + drawingObject.image( null ); clearBeforeDraw = true; break; @@ -1545,15 +1452,10 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], drawingObject.size( { "width": width, "height": height} ); drawingObject.stroke( userState.drawing_color ); drawingObject.strokeWidth( 2 ); - //drawingObject.border.width( width ); - //drawingObject.border.height( height ); drawingObject.lineCap( userState.lineCap ); drawingObject.lineJoin( userState.lineJoin ); drawingObject.dash( [ 2, 5 ] ); drawingObject.fill( null ); - //drawingObject.visible( true ); - //drawingObject.content.fontSize( userState.fontSize ? userState.fontSize : 16 ); - //drawingObject.content.fontStyle( 'bold' ); clearBeforeDraw = true; break; @@ -1597,15 +1499,10 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], //console.info( "setClientUIState " + JSON.stringify( stateObj ) ); if ( stateObj !== undefined ) { - //if ( !isValid( drawing_client ) ) { - // clientJoin( this.client ); - //} - //var clients = drawing_client; var userState = drawing_client; for ( var property in stateObj ) { userState[ property ] = stateObj[ property ]; } - //drawing_client = clients; } }; @@ -1813,7 +1710,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // Update the VWF node descriptor with attributes from the intermediate Kinetic nodes used // while editing - updateVWFdescriptor( drawing_private.drawingDef, drawing_private.drawingObject ); if ( drawing_private.drawingDef.children ) { @@ -1825,38 +1721,29 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } // Create the node in the model - viewDriver.kernel.createChild( drawing_private.drawingParentID, drawing_private.drawingChildName, drawing_private.drawingDef ); - // Delete the private node - we no longer need it // Remove the kinetic object from the tree and destroy the object - var nodeID = drawing_private.drawingObject.id(); - drawing_private.drawingObject.destroy(); - drawing_private.drawingObject = null; - drawing_private = {}; - private_node = undefined; - if ( viewDriver.state.nodes[ nodeID ] ) { - delete viewDriver.state.nodes[ nodeID ]; - } - + deletePrivateNode( true ); // Set a VWF descriptor's `properties` to describe a Kinetic node using its attributes - function updateVWFdescriptor( vwfDescriptor, kineticNode ) { var properties = vwfDescriptor.properties = { "attributes": $.extend( {}, kineticNode.getAttrs() ) }; - // Remove attributes related to editing with the intermediate node. + if ( drawing_private.imageDataURL ) { + properties[ "image" ] = drawing_private.imageDataURL; + } + // Remove attributes related to editing with the intermediate node. delete properties.attributes.id; delete properties.attributes.name; // Ensure that `radius` is the last attribute since `width` or `height` will override // `radius` if both are provided. - var radius = properties.attributes.radius; delete properties.attributes.radius; properties.attributes.radius = radius; @@ -1892,7 +1779,6 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], drawing_private.drawingObject.fontSize( userState.fontSize ? userState.fontSize : 16 ); drawing_private.drawingObject.fontStyle( 'bold' ); drawing_private.drawingObject.text( propertyValue ); - //kineticObj.content.stroke( userState.drawing_color ); drawing_private.drawingObject.fill( userState.drawing_color ); drawObject( drawing_private.drawingObject, true ); propagateNodeToModel(); @@ -1900,7 +1786,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], break; case "image": - kineticObj.image( propertyValue ); + setImage( propertyValue ); break; default: @@ -1964,13 +1850,8 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], }; // Delete the border rectangle - var nodeID = drawing_private.drawingObject.id(); - drawing_private.drawingObject.destroy(); - drawing_private.drawingObject = null; + deletePrivateNode( false ); drawing_private.drawingDef = shapeDef; - if ( viewDriver.state.nodes[ nodeID ] ) { - delete viewDriver.state.nodes[ nodeID ]; - } // Create the text object if ( textValue && ( textValue !== "" ) ) { @@ -1985,4 +1866,43 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], return textCreated; } + function setImage( dataURL ) { + + if ( drawing_private.drawingObject ) { + + if ( dataURL ) { + var imageObj = new Image(); + imageObj.onload = function() { + drawing_private.imageDataURL = dataURL; + var nodeID = drawing_private.drawingObject.id(); + // Propagate the node to the model + propagateNodeToModel(); + }; + imageObj.onerror = function() { + deletePrivateNode( true ); + }; + imageObj.src = dataURL; + } else { + deletePrivateNode( true ); + } + + } + + } + + function deletePrivateNode( fullyDelete ) { + var nodeID = drawing_private.drawingObject.id(); + drawing_private.drawingObject.destroy(); + drawing_private.drawingObject = null; + if ( viewDriver.state.nodes[ nodeID ] ) { + delete viewDriver.state.nodes[ nodeID ]; + } + drawing_private.imageDataURL = null; + + if ( fullyDelete ) { + drawing_private = {}; + private_node = undefined; + } + } + }); \ No newline at end of file diff --git a/support/proxy/vwf.example.com/kinetic/image.vwf.yaml b/support/proxy/vwf.example.com/kinetic/image.vwf.yaml index 6d7f20172..b935116c6 100644 --- a/support/proxy/vwf.example.com/kinetic/image.vwf.yaml +++ b/support/proxy/vwf.example.com/kinetic/image.vwf.yaml @@ -3,7 +3,7 @@ --- extends: http://vwf.example.com/kinetic/shape.vwf properties: - image: + image: crop: scaleOnLoad: false events: From 578cd526b54b934deed409e8e926a22283023a5c Mon Sep 17 00:00:00 2001 From: youngca Date: Mon, 4 Jan 2016 23:13:23 -0500 Subject: [PATCH 052/644] Maintain aspect ratio of the image for kinetic image objects. --- support/client/lib/vwf/view/kineticjs.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 12092c07d..72163131e 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -1875,6 +1875,21 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], imageObj.onload = function() { drawing_private.imageDataURL = dataURL; var nodeID = drawing_private.drawingObject.id(); + + // Set the width and height to maintain aspect ratio + var imgAspectRatio = imageObj.width / imageObj.height; + var width = drawing_private.drawingObject.width(); + var height = drawing_private.drawingObject.height(); + + // Use the larger dimension to set the width and height + if ( width >= height ) { + height = width / imgAspectRatio; + } else { + width = height * imgAspectRatio; + } + drawing_private.drawingObject.width( width ); + drawing_private.drawingObject.height( height ); + // Propagate the node to the model propagateNodeToModel(); }; From 3d3a25982e3193f9c09db5afef093b78fbb65572 Mon Sep 17 00:00:00 2001 From: David Easter Date: Tue, 5 Jan 2016 04:53:16 -0500 Subject: [PATCH 053/644] Select ids that express all local resources as host-relative. This allows the host name or port to change without invalidating documents saved on that host. Previously, only resources explicitly referenced at `/path/...` were saved with host-relative ids. aintact.express local resources as host-relative --- support/client/lib/vwf.js | 7 +++--- support/client/lib/vwf/utility.js | 37 ++++++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/support/client/lib/vwf.js b/support/client/lib/vwf.js index 36e3e758a..f4e52c242 100644 --- a/support/client/lib/vwf.js +++ b/support/client/lib/vwf.js @@ -1565,11 +1565,10 @@ if ( componentIsURI( nodeComponent ) ) { // URI // TODO: allow non-vwf URIs (models, images, etc.) to pass through to stage 2 and pass directly to createChild() - // Resolve relative URIs, but leave host-relative, locally-absolute - // references intact. + // Resolve relative URIs, but express local resources as host-relative. - nodeURI = nodeComponent[0] == "/" ? - nodeComponent : require( "vwf/utility" ).resolveURI( nodeComponent, baseURI ); + nodeURI = require( "vwf/utility" ).resolveURI( nodeComponent, baseURI, + document.location.protocol + "//" + document.location.host + "/dummypath/" ); // Load the document if we haven't seen this URI yet. Mark the components // list to indicate that this component is loading. diff --git a/support/client/lib/vwf/utility.js b/support/client/lib/vwf/utility.js index d364f2296..6119e6f8b 100644 --- a/support/client/lib/vwf/utility.js +++ b/support/client/lib/vwf/utility.js @@ -271,19 +271,22 @@ define( [ "module", /// An optional URI that provides the reference for uri. If baseURI is not provided, uri /// will be interpreted with respect to the document. If baseURI is relative, it will be /// interpreted with respect to the document before resolving uri. + /// @param {Boolean|String} [relative] + /// If set, express the result as relative to the document, or relative to the provided + /// uri. /// /// @returns {String} /// uri as an absolute URI. - resolveURI: function( uri, baseURI ) { + resolveURI: function( uri, baseURI, relative ) { - var doc = document; + var doc = document, result; - if ( baseURI ) { + // Create a temporary document anchored at baseURI. - // Create a temporary document anchored at baseURI. + if ( baseURI ) { - var doc = document.implementation.createHTMLDocument( "resolveURI" ); + doc = document.implementation.createHTMLDocument( "resolveURI" ); // Insert a with the reference URI: . @@ -300,7 +303,29 @@ define( [ "module", var a = doc.createElement( "a" ); a.href = uri; - return a.href; + result = a.href; + + // Interpret the result with respect to the reference uri. + + if ( relative ) { + + var aref = doc.createElement( "a" ); + aref.href = typeof relative === "string" ? relative : document.location.href; + aref.pathname = aref.pathname.replace( /[^/]*$/, "" ); + + var aref_ph = aref.protocol + "//" + aref.host; + + if ( result.substring( 0, aref.href.length ) === aref.href ) { + result = result.substring( aref.href.length ); + } else if ( result.substring( 0, aref_ph.length ) === aref_ph ) { + result = result.substring( aref_ph.length ); + } + + } + + // Return the result. + + return result; }, // -- merge -------------------------------------------------------------------------------- From b80d6087070718b7fc7cc5ca22d1b6a8fc478977 Mon Sep 17 00:00:00 2001 From: youngca Date: Mon, 11 Jan 2016 15:50:07 -0500 Subject: [PATCH 054/644] Use batchDraw when drawing the stage, remove unneeded events, only draw the hit when it's needed. --- support/client/lib/vwf/view/kineticjs.js | 59 ++++++++++++++++++------ 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 72163131e..e19f11684 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -302,7 +302,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], node.kineticObj.on( "dragstart", function( evt ) { var eData = processEvent( evt, node, false ); - viewDriver.kernel.fireEvent( node.ID, 'dragStart', eData.eventData ); + //viewDriver.kernel.fireEvent( node.ID, 'dragStart', eData.eventData ); var xPos = viewDriver.state.getProperty( node.kineticObj, "x" ); var yPos = viewDriver.state.getProperty( node.kineticObj, "y" ); @@ -317,7 +317,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var eData = processEvent( evt, node, false ); tapHold.moved( node, eData.eventData[0] ); - viewDriver.kernel.fireEvent( node.ID, 'dragMove', eData.eventData ); + //viewDriver.kernel.fireEvent( node.ID, 'dragMove', eData.eventData ); activelyDrawing = false; if ( node.kineticObj.mouseDragging ) { @@ -330,7 +330,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], node.kineticObj.on( "dragend", function( evt ) { var eData = processEvent( evt, node, false ); - viewDriver.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); + //viewDriver.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); activelyDrawing = false; node.kineticObj.mouseDragging = false; @@ -453,7 +453,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var protos = node.prototypes; if ( viewDriver.state.isKineticClass( protos, [ "kinetic", "stage", "vwf" ] ) ) { var stage = this.state.stage = node.kineticObj; - render( node.kineticObj ); + render( node.kineticObj, false ); } }, @@ -480,7 +480,9 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], viewDriver.kernel.getProperty( childID, "supportMouseEvents" ); viewDriver.kernel.getProperty( childID, "supportTouchEvents" ); - render( node.kineticObj ); + if ( node.kineticObj.isVisible() ) { + render( node.kineticObj, false ); + } } }, @@ -489,7 +491,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], deletedNode: function( nodeID ) { for ( var id in viewDriver.state.stages ) { - renderScene( viewDriver.state.stages[ id ], true ); + renderScene( viewDriver.state.stages[ id ], false ); } }, @@ -693,6 +695,16 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], swipe.listenForSwipes( methodParameters[0] ); break; + case "enableLayerHitGraph": + var layers = methodParameters[ 0 ]; + for ( var id in layers ) { + var layer = this.state.nodes[ nodeID ]; + if ( layer && ( layer.nodeType === "Layer" ) && layer.kineticObj ) { + ( layers[ id ] ? layer.kineticObj.enableHitGraph() : layer.kineticObj.disableHitGraph() ); + } + } + break; + } } @@ -823,26 +835,43 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } - for ( var id in viewDriver.state.stages ){ - renderScene( viewDriver.state.stages[ id ] ); + for ( var id in viewDriver.state.stages ) { + renderScene( viewDriver.state.stages[ id ], false, true ); } } - function renderScene( stage, force ) { + function renderScene( stage, force, drawHit ) { //window.requestAnimationFrame( renderScene( stage ) ); if ( stage && !activelyDrawing ) { - //stage.batchDraw(); - render( stage, force ); + //var now = Date.now(); + //if ( ( ( ( now - lastRenderTime ) > renderTimeout ) || force ) ) { + //stage.batchDraw(); + if ( stage.batchDraw instanceof Function ) { + batchRender( stage, force ); + } else { + render( stage, force, drawHit ); + } + //lastRenderTime = now; + //} } } - function render( kineticObj, force ) { + function render( kineticObj, force, drawHit ) { var now = Date.now(); if ( kineticObj && ( ( ( now - lastRenderTime ) > renderTimeout ) || force ) ) { - kineticObj.draw(); + ( drawHit ? kineticObj.draw() : kineticObj.drawScene() ); + //kineticObj.draw(); lastRenderTime = now; } } + + function batchRender( kineticObj, force ) { + var now = Date.now(); + if ( kineticObj && ( ( ( now - lastRenderTime ) > renderTimeout ) || force ) ) { + kineticObj.batchDraw(); + lastRenderTime = now; + } + } function processEvent( e, node, propagate ) { var returnData = { eventData: undefined, eventNodeData: undefined }; @@ -1147,8 +1176,8 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], console.info( ' === Nodes listening and visibility states ===' ); for(var key in viewDriver.state.nodes) { var kNode = viewDriver.state.nodes[ key ]; - var listening = ( kNode.kineticObj.listening instanceof Function ? kNode.kineticObj.listening() : undefined ); - var visible = ( kNode.kineticObj.visible instanceof Function ? kNode.kineticObj.visible() : undefined ); + var listening = ( kNode.kineticObj.isListening instanceof Function ? kNode.kineticObj.isListening() : undefined ); + var visible = ( kNode.kineticObj.isVisible instanceof Function ? kNode.kineticObj.isVisible() : undefined ); console.info( ' Node: ' + kNode.kineticObj.id() + ', listening: ' + listening + ', visibility: ' + visible ); } console.info( ' === End ===' ); From c577655c0fe98e006c32be46f9577c071b5177b0 Mon Sep 17 00:00:00 2001 From: David Easter Date: Tue, 12 Jan 2016 02:31:53 -0500 Subject: [PATCH 055/644] Support `hitGraphEnabled` for Layers --- support/client/lib/vwf/model/kineticjs.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index 0b7248b3d..4f56bdaca 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -746,6 +746,10 @@ define( [ "module", kineticObj.clearBeforeDraw( Boolean( propertyValue ) ); break; + case "hitGraphEnabled": + kineticObj.hitGraphEnabled( Boolean(propertyValue) ); + break; + default: value = undefined; break; From 01e16ad45bb7e848cbd47bdb4d45139e364d41fb Mon Sep 17 00:00:00 2001 From: youngca Date: Thu, 14 Jan 2016 15:05:01 -0500 Subject: [PATCH 056/644] Force an object render under certain property changes or node changes. --- support/client/lib/vwf/view/kineticjs.js | 72 ++++++++++++++++++------ 1 file changed, 56 insertions(+), 16 deletions(-) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index e19f11684..a9c19c161 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -38,8 +38,9 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var activelyDrawing = false; var clearBeforeDraw = false; var lastRenderTime = 0; // last time whole scene was rendered - var renderTimeout = 100; // ms between renders + var renderTimeout = 1000; // ms between renders var mouseDown = false; + var doRenderScene = false; // Object implements tapHold behavior (kineticJS doesn't have a built-in one) var tapHold = { @@ -251,7 +252,11 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], drawUp( node.ID, eData.eventData[0], node, true ); activelyDrawing = false; - render( node.kineticObj, true ); + //render( node.kineticObj, true ); + //batchRender( node.kineticObj, true ); + //doRenderScene = true; + //drawObject( node.kineticObj, true ); + if ( node.kineticObj.mouseDragging ) { viewDriver.kernel.fireEvent( node.ID, 'dragEnd', eData.eventData ); @@ -270,7 +275,10 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // Cancel tapHold event (if any) tapHold.cancel(); activelyDrawing = false; - render( node.kineticObj, true ); + //render( node.kineticObj, true ); + //drawObject( node.kineticObj, false ); + //batchRender( node.kineticObj, true ); + //doRenderScene = true; viewDriver.kernel.fireEvent( node.ID, 'pointerClick', eData.eventData ); } ); @@ -281,7 +289,9 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // Cancel tapHold event (if any) tapHold.cancel(); activelyDrawing = false; - render( node.kineticObj, true ); + //drawObject( node.kineticObj, false ); + //batchRender( node.kineticObj, true ); + //doRenderScene = true; viewDriver.kernel.fireEvent( node.ID, 'pointerDoubleClick', eData.eventData ); } ); @@ -377,7 +387,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], activelyDrawing = true; } - //swipe.swipedAcross( node ); + swipe.swipedAcross( node ); } ); node.kineticObj.on( "touchend", function( evt ) { @@ -389,7 +399,11 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], drawUp( node.ID, eData.eventData[0], node, true ); activelyDrawing = false; - render( node.kineticObj, true ); + //render( node.kineticObj, true ); + //batchRender( node.kineticObj, true ); + //doRenderScene = true; + //drawObject( node.kineticObj, true ); + } ); node.kineticObj.on( "tap", function( evt ) { @@ -401,7 +415,10 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], //viewDriver.kernel.dispatchEvent( node.ID, "tap", eData.eventData, eData.eventNodeData ); viewDriver.kernel.fireEvent( node.ID, 'tap', eData.eventData ); - render( node.kineticObj, true ); + //render( node.kineticObj, true ); + //batchRender( node.kineticObj, true ); + //drawObject( node.kineticObj, false ); + //doRenderScene = true; } ); node.kineticObj.on( "dbltap", function( evt ) { @@ -413,7 +430,10 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], //viewDriver.kernel.dispatchEvent( node.ID, "dragStart", eData.eventData, eData.eventNodeData ); viewDriver.kernel.fireEvent( node.ID, 'doubleTap', eData.eventData ); - render( node.kineticObj, true ); + //render( node.kineticObj, true ); + ///batchRender( node.kineticObj, true ); + //drawObject( node.kineticObj, false ); + //doRenderScene = true; } ); } @@ -480,8 +500,9 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], viewDriver.kernel.getProperty( childID, "supportMouseEvents" ); viewDriver.kernel.getProperty( childID, "supportTouchEvents" ); - if ( node.kineticObj.isVisible() ) { - render( node.kineticObj, false ); + if ( node.kineticObj.isVisible() && !activelyDrawing ) { + drawObject( node.kineticObj, false ); + //render( node.kineticObj, false ); } } @@ -518,6 +539,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], satProperty: function( nodeID, propertyName, propertyValue ) { var node = this.state.nodes[ nodeID ]; + var drawThis = false; //console.info( "kineticjs(view) satProperty. propertyName: " + propertyName + ", propertyValue: " + propertyValue + ", nodeID: " + nodeID ); @@ -617,16 +639,22 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], "x": node.model.scale.x, "y": node.model.scale.y } ); + //doRenderScene = true; + drawThis = !activelyDrawing; } break; case "scaleX": if ( node.model.scaleX !== undefined ) { kineticObj.scaleX( node.model.scaleX ); + //doRenderScene = true; + drawThis = !activelyDrawing; } break; case "scaleY": if ( node.model.scaleX !== undefined ) { kineticObj.scaleY( node.model.scaleX ); + //doRenderScene = true; + drawThis = !activelyDrawing; } break; @@ -646,7 +674,12 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } } break; + default: + drawThis = !activelyDrawing; + } + if ( drawThis ) { + drawObject( kineticObj, false ); } }, @@ -665,6 +698,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var isStatic = methodParameters.length > 1 ? methodParameters[ 2 ] : false ; setViewProperty( nodeID, prop, value, isStatic ); + doRenderScene = true; break; case "setClientUIState": @@ -829,15 +863,20 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], //if ( viewDriver.kernel.client() === viewDriver.kernel.moniker() ) { // node.model.position.ignoreNextPositionUpdate = true; //} + doRenderScene = true; } } } } - for ( var id in viewDriver.state.stages ) { - renderScene( viewDriver.state.stages[ id ], false, true ); - } + doRenderScene = !viewDriver.state[ "renderOverride" ] && ( doRenderScene || ( ( Date.now() - lastRenderTime ) > renderTimeout) ); + + if ( doRenderScene ) { + for ( var id in viewDriver.state.stages ) { + renderScene( viewDriver.state.stages[ id ], false, true ); + } + } } function renderScene( stage, force, drawHit ) { @@ -853,6 +892,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], } //lastRenderTime = now; //} + doRenderScene = false; } } @@ -1787,13 +1827,13 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // Draw the full layer var layer = findLayer( kineticObject ); if ( layer ) { - layer.draw(); + layer.drawScene(); } else { // Should never happen - object should always be a descendent of a layer - kineticObject.draw(); + kineticObject.drawScene(); } } else { - kineticObject.draw(); + kineticObject.drawScene(); } } From aad6f70a9d9a83751db1c3d0e09a06fe978d02ca Mon Sep 17 00:00:00 2001 From: youngca Date: Mon, 18 Jan 2016 07:52:47 -0500 Subject: [PATCH 057/644] Increase timeouts in effort to prevent random restarts. --- support/client/lib/socket.io-0.6.js | 8 ++-- support/client/lib/socket.io.js | 2 +- support/client/lib/vwf.js | 2 +- support/client/lib/vwf/configuration.js | 6 +-- support/client/lib/vwf/view/kineticjs.js | 50 +++++++++++++----------- 5 files changed, 37 insertions(+), 31 deletions(-) diff --git a/support/client/lib/socket.io-0.6.js b/support/client/lib/socket.io-0.6.js index 21203e146..91b1432dc 100644 --- a/support/client/lib/socket.io-0.6.js +++ b/support/client/lib/socket.io-0.6.js @@ -287,7 +287,7 @@ if (typeof window != 'undefined'){ Transport = io.Transport = function(base, options){ this.base = base; this.options = { - timeout: 15000 // based on heartbeat interval default + timeout: 300000 // based on heartbeat interval default }; io.util.merge(this.options, options); }; @@ -1480,13 +1480,13 @@ if (typeof window != 'undefined'){ transports: ['websocket', 'flashsocket', 'htmlfile', 'xhr-multipart', 'xhr-polling', 'jsonp-polling'], transportOptions: { 'xhr-polling': { - timeout: 25000 // based on polling duration default + timeout: 60000 // based on polling duration default }, 'jsonp-polling': { - timeout: 25000 + timeout: 60000 } }, - connectTimeout: 5000, + connectTimeout: 15000, tryTransportsOnConnectTimeout: true, reconnect: true, reconnectionDelay: 500, diff --git a/support/client/lib/socket.io.js b/support/client/lib/socket.io.js index 6ea5dd0a2..27e475b79 100644 --- a/support/client/lib/socket.io.js +++ b/support/client/lib/socket.io.js @@ -1516,7 +1516,7 @@ var io = ('undefined' === typeof module ? {} : module.exports); , document: 'document' in global ? document : false , resource: 'socket.io' , transports: io.transports - , 'connect timeout': 10000 + , 'connect timeout': 30000 , 'try multiple transports': true , 'reconnect': true , 'reconnection delay': 500 diff --git a/support/client/lib/vwf.js b/support/client/lib/vwf.js index f4e52c242..27b74abbe 100644 --- a/support/client/lib/vwf.js +++ b/support/client/lib/vwf.js @@ -879,7 +879,7 @@ // timeout is controlled by the server.) transportOptions: { - "websocket": { timeout: 90000 }, + "websocket": { timeout: 600000 }, }, } ); diff --git a/support/client/lib/vwf/configuration.js b/support/client/lib/vwf/configuration.js index b218bd533..b1ac2a8ab 100644 --- a/support/client/lib/vwf/configuration.js +++ b/support/client/lib/vwf/configuration.js @@ -174,13 +174,13 @@ define( function() { "randomize-ids": false, // randomize IDs to discourage assumptions about ID allocation "humanize-ids": false, // append recognizable strings to node IDs "preserve-script-closures": false, // retain method/event closures by not serializing functions (breaks replication, persistence) - "load-timeout": 10, // resource load timeout in seconds + "load-timeout": 60, // resource load timeout in seconds }, /// Changes for production environments. production: { - "load-timeout": 60, + "load-timeout": 120, }, /// Changes for development environments. @@ -189,7 +189,7 @@ define( function() { "log-level": "info", "randomize-ids": true, "humanize-ids": true, - "load-timeout": 30, + "load-timeout": 120, }, /// Changes for testing environments. diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index a9c19c161..d13db483d 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -60,7 +60,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], }, "moved": function( node, position ) { if ( node === this.node ) { - console.info( " tapHold moved for node: " + this.node.ID + " at position: [ " + position.client[0] + ", " + position.client[1] + " ], timerId = " + this.timerId ); + //console.info( " tapHold moved for node: " + this.node.ID + " at position: [ " + position.client[0] + ", " + position.client[1] + " ], timerId = " + this.timerId ); if ( this.timerId ) { var deltaPos = [ ( position.client[0] - this.initialPosition[0] ), ( position.client[1] - this.initialPosition[1] ) ]; @@ -73,7 +73,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], }, "cancel": function() { if ( this.timerId ) { - console.info( " Cancel tapHold for node: " + this.node.ID ); + //console.info( " Cancel tapHold for node: " + this.node.ID ); clearTimeout( this.timerId ); } this.node = null; @@ -97,7 +97,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], return found; }, "registerForTapHoldEvents": function( protoFilters ) { - console.info( " Registering for tapHold events for: "); + //console.info( " Registering for tapHold events for: "); for ( var i = 0; i < protoFilters.length; i++ ) { console.info( i + ". " + protoFilters[i] ); } @@ -114,7 +114,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], function fireTapHold() { if ( tapHold.node ) { - console.info( " tapHold event firing for node: " + tapHold.node.ID ); + //console.info( " tapHold event firing for node: " + tapHold.node.ID ); viewDriver.kernel.fireEvent( tapHold.node.ID, 'tapHold', [ tapHold.initialPosition ] ); tapHold.cancel(); } @@ -127,7 +127,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], "touchStartIsTap": null, "swipedAcross": function( node, isTouchStart, eventData ) { if ( this.isListening && this.isSwipe( node ) ) { - console.info( " swiped across node: " + node.ID ); + //console.info( " swiped across node: " + node.ID ); if ( isTouchStart && this.touchStartIsTap ) { viewDriver.kernel.fireEvent( node.ID, 'tap', eventData ); } else { @@ -156,10 +156,10 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], return found; }, "registerForSwipeEvents": function( protoFilters ) { - console.info( " Registering for swipe events for: "); - for ( var i = 0; i < protoFilters.length; i++ ) { - console.info( i + ". " + protoFilters[i] ); - } + //console.info( " Registering for swipe events for: "); + //for ( var i = 0; i < protoFilters.length; i++ ) { + // console.info( i + ". " + protoFilters[i] ); + //} this.protoFilter = protoFilters; }, "listenForSwipes": function( params ) { @@ -469,13 +469,13 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], if ( !node ) { return; } - + /* var protos = node.prototypes; if ( viewDriver.state.isKineticClass( protos, [ "kinetic", "stage", "vwf" ] ) ) { var stage = this.state.stage = node.kineticObj; render( node.kineticObj, false ); } - + */ }, initializedNode: function( nodeID, childID, childExtendsID, childImplementsIDs, @@ -499,11 +499,12 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], //vwf_view.kernel.getProperty( childID, "supportTouchEvents" ); viewDriver.kernel.getProperty( childID, "supportMouseEvents" ); viewDriver.kernel.getProperty( childID, "supportTouchEvents" ); - + /* if ( node.kineticObj.isVisible() && !activelyDrawing ) { drawObject( node.kineticObj, false ); //render( node.kineticObj, false ); } + */ } }, @@ -511,9 +512,9 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // -- deletedNode ------------------------------------------------------------------------------ deletedNode: function( nodeID ) { - for ( var id in viewDriver.state.stages ) { - renderScene( viewDriver.state.stages[ id ], false ); - } + //for ( var id in viewDriver.state.stages ) { + // renderScene( viewDriver.state.stages[ id ], false ); + //} }, // -- addedChild ------------------------------------------------------------------------------- @@ -686,7 +687,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], calledMethod: function( nodeID, methodName, methodParameters, methodValue ) { - console.info( "methodName = " + methodName ); + //console.info( "methodName = " + methodName ); if ( this.kernel.client() === this.kernel.moniker() ) { var prop, value, t; @@ -1025,7 +1026,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var modelValue = node.model[ propertyName ].value; if ( modelValue !== undefined ) { viewDriver.state.setProperty( node.kineticObj, propertyName, modelValue ); - console.info( "- deletes node.model and set kineticObject property: "+propertyName+" to: "+modelValue ); + //console.info( "- deletes node.model and set kineticObject property: "+propertyName+" to: "+modelValue ); } } } @@ -1165,7 +1166,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], function addNodeToHierarchy( node ) { - console.info( "addNodeToHierarchy ID: " + node.ID + " parentID: " + node.parentID ); + //console.info( "addNodeToHierarchy ID: " + node.ID + " parentID: " + node.parentID ); if ( node.kineticObj ) { @@ -1209,7 +1210,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], var node = viewDriver.state.nodes[ nodeID ]; var appID = viewDriver.kernel.application(); var drawAndPropagate = false; - var debugOn = true; + var debugOn = false; if ( debugOn ) { console.info( ' ' ); @@ -1827,13 +1828,13 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // Draw the full layer var layer = findLayer( kineticObject ); if ( layer ) { - layer.drawScene(); + layer.batchDraw(); } else { // Should never happen - object should always be a descendent of a layer - kineticObject.drawScene(); + kineticObject.draw(); } } else { - kineticObject.drawScene(); + kineticObject.draw(); } } @@ -1976,6 +1977,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], function deletePrivateNode( fullyDelete ) { var nodeID = drawing_private.drawingObject.id(); + var layer = findLayer( drawing_private.drawingObject ); drawing_private.drawingObject.destroy(); drawing_private.drawingObject = null; if ( viewDriver.state.nodes[ nodeID ] ) { @@ -1987,6 +1989,10 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], drawing_private = {}; private_node = undefined; } + + if ( layer ) { + layer.batchDraw(); + } } }); \ No newline at end of file From af9100dc0fe1fd2a6b047a51c0b761d1469dff4e Mon Sep 17 00:00:00 2001 From: youngca Date: Mon, 18 Jan 2016 10:32:26 -0500 Subject: [PATCH 058/644] Remove the private node's kineticObj from the view/hitgraph when finished drawing, then delete. --- support/client/lib/vwf/model/kineticjs.js | 1 + support/client/lib/vwf/view/kineticjs.js | 1 + 2 files changed, 2 insertions(+) diff --git a/support/client/lib/vwf/model/kineticjs.js b/support/client/lib/vwf/model/kineticjs.js index 4f56bdaca..b470c0fcd 100644 --- a/support/client/lib/vwf/model/kineticjs.js +++ b/support/client/lib/vwf/model/kineticjs.js @@ -1752,6 +1752,7 @@ define( [ "module", var node = this.state.nodes[ nodeID ]; if ( node.kineticObj !== undefined ) { // removes and destroys object + node.kineticObj.remove(); node.kineticObj.destroy(); node.kineticObj = undefined; } diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index d13db483d..66bea4859 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -1978,6 +1978,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], function deletePrivateNode( fullyDelete ) { var nodeID = drawing_private.drawingObject.id(); var layer = findLayer( drawing_private.drawingObject ); + drawing_private.drawingObject.remove(); drawing_private.drawingObject.destroy(); drawing_private.drawingObject = null; if ( viewDriver.state.nodes[ nodeID ] ) { From fbdc49db02c9b467f4f83749750e54dc9ff8ab2d Mon Sep 17 00:00:00 2001 From: youngca Date: Mon, 18 Jan 2016 15:29:06 -0500 Subject: [PATCH 059/644] Detect when mouse button is down as mouse is swiped across a kinetic drawing object. --- support/client/lib/vwf/view/kineticjs.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index 66bea4859..db4345622 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -201,13 +201,16 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], node.kineticObj.on( "mouseout", function( evt ) { var eData = processEvent( evt, node, false ); - viewDriver.kernel.fireEvent( node.ID, 'pointerOut', eData.eventData ); + //viewDriver.kernel.fireEvent( node.ID, 'pointerOut', eData.eventData ); + if ( mouseDown || ( evt.evt.buttons ) ) { + swipe.swipedAcross( node ); + } } ); node.kineticObj.on( "mouseenter", function( evt ) { var eData = processEvent( evt, node, false ); - if ( mouseDown ) { + if ( mouseDown || ( evt.evt.buttons ) ) { swipe.swipedAcross( node ); } } ); @@ -215,7 +218,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], node.kineticObj.on( "mouseleave", function( evt ) { var eData = processEvent( evt, node, false ); - if ( mouseDown ) { + if ( mouseDown || ( evt.evt.buttons ) ) { swipe.swipedAcross( node ); } @@ -415,6 +418,7 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], //viewDriver.kernel.dispatchEvent( node.ID, "tap", eData.eventData, eData.eventNodeData ); viewDriver.kernel.fireEvent( node.ID, 'tap', eData.eventData ); + swipe.swipedAcross( node, true, eData.eventData ); //render( node.kineticObj, true ); //batchRender( node.kineticObj, true ); //drawObject( node.kineticObj, false ); From b28e3357d571d793155a6094dce1e126be6b0bf6 Mon Sep 17 00:00:00 2001 From: youngca Date: Mon, 18 Jan 2016 16:23:01 -0500 Subject: [PATCH 060/644] Do not set width or height for circles and ellipses, only radius. Fixes issue of circle resizing when another client joins. --- support/client/lib/vwf/view/kineticjs.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/support/client/lib/vwf/view/kineticjs.js b/support/client/lib/vwf/view/kineticjs.js index db4345622..ab9af0be6 100644 --- a/support/client/lib/vwf/view/kineticjs.js +++ b/support/client/lib/vwf/view/kineticjs.js @@ -1818,9 +1818,16 @@ define( [ "module", "vwf/view", "jquery", "vwf/utility", "vwf/utility/color" ], // Ensure that `radius` is the last attribute since `width` or `height` will override // `radius` if both are provided. - var radius = properties.attributes.radius; - delete properties.attributes.radius; - properties.attributes.radius = radius; + switch ( kineticNode.className ) { + case "Circle": + case "Ellipse": + delete properties.attributes.height; + delete properties.attributes.width; + var radius = properties.attributes.radius; + delete properties.attributes.radius; + properties.attributes.radius = radius; + break; + } } From 260185d30b9ea61c10968554690ff951ac546451 Mon Sep 17 00:00:00 2001 From: David Easter Date: Mon, 18 Jan 2016 12:44:34 -0500 Subject: [PATCH 061/644] Add unminified `kinetic.js` The existing `kinetic.min.js` is from the KineticJS commit d8a429a, identified as KineticJS: v5.1.1, 2014-06-10. This `kinetic.js` is the matching unminified version. --- .../client/lib/vwf/model/kinetic/kinetic.js | 14828 ++++++++++++++++ 1 file changed, 14828 insertions(+) create mode 100644 support/client/lib/vwf/model/kinetic/kinetic.js diff --git a/support/client/lib/vwf/model/kinetic/kinetic.js b/support/client/lib/vwf/model/kinetic/kinetic.js new file mode 100644 index 000000000..13f0839af --- /dev/null +++ b/support/client/lib/vwf/model/kinetic/kinetic.js @@ -0,0 +1,14828 @@ + +/* + * KineticJS JavaScript Framework v5.1.1 + * http://www.kineticjs.com/ + * Copyright 2013, Eric Rowell + * Licensed under the MIT or GPL Version 2 licenses. + * Date: 2014-06-10 + * + * Copyright (C) 2011 - 2013 by Eric Rowell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +/** + * @namespace Kinetic + */ +/*jshint -W079, -W020*/ +var Kinetic = {}; +(function(root) { + var PI_OVER_180 = Math.PI / 180; + + Kinetic = { + // public + version: '5.1.1', + + // private + stages: [], + idCounter: 0, + ids: {}, + names: {}, + shapes: {}, + listenClickTap: false, + inDblClickWindow: false, + + // configurations + enableTrace: false, + traceArrMax: 100, + dblClickWindow: 400, + /** + * Global pixel ratio configuration. KineticJS automatically detect pixel ratio of current device. + * But you may override such property, if you want to use your value. + * @property + * @default undefined + * @memberof Kinetic + * @example + * Kinetic.pixelRatio = 1; + */ + pixelRatio: undefined, + /** + * Drag distance property. If you start to drag a node you may want to wait until pointer is moved to some distance from start point, + * only then start dragging. + * @property + * @default 0 + * @memberof Kinetic + * @example + * Kinetic.dragDistance = 10; + */ + dragDistance : 0, + /** + * Use degree values for angle properties. You may set this property to false if you want to use radiant values. + * @property + * @default true + * @memberof Kinetic + * @example + * node.rotation(45); // 45 degrees + * Kinetic.angleDeg = false; + * node.rotation(Math.PI / 2); // PI/2 radian + */ + angleDeg: true, + /** + * Show different warnings about errors or wrong API usage + * @property + * @default true + * @memberof Kinetic + * @example + * Kinetic.showWarnings = false; + */ + showWarnings : true, + + + + /** + * @namespace Filters + * @memberof Kinetic + */ + Filters: {}, + + /** + * Node constructor. Nodes are entities that can be transformed, layered, + * and have bound events. The stage, layers, groups, and shapes all extend Node. + * @constructor + * @memberof Kinetic + * @abstract + * @param {Object} config + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + */ + Node: function(config) { + this._init(config); + }, + + /** + * Shape constructor. Shapes are primitive objects such as rectangles, + * circles, text, lines, etc. + * @constructor + * @memberof Kinetic + * @augments Kinetic.Node + * @param {Object} config + * @param {String} [config.fill] fill color + * @param {Integer} [config.fillRed] set fill red component + * @param {Integer} [config.fillGreen] set fill green component + * @param {Integer} [config.fillBlue] set fill blue component + * @param {Integer} [config.fillAlpha] set fill alpha component + * @param {Image} [config.fillPatternImage] fill pattern image + * @param {Number} [config.fillPatternX] + * @param {Number} [config.fillPatternY] + * @param {Object} [config.fillPatternOffset] object with x and y component + * @param {Number} [config.fillPatternOffsetX] + * @param {Number} [config.fillPatternOffsetY] + * @param {Object} [config.fillPatternScale] object with x and y component + * @param {Number} [config.fillPatternScaleX] + * @param {Number} [config.fillPatternScaleY] + * @param {Number} [config.fillPatternRotation] + * @param {String} [config.fillPatternRepeat] can be "repeat", "repeat-x", "repeat-y", or "no-repeat". The default is "no-repeat" + * @param {Object} [config.fillLinearGradientStartPoint] object with x and y component + * @param {Number} [config.fillLinearGradientStartPointX] + * @param {Number} [config.fillLinearGradientStartPointY] + * @param {Object} [config.fillLinearGradientEndPoint] object with x and y component + * @param {Number} [config.fillLinearGradientEndPointX] + * @param {Number} [config.fillLinearGradientEndPointY] + * @param {Array} [config.fillLinearGradientColorStops] array of color stops + * @param {Object} [config.fillRadialGradientStartPoint] object with x and y component + * @param {Number} [config.fillRadialGradientStartPointX] + * @param {Number} [config.fillRadialGradientStartPointY] + * @param {Object} [config.fillRadialGradientEndPoint] object with x and y component + * @param {Number} [config.fillRadialGradientEndPointX] + * @param {Number} [config.fillRadialGradientEndPointY] + * @param {Number} [config.fillRadialGradientStartRadius] + * @param {Number} [config.fillRadialGradientEndRadius] + * @param {Array} [config.fillRadialGradientColorStops] array of color stops + * @param {Boolean} [config.fillEnabled] flag which enables or disables the fill. The default value is true + * @param {String} [config.fillPriority] can be color, linear-gradient, radial-graident, or pattern. The default value is color. The fillPriority property makes it really easy to toggle between different fill types. For example, if you want to toggle between a fill color style and a fill pattern style, simply set the fill property and the fillPattern properties, and then use setFillPriority('color') to render the shape with a color fill, or use setFillPriority('pattern') to render the shape with the pattern fill configuration + * @param {String} [config.stroke] stroke color + * @param {Integer} [config.strokeRed] set stroke red component + * @param {Integer} [config.strokeGreen] set stroke green component + * @param {Integer} [config.strokeBlue] set stroke blue component + * @param {Integer} [config.strokeAlpha] set stroke alpha component + * @param {Number} [config.strokeWidth] stroke width + * @param {Boolean} [config.strokeScaleEnabled] flag which enables or disables stroke scale. The default is true + * @param {Boolean} [config.strokeEnabled] flag which enables or disables the stroke. The default value is true + * @param {String} [config.lineJoin] can be miter, round, or bevel. The default + * is miter + * @param {String} [config.lineCap] can be butt, round, or sqare. The default + * is butt + * @param {String} [config.shadowColor] + * @param {Integer} [config.shadowRed] set shadow color red component + * @param {Integer} [config.shadowGreen] set shadow color green component + * @param {Integer} [config.shadowBlue] set shadow color blue component + * @param {Integer} [config.shadowAlpha] set shadow color alpha component + * @param {Number} [config.shadowBlur] + * @param {Object} [config.shadowOffset] object with x and y component + * @param {Number} [config.shadowOffsetX] + * @param {Number} [config.shadowOffsetY] + * @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number + * between 0 and 1 + * @param {Boolean} [config.shadowEnabled] flag which enables or disables the shadow. The default value is true + * @param {Array} [config.dash] + * @param {Boolean} [config.dashEnabled] flag which enables or disables the dashArray. The default value is true + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var customShape = new Kinetic.Shape({ + * x: 5, + * y: 10, + * fill: 'red', + * // a Kinetic.Canvas renderer is passed into the drawFunc function + * drawFunc: function(context) { + * context.beginPath(); + * context.moveTo(200, 50); + * context.lineTo(420, 80); + * context.quadraticCurveTo(300, 100, 260, 170); + * context.closePath(); + * context.fillStrokeShape(this); + * } + *}); + */ + Shape: function(config) { + this.__init(config); + }, + + /** + * Container constructor.  Containers are used to contain nodes or other containers + * @constructor + * @memberof Kinetic + * @augments Kinetic.Node + * @abstract + * @param {Object} config + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * * @param {Object} [config.clip] set clip + * @param {Number} [config.clipX] set clip x + * @param {Number} [config.clipY] set clip y + * @param {Number} [config.clipWidth] set clip width + * @param {Number} [config.clipHeight] set clip height + + */ + Container: function(config) { + this.__init(config); + }, + + /** + * Stage constructor. A stage is used to contain multiple layers + * @constructor + * @memberof Kinetic + * @augments Kinetic.Container + * @param {Object} config + * @param {String|DomElement} config.container Container id or DOM element + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * @example + * var stage = new Kinetic.Stage({ + * width: 500, + * height: 800, + * container: 'containerId' + * }); + */ + Stage: function(config) { + this.___init(config); + }, + + /** + * BaseLayer constructor. + * @constructor + * @memberof Kinetic + * @augments Kinetic.Container + * @param {Object} config + * @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want + * to clear the canvas before each layer draw. The default value is true. + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * * @param {Object} [config.clip] set clip + * @param {Number} [config.clipX] set clip x + * @param {Number} [config.clipY] set clip y + * @param {Number} [config.clipWidth] set clip width + * @param {Number} [config.clipHeight] set clip height + + * @example + * var layer = new Kinetic.Layer(); + */ + BaseLayer: function(config) { + this.___init(config); + }, + + /** + * Layer constructor. Layers are tied to their own canvas element and are used + * to contain groups or shapes. + * @constructor + * @memberof Kinetic + * @augments Kinetic.BaseLayer + * @param {Object} config + * @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want + * to clear the canvas before each layer draw. The default value is true. + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * * @param {Object} [config.clip] set clip + * @param {Number} [config.clipX] set clip x + * @param {Number} [config.clipY] set clip y + * @param {Number} [config.clipWidth] set clip width + * @param {Number} [config.clipHeight] set clip height + + * @example + * var layer = new Kinetic.Layer(); + */ + Layer: function(config) { + this.____init(config); + }, + + /** + * FastLayer constructor. Layers are tied to their own canvas element and are used + * to contain shapes only. If you don't need node nesting, mouse and touch interactions, + * or event pub/sub, you should use FastLayer instead of Layer to create your layers. + * It renders about 2x faster than normal layers. + * @constructor + * @memberof Kinetic + * @augments Kinetic.BaseLayer + * @param {Object} config + * @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want + * to clear the canvas before each layer draw. The default value is true. + * @param {Boolean} [config.visible] + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * * @param {Object} [config.clip] set clip + * @param {Number} [config.clipX] set clip x + * @param {Number} [config.clipY] set clip y + * @param {Number} [config.clipWidth] set clip width + * @param {Number} [config.clipHeight] set clip height + + * @example + * var layer = new Kinetic.FastLayer(); + */ + FastLayer: function(config) { + this.____init(config); + }, + + /** + * Group constructor. Groups are used to contain shapes or other groups. + * @constructor + * @memberof Kinetic + * @augments Kinetic.Container + * @param {Object} config + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.visible] + * @param {Boolean} [config.listening] whether or not the node is listening for events + * @param {String} [config.id] unique id + * @param {String} [config.name] non-unique name + * @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1 + * @param {Object} [config.scale] set scale + * @param {Number} [config.scaleX] set scale x + * @param {Number} [config.scaleY] set scale y + * @param {Number} [config.rotation] rotation in degrees + * @param {Object} [config.offset] offset from center point and rotation point + * @param {Number} [config.offsetX] set offset x + * @param {Number} [config.offsetY] set offset y + * @param {Boolean} [config.draggable] makes the node draggable. When stages are draggable, you can drag and drop + * the entire stage by dragging any portion of the stage + * @param {Number} [config.dragDistance] + * @param {Function} [config.dragBoundFunc] + * * @param {Object} [config.clip] set clip + * @param {Number} [config.clipX] set clip x + * @param {Number} [config.clipY] set clip y + * @param {Number} [config.clipWidth] set clip width + * @param {Number} [config.clipHeight] set clip height + + * @example + * var group = new Kinetic.Group(); + */ + Group: function(config) { + this.___init(config); + }, + + /** + * returns whether or not drag and drop is currently active + * @method + * @memberof Kinetic + */ + isDragging: function() { + var dd = Kinetic.DD; + + // if DD is not included with the build, then + // drag and drop is not even possible + if (!dd) { + return false; + } + // if DD is included with the build + else { + return dd.isDragging; + } + }, + /** + * returns whether or not a drag and drop operation is ready, but may + * not necessarily have started + * @method + * @memberof Kinetic + */ + isDragReady: function() { + var dd = Kinetic.DD; + + // if DD is not included with the build, then + // drag and drop is not even possible + if (!dd) { + return false; + } + // if DD is included with the build + else { + return !!dd.node; + } + }, + _addId: function(node, id) { + if(id !== undefined) { + this.ids[id] = node; + } + }, + _removeId: function(id) { + if(id !== undefined) { + delete this.ids[id]; + } + }, + _addName: function(node, name) { + if(name !== undefined) { + if(this.names[name] === undefined) { + this.names[name] = []; + } + this.names[name].push(node); + } + }, + _removeName: function(name, _id) { + if(name !== undefined) { + var nodes = this.names[name]; + if(nodes !== undefined) { + for(var n = 0; n < nodes.length; n++) { + var no = nodes[n]; + if(no._id === _id) { + nodes.splice(n, 1); + } + } + if(nodes.length === 0) { + delete this.names[name]; + } + } + } + }, + getAngle: function(angle) { + return this.angleDeg ? angle * PI_OVER_180 : angle; + }, + _parseUA: function(userAgent) { + var ua = userAgent.toLowerCase(), + // jQuery UA regex + match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || + /(webkit)[ \/]([\w.]+)/.exec( ua ) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || + /(msie) ([\w.]+)/.exec( ua ) || + ua.indexOf('compatible') < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || + [], + + // adding mobile flag as well + mobile = !!(userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)), + ieMobile = !!(userAgent.match(/IEMobile/i)); + + return { + browser: match[ 1 ] || '', + version: match[ 2 ] || '0', + + // adding mobile flab + mobile: mobile, + ieMobile: ieMobile // If this is true (i.e., WP8), then Kinetic touch events are executed instead of equivalent Kinetic mouse events + }; + }, + // user agent + UA: undefined + }; + + Kinetic.UA = Kinetic._parseUA((root.navigator && root.navigator.userAgent) || ''); + +})(this); + +// Uses Node, AMD or browser globals to create a module. + +// If you want something that will work in other stricter CommonJS environments, +// or if you need to create a circular dependency, see commonJsStrict.js + +// Defines a module "returnExports" that depends another module called "b". +// Note that the name of the module is implied by the file name. It is best +// if the file name and the exported global have matching names. + +// If the 'b' module also uses this type of boilerplate, then +// in the browser, it will create a global .b that is used below. + +// If you do not want to support the browser global path, then you +// can remove the `root` use and the passing `this` as the first arg to +// the top function. + +// if the module has no dependencies, the above pattern can be simplified to +( function(root, factory) { + if( typeof exports === 'object') { + var KineticJS = factory(); + // runtime-check for browserify + if(global.window === global) { + Kinetic.document = global.document; + Kinetic.window = global; + } else { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like enviroments that support module.exports, + // like Node. + var Canvas = require('canvas'); + var jsdom = require('jsdom').jsdom; + var doc = jsdom(''); + + Kinetic.document = doc; + Kinetic.window = Kinetic.document.createWindow(); + Kinetic.window.Image = Canvas.Image; + Kinetic._nodeCanvas = Canvas; + } + + Kinetic.root = root; + module.exports = KineticJS; + return; + } + else if( typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(factory); + } + Kinetic.document = document; + Kinetic.window = window; + Kinetic.root = root; + +}(this, function() { + + // Just return a value to define the module export. + // This example returns an object, but the module + // can return a function as the exported value. + return Kinetic; +})); +;(function() { + /** + * Collection constructor. Collection extends + * Array. This class is used in conjunction with {@link Kinetic.Container#get} + * @constructor + * @memberof Kinetic + */ + Kinetic.Collection = function() { + var args = [].slice.call(arguments), length = args.length, i = 0; + + this.length = length; + for(; i < length; i++) { + this[i] = args[i]; + } + return this; + }; + Kinetic.Collection.prototype = []; + /** + * iterate through node array and run a function for each node. + * The node and index is passed into the function + * @method + * @memberof Kinetic.Collection.prototype + * @param {Function} func + * @example + * // get all nodes with name foo inside layer, and set x to 10 for each + * layer.get('.foo').each(function(shape, n) { + * shape.setX(10); + * }); + */ + Kinetic.Collection.prototype.each = function(func) { + for(var n = 0; n < this.length; n++) { + func(this[n], n); + } + }; + /** + * convert collection into an array + * @method + * @memberof Kinetic.Collection.prototype + */ + Kinetic.Collection.prototype.toArray = function() { + var arr = [], + len = this.length, + n; + + for(n = 0; n < len; n++) { + arr.push(this[n]); + } + return arr; + }; + /** + * convert array into a collection + * @method + * @memberof Kinetic.Collection + * @param {Array} arr + */ + Kinetic.Collection.toCollection = function(arr) { + var collection = new Kinetic.Collection(), + len = arr.length, + n; + + for(n = 0; n < len; n++) { + collection.push(arr[n]); + } + return collection; + }; + + // map one method by it's name + Kinetic.Collection._mapMethod = function(methodName) { + Kinetic.Collection.prototype[methodName] = function() { + var len = this.length, + i; + + var args = [].slice.call(arguments); + for(i = 0; i < len; i++) { + this[i][methodName].apply(this[i], args); + } + + return this; + }; + }; + + Kinetic.Collection.mapMethods = function(constructor) { + var prot = constructor.prototype; + for(var methodName in prot) { + Kinetic.Collection._mapMethod(methodName); + } + }; + + /* + * Last updated November 2011 + * By Simon Sarris + * www.simonsarris.com + * sarris@acm.org + * + * Free to use and distribute at will + * So long as you are nice to people, etc + */ + + /* + * The usage of this class was inspired by some of the work done by a forked + * project, KineticJS-Ext by Wappworks, which is based on Simon's Transform + * class. Modified by Eric Rowell + */ + + /** + * Transform constructor + * @constructor + * @param {Array} Optional six-element matrix + * @memberof Kinetic + */ + Kinetic.Transform = function(m) { + this.m = (m && m.slice()) || [1, 0, 0, 1, 0, 0]; + }; + + Kinetic.Transform.prototype = { + /** + * Copy Kinetic.Transform object + * @method + * @memberof Kinetic.Transform.prototype + * @returns {Kinetic.Transform} + */ + copy: function() { + return new Kinetic.Transform(this.m); + }, + /** + * Transform point + * @method + * @memberof Kinetic.Transform.prototype + * @param {Object} 2D point(x, y) + * @returns {Object} 2D point(x, y) + */ + point: function(p) { + var m = this.m; + return { + x: m[0] * p.x + m[2] * p.y + m[4], + y: m[1] * p.x + m[3] * p.y + m[5] + }; + }, + /** + * Apply translation + * @method + * @memberof Kinetic.Transform.prototype + * @param {Number} x + * @param {Number} y + * @returns {Kinetic.Transform} + */ + translate: function(x, y) { + this.m[4] += this.m[0] * x + this.m[2] * y; + this.m[5] += this.m[1] * x + this.m[3] * y; + return this; + }, + /** + * Apply scale + * @method + * @memberof Kinetic.Transform.prototype + * @param {Number} sx + * @param {Number} sy + * @returns {Kinetic.Transform} + */ + scale: function(sx, sy) { + this.m[0] *= sx; + this.m[1] *= sx; + this.m[2] *= sy; + this.m[3] *= sy; + return this; + }, + /** + * Apply rotation + * @method + * @memberof Kinetic.Transform.prototype + * @param {Number} rad Angle in radians + * @returns {Kinetic.Transform} + */ + rotate: function(rad) { + var c = Math.cos(rad); + var s = Math.sin(rad); + var m11 = this.m[0] * c + this.m[2] * s; + var m12 = this.m[1] * c + this.m[3] * s; + var m21 = this.m[0] * -s + this.m[2] * c; + var m22 = this.m[1] * -s + this.m[3] * c; + this.m[0] = m11; + this.m[1] = m12; + this.m[2] = m21; + this.m[3] = m22; + return this; + }, + /** + * Returns the translation + * @method + * @memberof Kinetic.Transform.prototype + * @returns {Object} 2D point(x, y) + */ + getTranslation: function() { + return { + x: this.m[4], + y: this.m[5] + }; + }, + /** + * Apply skew + * @method + * @memberof Kinetic.Transform.prototype + * @param {Number} sx + * @param {Number} sy + * @returns {Kinetic.Transform} + */ + skew: function(sx, sy) { + var m11 = this.m[0] + this.m[2] * sy; + var m12 = this.m[1] + this.m[3] * sy; + var m21 = this.m[2] + this.m[0] * sx; + var m22 = this.m[3] + this.m[1] * sx; + this.m[0] = m11; + this.m[1] = m12; + this.m[2] = m21; + this.m[3] = m22; + return this; + }, + /** + * Transform multiplication + * @method + * @memberof Kinetic.Transform.prototype + * @param {Kinetic.Transform} matrix + * @returns {Kinetic.Transform} + */ + multiply: function(matrix) { + var m11 = this.m[0] * matrix.m[0] + this.m[2] * matrix.m[1]; + var m12 = this.m[1] * matrix.m[0] + this.m[3] * matrix.m[1]; + + var m21 = this.m[0] * matrix.m[2] + this.m[2] * matrix.m[3]; + var m22 = this.m[1] * matrix.m[2] + this.m[3] * matrix.m[3]; + + var dx = this.m[0] * matrix.m[4] + this.m[2] * matrix.m[5] + this.m[4]; + var dy = this.m[1] * matrix.m[4] + this.m[3] * matrix.m[5] + this.m[5]; + + this.m[0] = m11; + this.m[1] = m12; + this.m[2] = m21; + this.m[3] = m22; + this.m[4] = dx; + this.m[5] = dy; + return this; + }, + /** + * Invert the matrix + * @method + * @memberof Kinetic.Transform.prototype + * @returns {Kinetic.Transform} + */ + invert: function() { + var d = 1 / (this.m[0] * this.m[3] - this.m[1] * this.m[2]); + var m0 = this.m[3] * d; + var m1 = -this.m[1] * d; + var m2 = -this.m[2] * d; + var m3 = this.m[0] * d; + var m4 = d * (this.m[2] * this.m[5] - this.m[3] * this.m[4]); + var m5 = d * (this.m[1] * this.m[4] - this.m[0] * this.m[5]); + this.m[0] = m0; + this.m[1] = m1; + this.m[2] = m2; + this.m[3] = m3; + this.m[4] = m4; + this.m[5] = m5; + return this; + }, + /** + * return matrix + * @method + * @memberof Kinetic.Transform.prototype + */ + getMatrix: function() { + return this.m; + }, + /** + * set to absolute position via translation + * @method + * @memberof Kinetic.Transform.prototype + * @returns {Kinetic.Transform} + * @author ericdrowell + */ + setAbsolutePosition: function(x, y) { + var m0 = this.m[0], + m1 = this.m[1], + m2 = this.m[2], + m3 = this.m[3], + m4 = this.m[4], + m5 = this.m[5], + yt = ((m0 * (y - m5)) - (m1 * (x - m4))) / ((m0 * m3) - (m1 * m2)), + xt = (x - m4 - (m2 * yt)) / m0; + + return this.translate(xt, yt); + } + }; + + // CONSTANTS + var CANVAS = 'canvas', + CONTEXT_2D = '2d', + OBJECT_ARRAY = '[object Array]', + OBJECT_NUMBER = '[object Number]', + OBJECT_STRING = '[object String]', + PI_OVER_DEG180 = Math.PI / 180, + DEG180_OVER_PI = 180 / Math.PI, + HASH = '#', + EMPTY_STRING = '', + ZERO = '0', + KINETIC_WARNING = 'Kinetic warning: ', + KINETIC_ERROR = 'Kinetic error: ', + RGB_PAREN = 'rgb(', + COLORS = { + aqua: [0,255,255], + lime: [0,255,0], + silver: [192,192,192], + black: [0,0,0], + maroon: [128,0,0], + teal: [0,128,128], + blue: [0,0,255], + navy: [0,0,128], + white: [255,255,255], + fuchsia: [255,0,255], + olive:[128,128,0], + yellow: [255,255,0], + orange: [255,165,0], + gray: [128,128,128], + purple: [128,0,128], + green: [0,128,0], + red: [255,0,0], + pink: [255,192,203], + cyan: [0,255,255], + transparent: [255,255,255,0] + }, + + RGB_REGEX = /rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)/; + + /** + * @namespace Util + * @memberof Kinetic + */ + Kinetic.Util = { + /* + * cherry-picked utilities from underscore.js + */ + _isElement: function(obj) { + return !!(obj && obj.nodeType == 1); + }, + _isFunction: function(obj) { + return !!(obj && obj.constructor && obj.call && obj.apply); + }, + _isObject: function(obj) { + return (!!obj && obj.constructor == Object); + }, + _isArray: function(obj) { + return Object.prototype.toString.call(obj) == OBJECT_ARRAY; + }, + _isNumber: function(obj) { + return Object.prototype.toString.call(obj) == OBJECT_NUMBER; + }, + _isString: function(obj) { + return Object.prototype.toString.call(obj) == OBJECT_STRING; + }, + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. Normally, the throttled function will run + // as much as it can, without ever going more than once per `wait` duration; + // but if you'd like to disable the execution on the leading edge, pass + // `{leading: false}`. To disable execution on the trailing edge, ditto. + _throttle: function(func, wait, options) { + var context, args, result; + var timeout = null; + var previous = 0; + options || (options = {}); + var later = function() { + previous = options.leading === false ? 0 : new Date().getTime(); + timeout = null; + result = func.apply(context, args); + context = args = null; + }; + return function() { + var now = new Date().getTime(); + if (!previous && options.leading === false) previous = now; + var remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0) { + clearTimeout(timeout); + timeout = null; + previous = now; + result = func.apply(context, args); + context = args = null; + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }, + /* + * other utils + */ + _hasMethods: function(obj) { + var names = [], + key; + + for(key in obj) { + if(this._isFunction(obj[key])) { + names.push(key); + } + } + return names.length > 0; + }, + createCanvasElement: function() { + var canvas = Kinetic.document.createElement('canvas'); + canvas.style = canvas.style || {}; + return canvas; + }, + isBrowser: function() { + return (typeof exports !== 'object'); + }, + _isInDocument: function(el) { + while(el = el.parentNode) { + if(el == Kinetic.document) { + return true; + } + } + return false; + }, + _simplifyArray: function(arr) { + var retArr = [], + len = arr.length, + util = Kinetic.Util, + n, val; + + for (n=0; n> 16) & 255, + g: (bigint >> 8) & 255, + b: bigint & 255 + }; + }, + /** + * return random hex color + * @method + * @memberof Kinetic.Util.prototype + */ + getRandomColor: function() { + var randColor = (Math.random() * 0xFFFFFF << 0).toString(16); + while (randColor.length < 6) { + randColor = ZERO + randColor; + } + return HASH + randColor; + }, + /** + * return value with default fallback + * @method + * @memberof Kinetic.Util.prototype + */ + get: function(val, def) { + if (val === undefined) { + return def; + } + else { + return val; + } + }, + /** + * get RGB components of a color + * @method + * @memberof Kinetic.Util.prototype + * @param {String} color + * @example + * // each of the following examples return {r:0, g:0, b:255} + * var rgb = Kinetic.Util.getRGB('blue'); + * var rgb = Kinetic.Util.getRGB('#0000ff'); + * var rgb = Kinetic.Util.getRGB('rgb(0,0,255)'); + */ + getRGB: function(color) { + var rgb; + // color string + if (color in COLORS) { + rgb = COLORS[color]; + return { + r: rgb[0], + g: rgb[1], + b: rgb[2] + }; + } + // hex + else if (color[0] === HASH) { + return this._hexToRgb(color.substring(1)); + } + // rgb string + else if (color.substr(0, 4) === RGB_PAREN) { + rgb = RGB_REGEX.exec(color.replace(/ /g,'')); + return { + r: parseInt(rgb[1], 10), + g: parseInt(rgb[2], 10), + b: parseInt(rgb[3], 10) + }; + } + // default + else { + return { + r: 0, + g: 0, + b: 0 + }; + } + }, + // o1 takes precedence over o2 + _merge: function(o1, o2) { + var retObj = this._clone(o2); + for(var key in o1) { + if(this._isObject(o1[key])) { + retObj[key] = this._merge(o1[key], retObj[key]); + } + else { + retObj[key] = o1[key]; + } + } + return retObj; + }, + cloneObject: function(obj) { + var retObj = {}; + for(var key in obj) { + if(this._isObject(obj[key])) { + retObj[key] = this.cloneObject(obj[key]); + } + else if (this._isArray(obj[key])) { + retObj[key] = this.cloneArray(obj[key]); + } else { + retObj[key] = obj[key]; + } + } + return retObj; + }, + cloneArray: function(arr) { + return arr.slice(0); + }, + _degToRad: function(deg) { + return deg * PI_OVER_DEG180; + }, + _radToDeg: function(rad) { + return rad * DEG180_OVER_PI; + }, + _capitalize: function(str) { + return str.charAt(0).toUpperCase() + str.slice(1); + }, + error: function(str) { + throw new Error(KINETIC_ERROR + str); + }, + warn: function(str) { + /* + * IE9 on Windows7 64bit will throw a JS error + * if we don't use window.console in the conditional + */ + if(Kinetic.root.console && console.warn && Kinetic.showWarnings) { + console.warn(KINETIC_WARNING + str); + } + }, + extend: function(c1, c2) { + for(var key in c2.prototype) { + if(!( key in c1.prototype)) { + c1.prototype[key] = c2.prototype[key]; + } + } + }, + /** + * adds methods to a constructor prototype + * @method + * @memberof Kinetic.Util.prototype + * @param {Function} constructor + * @param {Object} methods + */ + addMethods: function(constructor, methods) { + var key; + + for (key in methods) { + constructor.prototype[key] = methods[key]; + } + }, + _getControlPoints: function(x0, y0, x1, y1, x2, y2, t) { + var d01 = Math.sqrt(Math.pow(x1 - x0, 2) + Math.pow(y1 - y0, 2)), + d12 = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)), + fa = t * d01 / (d01 + d12), + fb = t * d12 / (d01 + d12), + p1x = x1 - fa * (x2 - x0), + p1y = y1 - fa * (y2 - y0), + p2x = x1 + fb * (x2 - x0), + p2y = y1 + fb * (y2 - y0); + + return [p1x ,p1y, p2x, p2y]; + }, + _expandPoints: function(p, tension) { + var len = p.length, + allPoints = [], + n, cp; + + for (n=2; n= Kinetic.traceArrMax) { + traceArr.shift(); + } + }, + /** + * reset canvas context transform + * @method + * @memberof Kinetic.Context.prototype + */ + reset: function() { + var pixelRatio = this.getCanvas().getPixelRatio(); + this.setTransform(1 * pixelRatio, 0, 0, 1 * pixelRatio, 0, 0); + }, + /** + * get canvas + * @method + * @memberof Kinetic.Context.prototype + * @returns {Kinetic.Canvas} + */ + getCanvas: function() { + return this.canvas; + }, + /** + * clear canvas + * @method + * @memberof Kinetic.Context.prototype + * @param {Object} [bounds] + * @param {Number} [bounds.x] + * @param {Number} [bounds.y] + * @param {Number} [bounds.width] + * @param {Number} [bounds.height] + */ + clear: function(bounds) { + var canvas = this.getCanvas(); + + if (bounds) { + this.clearRect(bounds.x || 0, bounds.y || 0, bounds.width || 0, bounds.height || 0); + } + else { + this.clearRect(0, 0, canvas.getWidth(), canvas.getHeight()); + } + }, + _applyLineCap: function(shape) { + var lineCap = shape.getLineCap(); + if(lineCap) { + this.setAttr('lineCap', lineCap); + } + }, + _applyOpacity: function(shape) { + var absOpacity = shape.getAbsoluteOpacity(); + if(absOpacity !== 1) { + this.setAttr('globalAlpha', absOpacity); + } + }, + _applyLineJoin: function(shape) { + var lineJoin = shape.getLineJoin(); + if(lineJoin) { + this.setAttr('lineJoin', lineJoin); + } + }, + setAttr: function(attr, val) { + this._context[attr] = val; + }, + + // context pass through methods + arc: function() { + var a = arguments; + this._context.arc(a[0], a[1], a[2], a[3], a[4], a[5]); + }, + beginPath: function() { + this._context.beginPath(); + }, + bezierCurveTo: function() { + var a = arguments; + this._context.bezierCurveTo(a[0], a[1], a[2], a[3], a[4], a[5]); + }, + clearRect: function() { + var a = arguments; + this._context.clearRect(a[0], a[1], a[2], a[3]); + }, + clip: function() { + this._context.clip(); + }, + closePath: function() { + this._context.closePath(); + }, + createImageData: function() { + var a = arguments; + if(a.length === 2) { + return this._context.createImageData(a[0], a[1]); + } + else if(a.length === 1) { + return this._context.createImageData(a[0]); + } + }, + createLinearGradient: function() { + var a = arguments; + return this._context.createLinearGradient(a[0], a[1], a[2], a[3]); + }, + createPattern: function() { + var a = arguments; + return this._context.createPattern(a[0], a[1]); + }, + createRadialGradient: function() { + var a = arguments; + return this._context.createRadialGradient(a[0], a[1], a[2], a[3], a[4], a[5]); + }, + drawImage: function() { + var a = arguments, + _context = this._context; + + if(a.length === 3) { + _context.drawImage(a[0], a[1], a[2]); + } + else if(a.length === 5) { + _context.drawImage(a[0], a[1], a[2], a[3], a[4]); + } + else if(a.length === 9) { + _context.drawImage(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]); + } + }, + fill: function() { + this._context.fill(); + }, + fillText: function() { + var a = arguments; + this._context.fillText(a[0], a[1], a[2]); + }, + getImageData: function() { + var a = arguments; + return this._context.getImageData(a[0], a[1], a[2], a[3]); + }, + lineTo: function() { + var a = arguments; + this._context.lineTo(a[0], a[1]); + }, + moveTo: function() { + var a = arguments; + this._context.moveTo(a[0], a[1]); + }, + rect: function() { + var a = arguments; + this._context.rect(a[0], a[1], a[2], a[3]); + }, + putImageData: function() { + var a = arguments; + this._context.putImageData(a[0], a[1], a[2]); + }, + quadraticCurveTo: function() { + var a = arguments; + this._context.quadraticCurveTo(a[0], a[1], a[2], a[3]); + }, + restore: function() { + this._context.restore(); + }, + rotate: function() { + var a = arguments; + this._context.rotate(a[0]); + }, + save: function() { + this._context.save(); + }, + scale: function() { + var a = arguments; + this._context.scale(a[0], a[1]); + }, + setLineDash: function() { + var a = arguments, + _context = this._context; + + // works for Chrome and IE11 + if(this._context.setLineDash) { + _context.setLineDash(a[0]); + } + // verified that this works in firefox + else if('mozDash' in _context) { + _context.mozDash = a[0]; + } + // does not currently work for Safari + else if('webkitLineDash' in _context) { + _context.webkitLineDash = a[0]; + } + + // no support for IE9 and IE10 + }, + setTransform: function() { + var a = arguments; + this._context.setTransform(a[0], a[1], a[2], a[3], a[4], a[5]); + }, + stroke: function() { + this._context.stroke(); + }, + strokeText: function() { + var a = arguments; + this._context.strokeText(a[0], a[1], a[2]); + }, + transform: function() { + var a = arguments; + this._context.transform(a[0], a[1], a[2], a[3], a[4], a[5]); + }, + translate: function() { + var a = arguments; + this._context.translate(a[0], a[1]); + }, + _enableTrace: function() { + var that = this, + len = CONTEXT_METHODS.length, + _simplifyArray = Kinetic.Util._simplifyArray, + origSetter = this.setAttr, + n, args; + + // to prevent creating scope function at each loop + var func = function(methodName) { + var origMethod = that[methodName], + ret; + + that[methodName] = function() { + args = _simplifyArray(Array.prototype.slice.call(arguments, 0)); + ret = origMethod.apply(that, arguments); + + that._trace({ + method: methodName, + args: args + }); + + return ret; + }; + }; + // methods + for (n=0; n 255) { + return 255; + } + else if (val < 0) { + return 0; + } + else { + return Math.round(val); + } + }, + alphaComponent: function(val) { + if (val > 1) { + return 1; + } + // chrome does not honor alpha values of 0 + else if (val < 0.0001) { + return 0.0001; + } + else { + return val; + } + } + }; +})();;(function() { + // CONSTANTS + var ABSOLUTE_OPACITY = 'absoluteOpacity', + ABSOLUTE_TRANSFORM = 'absoluteTransform', + BEFORE = 'before', + CHANGE = 'Change', + CHILDREN = 'children', + DOT = '.', + EMPTY_STRING = '', + GET = 'get', + ID = 'id', + KINETIC = 'kinetic', + LISTENING = 'listening', + MOUSEENTER = 'mouseenter', + MOUSELEAVE = 'mouseleave', + NAME = 'name', + SET = 'set', + SHAPE = 'Shape', + SPACE = ' ', + STAGE = 'stage', + TRANSFORM = 'transform', + UPPER_STAGE = 'Stage', + VISIBLE = 'visible', + CLONE_BLACK_LIST = ['id'], + + TRANSFORM_CHANGE_STR = [ + 'xChange.kinetic', + 'yChange.kinetic', + 'scaleXChange.kinetic', + 'scaleYChange.kinetic', + 'skewXChange.kinetic', + 'skewYChange.kinetic', + 'rotationChange.kinetic', + 'offsetXChange.kinetic', + 'offsetYChange.kinetic', + 'transformsEnabledChange.kinetic' + ].join(SPACE); + + + Kinetic.Util.addMethods(Kinetic.Node, { + _init: function(config) { + var that = this; + this._id = Kinetic.idCounter++; + this.eventListeners = {}; + this.attrs = {}; + this._cache = {}; + this._filterUpToDate = false; + this.setAttrs(config); + + // event bindings for cache handling + this.on(TRANSFORM_CHANGE_STR, function() { + this._clearCache(TRANSFORM); + that._clearSelfAndDescendantCache(ABSOLUTE_TRANSFORM); + }); + this.on('visibleChange.kinetic', function() { + that._clearSelfAndDescendantCache(VISIBLE); + }); + this.on('listeningChange.kinetic', function() { + that._clearSelfAndDescendantCache(LISTENING); + }); + this.on('opacityChange.kinetic', function() { + that._clearSelfAndDescendantCache(ABSOLUTE_OPACITY); + }); + }, + _clearCache: function(attr){ + if (attr) { + delete this._cache[attr]; + } + else { + this._cache = {}; + } + }, + _getCache: function(attr, privateGetter){ + var cache = this._cache[attr]; + + // if not cached, we need to set it using the private getter method. + if (cache === undefined) { + this._cache[attr] = privateGetter.call(this); + } + + return this._cache[attr]; + }, + /* + * when the logic for a cached result depends on ancestor propagation, use this + * method to clear self and children cache + */ + _clearSelfAndDescendantCache: function(attr) { + this._clearCache(attr); + + if (this.children) { + this.getChildren().each(function(node) { + node._clearSelfAndDescendantCache(attr); + }); + } + }, + /** + * clear cached canvas + * @method + * @memberof Kinetic.Node.prototype + * @returns {Kinetic.Node} + * @example + * node.clearCache(); + */ + clearCache: function() { + delete this._cache.canvas; + this._filterUpToDate = false; + return this; + }, + /** + * cache node to improve drawing performance, apply filters, or create more accurate + * hit regions + * @method + * @memberof Kinetic.Node.prototype + * @param {Object} config + * @param {Number} [config.x] + * @param {Number} [config.y] + * @param {Number} [config.width] + * @param {Number} [config.height] + * @param {Boolean} [config.drawBorder] when set to true, a red border will be drawn around the cached + * region for debugging purposes + * @returns {Kinetic.Node} + * @example + * // cache a shape with the x,y position of the bounding box at the center and + * // the width and height of the bounding box equal to the width and height of + * // the shape obtained from shape.width() and shape.height() + * image.cache(); + * + * // cache a node and define the bounding box position and size + * node.cache({ + * x: -30, + * y: -30, + * width: 100, + * height: 200 + * }); + * + * // cache a node and draw a red border around the bounding box + * // for debugging purposes + * node.cache({ + * x: -30, + * y: -30, + * width: 100, + * height: 200, + * drawBorder: true + * }); + */ + cache: function(config) { + var conf = config || {}, + x = conf.x || 0, + y = conf.y || 0, + width = conf.width || this.width(), + height = conf.height || this.height(), + drawBorder = conf.drawBorder || false, + layer = this.getLayer(); + if (width === 0 || height === 0) { + Kinetic.Util.warn('Width or height of caching configuration equals 0. Cache is ignored.'); + return; + } + var cachedSceneCanvas = new Kinetic.SceneCanvas({ + pixelRatio: 1, + width: width, + height: height + }), + cachedFilterCanvas = new Kinetic.SceneCanvas({ + pixelRatio: 1, + width: width, + height: height + }), + cachedHitCanvas = new Kinetic.HitCanvas({ + width: width, + height: height + }), + origTransEnabled = this.transformsEnabled(), + origX = this.x(), + origY = this.y(), + sceneContext = cachedSceneCanvas.getContext(), + hitContext = cachedHitCanvas.getContext(); + + cachedHitCanvas.isCache = true; + + this.clearCache(); + + sceneContext.save(); + hitContext.save(); + + // this will draw a red border around the cached box for + // debugging purposes + if (drawBorder) { + sceneContext.save(); + sceneContext.beginPath(); + sceneContext.rect(0, 0, width, height); + sceneContext.closePath(); + sceneContext.setAttr('strokeStyle', 'red'); + sceneContext.setAttr('lineWidth', 5); + sceneContext.stroke(); + sceneContext.restore(); + } + + sceneContext.translate(x * -1, y * -1); + hitContext.translate(x * -1, y * -1); + + // don't need to translate canvas if shape is not added to layer + if (this.nodeType === 'Shape') { + sceneContext.translate(this.x() * -1, this.y() * -1); + hitContext.translate(this.x() * -1, this.y() * -1); + } + + this.drawScene(cachedSceneCanvas, this); + this.drawHit(cachedHitCanvas, this); + + sceneContext.restore(); + hitContext.restore(); + + this._cache.canvas = { + scene: cachedSceneCanvas, + filter: cachedFilterCanvas, + hit: cachedHitCanvas + }; + + return this; + }, + _drawCachedSceneCanvas: function(context) { + context.save(); + this.getLayer()._applyTransform(this, context); + context._applyOpacity(this); + context.drawImage(this._getCachedSceneCanvas()._canvas, 0, 0); + context.restore(); + }, + _getCachedSceneCanvas: function() { + var filters = this.filters(), + cachedCanvas = this._cache.canvas, + sceneCanvas = cachedCanvas.scene, + filterCanvas = cachedCanvas.filter, + filterContext = filterCanvas.getContext(), + len, imageData, n, filter; + + if (filters) { + if (!this._filterUpToDate) { + try { + len = filters.length; + filterContext.clear(); + // copy cached canvas onto filter context + filterContext.drawImage(sceneCanvas._canvas, 0, 0); + imageData = filterContext.getImageData(0, 0, filterCanvas.getWidth(), filterCanvas.getHeight()); + + // apply filters to filter context + for (n=0; n