[drape] object selection

This commit is contained in:
ExMix 2015-06-04 20:41:27 +03:00 committed by r.kuznetsov
parent 8e15f79d2d
commit eba6b49005
18 changed files with 591 additions and 52 deletions

View file

@ -0,0 +1,98 @@
#include "show_hide_animation.hpp"
#include "base_interpolator.hpp"
namespace df
{
class ShowHideAnimation::ShowHideInterpolator : public BaseInterpolator
{
public:
ShowHideInterpolator(ShowHideAnimation::EState & state, double startT, double endT, double duration)
: BaseInterpolator(duration)
, m_state(state)
, m_startT(startT)
, m_endT(endT)
{
m_state = m_endT > m_startT ? ShowHideAnimation::STATE_SHOW_DIRECTION : ShowHideAnimation::STATE_HIDE_DIRECTION;
}
void Advance(double elapsedSeconds) override
{
BaseInterpolator::Advance(elapsedSeconds);
if (IsFinished())
m_state = m_endT > m_startT ? ShowHideAnimation::STATE_VISIBLE : ShowHideAnimation::STATE_INVISIBLE;
}
double GetCurrentT() const
{
return m_startT + (m_endT - m_startT) * GetT();
}
private:
ShowHideAnimation::EState & m_state;
double m_startT;
double m_endT;
};
ShowHideAnimation::ShowHideAnimation(bool isInitialiVisible, double fullDuraction)
: m_state(isInitialiVisible ? STATE_VISIBLE : STATE_INVISIBLE)
, m_fullDuration(fullDuraction)
{
}
ShowHideAnimation::~ShowHideAnimation()
{
m_interpolator.reset();
}
void ShowHideAnimation::Show()
{
RefreshInterpolator({ STATE_VISIBLE, STATE_SHOW_DIRECTION }, 1.0);
}
void ShowHideAnimation::Hide()
{
//RefreshInterpolator({ STATE_INVISIBLE, STATE_HIDE_DIRECTION }, 0.0);
EState state = GetState();
if (state == STATE_VISIBLE || state == STATE_SHOW_DIRECTION)
{
m_state = STATE_INVISIBLE;
m_interpolator.reset();
}
}
ShowHideAnimation::EState ShowHideAnimation::GetState() const
{
return m_state;
}
double ShowHideAnimation::GetT() const
{
if (m_interpolator)
return m_interpolator->GetCurrentT();
ASSERT(m_state != STATE_SHOW_DIRECTION, ());
ASSERT(m_state != STATE_HIDE_DIRECTION, ());
return m_state == STATE_VISIBLE ? 1.0 : 0.0;
}
bool ShowHideAnimation::IsFinished() const
{
return m_interpolator == nullptr || m_interpolator->IsFinished();
}
void ShowHideAnimation::RefreshInterpolator(array<EState, 2> validStates, double endValue)
{
EState state = GetState();
if (state == validStates[0] || state == validStates[1])
return;
double start = GetT();
double end = endValue;
double duration = (end - start) * m_fullDuration;
m_interpolator.reset(new ShowHideInterpolator(m_state, start, end, duration));
}
} // namespace df

View file

@ -0,0 +1,39 @@
#pragma once
#include "drape/pointers.hpp"
#include "std/array.hpp"
namespace df
{
class ShowHideAnimation
{
public:
enum EState
{
STATE_INVISIBLE,
STATE_VISIBLE,
STATE_SHOW_DIRECTION,
STATE_HIDE_DIRECTION
};
ShowHideAnimation(bool isInitialiVisible, double fullDuraction);
~ShowHideAnimation();
void Show();
void Hide();
EState GetState() const;
double GetT() const;
bool IsFinished() const;
private:
void RefreshInterpolator(array<EState, 2> validStates, double endValue);
class ShowHideInterpolator;
drape_ptr<ShowHideInterpolator> m_interpolator;
ShowHideAnimation::EState m_state;
double m_fullDuration;
};
} // namespace df

View file

@ -213,10 +213,10 @@ void BackendRenderer::InitGLDependentResource()
m_texMng->Init(params);
drape_ptr<MyPosition> position = make_unique_dp<MyPosition>(m_texMng);
m_commutator->PostMessage(ThreadsCommutator::RenderThread,
make_unique_dp<MyPositionShapeMessage>(move(position)),
MessagePriority::High);
drape_ptr<MyPositionShapeMessage> msg = make_unique_dp<MyPositionShapeMessage>(make_unique_dp<MyPosition>(m_texMng),
make_unique_dp<SelectionShape>(m_texMng));
m_commutator->PostMessage(ThreadsCommutator::RenderThread, move(msg), MessagePriority::High);
}
void BackendRenderer::FlushGeometry(drape_ptr<Message> && message)

View file

@ -283,4 +283,18 @@ FeatureID DrapeEngine::GetVisiblePOI(m2::PointD const & glbPoint)
return result;
}
void DrapeEngine::SelectObject(SelectionShape::ESelectedObject obj, m2::PointD const & pt)
{
m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread,
make_unique_dp<SelectObjectMessage>(obj, pt),
MessagePriority::High);
}
void DrapeEngine::DeselectObject()
{
m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread,
make_unique_dp<SelectObjectMessage>(SelectObjectMessage::DismissTag()),
MessagePriority::High);
}
} // namespace df

View file

@ -3,6 +3,7 @@
#include "drape_frontend/backend_renderer.hpp"
#include "drape_frontend/frontend_renderer.hpp"
#include "drape_frontend/threads_commutator.hpp"
#include "drape_frontend/selection_shape.hpp"
#include "drape/pointers.hpp"
#include "drape/texture_manager.hpp"
@ -89,6 +90,8 @@ public:
void SetUserPositionListener(TUserPositionChangedFn const & fn);
FeatureID GetVisiblePOI(m2::PointD const & glbPoint);
void SelectObject(SelectionShape::ESelectedObject obj, m2::PointD const & pt);
void DeselectObject();
private:
void AddUserEvent(UserEvent const & e);

View file

@ -6,7 +6,7 @@ ROOT_DIR = ..
include($$ROOT_DIR/common.pri)
INCLUDEPATH *= $$ROOT_DIR/3party/protobuf/src
DEFINES += DRAW_INFO
#DEFINES += DRAW_INFO
SOURCES += \
animation/base_interpolator.cpp \
@ -52,6 +52,9 @@ SOURCES += \
user_marks_provider.cpp \
viewport.cpp \
visual_params.cpp \
selection_shape.cpp \
animation/show_hide_animation.cpp \
render_node.cpp
HEADERS += \
animation/base_interpolator.hpp \
@ -102,3 +105,6 @@ HEADERS += \
user_marks_provider.hpp \
viewport.hpp \
visual_params.hpp \
selection_shape.hpp \
animation/show_hide_animation.hpp \
render_node.hpp

View file

@ -193,7 +193,11 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
}
case Message::MyPositionShape:
m_myPositionController->SetRenderShape(ref_ptr<MyPositionShapeMessage>(message)->AcceptShape());
{
ref_ptr<MyPositionShapeMessage> msg = message;
m_myPositionController->SetRenderShape(msg->AcceptShape());
m_selectionShape = msg->AcceptSelection();
}
break;
case Message::ChangeMyPostitionMode:
@ -241,6 +245,24 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
break;
}
case Message::SelectObject:
{
ref_ptr<SelectObjectMessage> msg = message;
ASSERT(m_selectionShape != nullptr, ());
if (msg->IsDismiss())
{
m_selectionShape->Hide();
}
else
{
m_selectionShape->SetPosition(msg->GetPosition());
m_selectionShape->SetSelectedObject(msg->GetSelectedObject());
m_selectionShape->Hide();
m_selectionShape->Show();
}
break;
}
default:
ASSERT(false, ());
}
@ -425,30 +447,45 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView)
GLFunctions::glClear();
dp::GLState::DepthLayer prevLayer = dp::GLState::GeometryLayer;
for (drape_ptr<RenderGroup> const & group : m_renderGroups)
size_t currentRenderGroup = 0;
for (; currentRenderGroup < m_renderGroups.size(); ++currentRenderGroup)
{
group->UpdateAnimation();
drape_ptr<RenderGroup> const & group = m_renderGroups[currentRenderGroup];
dp::GLState const & state = group->GetState();
dp::GLState::DepthLayer layer = state.GetDepthLayer();
if (prevLayer != layer && layer == dp::GLState::OverlayLayer)
{
GLFunctions::glClearDepth();
m_myPositionController->Render(modelView, make_ref(m_gpuProgramManager), m_generalUniforms);
}
break;
prevLayer = layer;
ASSERT_LESS_OR_EQUAL(prevLayer, layer, ());
ref_ptr<dp::GpuProgram> program = m_gpuProgramManager->GetProgram(state.GetProgramIndex());
program->Bind();
ApplyUniforms(m_generalUniforms, program);
ApplyUniforms(group->GetUniforms(), program);
ApplyState(state, program);
group->Render(modelView);
RenderSingleGroup(modelView, make_ref(group));
}
GLFunctions::glClearDepth();
if (m_selectionShape != nullptr)
{
SelectionShape::ESelectedObject selectedObject = m_selectionShape->GetSelectedObject();
if (selectedObject == SelectionShape::OBJECT_MY_POSITION)
{
ASSERT(m_myPositionController->IsModeHasPosition(), ());
m_selectionShape->SetPosition(m_myPositionController->Position());
m_selectionShape->Render(modelView, make_ref(m_gpuProgramManager), m_generalUniforms);
}
else if (selectedObject == SelectionShape::OBJECT_POI)
m_selectionShape->Render(modelView, make_ref(m_gpuProgramManager), m_generalUniforms);
}
m_myPositionController->Render(modelView, make_ref(m_gpuProgramManager), m_generalUniforms);
for (; currentRenderGroup < m_renderGroups.size(); ++currentRenderGroup)
{
drape_ptr<RenderGroup> const & group = m_renderGroups[currentRenderGroup];
RenderSingleGroup(modelView, make_ref(group));
}
GLFunctions::glClearDepth();
if (m_selectionShape != nullptr && m_selectionShape->GetSelectedObject() == SelectionShape::OBJECT_USER_MARK)
m_selectionShape->Render(modelView, make_ref(m_gpuProgramManager), m_generalUniforms);
for (drape_ptr<UserMarkRenderGroup> const & group : m_userMarkRenderGroups)
{
@ -475,6 +512,20 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView)
#endif
}
void FrontendRenderer::RenderSingleGroup(ScreenBase const & modelView, ref_ptr<RenderGroup> group)
{
group->UpdateAnimation();
dp::GLState const & state = group->GetState();
ref_ptr<dp::GpuProgram> program = m_gpuProgramManager->GetProgram(state.GetProgramIndex());
program->Bind();
ApplyUniforms(m_generalUniforms, program);
ApplyUniforms(group->GetUniforms(), program);
ApplyState(state, program);
group->Render(modelView);
}
void FrontendRenderer::RefreshProjection()
{
array<float, 16> m;
@ -702,6 +753,7 @@ void FrontendRenderer::ReleaseResources()
m_userMarkRenderGroups.clear();
m_guiRenderer.reset();
m_myPositionController.reset();
m_selectionShape.release();
m_gpuProgramManager.reset();
}

View file

@ -14,9 +14,9 @@
#include "drape_frontend/tile_tree.hpp"
#include "drape_frontend/backend_renderer.hpp"
#include "drape_frontend/render_group.hpp"
#include "drape_frontend/my_position_controller.hpp"
#include "drape_frontend/navigator.hpp"
#include "drape_frontend/user_event_stream.hpp"
#include "drape_frontend/my_position_controller.hpp"
#include "drape_gui/layer_render.hpp"
@ -43,6 +43,8 @@ namespace dp
namespace df
{
class SelectionShape;
struct TapInfo
{
m2::PointD const m_pixelPoint;
@ -125,6 +127,7 @@ protected:
private:
void OnResize(ScreenBase const & screen);
void RenderScene(ScreenBase const & modelView);
void RenderSingleGroup(ScreenBase const & modelView, ref_ptr<RenderGroup> group);
void RefreshProjection();
void RefreshModelView(ScreenBase const & screen);
ScreenBase const & UpdateScene(bool & modelViewChanged);
@ -191,6 +194,7 @@ private:
drape_ptr<gui::LayerRenderer> m_guiRenderer;
drape_ptr<MyPositionController> m_myPositionController;
drape_ptr<SelectionShape> m_selectionShape;
drape_ptr<dp::OverlayTree> m_overlayTree;

View file

@ -29,7 +29,8 @@ public:
ChangeMyPostitionMode,
CompassInfo,
GpsInfo,
FindVisiblePOI
FindVisiblePOI,
SelectObject
};
virtual ~Message() {}

View file

@ -1,6 +1,7 @@
#pragma once
#include "drape_frontend/my_position.hpp"
#include "drape_frontend/selection_shape.hpp"
#include "drape_frontend/message.hpp"
#include "drape_frontend/viewport.hpp"
#include "drape_frontend/tile_utils.hpp"
@ -274,16 +275,19 @@ private:
class MyPositionShapeMessage : public Message
{
public:
MyPositionShapeMessage(drape_ptr<MyPosition> && shape)
MyPositionShapeMessage(drape_ptr<MyPosition> && shape, drape_ptr<SelectionShape> && selection)
: m_shape(move(shape))
, m_selection(move(selection))
{}
Type GetType() const override { return Message::MyPositionShape; }
drape_ptr<MyPosition> && AcceptShape() { return move(m_shape); }
drape_ptr<SelectionShape> AcceptSelection() { return move(m_selection); }
private:
drape_ptr<MyPosition> m_shape;
drape_ptr<SelectionShape> m_selection;
};
class StopRenderingMessage : public Message
@ -414,4 +418,31 @@ private:
FeatureID & m_featureID;
};
class SelectObjectMessage : public Message
{
public:
struct DismissTag {};
SelectObjectMessage(DismissTag)
: m_isDismiss(true)
{
}
SelectObjectMessage(SelectionShape::ESelectedObject selectedObject, m2::PointD const & glbPoint)
: m_selected(selectedObject)
, m_glbPoint(glbPoint)
, m_isDismiss(false)
{
}
Type GetType() const override { return SelectObject; }
m2::PointD const & GetPosition() const { return m_glbPoint; }
SelectionShape::ESelectedObject GetSelectedObject() const { return m_selected; }
bool IsDismiss() const { return m_isDismiss; }
private:
SelectionShape::ESelectedObject m_selected;
m2::PointD m_glbPoint;
bool m_isDismiss;
};
} // namespace df

View file

@ -1,6 +1,5 @@
#include "my_position.hpp"
#include "drape/batcher.hpp"
#include "drape/depth_constants.hpp"
#include "drape/glsl_func.hpp"
#include "drape/glsl_types.hpp"
@ -215,19 +214,7 @@ void MyPosition::RenderPart(ref_ptr<dp::GpuProgramManager> mng,
{
TPart const & accuracy = m_parts[part];
RenderNode & node = m_nodes[accuracy.second];
ref_ptr<dp::GpuProgram> prg = mng->GetProgram(node.m_state.GetProgramIndex());
prg->Bind();
if (!node.m_isBuilded)
{
node.m_buffer->Build(prg);
node.m_isBuilded = true;
}
dp::ApplyUniforms(uniforms, prg);
dp::ApplyState(node.m_state, prg);
node.m_buffer->RenderRange(accuracy.first);
node.Render(mng, uniforms, accuracy.first);
}
}

View file

@ -1,10 +1,13 @@
#pragma once
#include "render_node.hpp"
#include "drape/vertex_array_buffer.hpp"
#include "drape/glstate.hpp"
#include "drape/gpu_program_manager.hpp"
#include "drape/texture_manager.hpp"
#include "drape/uniform_values_storage.hpp"
#include "drape/batcher.hpp"
#include "geometry/screenbase.hpp"
@ -31,20 +34,6 @@ private:
void CachePointPosition(ref_ptr<dp::TextureManager> mng);
private:
struct RenderNode
{
RenderNode(dp::GLState const & state, drape_ptr<dp::VertexArrayBuffer> && buffer)
: m_state(state)
, m_buffer(move(buffer))
, m_isBuilded(false)
{
}
dp::GLState m_state;
drape_ptr<dp::VertexArrayBuffer> m_buffer;
bool m_isBuilded;
};
enum EMyPositionPart
{
// don't change order and values

View file

@ -0,0 +1,43 @@
#include "render_node.hpp"
#include "drape/vertex_array_buffer.hpp"
#include "drape/gpu_program_manager.hpp"
namespace df
{
RenderNode::RenderNode(dp::GLState const & state, drape_ptr<dp::VertexArrayBuffer> && buffer)
: m_state(state)
, m_buffer(move(buffer))
, m_isBuilded(false)
{
}
void RenderNode::Render(ref_ptr<dp::GpuProgramManager> mng, dp::UniformValuesStorage const & uniforms,
dp::IndicesRange const & range)
{
Apply(mng, uniforms);
m_buffer->RenderRange(range);
}
void RenderNode::Render(ref_ptr<dp::GpuProgramManager> mng, dp::UniformValuesStorage const & uniforms)
{
Apply(mng, uniforms);
m_buffer->Render();
}
void RenderNode::Apply(ref_ptr<dp::GpuProgramManager> mng, dp::UniformValuesStorage const & uniforms)
{
ref_ptr<dp::GpuProgram> prg = mng->GetProgram(m_state.GetProgramIndex());
prg->Bind();
if (!m_isBuilded)
{
m_buffer->Build(prg);
m_isBuilded = true;
}
dp::ApplyUniforms(uniforms, prg);
dp::ApplyState(m_state, prg);
}
}

View file

@ -0,0 +1,33 @@
#pragma once
#include "drape/glstate.hpp"
#include "drape/pointers.hpp"
namespace dp
{
class VertexArrayBuffer;
class GpuProgramManager;
struct IndicesRange;
}
namespace df
{
class RenderNode
{
public:
RenderNode(dp::GLState const & state, drape_ptr<dp::VertexArrayBuffer> && buffer);
void Render(ref_ptr<dp::GpuProgramManager> mng, dp::UniformValuesStorage const & uniforms);
void Render(ref_ptr<dp::GpuProgramManager> mng, dp::UniformValuesStorage const & uniforms, dp::IndicesRange const & range);
private:
void Apply(ref_ptr<dp::GpuProgramManager> mng, dp::UniformValuesStorage const & uniforms);
private:
dp::GLState m_state;
drape_ptr<dp::VertexArrayBuffer> m_buffer;
bool m_isBuilded;
};
}

View file

@ -0,0 +1,166 @@
#include "selection_shape.hpp"
#include "visual_params.hpp"
#include "drape/attribute_provider.hpp"
#include "drape/batcher.hpp"
#include "drape/binding_info.hpp"
#include "drape/glsl_func.hpp"
#include "drape/glsl_types.hpp"
#include "drape/gpu_program_manager.hpp"
#include "drape/shader_def.hpp"
#include "drape/texture_manager.hpp"
#include "drape/uniform_values_storage.hpp"
namespace df
{
namespace
{
struct Vertex
{
Vertex() = default;
Vertex(glsl::vec2 const & normal, glsl::vec2 const & texCoord)
: m_normal(normal)
, m_texCoord(texCoord)
{
}
glsl::vec2 m_normal;
glsl::vec2 m_texCoord;
};
dp::BindingInfo GetBindingInfo()
{
dp::BindingInfo info(2);
dp::BindingDecl & normal = info.GetBindingDecl(0);
normal.m_attributeName = "a_normal";
normal.m_componentCount = 2;
normal.m_componentType = gl_const::GLFloatType;
normal.m_offset = 0;
normal.m_stride = sizeof(Vertex);
dp::BindingDecl & texCoord = info.GetBindingDecl(1);
texCoord.m_attributeName = "a_colorTexCoords";
texCoord.m_componentCount = 2;
texCoord.m_componentType = gl_const::GLFloatType;
texCoord.m_offset = sizeof(glsl::vec2);
texCoord.m_stride = sizeof(Vertex);
return info;
}
} // namespace
SelectionShape::SelectionShape(ref_ptr<dp::TextureManager> mng)
: m_position(m2::PointD::Zero())
, m_animation(false, 0.25)
, m_selectionRadius(15.0f * VisualParams::Instance().GetVisualScale())
{
int const TriangleCount = 40;
int const VertexCount = 3 * TriangleCount;
float const etalonSector = math::twicePi / static_cast<double>(TriangleCount);
dp::TextureManager::ColorRegion color;
mng->GetColorRegion(dp::Color(0x17, 0xBF, 0x8E, 0x6F), color);
glsl::vec2 colorCoord = glsl::ToVec2(color.GetTexRect().Center());
buffer_vector<Vertex, TriangleCount> buffer;
glsl::vec2 startNormal(0.0f, 1.0f);
for (size_t i = 0; i < TriangleCount + 1; ++i)
{
glsl::vec2 normal = glsl::rotate(startNormal, i * etalonSector);
glsl::vec2 nextNormal = glsl::rotate(startNormal, (i + 1) * etalonSector);
buffer.emplace_back(startNormal, colorCoord);
buffer.emplace_back(normal, colorCoord);
buffer.emplace_back(nextNormal, colorCoord);
}
dp::GLState state(gpu::ACCURACY_PROGRAM, dp::GLState::OverlayLayer);
state.SetColorTexture(color.GetTexture());
{
dp::Batcher batcher(TriangleCount * dp::Batcher::IndexPerTriangle, VertexCount);
dp::SessionGuard guard(batcher, [this](dp::GLState const & state, drape_ptr<dp::RenderBucket> && b)
{
drape_ptr<dp::RenderBucket> bucket = move(b);
ASSERT(bucket->GetOverlayHandlesCount() == 0, ());
m_renderNode = make_unique_dp<RenderNode>(state, bucket->MoveBuffer());
});
dp::AttributeProvider provider(1 /*stream count*/, VertexCount);
provider.InitStream(0 /*stream index*/, GetBindingInfo(), make_ref(buffer.data()));
batcher.InsertTriangleList(state, make_ref(&provider), nullptr);
}
}
void SelectionShape::SetPosition(m2::PointD const & position)
{
m_position = position;
}
void SelectionShape::Show()
{
m_animation.Show();
}
void SelectionShape::Hide()
{
m_animation.Hide();
}
void SelectionShape::Render(ScreenBase const & screen, ref_ptr<dp::GpuProgramManager> mng,
dp::UniformValuesStorage const & commonUniforms)
{
ShowHideAnimation::EState state = m_animation.GetState();
if (state == ShowHideAnimation::STATE_VISIBLE ||
state == ShowHideAnimation::STATE_SHOW_DIRECTION)
{
dp::UniformValuesStorage uniforms = commonUniforms;
uniforms.SetFloatValue("u_position", m_position.x, m_position.y, 0.0);
uniforms.SetFloatValue("u_accuracy", GetCurrentRadius());
m_renderNode->Render(mng, uniforms);
}
}
void SelectionShape::SetSelectedObject(SelectionShape::ESelectedObject obj)
{
m_selectedObject = obj;
}
SelectionShape::ESelectedObject SelectionShape::GetSelectedObject() const
{
return m_selectedObject;
}
double SelectionShape::GetCurrentRadius() const
{
static double const firstT = 0.6;
static double const secondT = 0.85;
static double const thirdT = 1.0;
static double const dfsT = secondT - firstT;
static double const dstT = thirdT - secondT;
static double const firstRadius = 1.3 * m_selectionRadius;
static double const secondRadius = 0.8 * m_selectionRadius;
static double const dfsRadius = secondRadius - firstRadius;
static double const dstRadius = m_selectionRadius - secondRadius;
double t = m_animation.GetT();
if (m_animation.IsFinished())
return m_selectionRadius * t;
if (t < firstT)
return firstRadius * (t / firstT);
if (t < secondT)
return firstRadius + dfsRadius * (t - firstT) / dfsT;
return secondRadius + dstRadius * (t - secondT)/ dstT;
}
} // namespace df

View file

@ -0,0 +1,55 @@
#pragma once
#include "animation/show_hide_animation.hpp"
#include "render_node.hpp"
#include "geometry/point2d.hpp"
#include "geometry/screenbase.hpp"
namespace dp
{
class GpuProgramManager;
class UniformValuesStorage;
class TextureManager;
}
namespace df
{
class SelectionShape
{
public:
enum ESelectedObject
{
OBJECT_POI,
OBJECT_USER_MARK,
OBJECT_MY_POSITION
};
SelectionShape(ref_ptr<dp::TextureManager> mng);
void SetPosition(m2::PointD const & position);
void Show();
void Hide();
void Render(ScreenBase const & screen,
ref_ptr<dp::GpuProgramManager> mng,
dp::UniformValuesStorage const & commonUniforms);
void SetSelectedObject(ESelectedObject obj);
ESelectedObject GetSelectedObject() const;
private:
double GetCurrentRadius() const;
private:
m2::PointD m_position;
ShowHideAnimation m_animation;
ESelectedObject m_selectedObject;
drape_ptr<RenderNode> m_renderNode;
double const m_selectionRadius;
};
} // namespace df

View file

@ -1632,11 +1632,25 @@ void Framework::ActivateUserMark(UserMark const * mark, bool needAnim)
bool hasActive = activeMark != nullptr;
activeMark = mark;
if (mark)
{
m_activateUserMarkFn(mark->Copy());
m2::PointD pt = mark->GetPivot();
df::SelectionShape::ESelectedObject object = df::SelectionShape::OBJECT_USER_MARK;
UserMark::Type type = mark->GetMarkType();
if (type == UserMark::Type::MY_POSITION)
object = df::SelectionShape::OBJECT_MY_POSITION;
else if (type == UserMark::Type::POI)
object = df::SelectionShape::OBJECT_POI;
CallDrapeFunction(bind(&df::DrapeEngine::SelectObject, _1, object, pt));
}
else
{
if (hasActive)
{
m_activateUserMarkFn(nullptr);
CallDrapeFunction(bind(&df::DrapeEngine::DeselectObject, _1));
}
}
}
}

View file

@ -78,6 +78,10 @@ bool IsLocationEmulation(QMouseEvent * e)
QObject::connect(this, SIGNAL(heightChanged(int)), this, SLOT(sizeChanged(int)));
QObject::connect(this, SIGNAL(widthChanged(int)), this, SLOT(sizeChanged(int)));
m_framework->SetUserMarkActivationListener([](unique_ptr<UserMarkCopy> mark)
{
});
m_framework->SetRouteBuildingListener([] (routing::IRouter::ResultCode, vector<storage::TIndex> const &)
{
});