You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by jb...@apache.org on 2010/08/10 16:18:46 UTC

svn commit: r984026 - in /commons/sandbox/gsoc/2010/scxml-js/trunk/demo/drawing-tool: behaviour/canvas.xml behaviour/node.xml drawing-tool.html

Author: jbeard
Date: Tue Aug 10 14:18:45 2010
New Revision: 984026

URL: http://svn.apache.org/viewvc?rev=984026&view=rev
Log:
Intermediate and broken commit. Have an idea about better way to allocate responsibility among different actors.

Modified:
    commons/sandbox/gsoc/2010/scxml-js/trunk/demo/drawing-tool/behaviour/canvas.xml
    commons/sandbox/gsoc/2010/scxml-js/trunk/demo/drawing-tool/behaviour/node.xml
    commons/sandbox/gsoc/2010/scxml-js/trunk/demo/drawing-tool/drawing-tool.html

Modified: commons/sandbox/gsoc/2010/scxml-js/trunk/demo/drawing-tool/behaviour/canvas.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/gsoc/2010/scxml-js/trunk/demo/drawing-tool/behaviour/canvas.xml?rev=984026&r1=984025&r2=984026&view=diff
==============================================================================
--- commons/sandbox/gsoc/2010/scxml-js/trunk/demo/drawing-tool/behaviour/canvas.xml (original)
+++ commons/sandbox/gsoc/2010/scxml-js/trunk/demo/drawing-tool/behaviour/canvas.xml Tue Aug 10 14:18:45 2010
@@ -35,11 +35,15 @@
 		<data id="svg"/>
 		<data id="api"/>
 		<data id="toolbarStatechart"/>
+		<data id="scaleHandle"/>
+		<data id="rotationHandle"/>
+
 		<data id="tDelta"/>
 		<data id="firstEvent"/>
 		<data id="eventStamp"/>
 		<data id="nodeBeingDrawn"/>
 		<data id="svgNs" expr="'http://www.w3.org/2000/svg'"/>
+		<data id="selectedNodes" expr="[]"/>
 	</datamodel>
 
 	<state id="initial_default">
@@ -51,10 +55,53 @@
 	</state>
 
 	<state id="idle">
-		<transition event="mousedown" target="before_drawing_mode">
+		<transition event="mousedown" target="before_drawing_mode" 
+			cond="!(_event.data.target==scaleHandle || _event.data.target==rotationHandle)">
+
 			<assign location="firstEvent" expr="_event.data"/>
 			<assign location="eventStamp" expr="_event.data"/>
 		</transition>
+		<transition event="mousedown" target="idle" cond="_event.data.target==scaleHandle">
+			<script>
+				//send event to selected guys
+				$(selectedNodes).each(function(n){
+					n["scale_mousedown"](_event.data);
+				});
+			</script>
+		</transition>
+		<transition event="mousedown" target="idle" cond="_event.data.target==rotationHandle">
+			<script>
+				//send event to selected guys
+				$(selectedNodes).each(function(n){
+					n["rotation_mousedown"](_event.data);
+				});
+			</script>
+		</transition>
+
+		<!-- TODO: refactor the following to be static reactions (eventless transitions) -->
+		<transition event="mousemove" target="idle">
+			$(selectedNodes).each(function(n){
+				n["mousemove"](event._data);
+			});
+		</transition>
+		<transition event="CSGROUP_HAS_MOVED" target="idle">
+			<!-- TODO -->
+		</transition>
+		<transition event="OBJ_FINISHED_TRANSFORM" target="idle">
+			<!-- TODO -->
+		</transition>
+		<transition event="OBJ_SELECTED" target="idle">
+			<script>
+				selectedNodes.push(_event.data.target);
+
+				
+			</script>
+		</transition>
+		<transition event="OBJ_DESELECTED" target="idle">
+			<script>
+				selectedNodes.splice(selectedNodes.indexOf(_event.data.target),1);
+			</script>
+		</transition>
 	</state>
 
 	<state id="before_drawing_mode">

Modified: commons/sandbox/gsoc/2010/scxml-js/trunk/demo/drawing-tool/behaviour/node.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/gsoc/2010/scxml-js/trunk/demo/drawing-tool/behaviour/node.xml?rev=984026&r1=984025&r2=984026&view=diff
==============================================================================
--- commons/sandbox/gsoc/2010/scxml-js/trunk/demo/drawing-tool/behaviour/node.xml (original)
+++ commons/sandbox/gsoc/2010/scxml-js/trunk/demo/drawing-tool/behaviour/node.xml Tue Aug 10 14:18:45 2010
@@ -15,27 +15,136 @@
 			return {'dx':dx,'dy':dy};
 		}
 
+
+		function updateTransformHandles(rotationHandle,scaleHandle){
+			var sePtX = cachedBBox.width + cachedBBox.x;
+			var sePtY = cachedBBox.height + cachedBBox.y;
+
+			var sScale = scaleHandle.transform.baseVal.getItem(0);
+			var newM = identity.translate(sePtX,sePtY);
+			sScale.setMatrix(newM);
+
+			var rScale = rotationHandle.transform.baseVal.getItem(0);
+			var newM = identity.translate(sePtX,sePtY);
+			rScale.setMatrix(newM);
+		}
+
+		function getCenterPoint(rawNode){
+			var bbox = rawNode.getBBox();
+			var cPt = {
+				'x': bbox.x + (bbox.width / 2),
+				'y': bbox.y + (bbox.height / 2)
+			}	
+
+			return cPt;
+		}
+
+
+		function  computeRDelta(oldEvent,newEvent,cachedCenterPoint){
+			return _computeRotationAngle(cachedCenterPoint,{x:oldEvent.localX,y:oldEvent.localY},{x:newEvent.localX,y:newEvent.localY});
+		}
+
+		function  _computeRotationAngle(cpt,pt1,pt2){
+			var a1 = _computeAngle(cpt,pt1)
+			var a2 = _computeAngle(cpt,pt2)
+			var angleInDegrees = a2-a1
+			return angleInDegrees; 
+		}
+
+		function  _computeAngle(cpt,pt){
+			var angle=0;
+
+			//put him on the trig circle
+			var signedPt= {
+				x:pt.x-cpt.x,
+				y:pt.y-cpt.y
+			}
+
+			//put him in upper right corner
+			var normalizedPt= {
+				x:Math.abs(signedPt.x), 
+				y:Math.abs(signedPt.y)
+			};
+
+			//compute the angle
+			var angle=Math.abs(Math.atan2(normalizedPt.y, normalizedPt.x));
+
+			//get angle for signed coordinates
+			if(signedPt.x<0 && signedPt.y>=0){
+				angle=Math.PI-angle;
+			}else if(signedPt.x<0 && signedPt.y<0){
+				angle=Math.PI+angle;
+			}else if(signedPt.x>=0 && signedPt.y<0){
+				angle=2*Math.PI-angle;
+			}
+			return angle;
+		}
+
+		function applyTransformToBBox(bbox,matrix){
+			//takes a bbox and a matrix and returns the bbox with the matrix applied to all points
+			var nwX = bbox.x;
+			var nwY = bbox.y;
+			var neX = nwX + bbox.width;
+			var neY = nwY;
+			var swX = nwX;
+			var swY = nwX + bbox.height;
+			var seX = neX;
+			var seY = swY;
+
+			var nw = canvas.createSVGPoint();
+			nw.x = nwX;
+			nw.y + nwY;
+
+			var ne = canvas.createSVGPoint();
+			ne.x = neX;
+			ne.y = neY;
+
+			var sw = canvas.createSVGPoint();
+			sw.x = swX;
+			sw.y = swY;
+
+			var se = canvas.createSVGPoint();
+			se.x = seX;
+			se.y = seY;
+
+			nw = nw.matrixTransform(matrix);
+			ne = ne.matrixTransform(matrix);
+			sw = sw.matrixTransform(matrix);
+			se = se.matrixTransform(matrix);
+
+			var newWidth = Math.abs(ne.x - nw.x);
+			var newHeight = Math.abs(se.y - ne.y);
+
+			return {x:nw.x,y:nw.y,width:newWidth,height:newHeight}
+		}
+
 	]]></script>
 
 	<datamodel>
+		<!-- these are passed in during initialization-->
+		<data id="rawNode"/>
+		<data id="transformModule"/>
+		<data id="scaleHandle"/>
+		<data id="rotationHandle"/>
+
 		<data id="firstEvent"/>
 		<data id="eventStamp"/>
 		<data id="tDelta"/>
-		<data id="rawNode"/>
-		<data id="transformModule"/>
+		<data id="cachedCenterPoint"/>
+		<data id="cachedBBox"/>
 	</datamodel>
 
 	<state id="initial_default">
 		<transition event="init" target="idle">
 			<assign location="rawNode" expr="_event.data.rawNode"/>
 			<assign location="transformModule" expr="_event.data.transformModule"/>
+			<assign location="scaleHandle" expr="_event.data.scaleHandle"/>
+			<assign location="rotationHandle" expr="_event.data.rotationHandle"/>
 		</transition>
 	</state>
 
 	<state id="idle">
-		<transition event="mousedown" target="dragging">
-			<assign location="firstEvent" expr="_event.data"/>
-			<assign location="eventStamp" expr="_event.data"/>
+		<transition event="mousedown" target="before_mode_is_chosen">
 			<script>
 				//prevents the canvas from capturing the event (which would normally bubble up) and drawing another statechart
 				_event.data.stopPropagation();	
@@ -43,6 +152,166 @@
 		</transition>
 	</state>
 
+	<state id="before_mode_is_chosen">
+		<transition event="mousemove" target="selected_history">
+			<assign location="firstEvent" expr="_event.data"/>
+			<assign location="eventStamp" expr="_event.data"/>
+		</transition>
+
+		<transition event="mouseup" target="selected_r"/>
+	</state>
+
+	<state id="selected" initial="scale_mode">
+		<onentry>
+			<script>
+				//showTracker()
+				rawNode.parentNode.statechart["OBJ_SELECTED"]({target:rawNode})
+			</script>
+		</onentry>
+		<onexit>
+			<script>
+				//hideTracker()
+				rawNode.parentNode.statechart["OBJ_DESELECTED"]({target:rawNode})
+			</script>
+		</onexit>
+
+		<transition event="canvas_deselect" target="idle"/>
+
+		<history type="shallow" id="selected_history">
+			<transition target="translating_s"/>
+		</history>
+
+		<state id="scale_mode" initial="translating_s">
+			<state id="selected_s">
+				<transition event="scale_mousedown" target="scaling">
+					<assign location="firstEvent" expr="_event.data"/>
+					<assign location="eventStamp" expr="_event.data"/>
+				</transition>
+				<transition event="mousedown" target="ready_to_translate_s"/>
+			</state>
+			<state id="scaling">
+				<transition event="mousemove" target="scaling">
+					<script>
+						var sMatrix = transformModule.scale(rawNode,eventStamp,_event.data);
+						cachedBBox = applyTransformToBBox(cachedBBox,sMatrix);
+						cachedBBox = rawNode.getBBox();
+						eventStamp = _event.data;
+						//_event.data.stopPropagation();
+						rawNode.parentNode.statechart["CSGROUP_HAS_MOVED"]({target:rawNode,delta:tDelta,rawNode:rawNode,clientX:_event.data.clientX,clientY:_event.data.clientY})
+						updateTransformHandles(rotationHandle,scaleHandle);
+					</script>
+				</transition>
+				<transition event="mouseup" target="ready_to_translate_s">
+					<script>
+						cachedCenterPoint=getCenterPoint(rawNode);
+						rawNode.parentNode.statechart["OBJ_FINISHED_TRANSFORM"]({target:rawNode})
+						cachedBBox=rawNode.getBBox();
+						updateTransformHandles(rotationHandle,scaleHandle);
+					</script>	
+				</transition>
+			</state>
+			<state id="ready_to_translate_s">
+				<target event="mousemove" target="translating_s">
+					<assign location="firstEvent" expr="_event.data"/>
+					<assign location="eventStamp" expr="_event.data"/>
+					<script>
+						scaleHandle.setAttributeNS(null,"visibility","hidden");
+					</script>
+				</target>
+				<transition event="mouseup" target="selected_r"/>
+			</state>
+			<state id="translating_s">
+				<transition event="mousemove" target="translating_s">
+					<script>
+						tDelta = computeTDelta(eventStamp,_event.data);
+						transformModule.translate(rawNode,tDelta);
+						eventStamp = _event.data
+
+						//_event.data.stopPropagation();
+						rawNode.parentNode.statechart["CSGROUP_HAS_MOVED"]({target:rawNode,delta:tDelta,rawNode:rawNode,clientX:_event.data.clientX,clientY:_event.data.clientY})
+					</script>
+				</transition>
+				<transition event="mouseup" target="selected_s">
+					<script>
+						tDelta = computeTDelta(firstEvent,eventStamp);
+						cachedCenterPoint=getCenterPoint(rawNode);
+						cachedBBox=rawNode.getBBox();
+						rawNode.parentNode.statechart["OBJ_FINISHED_TRANSFORM"]({target:rawNode})
+						updateTransformHandles(rotationHandle,scaleHandle);
+
+						scaleHandle.setAttributeNS(null,"visibility","visible");
+					</script>
+				</transition>
+			</state>
+		</state>
+
+		<state id="rotation_mode">
+			<state id="selected_r">
+				<transition event="rotation_mousedown" target="rotating">
+					<assign location="firstEvent" expr="_event.data"/>
+					<assign location="eventStamp" expr="_event.data"/>
+				</transition>
+				<transition event="mousedown" target="translating_r">
+				</transition>
+			</state>
+			<state id="rotating">
+				<transition event="mousemove" target="rotating">
+					<script>
+						var rDelta = computeRDelta(eventStamp,_event.data,cachedCenterPoint);
+						transformModule.rotate(rawNode,rDelta,cachedCenterPoint.x,cachedCenterPoint.y);
+						transformModule.rotate(rotationHandle,rDelta,cachedCenterPoint.x,cachedCenterPoint.y);
+						eventStamp = _event.data;
+						//_event.data.stopPropagation();
+						rawNode.parentNode.statechart["CSGROUP_HAS_MOVED"]({target:rawNode,delta:tDelta,rawNode:rawNode,clientX:_event.data.clientX,clientY:_event.data.clientY})
+					</script>
+				</transition>
+				<transition event="mouseup" target="selected_r">
+					<script>
+						rawNode.parentNode.statechart['OBJ_FINISHED_TRANSFORM']({target:rawNode})
+						cachedBBox=rawNode.getBBox();
+						updateTransformHandles(rotationHandle,scaleHandle);
+					</script>
+				</transition>
+			</state>
+			<state id="ready_to_translate_r">
+				<transition event="mousemove" target="translating_r">
+					<assign location="firstEvent" expr="_event.data"/>
+					<assign location="eventStamp" expr="_event.data"/>
+					<script>
+						rotationHandle.setAttributeNS(null,"visibility","hidden");
+					</script>
+				</transition>
+				<transition event="mouseup" target="selected_s"/>
+			</state>
+			<state id="translating_r">
+				<transition event="mousemove" target="translating_r">
+					<script>
+						tDelta = computeTDelta(eventStamp,_event.data);
+						transformModule.translate(rawNode,tDelta);
+						eventStamp = _event.data;
+
+						//_event.data.stopPropagation();
+						rawNode.parentNode.statechart["CSGROUP_HAS_MOVED"]({target:rawNode,delta:tDelta,rawNode:rawNode,clientX:_event.data.clientX,clientY:_event.data.clientY});
+					</script>
+				</transition>
+				<transition event="mouseup" target="selected_r">
+					<script>
+						tDelta = computeTDelta(firstEvent,eventStamp);
+						cachedCenterPoint = getCenterPoint(rawNode);
+						cachedBBox = rawNode.getBBox();
+						rawNode.parentNode.statechart['OBJ_FINISHED_TRANSFORM']({sender:rawNode})
+						updateTransformHandles(rotationHandle,scaleHandle);
+
+						rotationHandle.setAttributeNS(null,"visibility","visible");
+					</script>
+				</transition>
+			</state>
+		</state>
+
+	</state>
+
+	
+
 	<state id="dragging">
 		<transition event="mouseup" target="idle">
 		</transition>

Modified: commons/sandbox/gsoc/2010/scxml-js/trunk/demo/drawing-tool/drawing-tool.html
URL: http://svn.apache.org/viewvc/commons/sandbox/gsoc/2010/scxml-js/trunk/demo/drawing-tool/drawing-tool.html?rev=984026&r1=984025&r2=984026&view=diff
==============================================================================
--- commons/sandbox/gsoc/2010/scxml-js/trunk/demo/drawing-tool/drawing-tool.html (original)
+++ commons/sandbox/gsoc/2010/scxml-js/trunk/demo/drawing-tool/drawing-tool.html Tue Aug 10 14:18:45 2010
@@ -106,6 +106,11 @@
                   stroke:"black"
                 });
 
+								var scaleHandle = svg.path("M 0 0 L -4 6 L -2 6 L -2 12 L -4 12 L 0 18 L 4 12 L 2 12 L 2 6 L 4 6 L 0 0 z",{
+									transform:"rotate(-45)",
+									visibility:"hidden"
+								})
+								var rotationHandle =  svg.path("M 12 0 L 17 5 L 15 5 Q 15 15 5 15 L 5 17 L 0 12 L 5 7 L 5 9 Q 9 9 9 5 L 7 5 L 12 0 z",{visibility:"hidden"})
 
                 function hookUpDOMEvents(node,compiledStatechartInstance){
                   //hook up DOM events
@@ -171,20 +176,30 @@
 
                         //hook up canvas behaviour
                         var canvasSC = new CanvasStatechartExecutionContext(); 
+
+												svg.statechart = canvasSC;	//hook up dom node reference
+
                         canvasSC.initialize();
                         
                         //pass in reference to rect
                         canvasSC.init({  
                           svg:svg,
                           toolbarStatechart:toolbarSC,
+													scaleHandle:scaleHandle,
+													rotationHandle:rotationHandle,
                           api:{
                             addBehaviourToNode:function(node){
                               //add behaviour
                               var nodeSc = new NodeStatechartExecutionContext();
+
+															node.statechart = nodeSc;		//hook up dom node reference
+
                               nodeSc.initialize();
                               nodeSc.init({
                                 rawNode:node,
-                                transformModule:svgTransformer
+                                transformModule:svgTransformer,
+																scaleHandle:scaleHandle,
+																rotationHandle:rotationHandle
                               });
                               hookUpDOMEvents(node,nodeSc);
                             }