|
|
@@ -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();
|
|
|
-}
|
|
|
-*/
|
|
|
+}
|