WIP: [core] Add Speed Limit widget #5233
28 changed files with 461 additions and 28 deletions
|
@ -35,6 +35,7 @@ public final class Map
|
|||
public static final int WIDGET_COMPASS = 0x02;
|
||||
public static final int WIDGET_COPYRIGHT = 0x04;
|
||||
public static final int WIDGET_SCALE_FPS_LABEL = 0x08;
|
||||
public static final int WIDGET_SPEED_LIMIT = 0x10;
|
||||
|
||||
// Should correspond to dp::Anchor from drape_global.hpp
|
||||
public static final int ANCHOR_CENTER = 0x00;
|
||||
|
@ -328,11 +329,13 @@ public final class Map
|
|||
if (mDisplayType == DisplayType.Device)
|
||||
{
|
||||
nativeSetupWidget(WIDGET_SCALE_FPS_LABEL, UiUtils.dimen(context, R.dimen.margin_base), UiUtils.dimen(context, R.dimen.margin_base) * 2, ANCHOR_LEFT_TOP);
|
||||
nativeSetupWidget(WIDGET_SPEED_LIMIT, mWidth / 2, mHeight / 2, ANCHOR_CENTER);
|
||||
updateCompassOffset(context, mCurrentCompassOffsetX, mCurrentCompassOffsetY, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
nativeSetupWidget(WIDGET_SCALE_FPS_LABEL, UiUtils.dimen(context, R.dimen.margin_base), mHeight - UiUtils.dimen(context, R.dimen.margin_base) * 5, ANCHOR_LEFT_TOP);
|
||||
nativeSetupWidget(WIDGET_SPEED_LIMIT, mWidth / 2, mHeight / 2, ANCHOR_CENTER);
|
||||
updateCompassOffset(context, mWidth, mCurrentCompassOffsetY, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,11 +23,6 @@ Color::Color(uint32_t rgba)
|
|||
: m_rgba(rgba)
|
||||
{}
|
||||
|
||||
Color::Color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
|
||||
{
|
||||
m_rgba = red << 24 | green << 16 | blue << 8 | alpha;
|
||||
}
|
||||
|
||||
uint8_t Color::GetRed() const
|
||||
{
|
||||
return EXTRACT_BYTE(m_rgba, 3);
|
||||
|
|
|
@ -12,7 +12,10 @@ struct Color
|
|||
{
|
||||
Color();
|
||||
explicit Color(uint32_t rgba);
|
||||
Color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha);
|
||||
constexpr Color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
|
||||
: m_rgba(red << 24 | green << 16 | blue << 8 | alpha)
|
||||
{
|
||||
}
|
||||
|
||||
uint8_t GetRed() const;
|
||||
uint8_t GetGreen() const;
|
||||
|
@ -37,13 +40,13 @@ struct Color
|
|||
|
||||
void PremultiplyAlpha(float opacity);
|
||||
|
||||
static Color Black() { return Color(0, 0, 0, 255); }
|
||||
static Color White() { return Color(255, 255, 255, 255); }
|
||||
static Color Red() { return Color(255, 0, 0, 255); }
|
||||
static Color Blue() { return Color(0, 0, 255, 255); }
|
||||
static Color Green() { return Color(0, 255, 0, 255); }
|
||||
static Color Yellow() { return Color(255, 255, 0, 255); }
|
||||
static Color Transparent() { return Color(0, 0, 0, 0); }
|
||||
static constexpr Color Black() { return Color(0, 0, 0, 255); }
|
||||
static constexpr Color White() { return Color(255, 255, 255, 255); }
|
||||
static constexpr Color Red() { return Color(255, 0, 0, 255); }
|
||||
static constexpr Color Blue() { return Color(0, 0, 255, 255); }
|
||||
static constexpr Color Green() { return Color(0, 255, 0, 255); }
|
||||
static constexpr Color Yellow() { return Color(255, 255, 0, 255); }
|
||||
static constexpr Color Transparent() { return Color(0, 0, 0, 0); }
|
||||
|
||||
private:
|
||||
uint32_t m_rgba;
|
||||
|
|
|
@ -77,6 +77,8 @@ set(SRC
|
|||
gps_track_point.hpp
|
||||
gps_track_renderer.cpp
|
||||
gps_track_renderer.hpp
|
||||
gui/elements/circle.cpp
|
||||
gui/elements/circle.hpp
|
||||
gui/choose_position_mark.cpp
|
||||
gui/choose_position_mark.hpp
|
||||
gui/compass.cpp
|
||||
|
@ -100,6 +102,10 @@ set(SRC
|
|||
gui/shape.hpp
|
||||
gui/skin.cpp
|
||||
gui/skin.hpp
|
||||
gui/speed_limit.cpp
|
||||
gui/speed_limit.hpp
|
||||
gui/speed_limit_helper.hpp
|
||||
gui/speed_limit_helper.cpp
|
||||
kinetic_scroller.cpp
|
||||
kinetic_scroller.hpp
|
||||
line_shape.cpp
|
||||
|
|
|
@ -497,6 +497,11 @@ void DrapeEngine::SetGpsInfo(location::GpsInfo const & info, bool isNavigable,
|
|||
MessagePriority::Normal);
|
||||
}
|
||||
|
||||
void DrapeEngine::SetSpeedLimitInfo(double speedLimitMps) const
|
||||
{
|
||||
gui::DrapeGui::Instance().GetSpeedLimitHelper().SetSpeedLimit(speedLimitMps);
|
||||
}
|
||||
|
||||
void DrapeEngine::SwitchMyPositionNextMode()
|
||||
{
|
||||
using Mode = ChangeMyPositionModeMessage::EChangeType;
|
||||
|
|
|
@ -156,6 +156,7 @@ public:
|
|||
void SetCompassInfo(location::CompassInfo const & info);
|
||||
void SetGpsInfo(location::GpsInfo const & info, bool isNavigable,
|
||||
location::RouteMatchingInfo const & routeInfo);
|
||||
void SetSpeedLimitInfo(double speedLimitMps) const;
|
||||
void SwitchMyPositionNextMode();
|
||||
void LoseLocation();
|
||||
void StopLocationFollow();
|
||||
|
|
|
@ -13,6 +13,7 @@ df::ColorConstant const kGuiTextColor = "GuiText";
|
|||
struct DrapeGui::Impl
|
||||
{
|
||||
RulerHelper m_rulerHelper;
|
||||
SpeedLimitHelper m_speedLimitHelper;
|
||||
};
|
||||
|
||||
DrapeGui::DrapeGui()
|
||||
|
@ -33,6 +34,11 @@ RulerHelper & DrapeGui::GetRulerHelper()
|
|||
return Instance().GetRulerHelperImpl();
|
||||
}
|
||||
|
||||
SpeedLimitHelper & DrapeGui::GetSpeedLimitHelper()
|
||||
{
|
||||
return Instance().GetSpeedLimitHelperImpl();
|
||||
}
|
||||
|
||||
dp::FontDecl DrapeGui::GetGuiTextFont()
|
||||
{
|
||||
return {df::GetColorConstant(kGuiTextColor), 14};
|
||||
|
@ -62,6 +68,12 @@ RulerHelper & DrapeGui::GetRulerHelperImpl()
|
|||
return m_impl->m_rulerHelper;
|
||||
}
|
||||
|
||||
SpeedLimitHelper & DrapeGui::GetSpeedLimitHelperImpl()
|
||||
{
|
||||
ASSERT(m_impl != nullptr, ());
|
||||
return m_impl->m_speedLimitHelper;
|
||||
}
|
||||
|
||||
void DrapeGui::ConnectOnCompassTappedHandler(Shape::TTapHandler const & handler)
|
||||
{
|
||||
m_onCompassTappedHandler = handler;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "drape_frontend/gui/compass.hpp"
|
||||
#include "drape_frontend/gui/scale_fps_helper.hpp"
|
||||
#include "drape_frontend/gui/skin.hpp"
|
||||
#include "drape_frontend/gui/speed_limit_helper.hpp"
|
||||
|
||||
#include "storage/storage_defines.hpp"
|
||||
|
||||
|
@ -23,6 +24,7 @@ class DrapeGui
|
|||
public:
|
||||
static DrapeGui & Instance();
|
||||
static RulerHelper & GetRulerHelper();
|
||||
static SpeedLimitHelper & GetSpeedLimitHelper();
|
||||
|
||||
static dp::FontDecl GetGuiTextFont();
|
||||
|
||||
|
@ -45,6 +47,7 @@ public:
|
|||
private:
|
||||
DrapeGui();
|
||||
RulerHelper & GetRulerHelperImpl();
|
||||
SpeedLimitHelper & GetSpeedLimitHelperImpl();
|
||||
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> m_impl;
|
||||
|
|
107
drape_frontend/gui/elements/circle.cpp
Normal file
107
drape_frontend/gui/elements/circle.cpp
Normal file
|
@ -0,0 +1,107 @@
|
|||
#include "circle.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
struct CircleVertex
|
||||
{
|
||||
CircleVertex() = default;
|
||||
|
||||
CircleVertex(glsl::vec2 position, glsl::vec3 color, glsl::vec3 outlineColor, float radius, float outlineWidthRatio)
|
||||
: m_position(position)
|
||||
, m_color(color)
|
||||
, m_outlineColor(outlineColor)
|
||||
, m_radius(radius)
|
||||
, m_outlineWidthRatio(outlineWidthRatio)
|
||||
{
|
||||
}
|
||||
|
||||
static dp::BindingInfo GetBindingInfo()
|
||||
{
|
||||
dp::BindingFiller<CircleVertex> filler(5);
|
||||
filler.FillDecl<glsl::vec2>("a_position");
|
||||
filler.FillDecl<glsl::vec3>("a_color");
|
||||
filler.FillDecl<glsl::vec3>("a_outlineColor");
|
||||
filler.FillDecl<float>("a_radius");
|
||||
filler.FillDecl<float>("a_outlineWidthRatio");
|
||||
return filler.m_info;
|
||||
}
|
||||
|
||||
glsl::vec2 m_position{};
|
||||
glsl::vec3 m_color{};
|
||||
glsl::vec3 m_outlineColor{};
|
||||
float m_radius{};
|
||||
float m_outlineWidthRatio{};
|
||||
};
|
||||
|
||||
using CircleVertexData = buffer_vector<CircleVertex, dp::Batcher::VertexPerQuad>;
|
||||
|
||||
CircleVertexData createCircleVertexData(glsl::vec3 color, glsl::vec3 outlineColor, float radius,
|
||||
float outlineWidthRatio)
|
||||
{
|
||||
CircleVertexData data;
|
||||
data.emplace_back(glsl::vec2(-1.0, 1.0), color, outlineColor, radius, outlineWidthRatio);
|
||||
data.emplace_back(glsl::vec2(-1.0, -1.0), color, outlineColor, radius, outlineWidthRatio);
|
||||
data.emplace_back(glsl::vec2(1.0, 1.0), color, outlineColor, radius, outlineWidthRatio);
|
||||
data.emplace_back(glsl::vec2(1.0, -1.0), color, outlineColor, radius, outlineWidthRatio);
|
||||
return data;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace gui::elements
|
||||
{
|
||||
CircleHandle::CircleHandle(uint32_t id, dp::Anchor anchor, const m2::PointF & pivot, const m2::PointF & size)
|
||||
: Handle(id, anchor, pivot, size)
|
||||
{
|
||||
SetIsVisible(true);
|
||||
}
|
||||
|
||||
void Circle::SetHandleId(uint32_t handleId) { m_handleId = handleId; }
|
||||
|
||||
void Circle::SetPosition(const Position & position) { m_position = position; }
|
||||
|
||||
void Circle::SetRadius(float radius) { m_radius = radius; }
|
||||
|
||||
void Circle::SetOutlineWidthRatio(float widthRatio) { m_outlineWidthRatio = widthRatio; }
|
||||
|
||||
void Circle::SetColor(dp::Color const & color) { m_color = color; }
|
||||
|
||||
void Circle::SetOutlineColor(dp::Color const & color) { m_outlineColor = color; }
|
||||
|
||||
void Circle::SetHandleCreator(HandleCreator handleCreator)
|
||||
{
|
||||
m_handleCreator = std::move(handleCreator);
|
||||
}
|
||||
|
||||
|
||||
void Circle::Draw(ref_ptr<dp::GraphicsContext> context, ShapeControl & control) const
|
||||
{
|
||||
Validate();
|
||||
|
||||
float const radiusInPixels = m_radius * df::VisualParams::Instance().GetVisualScale();
|
||||
CircleVertexData data =
|
||||
createCircleVertexData(glsl::ToVec3(m_color), glsl::ToVec3(m_outlineColor), radiusInPixels, m_outlineWidthRatio);
|
||||
|
||||
auto state = df::CreateRenderState(gpu::Program::GuiCircle, df::DepthLayer::GuiLayer);
|
||||
state.SetDepthTestEnabled(false);
|
||||
|
||||
dp::AttributeProvider provider(1, 4);
|
||||
provider.InitStream(0, CircleVertex::GetBindingInfo(), make_ref(data.data()));
|
||||
drape_ptr<dp::OverlayHandle> handle = m_handleCreator(
|
||||
m_handleId, m_position.m_anchor, m_position.m_pixelPivot, m2::PointF{radiusInPixels * 2, radiusInPixels * 2});
|
||||
|
||||
dp::Batcher batcher(dp::Batcher::IndexPerQuad, dp::Batcher::VertexPerQuad);
|
||||
batcher.SetBatcherHash(static_cast<uint64_t>(df::BatcherBucket::Default));
|
||||
dp::SessionGuard guard(context, batcher, std::bind(&ShapeControl::AddShape, &control, _1, _2));
|
||||
batcher.InsertTriangleStrip(context, state, make_ref(&provider), std::move(handle));
|
||||
}
|
||||
|
||||
void Circle::Validate() const
|
||||
{
|
||||
ASSERT_NOT_EQUAL(m_handleId, 0, ("Handle id must be set."));
|
||||
ASSERT_EQUAL(m_position.m_anchor, dp::Center, ("Only dp::Center is supported for Circle."));
|
||||
ASSERT_NOT_EQUAL(m_radius, 0.0f, ("Radius must be set."));
|
||||
ASSERT_GREATER_OR_EQUAL(m_outlineWidthRatio, 0.0f, ("Outline width ratio must be in the range [0.0, 1.0]."));
|
||||
ASSERT_LESS_OR_EQUAL(m_outlineWidthRatio, 1.0f, ("Outline width ratio must be in the range [0.0, 1.0]."));
|
||||
ASSERT_NOT_EQUAL(m_color, dp::Color::Transparent(), ("Color must be set."));
|
||||
ASSERT(m_handleCreator, ("HandleCreator must be set."));
|
||||
}
|
||||
} // namespace gui::elements
|
42
drape_frontend/gui/elements/circle.hpp
Normal file
42
drape_frontend/gui/elements/circle.hpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
#pragma once
|
||||
|
||||
#include "drape_frontend/gui/shape.hpp"
|
||||
|
||||
namespace gui::elements
|
||||
{
|
||||
class CircleHandle : public Handle
|
||||
{
|
||||
public:
|
||||
CircleHandle(uint32_t id, dp::Anchor anchor, m2::PointF const & pivot, m2::PointF const & size);
|
||||
};
|
||||
|
||||
class Circle
|
||||
{
|
||||
public:
|
||||
using HandleCreator =
|
||||
std::function<drape_ptr<CircleHandle>(uint32_t, dp::Anchor, m2::PointF const &, m2::PointF const &)>;
|
||||
|
||||
Circle() = default;
|
||||
|
||||
void SetHandleId(uint32_t handleId);
|
||||
void SetPosition(Position const & position);
|
||||
void SetRadius(float radius);
|
||||
void SetOutlineWidthRatio(float widthRatio);
|
||||
void SetColor(dp::Color const & color);
|
||||
void SetOutlineColor(dp::Color const & color);
|
||||
void SetHandleCreator(HandleCreator handleCreator);
|
||||
|
||||
void Draw(ref_ptr<dp::GraphicsContext> context, ShapeControl & control) const;
|
||||
|
||||
private:
|
||||
void Validate() const;
|
||||
|
||||
uint32_t m_handleId = 0;
|
||||
Position m_position{};
|
||||
float m_radius = 0.0f;
|
||||
float m_outlineWidthRatio = 0.0f;
|
||||
dp::Color m_color = dp::Color::Transparent();
|
||||
dp::Color m_outlineColor = dp::Color::Transparent();
|
||||
HandleCreator m_handleCreator;
|
||||
};
|
||||
} // namespace gui::elements
|
|
@ -348,9 +348,25 @@ void MutableLabel::Precache(PrecacheParams const & params, PrecacheResult & resu
|
|||
glsl::vec2 colorTex = glsl::ToVec2(color.GetTexRect().Center());
|
||||
glsl::vec2 outlineTex = glsl::ToVec2(outlineColor.GetTexRect().Center());
|
||||
|
||||
uint32_t maxGlyphWidth = 0;
|
||||
uint32_t maxGlyphHeight = 0;
|
||||
for (const auto & node : m_alphabet)
|
||||
{
|
||||
dp::TextureManager::GlyphRegion const & reg = node.second;
|
||||
m2::PointU pixelSize(reg.GetPixelSize());
|
||||
maxGlyphWidth = std::max(maxGlyphWidth, pixelSize.x);
|
||||
maxGlyphHeight = std::max(maxGlyphHeight, pixelSize.y);
|
||||
}
|
||||
|
||||
float offsetWidth = 0;
|
||||
if (params.m_anchor == dp::Center)
|
||||
{
|
||||
offsetWidth -= maxGlyphWidth / (1.5f * vparams.GetVisualScale());
|
||||
}
|
||||
![]() 1.5 is an experiment? Don't forget 1.5 is an experiment? Don't forget
|
||||
|
||||
auto const vertexCount = static_cast<size_t>(m_maxLength) * 4;
|
||||
result.m_buffer.resize(vertexCount,
|
||||
StaticVertex(glsl::vec3(0.0, 0.0, 0.0), colorTex, outlineTex));
|
||||
StaticVertex(glsl::vec3(offsetWidth, 0.0, 0.0), colorTex, outlineTex));
|
||||
|
||||
float depth = 0.0f;
|
||||
for (size_t i = 0; i < vertexCount; i += 4)
|
||||
|
@ -362,16 +378,6 @@ void MutableLabel::Precache(PrecacheParams const & params, PrecacheResult & resu
|
|||
depth += 10.0f;
|
||||
}
|
||||
|
||||
uint32_t maxGlyphWidth = 0;
|
||||
uint32_t maxGlyphHeight = 0;
|
||||
for (const auto & node : m_alphabet)
|
||||
{
|
||||
dp::TextureManager::GlyphRegion const & reg = node.second;
|
||||
m2::PointU pixelSize(reg.GetPixelSize());
|
||||
maxGlyphWidth = std::max(maxGlyphWidth, pixelSize.x);
|
||||
maxGlyphHeight = std::max(maxGlyphHeight, pixelSize.y);
|
||||
}
|
||||
|
||||
result.m_maxPixelSize = m2::PointF(m_maxLength * maxGlyphWidth, maxGlyphHeight);
|
||||
}
|
||||
|
||||
|
@ -556,6 +562,7 @@ m2::PointF MutableLabelDrawer::Draw(ref_ptr<dp::GraphicsContext> context, Params
|
|||
drape_ptr<MutableLabelHandle> handle = params.m_handleCreator(params.m_anchor, params.m_pivot);
|
||||
|
||||
MutableLabel::PrecacheParams preCacheP;
|
||||
preCacheP.m_anchor = params.m_anchor;
|
||||
preCacheP.m_alphabet = params.m_alphabet;
|
||||
preCacheP.m_font = params.m_font;
|
||||
preCacheP.m_maxLength = params.m_maxLength;
|
||||
|
|
|
@ -95,6 +95,7 @@ public:
|
|||
|
||||
struct PrecacheParams
|
||||
{
|
||||
dp::Anchor m_anchor;
|
||||
std::string m_alphabet;
|
||||
size_t m_maxLength;
|
||||
dp::FontDecl m_font;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "drape_frontend/gui/layer_render.hpp"
|
||||
#include "drape_frontend/gui/ruler.hpp"
|
||||
#include "drape_frontend/gui/ruler_helper.hpp"
|
||||
#include "drape_frontend/gui/speed_limit.hpp"
|
||||
|
||||
#include "drape_frontend/visual_params.hpp"
|
||||
|
||||
|
@ -206,6 +207,7 @@ drape_ptr<LayerRenderer> LayerCacher::RecacheWidgets(ref_ptr<dp::GraphicsContext
|
|||
{WIDGET_RULER, std::bind(&LayerCacher::CacheRuler, this, _1, _2, _3, _4)},
|
||||
{WIDGET_COPYRIGHT, std::bind(&LayerCacher::CacheCopyright, this, _1, _2, _3, _4)},
|
||||
{WIDGET_SCALE_FPS_LABEL, std::bind(&LayerCacher::CacheScaleFpsLabel, this, _1, _2, _3, _4)},
|
||||
{WIDGET_SPEED_LIMIT, std::bind(&LayerCacher::CacheSpeedLimit, this, _1, _2, _3, _4)},
|
||||
};
|
||||
|
||||
drape_ptr<LayerRenderer> renderer = make_unique_dp<LayerRenderer>();
|
||||
|
@ -397,4 +399,14 @@ m2::PointF LayerCacher::CacheScaleFpsLabel(ref_ptr<dp::GraphicsContext> context,
|
|||
renderer->AddShapeRenderer(WIDGET_SCALE_FPS_LABEL, std::move(scaleRenderer));
|
||||
return size;
|
||||
}
|
||||
|
||||
m2::PointF LayerCacher::CacheSpeedLimit(ref_ptr<dp::GraphicsContext> context,
|
||||
Position const & position, ref_ptr<LayerRenderer> renderer,
|
||||
ref_ptr<dp::TextureManager> textures)
|
||||
{
|
||||
drape_ptr<ShapeRenderer> shape = SpeedLimit(position).Draw(context, textures);
|
||||
renderer->AddShapeRenderer(WIDGET_SPEED_LIMIT, std::move(shape));
|
||||
|
||||
return {};
|
||||
}
|
||||
} // namespace gui
|
||||
|
|
|
@ -80,5 +80,7 @@ private:
|
|||
ref_ptr<dp::TextureManager> textures);
|
||||
m2::PointF CacheWatermark(ref_ptr<dp::GraphicsContext> context, Position const & position,
|
||||
ref_ptr<LayerRenderer> renderer, ref_ptr<dp::TextureManager> textures);
|
||||
m2::PointF CacheSpeedLimit(ref_ptr<dp::GraphicsContext> context, Position const & position,
|
||||
ref_ptr<LayerRenderer> renderer, ref_ptr<dp::TextureManager> textures);
|
||||
};
|
||||
} // namespace gui
|
||||
|
|
|
@ -19,6 +19,7 @@ enum EWidget
|
|||
WIDGET_COMPASS = 0x2,
|
||||
WIDGET_COPYRIGHT = 0x4,
|
||||
WIDGET_SCALE_FPS_LABEL = 0x8,
|
||||
WIDGET_SPEED_LIMIT = 0x10,
|
||||
// The following widgets are controlled by the engine. Don't use them in platform code.
|
||||
WIDGET_CHOOSE_POSITION_MARK = 0x8000,
|
||||
#ifdef RENDER_DEBUG_INFO_LABELS
|
||||
|
@ -31,6 +32,8 @@ enum EGuiHandle
|
|||
GuiHandleScaleLabel,
|
||||
GuiHandleCopyright,
|
||||
GuiHandleCompass,
|
||||
GuiHandleSpeedSign,
|
||||
GuiHandleSpeedSignLabel,
|
||||
GuiHandleRuler,
|
||||
GuiHandleRulerLabel,
|
||||
GuiHandleChoosePositionMark,
|
||||
|
|
102
drape_frontend/gui/speed_limit.cpp
Normal file
102
drape_frontend/gui/speed_limit.cpp
Normal file
|
@ -0,0 +1,102 @@
|
|||
#include "drape_frontend/gui/speed_limit.hpp"
|
||||
|
||||
#include "drape_frontend/animation/show_hide_animation.hpp"
|
||||
#include "drape_frontend/gui/drape_gui.hpp"
|
||||
|
||||
#include "shaders/programs.hpp"
|
||||
|
||||
#include "drape/glsl_func.hpp"
|
||||
#include "drape/glsl_types.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
using namespace std::placeholders;
|
||||
|
||||
namespace gui
|
||||
{
|
||||
namespace
|
||||
{
|
||||
class TextHandle : public MutableLabelHandle
|
||||
{
|
||||
using TBase = MutableLabelHandle;
|
||||
|
||||
public:
|
||||
TextHandle(uint32_t id, m2::PointF const & pivot, ref_ptr<dp::TextureManager> textures)
|
||||
: TBase(id, dp::Center, pivot)
|
||||
{
|
||||
SetTextureManager(textures);
|
||||
}
|
||||
|
||||
private:
|
||||
bool Update(ScreenBase const & screen) override
|
||||
{
|
||||
SpeedLimitHelper const & helper = DrapeGui::Instance().GetSpeedLimitHelper();
|
||||
SetIsVisible(helper.IsSpeedLimitAvailable());
|
||||
if (IsVisible())
|
||||
{
|
||||
SetContent(helper.GetSpeedLimit());
|
||||
}
|
||||
|
||||
return TBase::Update(screen);
|
||||
}
|
||||
};
|
||||
|
||||
class BackgroundHandle : public elements::CircleHandle
|
||||
{
|
||||
public:
|
||||
using CircleHandle::CircleHandle;
|
||||
|
||||
bool Update(const ScreenBase & screen) override
|
||||
{
|
||||
SpeedLimitHelper const & helper = DrapeGui::Instance().GetSpeedLimitHelper();
|
||||
SetIsVisible(helper.IsSpeedLimitAvailable());
|
||||
return CircleHandle::Update(screen);
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
SpeedLimit::SpeedLimit(const Position & position) : Shape(position)
|
||||
{
|
||||
m_background.SetHandleId(EGuiHandle::GuiHandleSpeedSign);
|
||||
m_background.SetPosition(position);
|
||||
m_background.SetRadius(Config::kBackgroundRadius);
|
||||
m_background.SetOutlineWidthRatio(Config::kBackgroundOutlineWidthRatio);
|
||||
m_background.SetColor(Config::kBackgroundColor);
|
||||
m_background.SetOutlineColor(Config::kBackgroundOutlineColor);
|
||||
m_background.SetHandleCreator(
|
||||
[](uint32_t id, dp::Anchor anchor, m2::PointF const & pivot, m2::PointF const & size)
|
||||
{ return make_unique_dp<BackgroundHandle>(id, anchor, pivot, size); });
|
||||
![]() Hm, probably not related to this PR (or GUI elements arch), but from my perspective, the whole SpeedLimit should be one GUI-handle element, but we create separate handles, (text, circle) .. Hm, probably not related to this PR (or GUI elements arch), but from my perspective, the whole SpeedLimit should be one GUI-handle element, but we create separate handles, (text, circle) ..
AndrewShkrob
commented
Do you have any idea or example how to make only one handle for many shapes? Do you have any idea or example how to make only one handle for many shapes?
|
||||
}
|
||||
|
||||
drape_ptr<ShapeRenderer> SpeedLimit::Draw(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::TextureManager> tex) const
|
||||
{
|
||||
ShapeControl control;
|
||||
m_background.Draw(context, control);
|
||||
DrawText(context, control, tex);
|
||||
|
||||
drape_ptr<ShapeRenderer> renderer = make_unique_dp<ShapeRenderer>();
|
||||
renderer->AddShapeControl(std::move(control));
|
||||
return renderer;
|
||||
}
|
||||
|
||||
void SpeedLimit::DrawText(ref_ptr<dp::GraphicsContext> context, ShapeControl & control,
|
||||
ref_ptr<dp::TextureManager> tex) const
|
||||
{
|
||||
ASSERT_EQUAL(m_position.m_anchor, dp::Center, ());
|
||||
|
||||
MutableLabelDrawer::Params params;
|
||||
params.m_anchor = m_position.m_anchor;
|
||||
params.m_alphabet = "0123456789";
|
||||
params.m_maxLength = 3;
|
||||
params.m_font = DrapeGui::GetGuiTextFont();
|
||||
params.m_font.m_color = Config::kTextColor;
|
||||
params.m_font.m_outlineColor = Config::kTextColor;
|
||||
params.m_font.m_size *= df::VisualParams::Instance().GetVisualScale() * 0.8f;
|
||||
params.m_pivot = m_position.m_pixelPivot;
|
||||
params.m_handleCreator = [tex](dp::Anchor anchor, m2::PointF const & pivot)
|
||||
{ return make_unique_dp<TextHandle>(EGuiHandle::GuiHandleSpeedSignLabel, pivot, tex); };
|
||||
|
||||
MutableLabelDrawer::Draw(context, params, tex, std::bind(&ShapeControl::AddShape, &control, _1, _2));
|
||||
}
|
||||
} // namespace gui
|
29
drape_frontend/gui/speed_limit.hpp
Normal file
29
drape_frontend/gui/speed_limit.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#pragma once
|
||||
|
||||
#include "drape_frontend/gui/elements/circle.hpp"
|
||||
#include "drape_frontend/gui/shape.hpp"
|
||||
|
||||
namespace gui
|
||||
{
|
||||
class SpeedLimit : public Shape
|
||||
{
|
||||
struct Config
|
||||
{
|
||||
static constexpr float kBackgroundRadius = 40.0f;
|
||||
static constexpr float kBackgroundOutlineWidthRatio = 0.2f;
|
||||
static constexpr dp::Color kBackgroundColor = dp::Color::White();
|
||||
static constexpr dp::Color kBackgroundOutlineColor = dp::Color::Red();
|
||||
static constexpr dp::Color kTextColor = dp::Color::Black();
|
||||
};
|
||||
|
||||
public:
|
||||
explicit SpeedLimit(gui::Position const & position);
|
||||
|
||||
drape_ptr<ShapeRenderer> Draw(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::TextureManager> tex) const;
|
||||
|
||||
private:
|
||||
void DrawText(ref_ptr<dp::GraphicsContext> context, ShapeControl & control, ref_ptr<dp::TextureManager> tex) const;
|
||||
|
||||
elements::Circle m_background;
|
||||
};
|
||||
} // namespace gui
|
18
drape_frontend/gui/speed_limit_helper.cpp
Normal file
18
drape_frontend/gui/speed_limit_helper.cpp
Normal file
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include "speed_limit_helper.hpp"
|
||||
|
||||
#include "platform/measurement_utils.hpp"
|
||||
|
||||
namespace gui
|
||||
{
|
||||
void SpeedLimitHelper::SetSpeedLimit(double speedLimitMps) { m_speedLimitMps = speedLimitMps; }
|
||||
|
||||
bool SpeedLimitHelper::IsSpeedLimitAvailable() const { return true; }
|
||||
|
||||
std::string SpeedLimitHelper::GetSpeedLimit() const
|
||||
{
|
||||
return "120";
|
||||
return measurement_utils::FormatSpeedNumeric(m_speedLimitMps, measurement_utils::GetMeasurementUnits());
|
||||
![]() Don't forget :) Don't forget :)
|
||||
}
|
||||
} // namespace gui
|
18
drape_frontend/gui/speed_limit_helper.hpp
Normal file
18
drape_frontend/gui/speed_limit_helper.hpp
Normal file
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace gui
|
||||
{
|
||||
class SpeedLimitHelper
|
||||
{
|
||||
public:
|
||||
void SetSpeedLimit(double speedLimitMps);
|
||||
|
||||
bool IsSpeedLimitAvailable() const;
|
||||
std::string GetSpeedLimit() const;
|
||||
|
||||
private:
|
||||
double m_speedLimitMps;
|
||||
};
|
||||
} // namespace gui
|
|
@ -563,6 +563,7 @@ void RoutingManager::RemoveRoute(bool deactivateFollowing)
|
|||
// Remove all subroutes.
|
||||
m_drapeEngine.SafeCall(&df::DrapeEngine::RemoveSubroute,
|
||||
dp::DrapeID(), true /* deactivateFollowing */);
|
||||
m_drapeEngine.SafeCall(&df::DrapeEngine::SetSpeedLimitInfo, -1.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -796,6 +797,12 @@ void RoutingManager::CloseRouting(bool removeRoutePoints)
|
|||
}
|
||||
}
|
||||
|
||||
void RoutingManager::GetRouteFollowingInfo(routing::FollowingInfo & info)
|
||||
{
|
||||
m_routingSession.GetRouteFollowingInfo(info);
|
||||
m_drapeEngine.SafeCall(&df::DrapeEngine::SetSpeedLimitInfo, info.m_speedLimitMps);
|
||||
}
|
||||
|
||||
void RoutingManager::SetLastUsedRouter(RouterType type)
|
||||
{
|
||||
settings::Set(kRouterTypeKey, ToString(type));
|
||||
|
|
|
@ -169,10 +169,7 @@ public:
|
|||
}
|
||||
void FollowRoute();
|
||||
void CloseRouting(bool removeRoutePoints);
|
||||
void GetRouteFollowingInfo(routing::FollowingInfo & info) const
|
||||
{
|
||||
m_routingSession.GetRouteFollowingInfo(info);
|
||||
}
|
||||
void GetRouteFollowingInfo(routing::FollowingInfo & info);
|
||||
|
||||
TransitRouteInfo GetTransitRouteInfo() const;
|
||||
|
||||
|
|
|
@ -104,6 +104,7 @@ void MapWidget::CreateEngine()
|
|||
[&p](gui::EWidget widget, gui::Position const & pos) { p.m_widgetsInitInfo[widget] = pos; });
|
||||
|
||||
p.m_widgetsInitInfo[gui::WIDGET_SCALE_FPS_LABEL] = gui::Position(dp::LeftTop);
|
||||
p.m_widgetsInitInfo[gui::WIDGET_SPEED_LIMIT] = gui::Position(m2::PointF(100, 100), dp::Center);
|
||||
|
||||
m_framework.CreateDrapeEngine(make_ref(m_contextFactory), std::move(p));
|
||||
m_framework.SetViewportListener(std::bind(&MapWidget::OnViewportChanged, this, std::placeholders::_1));
|
||||
|
|
|
@ -24,6 +24,8 @@ set(shader_files
|
|||
GL/dashed_line.vsh.glsl
|
||||
GL/debug_rect.fsh.glsl
|
||||
GL/debug_rect.vsh.glsl
|
||||
GL/gui_circle.fsh.glsl
|
||||
GL/gui_circle.vsh.glsl
|
||||
GL/hatching_area.fsh.glsl
|
||||
GL/hatching_area.vsh.glsl
|
||||
GL/line.fsh.glsl
|
||||
|
|
26
shaders/GL/gui_circle.fsh.glsl
Normal file
26
shaders/GL/gui_circle.fsh.glsl
Normal file
|
@ -0,0 +1,26 @@
|
|||
in vec2 v_position;
|
||||
in vec3 v_color;
|
||||
in vec3 v_outlineColor;
|
||||
in float v_outlineWidthRatio;
|
||||
|
||||
void main()
|
||||
{
|
||||
float R = 1.0;
|
||||
float R2 = R - v_outlineWidthRatio;
|
||||
float dist = sqrt(dot(v_position, v_position));
|
||||
if (dist >= R)
|
||||
{
|
||||
gl_FragColor.w = 0.0;
|
||||
}
|
||||
else if (dist <= R2)
|
||||
{
|
||||
gl_FragColor = vec4(v_color, 255.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
float sm = smoothstep(R, R-0.01, dist);
|
||||
float sm2 = smoothstep(R2, R2+0.01, dist);
|
||||
float alpha = sm*sm2;
|
||||
gl_FragColor = vec4(v_outlineColor, alpha);
|
||||
}
|
||||
}
|
27
shaders/GL/gui_circle.vsh.glsl
Normal file
27
shaders/GL/gui_circle.vsh.glsl
Normal file
|
@ -0,0 +1,27 @@
|
|||
in vec2 a_position;
|
||||
in vec3 a_color;
|
||||
in vec3 a_outlineColor;
|
||||
in float a_radius;
|
||||
in float a_outlineWidthRatio;
|
||||
|
||||
uniform mat4 u_modelView;
|
||||
uniform mat4 u_projection;
|
||||
|
||||
out vec2 v_position;
|
||||
out vec3 v_color;
|
||||
out vec3 v_outlineColor;
|
||||
out float v_outlineWidthRatio;
|
||||
|
||||
void main()
|
||||
{
|
||||
v_position = a_position;
|
||||
v_color = a_color;
|
||||
v_outlineColor = a_outlineColor;
|
||||
v_outlineWidthRatio = a_outlineWidthRatio;
|
||||
|
||||
gl_Position = vec4(a_position * a_radius, 0, 1) * u_modelView * u_projection;
|
||||
#ifdef VULKAN
|
||||
gl_Position.y = -gl_Position.y;
|
||||
gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;
|
||||
#endif
|
||||
}
|
|
@ -19,6 +19,7 @@ DashedLine dashed_line.vsh.glsl dashed_line.fsh.glsl
|
|||
PathSymbol path_symbol.vsh.glsl texturing.fsh.glsl
|
||||
HatchingArea hatching_area.vsh.glsl hatching_area.fsh.glsl
|
||||
TexturingGui texturing_gui.vsh.glsl texturing.fsh.glsl
|
||||
GuiCircle gui_circle.vsh.glsl gui_circle.fsh.glsl
|
||||
Ruler ruler.vsh.glsl texturing.fsh.glsl
|
||||
Accuracy position_accuracy3d.vsh.glsl texturing.fsh.glsl
|
||||
MyPosition my_position.vsh.glsl texturing.fsh.glsl
|
||||
|
|
|
@ -163,6 +163,7 @@ struct GuiProgramParams
|
|||
Program::TextStaticOutlinedGui,
|
||||
Program::TextOutlinedGui,
|
||||
Program::TexturingGui,
|
||||
Program::GuiCircle,
|
||||
Program::Ruler)
|
||||
} ALIGNMENT;
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ enum class Program
|
|||
PathSymbol,
|
||||
HatchingArea,
|
||||
TexturingGui,
|
||||
GuiCircle,
|
||||
Ruler,
|
||||
Accuracy,
|
||||
MyPosition,
|
||||
|
@ -94,6 +95,7 @@ inline std::string DebugPrint(Program p)
|
|||
case Program::PathSymbol: return "PathSymbol";
|
||||
case Program::HatchingArea: return "HatchingArea";
|
||||
case Program::TexturingGui: return "TexturingGui";
|
||||
case Program::GuiCircle: return "GuiCircle";
|
||||
case Program::Ruler: return "Ruler";
|
||||
case Program::Accuracy: return "Accuracy";
|
||||
case Program::MyPosition: return "MyPosition";
|
||||
|
|
Reference in a new issue
nit: You can put all these setters into hpp, no?