forked from organicmaps/organicmaps
pin animation
This commit is contained in:
parent
e559265e4e
commit
e68d3d1ee3
3 changed files with 206 additions and 4 deletions
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -617,6 +617,7 @@ void Framework::GetLocalMaps(vector<string> & outMaps) const
|
|||
|
||||
void Framework::PrepareToShutdown()
|
||||
{
|
||||
m_balloonManager.Shutdown();
|
||||
SetRenderPolicy(0);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue