diff --git a/oxygine/src/oxygine/actor/Actor.cpp b/oxygine/src/oxygine/actor/Actor.cpp index 59bcc0f4f..15112f9a5 100644 --- a/oxygine/src/oxygine/actor/Actor.cpp +++ b/oxygine/src/oxygine/actor/Actor.cpp @@ -20,6 +20,7 @@ namespace oxygine { CREATE_COPYCLONE_NEW(Actor); + unsigned int Actor::DEFAULT_FLAGS = flag_visible | flag_touchEnabled | flag_touchChildrenEnabled | flag_fastTransform; std::string div(const std::string& val, const Color& color) { @@ -33,7 +34,7 @@ namespace oxygine _zOrder(0), _scale(1, 1), _rotation(0), - _flags(flag_visible | flag_touchEnabled | flag_touchChildrenEnabled | flag_fastTransform), + _flags(Actor::DEFAULT_FLAGS), _parent(0), _alpha(255), _stage(0), @@ -792,21 +793,22 @@ namespace oxygine -s * _scale.y, c * _scale.y, _pos.x, _pos.y); } - - Vector2 offset; - if (_flags & flag_anchorInPixels) - { - offset.x = -_anchor.x; - offset.y = -_anchor.y; - } - else - { - offset.x = -float(_size.x * _anchor.x); - offset.y = -float(_size.y * _anchor.y);//todo, what to do? (per pixel quality) + if (!(_flags&flag_anchorAffectsOrigin)) { + Vector2 offset; + if (_flags & flag_anchorInPixels) + { + offset.x = -_anchor.x; + offset.y = -_anchor.y; + } + else + { + offset.x = -float(_size.x * _anchor.x); + offset.y = -float(_size.y * _anchor.y);//todo, what to do? (per pixel quality) + } + + tr.translate(offset); } - tr.translate(offset); - _transform = tr; _flags &= ~flag_transformDirty; @@ -1154,8 +1156,6 @@ namespace oxygine } else Transform::multiply(rs.transform, tr, parentRS.transform); - - if (_flags & flag_cull) { RectF ss_rect = getActorTransformedDestRect(this, rs.transform); @@ -1168,9 +1168,7 @@ namespace oxygine return true; } - void Actor::completeRender(const RenderState& rs) - { - + void Actor::completeRender(const RenderState& rs) { } bool Actor::internalRender(RenderState& rs, const RenderState& parentRS) @@ -1215,7 +1213,8 @@ namespace oxygine RectF Actor::getDestRect() const { - return RectF(Vector2(0, 0), getSize()); + Vector2 origin; + return RectF(alterOrigin(origin), getSize()); } spTween Actor::_addTween(spTween tween, bool rel) @@ -1667,4 +1666,17 @@ namespace oxygine return false; } + Vector2 Actor::alterOrigin(const Vector2& pos) const { + Vector2 delta; + if (_flags&flag_anchorAffectsOrigin && delta!= getAnchor()) { + if (_flags&flag_anchorInPixels) { + delta = getAnchor()*-1; + } else { + delta.x = -getAnchorX()*getSize().x; + delta.y = -getAnchorY()*getSize().y; + } + return pos+delta; + } + return pos; + } } diff --git a/oxygine/src/oxygine/actor/Actor.h b/oxygine/src/oxygine/actor/Actor.h index d604a4868..6b60a6304 100644 --- a/oxygine/src/oxygine/actor/Actor.h +++ b/oxygine/src/oxygine/actor/Actor.h @@ -42,7 +42,8 @@ namespace oxygine class Actor: public EventDispatcher, public intrusive_list_item, public Serializable { typedef intrusive_list_item intr_list; - + public: + static unsigned int DEFAULT_FLAGS; public: Actor(const Actor& src, cloneOptions opt = 0); virtual Actor* clone(cloneOptions opt = 0) const; @@ -95,6 +96,7 @@ namespace oxygine float getRotationDegrees() const {return _rotation / MATH_PI * 180.0f;} int getPriority() const {return _zOrder;} bool getVisible() const {return (_flags & flag_visible) != 0;} + bool getAnchorAffectsOrigin() const {return (_flags & flag_anchorAffectsOrigin) != 0;} Actor* getParent() {return _parent;} const Actor* getParent() const {return _parent;} const Vector2& getSize() const {return _size;} @@ -173,6 +175,7 @@ namespace oxygine /**Show/Hide actor and children. Invisible Actor doesn't receive Touch events.*/ void setVisible(bool vis) {_flags &= ~flag_visible; if (vis) _flags |= flag_visible;} + void setAnchorAffectsOrigin(bool aff) {_flags &= ~flag_anchorAffectsOrigin; if (aff) _flags |= flag_anchorAffectsOrigin;} /**Enable/Disable culling this actor outside of clip area (use it in pair with ClipRectActor)*/ void setCull(bool enable) {_flags &= ~flag_cull; if (enable) _flags |= flag_cull;} /**Sets transparency. if alpha is 0 actor and children are completely invisible. Invisible Actor doesn't receive Touch events.*/ @@ -261,6 +264,7 @@ namespace oxygine virtual Vector2 parent2local(const Vector2& pos) const; //converts local position to parent space virtual Vector2 local2parent(const Vector2& pos = Vector2(0, 0)) const; + virtual Vector2 alterOrigin(const Vector2& pos) const; //converts local position to Stage Vector2 local2stage(const Vector2& pos = Vector2(0, 0), Actor* stage = 0) const; @@ -348,24 +352,6 @@ namespace oxygine mutable Transform _transform; mutable Transform _transformInvert; - - enum flags - { - flag_anchorInPixels = 1, - flag_visible = 1 << 1, - flag_touchEnabled = 1 << 2, - flag_transformDirty = 1 << 3, - flag_transformInvertDirty = 1 << 4, - flag_touchChildrenEnabled = 1 << 5, - flag_cull = 1 << 6, - flag_fastTransform = 1 << 7, - flag_boundsNoChildren = 1 << 8, - flag_actorHasBounds = 1 << 9, - flag_clickableWithZeroAlpha = 1 << 10, - flag_reserved = 1 << 11, - flag_last = flag_reserved - }; - mutable unsigned int _flags; unsigned char _alpha; char _extendedIsOn; @@ -388,8 +374,24 @@ namespace oxygine }; int32_t _pressedOvered; }; - - + public: + enum flags + { + flag_anchorInPixels = 1, + flag_visible = 1 << 1, + flag_touchEnabled = 1 << 2, + flag_transformDirty = 1 << 3, + flag_transformInvertDirty = 1 << 4, + flag_touchChildrenEnabled = 1 << 5, + flag_cull = 1 << 6, + flag_fastTransform = 1 << 7, + flag_boundsNoChildren = 1 << 8, + flag_actorHasBounds = 1 << 9, + flag_clickableWithZeroAlpha = 1 << 10, + flag_reserved = 1 << 11, + flag_anchorAffectsOrigin = 1 << 12, + flag_last = flag_anchorAffectsOrigin + }; private: Vector2 _pos; @@ -439,4 +441,4 @@ namespace oxygine } -EDITOR_INCLUDE(Actor); \ No newline at end of file +EDITOR_INCLUDE(Actor); diff --git a/oxygine/src/oxygine/actor/DebugActor.cpp b/oxygine/src/oxygine/actor/DebugActor.cpp index 70e4cee9a..e9c53cea0 100644 --- a/oxygine/src/oxygine/actor/DebugActor.cpp +++ b/oxygine/src/oxygine/actor/DebugActor.cpp @@ -397,6 +397,12 @@ namespace oxygine pos.y -= realSize.y; break; } + Vector2 o = getStage()->getAnchor(); + if (getStage()->getAnchorAffectsOrigin() && o != Vector2()) { + Vector2 sz = getStage()->getSize(); + pos.x -= sz.x*o.x; + pos.y -= sz.y*o.y; + } setPosition(pos); setScale(1.0f / getStage()->getScaleX()); diff --git a/oxygine/src/oxygine/actor/Sprite.cpp b/oxygine/src/oxygine/actor/Sprite.cpp index 9d6dc966e..9605fcc9f 100644 --- a/oxygine/src/oxygine/actor/Sprite.cpp +++ b/oxygine/src/oxygine/actor/Sprite.cpp @@ -95,8 +95,11 @@ namespace oxygine const int BITS = (sizeof(int32_t) * 8); const unsigned char* buff = ad.data; - Vector2 pos = localPosition * _frame.getResAnim()->getAppliedScale(); + + Vector2 pos = localPosition*_frame.getResAnim()->getAppliedScale(); pos = pos.div(_localScale); + pos = -alterOrigin(-pos); + Point lp = pos.cast() / HIT_TEST_DOWNSCALE; Rect r(0, 0, ad.w, ad.h); if (r.pointIn(lp)) @@ -105,7 +108,7 @@ namespace oxygine int n = lp.x / BITS; int b = lp.x % BITS; - + return (ints[n] >> b) & 1; } return false; @@ -288,6 +291,9 @@ namespace oxygine RectF r = _frame.getDestRect(); r.pos = r.pos.mult(_localScale); r.size = r.size.mult(_localScale); + + r.pos = alterOrigin(r.pos); + return r; } diff --git a/oxygine/src/oxygine/actor/TextField.cpp b/oxygine/src/oxygine/actor/TextField.cpp index 9bcf1e49f..8d7f4efad 100644 --- a/oxygine/src/oxygine/actor/TextField.cpp +++ b/oxygine/src/oxygine/actor/TextField.cpp @@ -309,14 +309,22 @@ namespace oxygine _root = new text::TextNode(_text.c_str()); } + Vector2 offset = alterOrigin(Vector2(0,0)); + text::Aligner rd(_style, _mat, font, scale, getSize()); rd.begin(); _root->resize(rd); rd.end(); - + + Point origin = rd.bounds.pos; + rd.bounds.pos.x = 0; + rd.bounds.pos += offset.cast()*rd.getScale(); + _root->finalPass(rd); + rd.bounds.pos.x += origin.x; + rd.bounds = (rd.bounds.cast() / rd.getScale()).cast(); - + _textRect = rd.bounds; Event ev(EVENT_REBUILD); @@ -387,7 +395,6 @@ namespace oxygine { stream << " font='" << s.font->getName() << "'"; } - return stream.str(); } @@ -414,7 +421,7 @@ namespace oxygine Rect r = const_cast(this)->getTextRect(); stream << " textRect=(" << r.pos.x << ", " << r.pos.y << ", " << r.size.x << ", " << r.size.y << ")"; - + stream << "\n" << Actor::dump(options); return stream.str(); diff --git a/oxygine/src/oxygine/text_utils/Node.cpp b/oxygine/src/oxygine/text_utils/Node.cpp index b980cde64..3f50604f9 100644 --- a/oxygine/src/oxygine/text_utils/Node.cpp +++ b/oxygine/src/oxygine/text_utils/Node.cpp @@ -261,11 +261,14 @@ namespace oxygine float scaleFactor = rd.getScale(); int offsetY = rd.bounds.pos.y; + int offsetX = rd.bounds.pos.x; + for (size_t i = 0; i < _data.size(); ++i) { Symbol& s = _data[i]; s.y += offsetY; + s.x += offsetX; if (s.gl.texture) s.destRect = RectF(mlt(s.x, scaleFactor), mlt(s.y, scaleFactor), mlt(s.gl.sw, scaleFactor), mlt(s.gl.sh, scaleFactor));