pin animation

This commit is contained in:
ExMix 2014-03-04 09:55:41 +03:00 committed by Alex Zolotarev
parent e559265e4e
commit e68d3d1ee3
3 changed files with 206 additions and 4 deletions

View file

@ -3,23 +3,196 @@
#include "../search/result.hpp"
#include "../anim/task.hpp"
#include "../anim/controller.hpp"
#include "../graphics/depth_constants.hpp"
#include "../graphics/opengl/base_texture.hpp"
#include "../graphics/display_list.hpp"
#include "../graphics/icon.hpp"
#include "../geometry/transformations.hpp"
#include "../gui/controller.hpp"
namespace
{
struct AnimPhase
{
AnimPhase(double endScale, double timeInterval)
: m_endScale(endScale)
, m_timeInterval(timeInterval)
{
}
double m_endScale;
double m_timeInterval;
};
class PinAnimation : public anim::Task
{
public:
PinAnimation(Framework & f)
: m_f(f)
, m_scale(0.0)
{
}
void AddAnimPhase(AnimPhase const & phase)
{
m_animPhases.push_back(phase);
}
virtual void OnStart(double ts)
{
m_startTime = ts;
m_startScale = m_scale;
m_phaseIndex = 0;
}
virtual void OnStep(double ts)
{
ASSERT(m_phaseIndex < m_animPhases.size(), ());
AnimPhase const * phase = &m_animPhases[m_phaseIndex];
double elapsedTime = ts - m_startTime;
if (elapsedTime > phase->m_timeInterval)
{
m_startTime = ts;
m_scale = phase->m_endScale;
m_startScale = m_scale;
m_phaseIndex++;
if (m_phaseIndex >= m_animPhases.size())
{
End();
return;
}
}
elapsedTime = ts - m_startTime;
double t = elapsedTime / phase->m_timeInterval;
m_scale = m_startScale + t * (phase->m_endScale - m_startScale);
m_f.Invalidate();
}
double GetScale() const
{
return m_scale;
}
private:
Framework & m_f;
vector<AnimPhase> m_animPhases;
size_t m_phaseIndex;
double m_scale;
double m_startTime;
double m_startScale;
};
}
PinClickManager::PinClickManager(Framework & f)
: m_f(f)
: m_searchPinDL(NULL)
, m_f(f)
, m_updateForLocation(false)
, m_hasPin(false)
{}
PinClickManager::~PinClickManager()
{
ASSERT(m_searchPinDL == NULL, ());
}
void PinClickManager::Shutdown()
{
delete m_searchPinDL;
m_searchPinDL = NULL;
}
void PinClickManager::RenderPolicyCreated(graphics::EDensity density)
{}
{
Shutdown();
}
void PinClickManager::LocationChanged(location::GpsInfo const & info)
{}
void PinClickManager::StartAnimation()
{
PinAnimation * anim = new PinAnimation(m_f);
anim->AddAnimPhase(AnimPhase(1.2, 0.15));
anim->AddAnimPhase(AnimPhase(0.8, 0.08));
anim->AddAnimPhase(AnimPhase(1, 0.05));
m_animTask.reset(anim);
m_f.GetAnimController()->AddTask(m_animTask);
}
void PinClickManager::ResetAnimation()
{
m_animTask.reset();
}
double PinClickManager::GetCurrentPinScale()
{
if (m_animTask != NULL)
{
PinAnimation * a = static_cast<PinAnimation *>(m_animTask.get());
return a->GetScale();
}
return 1.0;
}
graphics::DisplayList * PinClickManager::GetSearchPinDL()
{
using namespace graphics;
if (!m_searchPinDL)
{
Screen * cacheScreen = m_f.GetGuiController()->GetCacheScreen();
m_searchPinDL = cacheScreen->createDisplayList();
cacheScreen->beginFrame();
cacheScreen->setDisplayList(m_searchPinDL);
Icon::Info infoKey("search-result-active");
Resource const * res = cacheScreen->fromID(cacheScreen->findInfo(infoKey));
shared_ptr<gl::BaseTexture> texture = cacheScreen->pipeline(res->m_pipelineID).texture();
m2::RectU texRect = res->m_texRect;
double sizeX = texRect.SizeX();
double halfSizeX = sizeX / 2.0;
double sizeY = texRect.SizeY();
m2::PointD coords[] =
{
m2::PointD(-halfSizeX, -sizeY),
m2::PointD(-halfSizeX, 0.0),
m2::PointD(halfSizeX, -sizeY),
m2::PointD(halfSizeX, 0.0)
};
m2::PointF normal(0.0, 0.0);
m2::PointF texCoords[] =
{
texture->mapPixel(m2::PointF(texRect.minX(), texRect.minY())),
texture->mapPixel(m2::PointF(texRect.minX(), texRect.maxY())),
texture->mapPixel(m2::PointF(texRect.maxX(), texRect.minY())),
texture->mapPixel(m2::PointF(texRect.maxX(), texRect.maxY()))
};
cacheScreen->addTexturedStripStrided(coords, sizeof(m2::PointD),
&normal, 0,
texCoords, sizeof(m2::PointF),
4, graphics::poiAndBookmarkDepth, res->m_pipelineID);
cacheScreen->setDisplayList(NULL);
cacheScreen->endFrame();
}
return m_searchPinDL;
}
void PinClickManager::OnPositionClicked(m2::PointD const & pt)
{
m_positionListener(pt.x, pt.y);
@ -96,7 +269,10 @@ void PinClickManager::OnClick(m2::PointD const & pxPoint, bool isLongTouch)
{
OnDismiss();
m_hasPin = false;
ResetAnimation();
}
else
StartAnimation();
m_f.Invalidate();
}
@ -106,17 +282,29 @@ void PinClickManager::DrawPin(const shared_ptr<PaintEvent> & e)
if (m_hasPin)
{
Navigator const & navigator = m_f.GetNavigator();
InformationDisplay & informationDisplay = m_f.GetInformationDisplay();
m2::AnyRectD const & glbRect = navigator.Screen().GlobalRect();
// @todo change pin picture
if (glbRect.IsPointInside(m_pinGlobalLocation))
informationDisplay.drawPlacemark(e->drawer(), "search-result-active", navigator.GtoP(m_pinGlobalLocation));
{
m2::PointD pxPoint = navigator.GtoP(m_pinGlobalLocation);
graphics::DisplayList * dl = GetSearchPinDL();
double scale = GetCurrentPinScale();
LOG(LINFO, ("Pin Scale = ", scale));
math::Matrix<double, 3, 3> m = math::Shift(
math::Scale(math::Identity<double, 3>(),
scale, scale),
pxPoint.x, pxPoint.y);
e->drawer()->screen()->drawDisplayList(dl, m);
}
}
}
void PinClickManager::RemovePin()
{
ResetAnimation();
m_hasPin = false;
m_f.Invalidate();
}

View file

@ -11,6 +11,8 @@
class Framework;
class PaintEvent;
namespace anim { class Task; }
namespace graphics { class DisplayList; }
namespace location { class GpsInfo; }
namespace gui { class Element; }
namespace search { struct AddressInfo; }
@ -22,6 +24,14 @@ namespace url_scheme
class PinClickManager
{
shared_ptr<anim::Task> m_animTask;
void StartAnimation();
void ResetAnimation();
double GetCurrentPinScale();
graphics::DisplayList * m_searchPinDL;
graphics::DisplayList * GetSearchPinDL();
Framework & m_f;
bool m_updateForLocation;
@ -35,6 +45,9 @@ class PinClickManager
public:
PinClickManager(Framework & f);
~PinClickManager();
void Shutdown();
void RenderPolicyCreated(graphics::EDensity density);
void LocationChanged(location::GpsInfo const & info);

View file

@ -617,6 +617,7 @@ void Framework::GetLocalMaps(vector<string> & outMaps) const
void Framework::PrepareToShutdown()
{
m_balloonManager.Shutdown();
SetRenderPolicy(0);
}