Browse Source

Started rewriting ScreenEntity input events, broke UI temporarily

Ivan Safrin 14 years ago
parent
commit
0374c77167

+ 2 - 2
Core/Contents/Include/PolyScreenEntity.h

@@ -84,7 +84,7 @@ class _PolyExport ScreenEntity : public Entity, public EventDispatcher {
 		*/						
 		Number getRotation() const;
 			
-		bool _onMouseDown(Number x, Number y, int mouseButton, int timestamp);
+		bool _onMouseDown(Number x, Number y, int mouseButton, int timestamp, Vector2 parentAdjust = Vector2(0,0));
 		bool _onMouseUp(Number x, Number y, int mouseButton, int timestamp);
 		void _onMouseMove(Number x, Number y, int timestamp);
 		void _onMouseWheelUp(Number x, Number y, int timestamp);
@@ -115,7 +115,6 @@ class _PolyExport ScreenEntity : public Entity, public EventDispatcher {
 		
 		/**
 		* Returns the height of the screen entity.
-		* @param w New height value.
 		*/											
 		Number getHeight() const;
 	
@@ -171,6 +170,7 @@ class _PolyExport ScreenEntity : public Entity, public EventDispatcher {
 		*/
 		bool snapToPixels;
 
+		bool processInputEvents;
 
 	protected:
 	

+ 13 - 1
Core/Contents/Include/PolyVector2.h

@@ -140,7 +140,19 @@ namespace Polycode {
 			*/
 			inline Number crossProduct( const Vector2& vec2 ) const {
 				return x * vec2.y - y * vec2.x;
-			}			
+			}
+			
+			inline Number angle(const Vector2& vec2 ) const {
+				Number dtheta,theta1,theta2;
+				theta1 = atan2(y,x);
+				theta2 = atan2(vec2.y,vec2.x);
+				dtheta = theta2 - theta1;
+				while (dtheta > PI)
+					dtheta -= PI*2.0;
+				while (dtheta < -PI)
+					dtheta += PI*2.0;
+				return(dtheta);
+			}									
 
 			/**
 			* Normalizes the vector.

+ 123 - 85
Core/Contents/Source/PolyScreenEntity.cpp

@@ -23,6 +23,8 @@
 #include "PolyScreenEntity.h"
 #include "PolyInputEvent.h"
 #include "PolyRectangle.h"
+#include "PolyPolygon.h"
+#include "PolyVertex.h"
 #include "PolyRenderer.h"
 
 inline double round(double x) { return floor(x + 0.5); }
@@ -62,6 +64,8 @@ ScreenEntity::ScreenEntity() : Entity(), EventDispatcher() {
 	xmouse = 0;
 	ymouse = 0;
 	
+	processInputEvents = false;
+	
 }
 
 void ScreenEntity::focusNextChild() {
@@ -154,30 +158,59 @@ Number ScreenEntity::getHeight() const {
 	return height;
 }
 
-bool ScreenEntity::hitTest(Number x, Number y) const {
-	bool retVal = false;
-    // apply compound scale to test hit against
-    Vector3 compScale = getCompoundScale();
-    Number hx = position.x * compScale.x;
-    Number hy = position.y * compScale.y;
-    Number hw = hitwidth * compScale.x;
-    Number hh = hitheight * compScale.y;
-    //        Logger::log("hittest %f,%f in %f %f %f %f\n",x, y, hx, hy, hw, hh);
-	switch(positionMode) {
-		case ScreenEntity::POSITION_TOPLEFT:
-						
-            if(x > hx && x < (hx + hw)
-                && y > hy && y < (hy + hh))
-				retVal = true;			
-		break;
-		case ScreenEntity::POSITION_CENTER:
-            if(x > (hx - hw/2.0f) && x < (hx + hw/2.0f)
-                && y > (hy - hh/2.0f) && y < (hy + hh/2.0f))
-				retVal = true;	
-		break;
+bool isPointInsidePolygon2D(Polycode::Polygon *poly, const Vector2 &p) {
+	Number angle = 0.0;
+	Vector2 p1,p2;
+/*	
+	printf("PIP: %f,%f in [%f,%f], [%f,%f], [%f,%f], [%f,%f]\n", p.x, p.y, 
+		poly->getVertex(0)->x, poly->getVertex(0)->y,
+		poly->getVertex(1)->x, poly->getVertex(1)->y,
+		poly->getVertex(2)->x, poly->getVertex(2)->y,
+		poly->getVertex(3)->x, poly->getVertex(3)->y);
+*/
+	for (int i=0; i < poly->getVertexCount(); i++) {
+
+		p1.x = poly->getVertex(i)->x - p.x;
+		p1.y = poly->getVertex(i)->y - p.y;
+		p2.x = poly->getVertex((i+1)%poly->getVertexCount())->x - p.x;
+		p2.y = poly->getVertex((i+1)%poly->getVertexCount())->y - p.y;
+		
+		Vector2 vec(p1.x,p1.y);
+		angle += vec.angle(Vector2(p2.x,p2.y));
+
 	}
 
-	return retVal;
+	if (fabs(angle) < PI)
+		return false;
+	else
+		return true;
+}
+
+bool ScreenEntity::hitTest(const Number x, const Number y) const {
+
+	Vector3 v;	
+	Polygon testPoly;
+	
+	Matrix4 transformMatrix = getConcatenatedMatrix();
+	
+	v = Vector3(-hitwidth/2.0, -hitheight/2.0,0);
+	v = transformMatrix * v;	
+	testPoly.addVertex(v.x, v.y, 0.0);
+	
+	v = Vector3(hitwidth/2.0, -hitheight/2.0,0);
+	v = transformMatrix * v;	
+	testPoly.addVertex(v.x, v.y, 0.0);
+
+	v = Vector3(hitwidth/2.0, hitheight/2.0,0);
+	v = transformMatrix * v;	
+	testPoly.addVertex(v.x, v.y, 0.0);
+
+	v = Vector3(-hitwidth/2.0,hitheight/2.0,0);
+	v = transformMatrix * v;	
+	testPoly.addVertex(v.x, v.y, 0.0);
+		
+	return isPointInsidePolygon2D(&testPoly, Vector2(x,y));
+	
 }
 
 void ScreenEntity::setPositionMode(int newPositionMode) {
@@ -228,11 +261,11 @@ void ScreenEntity::_onMouseMove(Number x, Number y, int timestamp) {
 		}
 	}
 	
-	xmouse = x-position.x;
-	ymouse = y-position.y;
+	xmouse = x;
+	ymouse = y;
 
 	onMouseMove(x,y);
-	if(enabled) {
+	if(processInputEvents && enabled) {
 		if(hitTest(x,y)) {
 			dispatchEvent(new InputEvent(Vector2(x,y), timestamp), InputEvent::EVENT_MOUSEMOVE);
 			if(!mouseOver) {
@@ -249,31 +282,57 @@ void ScreenEntity::_onMouseMove(Number x, Number y, int timestamp) {
 	
 	if(enabled) {
 		for(int i=0;i<children.size();i++) {
-			((ScreenEntity*)children[i])->_onMouseMove(x-position.x,y-position.y, timestamp);
+			((ScreenEntity*)children[i])->_onMouseMove(x,y, timestamp);
 		}
 	}
 }
 
 bool ScreenEntity::_onMouseUp(Number x, Number y, int mouseButton, int timestamp) {
 	bool retVal = false;
-	if(hitTest(x,y) && enabled) {
-		onMouseUp(x,y);
+	
+	if(processInputEvents && enabled) {	
+	if(hitTest(x,y)) {
+	
+		Vector3 localCoordinate = Vector3(x,y,0);
+		
+		Matrix4 inverse = getConcatenatedMatrix().inverse();
+		localCoordinate = inverse * localCoordinate;
+		if(positionMode == POSITION_TOPLEFT)
+			localCoordinate.x += hitwidth/2.0;
+		if(positionMode == POSITION_TOPLEFT)
+			localCoordinate.y += hitheight/2.0;
+	
+		onMouseUp(localCoordinate.x,localCoordinate.y);
 		
-		InputEvent *inputEvent = new InputEvent(Vector2(x,y), timestamp);		
+		InputEvent *inputEvent = new InputEvent(Vector2(localCoordinate.x,localCoordinate.y), timestamp);		
 		inputEvent->mouseButton = mouseButton;		
 		dispatchEvent(inputEvent, InputEvent::EVENT_MOUSEUP);
 		retVal = true;		
 	} else {
 		
-		InputEvent *inputEvent = new InputEvent(Vector2(x,y), timestamp);		
+		Vector3 localCoordinate = Vector3(x,y,0);
+		
+		Matrix4 inverse = getConcatenatedMatrix().inverse();
+		localCoordinate = inverse * localCoordinate;
+		if(positionMode == POSITION_TOPLEFT)
+			localCoordinate.x += hitwidth/2.0;
+		if(positionMode == POSITION_TOPLEFT)
+			localCoordinate.y += hitheight/2.0;
+	
+		
+		InputEvent *inputEvent = new InputEvent(Vector2(localCoordinate.x,localCoordinate.y), timestamp);		
 		inputEvent->mouseButton = mouseButton;
 		
 		dispatchEvent(inputEvent, InputEvent::EVENT_MOUSEUP_OUTSIDE);
 	}
-	
+	}
 	if(enabled) {
+		Vector2 adjust;
+		if(positionMode == POSITION_TOPLEFT)
+			adjust = Vector2(width/2.0, height/2.0);
+	
 		for(int i=0;i<children.size();i++) {
-			((ScreenEntity*)children[i])->_onMouseUp(x-position.x,y-position.y, mouseButton, timestamp);
+			((ScreenEntity*)children[i])->_onMouseUp(x+adjust.x,y+adjust.y, mouseButton, timestamp);
 		}
 	}
 	return retVal;
@@ -283,7 +342,7 @@ void ScreenEntity::_onMouseWheelUp(Number x, Number y, int timestamp) {
 	bool doTest = true;
 	
 	if(hasMask) {
-		if(!((ScreenEntity*)maskEntity)->hitTest(x-position.x,y-position.y)) {
+		if(!((ScreenEntity*)maskEntity)->hitTest(x,y)) {
 			doTest = false;
 		}	
 	}
@@ -295,9 +354,9 @@ void ScreenEntity::_onMouseWheelUp(Number x, Number y, int timestamp) {
 		}
 		if(enabled) {
 			for(int i=children.size()-1;i>=0;i--) {				
-				((ScreenEntity*)children[i])->_onMouseWheelUp(x-position.x,y-position.y, timestamp);
+				((ScreenEntity*)children[i])->_onMouseWheelUp(x,y, timestamp);
 				if(((ScreenEntity*)children[i])->blockMouseInput && ((ScreenEntity*)children[i])->enabled) {
-					if(((ScreenEntity*)children[i])->hitTest(x-position.x,y-position.y))
+					if(((ScreenEntity*)children[i])->hitTest(x,y))
 						break;
 				}
 			}
@@ -309,7 +368,7 @@ void ScreenEntity::_onMouseWheelDown(Number x, Number y, int timestamp) {
 	bool doTest = true;
 	
 	if(hasMask) {
-		if(!((ScreenEntity*)maskEntity)->hitTest(x-position.x,y-position.y)) {
+		if(!((ScreenEntity*)maskEntity)->hitTest(x,y)) {
 			doTest = false;
 		}	
 	}
@@ -321,9 +380,9 @@ void ScreenEntity::_onMouseWheelDown(Number x, Number y, int timestamp) {
 		}
 		if(enabled) {
 			for(int i=children.size()-1;i>=0;i--) {				
-				((ScreenEntity*)children[i])->_onMouseWheelDown(x-position.x,y-position.y, timestamp);
+				((ScreenEntity*)children[i])->_onMouseWheelDown(x,y, timestamp);
 				if(((ScreenEntity*)children[i])->blockMouseInput && ((ScreenEntity*)children[i])->enabled) {
-					if(((ScreenEntity*)children[i])->hitTest(x-position.x,y-position.y))
+					if(((ScreenEntity*)children[i])->hitTest(x,y))
 						break;
 				}
 			}
@@ -332,22 +391,34 @@ void ScreenEntity::_onMouseWheelDown(Number x, Number y, int timestamp) {
 }
 
 
-bool ScreenEntity::_onMouseDown(Number x, Number y, int mouseButton, int timestamp) {
+bool ScreenEntity::_onMouseDown(Number x, Number y, int mouseButton, int timestamp, Vector2 parentAdjust) {
 	bool retVal = false;
 	
-	bool doTest = true;
+	bool doTest = true;	
 	
 	if(hasMask) {
-		if(!((ScreenEntity*)maskEntity)->hitTest(x,y)) {
+		if(!((ScreenEntity*)maskEntity)->hitTest(x+parentAdjust.x,y+parentAdjust.y)) {
 			doTest = false;
 		}	
 	}
 	
 	if(doTest) {
-	if(hitTest(x,y) && enabled) {
-		onMouseDown(x,y);
+	if(processInputEvents && enabled) {
+	if(hitTest(x+parentAdjust.x,y+parentAdjust.y)) {
+		Vector3 localCoordinate = Vector3(x+(parentAdjust.x*2.0),y+(parentAdjust.y*2.0),0);
+		
+		Matrix4 inverse = getConcatenatedMatrix().inverse();
+		localCoordinate = inverse * localCoordinate;
+		if(positionMode == POSITION_TOPLEFT)
+			localCoordinate.x += hitwidth/2.0;
+		if(positionMode == POSITION_TOPLEFT)
+			localCoordinate.y += hitheight/2.0;
+
+		
+		onMouseDown(localCoordinate.x,localCoordinate.y);
+		
+		InputEvent *inputEvent = new InputEvent(Vector2(localCoordinate.x,localCoordinate.y)-parentAdjust, timestamp);
 		
-		InputEvent *inputEvent = new InputEvent(Vector2(x,y), timestamp);		
 		inputEvent->mouseButton = mouseButton;
 		dispatchEvent(inputEvent, InputEvent::EVENT_MOUSEDOWN);
 		
@@ -359,12 +430,15 @@ bool ScreenEntity::_onMouseDown(Number x, Number y, int mouseButton, int timesta
 		lastClickTicks = timestamp;		
 		retVal = true;
 	}
+	}
 	if(enabled) {
-		for(int i=children.size()-1;i>=0;i--) {
-			
-			((ScreenEntity*)children[i])->_onMouseDown(x-position.x,y-position.y, mouseButton, timestamp);
+		for(int i=children.size()-1;i>=0;i--) {			
+			Vector2 adjust = parentAdjust;
+			if(positionMode == POSITION_TOPLEFT)
+				adjust += Vector2(width/2.0, height/2.0);
+			((ScreenEntity*)children[i])->_onMouseDown(x,y, mouseButton, timestamp, adjust);
 			if(((ScreenEntity*)children[i])->blockMouseInput && ((ScreenEntity*)children[i])->enabled) {
-				if(((ScreenEntity*)children[i])->hitTest(x-position.x,y-position.y))
+				if(((ScreenEntity*)children[i])->hitTest(x,y))
 				   break;
 			}
 		}
@@ -386,7 +460,6 @@ Matrix4 ScreenEntity::buildPositionMatrix() {
 	Matrix4 posMatrix;
 	switch(positionMode) {
 		case POSITION_TOPLEFT:
-//			renderer->translate2D(position.x+ceil(width/2.0f)*scale->x, position.y+ceil(height/2.0f)*scale->y);
 			posMatrix.m[3][0] = (position.x+floor(width/2.0f)*scale.x)*matrixAdj;
 			posMatrix.m[3][1] = (position.y+floor(height/2.0f)*scale.y)*matrixAdj;
 			posMatrix.m[3][2] = position.z*matrixAdj;			
@@ -411,39 +484,4 @@ Matrix4 ScreenEntity::buildPositionMatrix() {
 void ScreenEntity::adjustMatrixForChildren() {
 	if(positionMode == POSITION_TOPLEFT)
 		renderer->translate2D(-floor(width/2.0f), -floor(height/2.0f));	
-}
-
-/*
-void ScreenEntity::transformAndRender() {
-
-	Update();
-
-	if(!renderer || !visible)
-		return;
-
-	renderer->pushMatrix();
-	switch(positionMode) {
-		case POSITION_TOPLEFT:
-			renderer->translate2D(position.x+ceil(width/2.0f)*scale->x, position.y+ceil(height/2.0f)*scale->y);
-		break;
-		case POSITION_CENTER:
-			renderer->translate2D(position.x, position.y);
-		break;
-	}
-	renderer->scale2D(scale);
-	renderer->rotate2D(rotation);
-	if(parentEntity) {
-		Color combined = getCombinedColor();
-		renderer->setVertexColor(combined.r,combined.g,combined.b,combined.a);
-	} else {
-		renderer->setVertexColor(color.r,color.g,color.b,color.a);
-	}
-	
-	renderer->setBlendingMode(blendingMode);
-	Render();
-	if(positionMode == POSITION_TOPLEFT)
-		renderer->translate2D(-ceil(width/2.0f)*scale->x, -ceil(height/2.0f)*scale->y);
-	renderChildren();
-	renderer->popMatrix();
-}
-*/
+}

+ 5 - 0
IDE/Contents/Source/PolycodeScreenEditor.cpp

@@ -60,6 +60,7 @@ PolycodeScreenEditor::PolycodeScreenEditor() : PolycodeEditor(true){
 	baseEntity->addEventListener(this, InputEvent::EVENT_MOUSEUP);
 	baseEntity->addEventListener(this, InputEvent::EVENT_MOUSEUP_OUTSIDE);
 	baseEntity->addEventListener(this, InputEvent::EVENT_MOUSEMOVE);
+	baseEntity->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
 					
 	screenTransform = new UIBox("screenTransform.png", 16,16,16,16, 100,100);
 	screenTransform->visible = false;
@@ -130,6 +131,10 @@ void PolycodeScreenEditor::handleEvent(Event *event) {
 	
 	if(event->getDispatcher() == baseEntity) {
 		switch (event->getEventCode()) {
+			case InputEvent::EVENT_MOUSEDOWN:
+				selectedEntity = NULL;
+				screenTransform->visible = false;
+			break;		
 			case InputEvent::EVENT_MOUSEUP:
 			case InputEvent::EVENT_MOUSEUP_OUTSIDE:			
 				isDraggingEntity = false;	

+ 4 - 1
Modules/Contents/UI/Source/PolyUITree.cpp

@@ -105,12 +105,15 @@ UITree::UITree(String icon, String text, Number treeWidth, Number treeOffset) :
 	parent = NULL;
 	selectedNode = NULL;
 	arrowIconImage->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
+	arrowIconImage->processInputEvents = true;
+	
 	bgBox->addEventListener(this, InputEvent::EVENT_MOUSEUP);
 	bgBox->addEventListener(this, InputEvent::EVENT_MOUSEUP_OUTSIDE);	
 	bgBox->addEventListener(this, InputEvent::EVENT_MOUSEMOVE);		
 	bgBox->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);	
 	bgBox->addEventListener(this, InputEvent::EVENT_DOUBLECLICK);	
-	
+	bgBox->processInputEvents = true;
+		
 	setPositionMode(ScreenEntity::POSITION_CENTER);
 	
 	refreshTree();

+ 4 - 0
Modules/Contents/UI/Source/PolyUIWindow.cpp

@@ -62,6 +62,7 @@ UIWindow::UIWindow(String windowName, Number width, Number height) : ScreenEntit
 	titlebarRect = new ScreenShape(ScreenShape::SHAPE_RECT, width, st);
 	titlebarRect->setColor(0,0,0,0);
 	titlebarRect->setPositionMode(ScreenEntity::POSITION_TOPLEFT);
+	titlebarRect->processInputEvents = true;
 	addChild(titlebarRect);
 	
 	ScreenLabel *titleLabel = new ScreenLabel(windowName, fontSize, fontName, Label::ANTIALIAS_FULL);
@@ -73,6 +74,7 @@ UIWindow::UIWindow(String windowName, Number width, Number height) : ScreenEntit
 	closeBtn->setPosition(width-closeBtn->getWidth()-conf->getNumericValue("Polycode", "uiCloseIconX"), conf->getNumericValue("Polycode", "uiCloseIconY"));
 
 	titlebarRect->addEventListener(this, InputEvent::EVENT_MOUSEUP);
+	titlebarRect->addEventListener(this, InputEvent::EVENT_MOUSEUP_OUTSIDE);	
 	titlebarRect->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
 	closeBtn->addEventListener(this, UIEvent::CLICK_EVENT);
 	
@@ -151,9 +153,11 @@ void UIWindow::handleEvent(Event *event) {
 		InputEvent *inputEvent = (InputEvent*)event;
 		switch(event->getEventCode()) {
 			case InputEvent::EVENT_MOUSEUP:
+			case InputEvent::EVENT_MOUSEUP_OUTSIDE:			
 				stopDrag();
 			break;
 			case InputEvent::EVENT_MOUSEDOWN:
+				printf("DRAG OFFSET: %f, %f\n", inputEvent->mousePosition.x,inputEvent->mousePosition.y);
 				startDrag(inputEvent->mousePosition.x,inputEvent->mousePosition.y);
 			break;
 		}