Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorExMix <rahuba.youri@mapswithme.com>2014-03-05 17:37:05 +0400
committerAlex Zolotarev <alex@maps.me>2015-09-23 02:12:28 +0300
commit085671af831192739bbf8d98af05f97eaa2de144 (patch)
tree6dc0a75b3a5c1f81ef9aaec1dcff63f201914ba0 /map/compass_arrow.cpp
parent3f0c39f347820359cd3b551e84bec3deb4cbbb3c (diff)
new compass with animation
Diffstat (limited to 'map/compass_arrow.cpp')
-rw-r--r--map/compass_arrow.cpp248
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();
}