diff options
author | ExMix <rahuba.youri@mapswithme.com> | 2014-03-05 17:37:05 +0400 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 02:12:28 +0300 |
commit | 085671af831192739bbf8d98af05f97eaa2de144 (patch) | |
tree | 6dc0a75b3a5c1f81ef9aaec1dcff63f201914ba0 /map/compass_arrow.cpp | |
parent | 3f0c39f347820359cd3b551e84bec3deb4cbbb3c (diff) |
new compass with animation
Diffstat (limited to 'map/compass_arrow.cpp')
-rw-r--r-- | map/compass_arrow.cpp | 248 |
1 files changed, 178 insertions, 70 deletions
diff --git a/map/compass_arrow.cpp b/map/compass_arrow.cpp index 3965a090a4..e06556b892 100644 --- a/map/compass_arrow.cpp +++ b/map/compass_arrow.cpp @@ -3,50 +3,134 @@ #include "framework.hpp" #include "../anim/controller.hpp" +#include "../anim/task.hpp" #include "../gui/controller.hpp" #include "../geometry/any_rect2d.hpp" #include "../geometry/transformations.hpp" +#include "../graphics/display_list.hpp" #include "../graphics/display_list.hpp" #include "../graphics/screen.hpp" #include "../graphics/pen.hpp" +using namespace graphics; + +namespace +{ + class AlfaCompassAnim : public anim::Task + { + typedef anim::Task base_t; + public: + AlfaCompassAnim(double start, double end, double timeInterval, double timeOffset, Framework * f) + : m_start(start) + , m_end(end) + , m_current(start) + , m_timeInterval(timeInterval) + , m_timeOffset(timeOffset) + , m_f(f) + { + } + + bool IsHiding() const + { + return m_start > m_end; + } + + float GetCurrentAlfa() const + { + return m_current; + } + + virtual void OnStart(double ts) + { + m_timeStart = ts; + base_t::OnStart(ts); + m_f->Invalidate(); + } + + virtual void OnStep(double ts) + { + base_t::OnStep(ts); + double elapsed = ts - (m_timeStart + m_timeOffset); + if (elapsed >= 0.0) + { + double t = elapsed / m_timeInterval; + if (t > 1.0) + { + m_current = m_end; + End(); + } + else + m_current = m_start + t * (m_end - m_start); + } + + m_f->Invalidate(); + } + + private: + double m_start; + double m_end; + double m_current; + double m_timeInterval; + double m_timeOffset; + double m_timeStart; + + Framework * m_f; + }; +} + CompassArrow::Params::Params() - : m_arrowWidth(0), - m_arrowHeight(0), - m_framework(0) + : m_framework(0) {} CompassArrow::CompassArrow(Params const & p) : base_t(p), - m_arrowWidth(p.m_arrowWidth), - m_arrowHeight(p.m_arrowHeight), - m_northLeftColor(0xcc, 0x33, 0x00, 0xcc), - m_northRightColor(0xff, 0x33, 0x00, 0xcc), - m_southLeftColor(0xcc, 0xcc, 0xcc, 0xcc), - m_southRightColor(0xff, 0xff, 0xff, 0xcc), m_angle(0), + m_displayList(NULL), m_boundRects(1), m_framework(p.m_framework) { } +void CompassArrow::AnimateShow() +{ + if (!isVisible() && (m_animTask == NULL || IsHidingAnim())) + { + setIsVisible(true); + CreateAnim(0.1, 1.0, 0.2, 0.0, true); + } + + if (isVisible() && (m_animTask == NULL || IsHidingAnim())) + CreateAnim(GetCurrentAlfa(), 1.0, 0.2, 0.0, true); +} + +void CompassArrow::AnimateHide() +{ + if (isVisible() && (m_animTask == NULL || !IsHidingAnim())) + CreateAnim(1.0, 0.0, 0.3, 1.0, false); +} + void CompassArrow::SetAngle(double angle) { m_angle = angle; setIsDirtyRect(true); } +m2::PointD CompassArrow::GetPixelSize() const +{ + Resource const * res = GetCompassResource(); + return m2::PointD(res->m_texRect.SizeX(), res->m_texRect.SizeY()); +} + vector<m2::AnyRectD> const & CompassArrow::boundRects() const { if (isDirtyRect()) { - double k = visualScale(); - - double halfW = m_arrowWidth / 2.0 * k; - double halfH = m_arrowHeight / 2.0 * k; + Resource const * res = GetCompassResource(); + double halfW = res->m_texRect.SizeX() / 2.0; + double halfH = res->m_texRect.SizeY() / 2.0; m_boundRects[0] = m2::AnyRectD(pivot(), -math::pi / 2 + m_angle, @@ -65,86 +149,114 @@ void CompassArrow::draw(graphics::OverlayRenderer * r, { checkDirtyLayout(); + UniformsHolder holder; + float a = GetCurrentAlfa(); + LOG(LINFO, ("Compass alfa = ", a)); + holder.insertValue(ETransparency, a); + math::Matrix<double, 3, 3> drawM = math::Shift( math::Rotate( math::Identity<double, 3>(), m_angle), pivot()); - r->drawDisplayList(m_displayList.get(), drawM * m); + r->drawDisplayList(m_displayList, drawM * m, &holder); } } -void CompassArrow::cache() +void CompassArrow::AlfaAnimEnded(bool isVisible) { - graphics::Screen * cacheScreen = m_controller->GetCacheScreen(); + setIsVisible(isVisible); + m_animTask.reset(); +} - m_displayList.reset(); - m_displayList.reset(cacheScreen->createDisplayList()); +bool CompassArrow::IsHidingAnim() const +{ + ASSERT(m_animTask != NULL, ()); + AlfaCompassAnim * a = static_cast<AlfaCompassAnim *>(m_animTask.get()); + return a->IsHiding(); +} - cacheScreen->beginFrame(); - cacheScreen->setDisplayList(m_displayList.get()); +float CompassArrow::GetCurrentAlfa() const +{ + if (m_animTask) + { + AlfaCompassAnim * a = static_cast<AlfaCompassAnim *>(m_animTask.get()); + return a->GetCurrentAlfa(); + } - double const k = visualScale(); + return 1.0; +} - double const halfW = m_arrowWidth / 2.0 * k; - double const halfH = m_arrowHeight / 2.0 * k; +void CompassArrow::CreateAnim(double startAlfa, double endAlfa, double timeInterval, double timeOffset, bool isVisibleAtEnd) +{ + if (m_framework->GetAnimController() == NULL) + return; + + if (m_animTask) + m_animTask->Cancel(); + m_animTask.reset(new AlfaCompassAnim(startAlfa, endAlfa, timeInterval, timeOffset, m_framework)); + m_animTask->AddCallback(anim::Task::EEnded, bind(&CompassArrow::AlfaAnimEnded, this, isVisibleAtEnd)); + m_framework->GetAnimController()->AddTask(m_animTask); +} - m2::PointF const northLeftPts[3] = { - m2::PointF(-halfW, 0), - m2::PointF(0, -halfH), - m2::PointF(0, 0) - }; - cacheScreen->drawConvexPolygon(northLeftPts, 3, m_northLeftColor, depth()); +const Resource * CompassArrow::GetCompassResource() const +{ + Screen * cacheScreen = m_controller->GetCacheScreen(); + Icon::Info icon("compass-image"); + Resource const * res = m_controller->GetCacheScreen()->fromID(cacheScreen->findInfo(icon)); + ASSERT(res, ("Commpass-image not founded")); + return res; +} - m2::PointF const northRightPts[3] = { - m2::PointF(0, 0), - m2::PointF(0, -halfH), - m2::PointF(halfW, 0) - }; - cacheScreen->drawConvexPolygon(northRightPts, 3, m_northRightColor, depth()); +void CompassArrow::cache() +{ + graphics::Screen * cacheScreen = m_controller->GetCacheScreen(); - m2::PointF const southLeftPts[3] = { - m2::PointF(-halfW, 0), - m2::PointF(0, 0), - m2::PointF(0, halfH), - }; - cacheScreen->drawConvexPolygon(southLeftPts, 3, m_southLeftColor, depth()); + purge(); + m_displayList = cacheScreen->createDisplayList(); + + cacheScreen->beginFrame(); + cacheScreen->setDisplayList(m_displayList); + cacheScreen->applyVarAlfaStates(); + + Resource const * res = GetCompassResource(); + shared_ptr<gl::BaseTexture> texture = cacheScreen->pipeline(res->m_pipelineID).texture(); + m2::RectU rect = res->m_texRect; + double halfW = rect.SizeX() / 2.0; + double halfH = rect.SizeY() / 2.0; - m2::PointF const southRightPts[3] = { - m2::PointF(0, 0), - m2::PointF(halfW, 0), - m2::PointF(0, halfH), + m2::PointD coords[] = + { + m2::PointD(-halfW, -halfH), + m2::PointD(-halfW, halfH), + m2::PointD(halfW, -halfH), + m2::PointD(halfW, halfH), }; - cacheScreen->drawConvexPolygon(southRightPts, 3, m_southRightColor, depth()); - - m2::PointD outlinePts[6] = { - m2::PointD(-halfW, 0), - m2::PointD(0, -halfH), - m2::PointD(halfW, 0), - m2::PointD(0, halfH), - m2::PointD(-halfW, 0), - m2::PointD(halfW, 0) + + m2::PointF normal(0.0, 0.0); + m2::PointF texCoords[] = + { + texture->mapPixel(m2::PointF(rect.minX(), rect.minY())), + texture->mapPixel(m2::PointF(rect.minX(), rect.maxY())), + texture->mapPixel(m2::PointF(rect.maxX(), rect.minY())), + texture->mapPixel(m2::PointF(rect.maxX(), rect.maxY())), }; - graphics::Pen::Info const outlinePenInfo(graphics::Color(0x66, 0x66, 0x66, 0xcc), 1, 0, 0, 0); + cacheScreen->addTexturedStripStrided(coords, sizeof(m2::PointD), + &normal, 0, + texCoords, sizeof(m2::PointF), + 4, depth(), res->m_pipelineID); - cacheScreen->drawPath(outlinePts, - sizeof(outlinePts) / sizeof(m2::PointD), - 0, - cacheScreen->mapInfo(outlinePenInfo), - depth()); cacheScreen->setDisplayList(0); cacheScreen->endFrame(); - - // we should not call cacheScreen->completeCommands - // as the gui::Element::cache is called on the GUI thread. } void CompassArrow::purge() { - m_displayList.reset(); + delete m_displayList; + m_displayList = NULL; } bool CompassArrow::onTapEnded(m2::PointD const & pt) @@ -165,11 +277,6 @@ bool CompassArrow::onTapEnded(m2::PointD const & pt) return true; } -unsigned CompassArrow::GetArrowHeight() const -{ - return m_arrowHeight; -} - bool CompassArrow::roughHitTest(m2::PointD const & pt) const { return hitTest(pt); @@ -177,6 +284,7 @@ bool CompassArrow::roughHitTest(m2::PointD const & pt) const bool CompassArrow::hitTest(m2::PointD const & pt) const { - double rad = 1.5 * max(m_arrowWidth / 2, m_arrowHeight / 2); + Resource const * res = GetCompassResource(); + double rad = 1.5 * max(res->m_texRect.SizeX() / 2.0, res->m_texRect.SizeY() / 2.0); return pt.Length(pivot()) < rad * visualScale(); } |