diff --git a/data/resources-default/default.ui b/data/resources-default/default.ui
index 51b96c6f8e..f7f55ac059 100644
--- a/data/resources-default/default.ui
+++ b/data/resources-default/default.ui
@@ -35,16 +35,4 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/drape/binding_info.hpp b/drape/binding_info.hpp
index 8292e70e43..70e0a27402 100644
--- a/drape/binding_info.hpp
+++ b/drape/binding_info.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "drape/glfunctions.hpp"
+#include "drape/glsl_types.hpp"
#include "std/string.hpp"
#include "std/shared_array.hpp"
@@ -41,4 +42,17 @@ protected:
uint16_t m_info;
};
+template
+uint8_t FillDecl(size_t index, string const & attrName, dp::BindingInfo & info, uint8_t offset)
+{
+ dp::BindingDecl & decl = info.GetBindingDecl(index);
+ decl.m_attributeName = attrName;
+ decl.m_componentCount = glsl::GetComponentCount();
+ decl.m_componentType = gl_const::GLFloatType;
+ decl.m_offset = offset;
+ decl.m_stride = sizeof(TVertexType);
+
+ return sizeof(TFieldType);
+}
+
} // namespace dp
diff --git a/drape/glyph_manager.cpp b/drape/glyph_manager.cpp
index 3ab6f7fd62..a7f8d6c779 100644
--- a/drape/glyph_manager.cpp
+++ b/drape/glyph_manager.cpp
@@ -263,7 +263,9 @@ struct UnicodeBlock
int GetFontOffset(int idx) const
{
- ASSERT(!m_fontsWeight.empty(), ());
+ if (m_fontsWeight.empty())
+ return -1;
+
int maxWight = 0;
int upperBoundWeight = numeric_limits::max();
if (idx != -1)
diff --git a/drape/shaders/ruler_vertex_shader.vsh b/drape/shaders/ruler_vertex_shader.vsh
index 3bb107ed1c..3e2575c474 100644
--- a/drape/shaders/ruler_vertex_shader.vsh
+++ b/drape/shaders/ruler_vertex_shader.vsh
@@ -2,6 +2,7 @@ attribute vec2 a_position;
attribute vec2 a_normal;
attribute vec2 a_colorTexCoords;
+uniform vec2 u_position;
uniform float u_length;
uniform mat4 projection;
@@ -9,6 +10,6 @@ varying vec2 v_colorTexCoords;
void main(void)
{
- gl_Position = vec4(a_position + u_length * a_normal, 0, 1) * projection;
+ gl_Position = vec4(u_position + a_position + u_length * a_normal, 0, 1) * projection;
v_colorTexCoords = a_colorTexCoords;
}
diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp
index 42e68e1fdd..8de3005fa3 100644
--- a/drape_frontend/backend_renderer.cpp
+++ b/drape_frontend/backend_renderer.cpp
@@ -28,12 +28,11 @@ BackendRenderer::BackendRenderer(Params const & params)
, m_model(params.m_model)
, m_batchersPool(make_unique_dp(ReadManager::ReadCount(), bind(&BackendRenderer::FlushGeometry, this, _1)))
, m_readManager(make_unique_dp(params.m_commutator, m_model))
- , m_guiCacher("default")
{
- gui::DrapeGui::Instance().SetRecacheSlot([this](gui::Skin::ElementName elements)
+ gui::DrapeGui::Instance().SetRecacheCountryStatusSlot([this]()
{
m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
- make_unique_dp(elements),
+ make_unique_dp(),
MessagePriority::High);
});
@@ -50,7 +49,7 @@ BackendRenderer::BackendRenderer(Params const & params)
BackendRenderer::~BackendRenderer()
{
- gui::DrapeGui::Instance().ClearRecacheSlot();
+ gui::DrapeGui::Instance().ClearRecacheCountryStatusSlot();
StopThread();
}
@@ -59,9 +58,16 @@ unique_ptr BackendRenderer::CreateRoutine()
return make_unique(*this);
}
-void BackendRenderer::RecacheGui(gui::Skin::ElementName elements)
+void BackendRenderer::RecacheGui(gui::TWidgetsInitInfo const & initInfo, gui::TWidgetsSizeInfo & sizeInfo)
{
- drape_ptr layerRenderer = m_guiCacher.Recache(elements, m_texMng);
+ drape_ptr layerRenderer = m_guiCacher.RecacheWidgets(initInfo, sizeInfo, m_texMng);
+ drape_ptr outputMsg = make_unique_dp(move(layerRenderer));
+ m_commutator->PostMessage(ThreadsCommutator::RenderThread, move(outputMsg), MessagePriority::High);
+}
+
+void BackendRenderer::RecacheCountryStatus()
+{
+ drape_ptr layerRenderer = m_guiCacher.RecacheCountryStatus(m_texMng);
drape_ptr outputMsg = make_unique_dp(move(layerRenderer));
m_commutator->PostMessage(ThreadsCommutator::RenderThread, move(outputMsg), MessagePriority::High);
}
@@ -88,23 +94,29 @@ void BackendRenderer::AcceptMessage(ref_ptr message)
break;
}
- case Message::Resize:
- {
- ref_ptr msg = message;
- df::Viewport const & v = msg->GetViewport();
- m_guiCacher.Resize(v.GetWidth(), v.GetHeight());
- RecacheGui(gui::Skin::AllElements);
- break;
- }
case Message::InvalidateReadManagerRect:
{
ref_ptr msg = message;
m_readManager->Invalidate(msg->GetTilesForInvalidate());
break;
}
+ case Message::CountryStatusRecache:
+ {
+ RecacheCountryStatus();
+ break;
+ }
case Message::GuiRecache:
{
- RecacheGui(static_cast>(message)->GetElements());
+ ref_ptr msg = message;
+ RecacheGui(msg->GetInitInfo(), msg->GetSizeInfoMap());
+ break;
+ }
+ case Message::GuiLayerLayout:
+ {
+ ref_ptr msg = message;
+ m_commutator->PostMessage(ThreadsCommutator::RenderThread,
+ make_unique_dp(msg->AcceptLayoutInfo()),
+ MessagePriority::Normal);
break;
}
case Message::TileReadStarted:
diff --git a/drape_frontend/backend_renderer.hpp b/drape_frontend/backend_renderer.hpp
index eb34d21826..3fce7356fb 100644
--- a/drape_frontend/backend_renderer.hpp
+++ b/drape_frontend/backend_renderer.hpp
@@ -46,7 +46,8 @@ protected:
unique_ptr CreateRoutine() override;
private:
- void RecacheGui(gui::Skin::ElementName elements);
+ void RecacheGui(gui::TWidgetsInitInfo const & initInfo, gui::TWidgetsSizeInfo & sizeInfo);
+ void RecacheCountryStatus();
private:
MapDataProvider m_model;
diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp
index 1f53804206..96cf0d9ead 100644
--- a/drape_frontend/drape_engine.cpp
+++ b/drape_frontend/drape_engine.cpp
@@ -34,7 +34,7 @@ string const LocationStateMode = "LastLocationStateMode";
}
-DrapeEngine::DrapeEngine(Params const & params)
+DrapeEngine::DrapeEngine(Params && params)
: m_viewport(params.m_viewport)
{
VisualParams::Init(params.m_vs, df::CalculateTileSize(m_viewport.GetWidth(), m_viewport.GetHeight()));
@@ -51,6 +51,7 @@ DrapeEngine::DrapeEngine(Params const & params)
gui::DrapeGui & guiSubsystem = gui::DrapeGui::Instance();
guiSubsystem.Init(scaleFn, gnLvlFn);
guiSubsystem.SetLocalizator(bind(&StringsBundle::GetString, params.m_stringsBundle.get(), _1));
+ guiSubsystem.SetSurfaceSize(m2::PointF(m_viewport.GetWidth(), m_viewport.GetHeight()));
ConnectDownloadFn(gui::CountryStatusHelper::BUTTON_TYPE_MAP, params.m_model.GetDownloadMapHandler());
ConnectDownloadFn(gui::CountryStatusHelper::BUTTON_TYPE_MAP_ROUTING, params.m_model.GetDownloadMapRoutingHandler());
@@ -77,6 +78,11 @@ DrapeEngine::DrapeEngine(Params const & params)
BackendRenderer::Params brParams(frParams.m_commutator, frParams.m_oglContextFactory,
frParams.m_texMng, params.m_model);
m_backend = make_unique_dp(brParams);
+
+ GuiRecacheMessage::Blocker blocker;
+ drape_ptr message( new GuiRecacheMessage(blocker, move(params.m_info), m_widgetSizes));
+ m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, move(message), MessagePriority::High);
+ blocker.Wait();
}
DrapeEngine::~DrapeEngine()
@@ -92,8 +98,12 @@ DrapeEngine::~DrapeEngine()
void DrapeEngine::Resize(int w, int h)
{
- m_viewport.SetViewport(0, 0, w, h);
- AddUserEvent(ResizeEvent(w, h));
+ if (m_viewport.GetHeight() != h || m_viewport.GetWidth() != w)
+ {
+ gui::DrapeGui::Instance().SetSurfaceSize(m2::PointF(w, h));
+ m_viewport.SetViewport(0, 0, w, h);
+ AddUserEvent(ResizeEvent(w, h));
+ }
}
void DrapeEngine::AddTouchEvent(TouchEvent const & event)
@@ -323,4 +333,16 @@ void DrapeEngine::RemoveRoute(bool deactivateFollowing)
MessagePriority::Normal);
}
+void DrapeEngine::SetWidgetLayout(gui::TWidgetsLayoutInfo && info)
+{
+ m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
+ make_unique_dp(move(info)),
+ MessagePriority::Normal);
+}
+
+gui::TWidgetsSizeInfo const & DrapeEngine::GetWidgetSizes()
+{
+ return m_widgetSizes;
+}
+
} // namespace df
diff --git a/drape_frontend/drape_engine.hpp b/drape_frontend/drape_engine.hpp
index 640c54d7b0..6885da5608 100644
--- a/drape_frontend/drape_engine.hpp
+++ b/drape_frontend/drape_engine.hpp
@@ -37,12 +37,14 @@ public:
ref_ptr stringBundle,
Viewport const & viewport,
MapDataProvider const & model,
- double vs)
+ double vs,
+ gui::TWidgetsInitInfo && info)
: m_factory(factory)
, m_stringsBundle(stringBundle)
, m_viewport(viewport)
, m_model(model)
, m_vs(vs)
+ , m_info(move(info))
{
}
@@ -51,9 +53,10 @@ public:
Viewport m_viewport;
MapDataProvider m_model;
double m_vs;
+ gui::TWidgetsInitInfo m_info;
};
- DrapeEngine(Params const & params);
+ DrapeEngine(Params && params);
~DrapeEngine();
void Resize(int w, int h);
@@ -98,6 +101,9 @@ public:
void AddRoute(m2::PolylineD const & routePolyline, dp::Color const & color);
void RemoveRoute(bool deactivateFollowing);
+ void SetWidgetLayout(gui::TWidgetsLayoutInfo && info);
+ gui::TWidgetsSizeInfo const & GetWidgetSizes();
+
private:
void AddUserEvent(UserEvent const & e);
void ModelViewChanged(ScreenBase const & screen);
@@ -121,6 +127,8 @@ private:
location::TMyPositionModeChanged m_myPositionModeChanged;
TTapEventInfoFn m_tapListener;
TUserPositionChangedFn m_userPositionChangedFn;
+
+ gui::TWidgetsSizeInfo m_widgetSizes;
};
} // namespace df
diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp
index d1528a1f5f..dfb4a3c17b 100755
--- a/drape_frontend/frontend_renderer.cpp
+++ b/drape_frontend/frontend_renderer.cpp
@@ -187,6 +187,13 @@ void FrontendRenderer::AcceptMessage(ref_ptr message)
break;
}
+ case Message::GuiLayerLayout:
+ {
+ ASSERT(m_guiRenderer != nullptr, ());
+ m_guiRenderer->SetLayout(ref_ptr(message)->GetLayoutInfo());
+ break;
+ }
+
case Message::StopRendering:
{
ProcessStopRenderingMessage();
@@ -309,10 +316,6 @@ void FrontendRenderer::OnResize(ScreenBase const & screen)
m_myPositionController->SetPixelRect(screen.PixelRect());
m_contextFactory->getDrawContext()->resize(m_viewport.GetWidth(), m_viewport.GetHeight());
RefreshProjection();
-
- m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
- make_unique_dp(m_viewport),
- MessagePriority::High);
}
void FrontendRenderer::AddToRenderGroup(vector> & groups,
diff --git a/drape_frontend/message.hpp b/drape_frontend/message.hpp
index 7366e06e45..edd5de8c28 100644
--- a/drape_frontend/message.hpp
+++ b/drape_frontend/message.hpp
@@ -17,14 +17,15 @@ public:
UpdateReadManager,
InvalidateRect,
InvalidateReadManagerRect,
- Resize,
ClearUserMarkLayer,
ChangeUserMarkLayerVisibility,
UpdateUserMarkLayer,
GuiLayerRecached,
GuiRecache,
+ GuiLayerLayout,
MyPositionShape,
CountryInfoUpdate,
+ CountryStatusRecache,
StopRendering,
ChangeMyPostitionMode,
CompassInfo,
diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp
index 53c34f61d3..c467a60148 100644
--- a/drape_frontend/message_subclasses.hpp
+++ b/drape_frontend/message_subclasses.hpp
@@ -30,6 +30,47 @@
namespace df
{
+class BaseBlockingMessage : public Message
+{
+public:
+ struct Blocker
+ {
+ void Wait()
+ {
+ unique_lock lock(m_lock);
+ m_signal.wait(lock, [this]{return !m_blocked;} );
+ }
+
+ private:
+ friend class BaseBlockingMessage;
+
+ void Signal()
+ {
+ lock_guard lock(m_lock);
+ m_blocked = false;
+ m_signal.notify_one();
+ }
+
+ private:
+ mutex m_lock;
+ condition_variable m_signal;
+ bool m_blocked = true;
+ };
+
+ BaseBlockingMessage(Blocker & blocker)
+ : m_blocker(blocker)
+ {
+ }
+
+ ~BaseBlockingMessage()
+ {
+ m_blocker.Signal();
+ }
+
+private:
+ Blocker & m_blocker;
+};
+
class BaseTileMessage : public Message
{
public:
@@ -95,20 +136,6 @@ private:
drape_ptr m_buffer;
};
-class ResizeMessage : public Message
-{
-public:
- ResizeMessage(Viewport const & viewport)
- : m_viewport(viewport) {}
-
- Type GetType() const override { return Message::Resize; }
-
- Viewport const & GetViewport() const { return m_viewport; }
-
-private:
- Viewport m_viewport;
-};
-
class InvalidateRectMessage : public Message
{
public:
@@ -237,19 +264,40 @@ private:
drape_ptr m_renderer;
};
-class GuiRecacheMessage : public Message
+class GuiRecacheMessage : public BaseBlockingMessage
{
public:
- GuiRecacheMessage(gui::Skin::ElementName elements)
- : m_elements(elements)
+ GuiRecacheMessage(Blocker & blocker, gui::TWidgetsInitInfo && initInfo, gui::TWidgetsSizeInfo & resultInfo)
+ : BaseBlockingMessage(blocker)
+ , m_initInfo(move(initInfo))
+ , m_sizeInfo(resultInfo)
{
}
Type GetType() const override { return Message::GuiRecache;}
- gui::Skin::ElementName GetElements() const { return m_elements; }
+ gui::TWidgetsInitInfo const & GetInitInfo() const { return m_initInfo; }
+ gui::TWidgetsSizeInfo & GetSizeInfoMap() const { return m_sizeInfo; }
private:
- gui::Skin::ElementName m_elements;
+ gui::TWidgetsInitInfo m_initInfo;
+ gui::TWidgetsSizeInfo & m_sizeInfo;
+};
+
+class GuiLayerLayoutMessage : public Message
+{
+public:
+ GuiLayerLayoutMessage(gui::TWidgetsLayoutInfo && info)
+ : m_layoutInfo(move(info))
+ {
+ }
+
+ Type GetType() const override { return GuiLayerLayout; }
+
+ gui::TWidgetsLayoutInfo const & GetLayoutInfo() const { return m_layoutInfo; }
+ gui::TWidgetsLayoutInfo AcceptLayoutInfo() { return move(m_layoutInfo); }
+
+private:
+ gui::TWidgetsLayoutInfo m_layoutInfo;
};
class CountryInfoUpdateMessage : public Message
@@ -273,6 +321,13 @@ private:
bool m_isCountryLoaded;
};
+class CountryStatusRecacheMessage : public Message
+{
+public:
+ CountryStatusRecacheMessage() {}
+ Type GetType() const override { return Message::CountryStatusRecache ;}
+};
+
class MyPositionShapeMessage : public Message
{
public:
@@ -356,47 +411,6 @@ private:
location::RouteMatchingInfo const m_routeInfo;
};
-class BaseBlockingMessage : public Message
-{
-public:
- struct Blocker
- {
- void Wait()
- {
- unique_lock lock(m_lock);
- m_signal.wait(lock, [this]{return !m_blocked;} );
- }
-
- private:
- friend class BaseBlockingMessage;
-
- void Signal()
- {
- lock_guard lock(m_lock);
- m_blocked = false;
- m_signal.notify_one();
- }
-
- private:
- mutex m_lock;
- condition_variable m_signal;
- bool m_blocked = true;
- };
-
- BaseBlockingMessage(Blocker & blocker)
- : m_blocker(blocker)
- {
- }
-
- ~BaseBlockingMessage()
- {
- m_blocker.Signal();
- }
-
-private:
- Blocker & m_blocker;
-};
-
class FindVisiblePOIMessage : public BaseBlockingMessage
{
public:
diff --git a/drape_frontend/user_mark_shapes.cpp b/drape_frontend/user_mark_shapes.cpp
index 22ce3da0f1..91e5680152 100644
--- a/drape_frontend/user_mark_shapes.cpp
+++ b/drape_frontend/user_mark_shapes.cpp
@@ -73,19 +73,6 @@ void AlignVertical(float halfHeight, dp::Anchor anchor,
AlignFormingNormals([&halfHeight]{ return glsl::vec2(0.0f, -halfHeight); }, anchor, dp::Top, dp::Bottom, up, down);
}
-template
-uint8_t FillDecl(size_t index, string const & attrName, dp::BindingInfo & info, uint8_t offset)
-{
- dp::BindingDecl & decl = info.GetBindingDecl(index);
- decl.m_attributeName = attrName;
- decl.m_componentCount = glsl::GetComponentCount();
- decl.m_componentType = gl_const::GLFloatType;
- decl.m_offset = offset;
- decl.m_stride = sizeof(TVertexType);
-
- return sizeof(TFieldType);
-}
-
struct UserPointVertex : gpu::BaseVertex
{
UserPointVertex() = default;
@@ -101,10 +88,10 @@ struct UserPointVertex : gpu::BaseVertex
{
dp::BindingInfo info(4);
uint8_t offset = 0;
- offset += FillDecl(0, "a_position", info, offset);
- offset += FillDecl(1, "a_normal", info, offset);
- offset += FillDecl(2, "a_colorTexCoords", info, offset);
- offset += FillDecl(3, "a_animate", info, offset);
+ offset += dp::FillDecl(0, "a_position", info, offset);
+ offset += dp::FillDecl(1, "a_normal", info, offset);
+ offset += dp::FillDecl(2, "a_colorTexCoords", info, offset);
+ offset += dp::FillDecl(3, "a_animate", info, offset);
return info;
}
diff --git a/drape_gui/compass.cpp b/drape_gui/compass.cpp
index 181abf7f36..1e20274a92 100644
--- a/drape_gui/compass.cpp
+++ b/drape_gui/compass.cpp
@@ -57,7 +57,8 @@ namespace
};
}
-drape_ptr Compass::Draw(ref_ptr tex, TTapHandler const & tapHandler) const
+drape_ptr Compass::Draw(m2::PointF & compassSize, ref_ptr tex,
+ TTapHandler const & tapHandler) const
{
dp::TextureManager::SymbolRegion region;
tex->GetSymbolRegion("compass-image", region);
@@ -95,7 +96,7 @@ drape_ptr Compass::Draw(ref_ptr tex, TTapHand
provider.InitStream(0, info, make_ref(&vertexes));
- m2::PointF compassSize = region.GetPixelSize();
+ compassSize = region.GetPixelSize();
drape_ptr handle = make_unique_dp(m_position.m_pixelPivot, compassSize, tapHandler);
drape_ptr renderer = make_unique_dp();
diff --git a/drape_gui/compass.hpp b/drape_gui/compass.hpp
index f178f0fba6..1a93c74b2d 100644
--- a/drape_gui/compass.hpp
+++ b/drape_gui/compass.hpp
@@ -12,7 +12,8 @@ public:
: Shape(position)
{}
- drape_ptr Draw(ref_ptr tex, TTapHandler const & tapHandler) const;
+ drape_ptr Draw(m2::PointF & compassSize, ref_ptr tex,
+ TTapHandler const & tapHandler) const;
};
}
diff --git a/drape_gui/copyright_label.cpp b/drape_gui/copyright_label.cpp
index 6a67e28c4f..c53900b1d0 100644
--- a/drape_gui/copyright_label.cpp
+++ b/drape_gui/copyright_label.cpp
@@ -56,7 +56,7 @@ CopyrightLabel::CopyrightLabel(Position const & position)
{
}
-drape_ptr CopyrightLabel::Draw(ref_ptr tex) const
+drape_ptr CopyrightLabel::Draw(m2::PointF & size, ref_ptr tex) const
{
StaticLabel::LabelResult result;
StaticLabel::CacheStaticText("Map data © OpenStreetMap", "", m_position.m_anchor,
@@ -70,7 +70,7 @@ drape_ptr CopyrightLabel::Draw(ref_ptr tex) c
ASSERT(vertexCount % dp::Batcher::VertexPerQuad == 0, ());
size_t indexCount = dp::Batcher::IndexPerQuad * vertexCount / dp::Batcher::VertexPerQuad;
- m2::PointF size(result.m_boundRect.SizeX(), result.m_boundRect.SizeY());
+ size = m2::PointF(result.m_boundRect.SizeX(), result.m_boundRect.SizeY());
drape_ptr handle = make_unique_dp(m_position.m_anchor, m_position.m_pixelPivot, size);
drape_ptr renderer = make_unique_dp();
diff --git a/drape_gui/copyright_label.hpp b/drape_gui/copyright_label.hpp
index a0be48986e..9345b19849 100644
--- a/drape_gui/copyright_label.hpp
+++ b/drape_gui/copyright_label.hpp
@@ -10,7 +10,7 @@ class CopyrightLabel : public Shape
using TBase = Shape;
public:
CopyrightLabel(gui::Position const & position);
- drape_ptr Draw(ref_ptr tex) const;
+ drape_ptr Draw(m2::PointF & size, ref_ptr tex) const;
};
}
diff --git a/drape_gui/country_status_helper.cpp b/drape_gui/country_status_helper.cpp
index c7f2981b01..5e5433bf1d 100644
--- a/drape_gui/country_status_helper.cpp
+++ b/drape_gui/country_status_helper.cpp
@@ -110,7 +110,7 @@ void CountryStatusHelper::SetState(ECountryState state)
{
m_state = state;
FillControlsForState();
- DrapeGui::Instance().EmitRecacheSignal(Skin::CountryStatus);
+ DrapeGui::Instance().EmitRecacheCountryStatusSignal();
}
CountryStatusHelper::ECountryState CountryStatusHelper::GetState() const
diff --git a/drape_gui/drape_gui.cpp b/drape_gui/drape_gui.cpp
index dffeb3d5c7..9369b4eb0f 100644
--- a/drape_gui/drape_gui.cpp
+++ b/drape_gui/drape_gui.cpp
@@ -13,7 +13,7 @@ struct DrapeGui::Impl
DrapeGui::TGeneralizationLevelFn m_gnLvlFn;
DrapeGui::TLocalizeStringFn m_localizeFn;
- DrapeGui::TRecacheSlot m_recacheSlot;
+ DrapeGui::TRecacheCountryStatusSlot m_recacheSlot;
RulerHelper m_rulerHelper;
CountryStatusHelper m_countryHelper;
@@ -55,6 +55,11 @@ void DrapeGui::Destroy()
m_impl.reset();
}
+void DrapeGui::SetSurfaceSize(m2::PointF const & size)
+{
+ m_surfaceSize = size;
+}
+
void DrapeGui::SetLocalizator(const DrapeGui::TLocalizeStringFn & fn)
{
ASSERT(m_impl != nullptr, ());
@@ -73,22 +78,22 @@ int DrapeGui::GetGeneralization(ScreenBase const & screen)
return m_impl->m_gnLvlFn(screen);
}
-void DrapeGui::SetRecacheSlot(DrapeGui::TRecacheSlot const & fn)
+void DrapeGui::SetRecacheCountryStatusSlot(TRecacheCountryStatusSlot const & fn)
{
ASSERT(m_impl != nullptr, ());
m_impl->m_recacheSlot = fn;
}
-void DrapeGui::EmitRecacheSignal(Skin::ElementName elements)
+void DrapeGui::EmitRecacheCountryStatusSignal()
{
ASSERT(m_impl != nullptr, ());
if (m_impl->m_recacheSlot)
- m_impl->m_recacheSlot(elements);
+ m_impl->m_recacheSlot();
}
-void DrapeGui::ClearRecacheSlot()
+void DrapeGui::ClearRecacheCountryStatusSlot()
{
- SetRecacheSlot(TRecacheSlot());
+ SetRecacheCountryStatusSlot(TRecacheCountryStatusSlot());
}
string DrapeGui::GetLocalizedString(string const & stringID) const
diff --git a/drape_gui/drape_gui.hpp b/drape_gui/drape_gui.hpp
index 7e7fcea5d0..5590f7f87a 100644
--- a/drape_gui/drape_gui.hpp
+++ b/drape_gui/drape_gui.hpp
@@ -11,6 +11,7 @@
#include "std/function.hpp"
#include "std/unique_ptr.hpp"
+#include "std/atomic.hpp"
class ScreenBase;
@@ -23,7 +24,7 @@ class CountryStatusHelper;
class DrapeGui
{
public:
- using TRecacheSlot = function;
+ using TRecacheCountryStatusSlot = function;
using TScaleFactorFn = function;
using TGeneralizationLevelFn = function;
using TLocalizeStringFn = function;
@@ -37,14 +38,16 @@ public:
void Init(TScaleFactorFn const & scaleFn, TGeneralizationLevelFn const & gnLvlFn);
void SetLocalizator(TLocalizeStringFn const & fn);
void Destroy();
+ void SetSurfaceSize(m2::PointF const & size);
+ m2::PointF GetSurfaceSize() const { return m_surfaceSize; }
double GetScaleFactor();
int GetGeneralization(ScreenBase const & screen);
string GetLocalizedString(string const & stringID) const;
- void SetRecacheSlot(TRecacheSlot const & fn);
- void EmitRecacheSignal(Skin::ElementName elements);
- void ClearRecacheSlot();
+ void SetRecacheCountryStatusSlot(TRecacheCountryStatusSlot const & fn);
+ void EmitRecacheCountryStatusSignal();
+ void ClearRecacheCountryStatusSlot();
bool IsCopyrightActive() const { return m_isCopyrightActive; }
void DeactivateCopyright() { m_isCopyrightActive = false; }
@@ -66,6 +69,7 @@ private:
Shape::TTapHandler m_onCompassTappedHandler;
CountryStatus::TButtonHandlers m_buttonHandlers;
+ atomic m_surfaceSize;
};
}
diff --git a/drape_gui/drape_gui_tests/skin_tests.cpp b/drape_gui/drape_gui_tests/skin_tests.cpp
index c330b4cb5c..39c5dece8b 100644
--- a/drape_gui/drape_gui_tests/skin_tests.cpp
+++ b/drape_gui/drape_gui_tests/skin_tests.cpp
@@ -6,55 +6,44 @@
UNIT_TEST(ParseDefaultSkinTest)
{
- gui::DrapeGui::Instance().Init([]{ return 2.0; }, [] (ScreenBase const &) { return 6.0f; });
- gui::Skin skin(gui::ResolveGuiSkinFile("default"));
+ gui::Skin skin(gui::ResolveGuiSkinFile("default"), 2.0);
float width = 600.0f;
float height = 800.0f;
skin.Resize(width, height);
- gui::Position compassPos = skin.ResolvePosition(gui::Skin::ElementName::Compass);
+ gui::Position compassPos = skin.ResolvePosition(gui::WIDGET_COMPASS);
TEST_EQUAL(compassPos.m_anchor, dp::Center, ());
TEST_ALMOST_EQUAL(compassPos.m_pixelPivot.x, 27.0f * 2.0f, ());
TEST_ALMOST_EQUAL(compassPos.m_pixelPivot.y, height - 57.0f * 2.0f, ());
- gui::Position rulerPos = skin.ResolvePosition(gui::Skin::ElementName::Ruler);
+ gui::Position rulerPos = skin.ResolvePosition(gui::WIDGET_RULER);
TEST_EQUAL(rulerPos.m_anchor, dp::Right, ());
TEST_ALMOST_EQUAL(rulerPos.m_pixelPivot.x, width - 6.0f * 2.0f, ());
TEST_ALMOST_EQUAL(rulerPos.m_pixelPivot.y, height - 42.0f * 2.0f, ());
- gui::Position copyRightPos = skin.ResolvePosition(gui::Skin::ElementName::Copyright);
+ gui::Position copyRightPos = skin.ResolvePosition(gui::WIDGET_COPYRIGHT);
TEST_EQUAL(copyRightPos.m_anchor, dp::Right, ());
TEST_ALMOST_EQUAL(copyRightPos.m_pixelPivot.x, width - 6.0f * 2.0f, ());
TEST_ALMOST_EQUAL(copyRightPos.m_pixelPivot.y, height - 42.0f * 2.0f, ());
- gui::Position countryStatusPos = skin.ResolvePosition(gui::Skin::ElementName::CountryStatus);
- TEST_EQUAL(countryStatusPos.m_anchor, dp::Center, ());
- TEST_ALMOST_EQUAL(countryStatusPos.m_pixelPivot.x, width / 2.0f, ());
- TEST_ALMOST_EQUAL(countryStatusPos.m_pixelPivot.y, height / 2.0f, ());
-
{
width = 800.0f;
height = 600.0f;
skin.Resize(width, height);
- gui::Position compassPos = skin.ResolvePosition(gui::Skin::ElementName::Compass);
+ gui::Position compassPos = skin.ResolvePosition(gui::WIDGET_COMPASS);
TEST_EQUAL(compassPos.m_anchor, dp::Center, ());
TEST_ALMOST_EQUAL(compassPos.m_pixelPivot.x, 18.0f * 2.0f, ());
TEST_ALMOST_EQUAL(compassPos.m_pixelPivot.y, height - 11.4f * 2.0f, ());
- gui::Position rulerPos = skin.ResolvePosition(gui::Skin::ElementName::Ruler);
+ gui::Position rulerPos = skin.ResolvePosition(gui::WIDGET_RULER);
TEST_EQUAL(rulerPos.m_anchor, dp::Right, ());
TEST_ALMOST_EQUAL(rulerPos.m_pixelPivot.x, width - 70.4f * 2.0f, ());
TEST_ALMOST_EQUAL(rulerPos.m_pixelPivot.y, height - 10.5f * 2.0f, ());
- gui::Position copyRightPos = skin.ResolvePosition(gui::Skin::ElementName::Copyright);
+ gui::Position copyRightPos = skin.ResolvePosition(gui::WIDGET_COPYRIGHT);
TEST_EQUAL(copyRightPos.m_anchor, dp::Right, ());
TEST_ALMOST_EQUAL(copyRightPos.m_pixelPivot.x, width - 70.4f * 2.0f, ());
TEST_ALMOST_EQUAL(copyRightPos.m_pixelPivot.y, height - 10.5f * 2.0f, ());
-
- gui::Position countryStatusPos = skin.ResolvePosition(gui::Skin::ElementName::CountryStatus);
- TEST_EQUAL(countryStatusPos.m_anchor, dp::Center, ());
- TEST_ALMOST_EQUAL(countryStatusPos.m_pixelPivot.x, width / 2.0f, ());
- TEST_ALMOST_EQUAL(countryStatusPos.m_pixelPivot.y, height / 2.0f, ());
}
}
diff --git a/drape_gui/gui_text.cpp b/drape_gui/gui_text.cpp
index f865498c0a..c95714bb45 100644
--- a/drape_gui/gui_text.cpp
+++ b/drape_gui/gui_text.cpp
@@ -112,8 +112,8 @@ StaticLabel::LabelResult::LabelResult() : m_state(gpu::TEXT_PROGRAM, dp::GLState
char const * StaticLabel::DefaultDelim = "\n";
void StaticLabel::CacheStaticText(string const & text, char const * delim,
- dp::Anchor anchor, dp::FontDecl const & font,
- ref_ptr mng, LabelResult & result)
+ dp::Anchor anchor, dp::FontDecl const & font,
+ ref_ptr mng, LabelResult & result)
{
ASSERT(!text.empty(), ());
@@ -213,9 +213,11 @@ void StaticLabel::CacheStaticText(string const & text, char const * delim,
else if (anchor & dp::Bottom)
yOffset = 0.0f;
+ float maxLineLength = 0.0;
size_t startIndex = 0;
for (size_t i = 0; i < ranges.size(); ++i)
{
+ maxLineLength = max(lineLengths[i], maxLineLength);
float xOffset = -lineLengths[i] / 2.0f;
if (anchor & dp::Left)
xOffset = 0;
@@ -345,6 +347,18 @@ void MutableLabel::Precache(PrecacheParams const & params, PrecacheResult & resu
result.m_buffer[i + 3].m_position.z = depth;
depth += 10.0f;
}
+
+ uint32_t maxGlyphWidth = 0.0;
+ uint32_t maxGlyphHeight = 0.0;
+ for (auto node : m_alphabet)
+ {
+ dp::TextureManager::GlyphRegion const & reg = node.second;
+ m2::PointU pixelSize = reg.GetPixelSize();
+ maxGlyphWidth = max(maxGlyphWidth, pixelSize.x);
+ maxGlyphHeight = max(maxGlyphHeight, pixelSize.y);
+ }
+
+ result.m_maxPixelSize = m2::PointF(m_maxLength * maxGlyphWidth, maxGlyphHeight);
}
void MutableLabel::SetText(LabelResult & result, string text) const
@@ -481,8 +495,8 @@ void MutableLabelHandle::SetContent(string const & content)
}
}
-void MutableLabelDrawer::Draw(Params const & params, ref_ptr mng,
- dp::Batcher::TFlushFn const & flushFn)
+m2::PointF MutableLabelDrawer::Draw(Params const & params, ref_ptr mng,
+ dp::Batcher::TFlushFn const & flushFn)
{
uint32_t vertexCount = dp::Batcher::VertexPerQuad * params.m_maxLength;
uint32_t indexCount = dp::Batcher::IndexPerQuad * params.m_maxLength;
@@ -517,6 +531,8 @@ void MutableLabelDrawer::Draw(Params const & params, ref_ptr
batcher.InsertListOfStrip(staticData.m_state, make_ref(&provider),
move(handle), dp::Batcher::VertexPerQuad);
}
+
+ return staticData.m_maxPixelSize;
}
}
diff --git a/drape_gui/gui_text.hpp b/drape_gui/gui_text.hpp
index b29e9b0bf1..5cc8c42468 100644
--- a/drape_gui/gui_text.hpp
+++ b/drape_gui/gui_text.hpp
@@ -49,9 +49,10 @@ public:
m2::RectF m_boundRect;
};
+ /// return pixelSize of text
static void CacheStaticText(string const & text, char const * delim,
- dp::Anchor anchor, dp::FontDecl const & font,
- ref_ptr mng, LabelResult & result);
+ dp::Anchor anchor, dp::FontDecl const & font,
+ ref_ptr mng, LabelResult & result);
};
////////////////////////////////////////////////////////////////////////////////////////////////
@@ -106,6 +107,7 @@ public:
dp::GLState m_state;
buffer_vector m_buffer;
+ m2::PointF m_maxPixelSize;
};
struct LabelResult
@@ -173,7 +175,8 @@ public:
THandleCreator m_handleCreator;
};
- static void Draw(Params const & params, ref_ptr mng,
- dp::Batcher::TFlushFn const & flushFn);
+ /// return maximum pixel size
+ static m2::PointF Draw(Params const & params, ref_ptr mng,
+ dp::Batcher::TFlushFn const & flushFn);
};
}
diff --git a/drape_gui/layer_render.cpp b/drape_gui/layer_render.cpp
index 26addceac5..de6f96b362 100644
--- a/drape_gui/layer_render.cpp
+++ b/drape_gui/layer_render.cpp
@@ -17,6 +17,100 @@
namespace gui
{
+LayerRenderer::~LayerRenderer()
+{
+ DestroyRenderers();
+}
+
+void LayerRenderer::Build(ref_ptr mng)
+{
+ for (TRenderers::value_type & r : m_renderers)
+ r.second->Build(mng);
+}
+
+void LayerRenderer::Render(ref_ptr mng, ScreenBase const & screen)
+{
+ DrapeGui::Instance().GetRulerHelper().Update(screen);
+ for (TRenderers::value_type & r : m_renderers)
+ r.second->Render(screen, mng);
+}
+
+void LayerRenderer::Merge(ref_ptr other)
+{
+ for (TRenderers::value_type & r : other->m_renderers)
+ {
+ TRenderers::iterator it = m_renderers.find(r.first);
+ if (it != m_renderers.end())
+ it->second = move(r.second);
+ else
+ m_renderers.insert(make_pair(r.first, move(r.second)));
+ }
+
+ other->m_renderers.clear();
+}
+
+void LayerRenderer::SetLayout(TWidgetsLayoutInfo const & info)
+{
+ for (auto node : info)
+ {
+ auto renderer = m_renderers.find(node.first);
+ if (renderer != m_renderers.end())
+ renderer->second->SetPivot(node.second);
+ }
+}
+
+void LayerRenderer::DestroyRenderers()
+{
+ m_renderers.clear();
+}
+
+void LayerRenderer::AddShapeRenderer(EWidget widget, drape_ptr && shape)
+{
+ if (shape == nullptr)
+ return;
+
+ VERIFY(m_renderers.insert(make_pair(widget, move(shape))).second, ());
+}
+
+bool LayerRenderer::OnTouchDown(m2::RectD const & touchArea)
+{
+ for (TRenderers::value_type & r : m_renderers)
+ {
+ m_activeOverlay = r.second->ProcessTapEvent(touchArea);
+ if (m_activeOverlay != nullptr)
+ {
+ m_activeOverlay->OnTapBegin();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void LayerRenderer::OnTouchUp(m2::RectD const & touchArea)
+{
+ if (m_activeOverlay != nullptr)
+ {
+ if (m_activeOverlay->IsTapped(touchArea))
+ m_activeOverlay->OnTap();
+
+ m_activeOverlay->OnTapEnd();
+ m_activeOverlay = nullptr;
+ }
+}
+
+void LayerRenderer::OnTouchCancel(m2::RectD const & touchArea)
+{
+ UNUSED_VALUE(touchArea);
+ if (m_activeOverlay != nullptr)
+ {
+ m_activeOverlay->OnTapEnd();
+ m_activeOverlay = nullptr;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+
namespace
{
@@ -58,163 +152,97 @@ void RegisterButtonHandler(CountryStatus::TButtonHandlers & handlers,
&DrapeGui::Instance(), buttonType);
}
-}
+} // namespace
-LayerCacher::LayerCacher(string const & deviceType)
+drape_ptr LayerCacher::RecacheWidgets(TWidgetsInitInfo const & initInfo,
+ TWidgetsSizeInfo & sizeInfo,
+ ref_ptr textures)
{
- m_skin.reset(new Skin(ResolveGuiSkinFile(deviceType)));
-}
+ using TCacheShape = function renderer, ref_ptr textures)>;
+ static map cacheFunctions
+ {
+ make_pair(WIDGET_COMPASS, bind(&LayerCacher::CacheCompass, this, _1, _2, _3)),
+ make_pair(WIDGET_RULER, bind(&LayerCacher::CacheRuler, this, _1, _2, _3)),
+ make_pair(WIDGET_COPYRIGHT, bind(&LayerCacher::CacheCopyright, this, _1, _2, _3)),
+ make_pair(WIDGET_SCALE_LABLE, bind(&LayerCacher::CacheScaleLabel, this, _1, _2, _3))
+ };
-void LayerCacher::Resize(int w, int h)
-{
- m_skin->Resize(w, h);
-}
-
-drape_ptr LayerCacher::Recache(Skin::ElementName names,
- ref_ptr textures)
-{
drape_ptr renderer = make_unique_dp();
-
- if (names & Skin::Compass)
+ for (auto node : initInfo)
{
- Compass compass = Compass(GetPos(Skin::Compass));
- renderer->AddShapeRenderer(Skin::Compass, compass.Draw(textures, bind(&DrapeGui::CallOnCompassTappedHandler,
- &DrapeGui::Instance())));
+ auto cacheFunction = cacheFunctions.find(node.first);
+ if (cacheFunction != cacheFunctions.end())
+ sizeInfo[node.first] = cacheFunction->second(node.second, make_ref(renderer), textures);
}
- if (names & Skin::Ruler)
- {
- renderer->AddShapeRenderer(Skin::Ruler,
- Ruler(GetPos(Skin::Ruler)).Draw(textures));
- }
+ return renderer;
+}
- if (names & Skin::CountryStatus)
- {
- CountryStatus countryStatus = CountryStatus(GetPos(Skin::CountryStatus));
+drape_ptr LayerCacher::RecacheCountryStatus(ref_ptr textures)
+{
+ m2::PointF surfSize = DrapeGui::Instance().GetSurfaceSize();
+ drape_ptr renderer = make_unique_dp();
+ CountryStatus countryStatus = CountryStatus(Position(surfSize * 0.5, dp::Center));
- CountryStatus::TButtonHandlers handlers;
- RegisterButtonHandler(handlers, CountryStatusHelper::BUTTON_TYPE_MAP);
- RegisterButtonHandler(handlers, CountryStatusHelper::BUTTON_TYPE_MAP_ROUTING);
- RegisterButtonHandler(handlers, CountryStatusHelper::BUTTON_TRY_AGAIN);
+ CountryStatus::TButtonHandlers handlers;
+ RegisterButtonHandler(handlers, CountryStatusHelper::BUTTON_TYPE_MAP);
+ RegisterButtonHandler(handlers, CountryStatusHelper::BUTTON_TYPE_MAP_ROUTING);
+ RegisterButtonHandler(handlers, CountryStatusHelper::BUTTON_TRY_AGAIN);
- renderer->AddShapeRenderer(Skin::CountryStatus, countryStatus.Draw(textures, handlers));
- }
+ renderer->AddShapeRenderer(WIDGET_COUNTRY_STATUS, countryStatus.Draw(textures, handlers));
+ return renderer;
+}
- if (DrapeGui::Instance().IsCopyrightActive() && (names & Skin::Copyright))
- {
- renderer->AddShapeRenderer(Skin::Copyright,
- CopyrightLabel(GetPos(Skin::Copyright)).Draw(textures));
- }
+m2::PointF LayerCacher::CacheCompass(Position const & position, ref_ptr renderer,
+ ref_ptr textures)
+{
+ m2::PointF compassSize;
+ Compass compass = Compass(position);
+ drape_ptr shape = compass.Draw(compassSize, textures, bind(&DrapeGui::CallOnCompassTappedHandler,
+ &DrapeGui::Instance()));
+ renderer->AddShapeRenderer(WIDGET_COMPASS, move(shape));
-#ifdef DEBUG
+ return compassSize;
+}
+
+m2::PointF LayerCacher::CacheRuler(Position const & position, ref_ptr renderer,
+ ref_ptr textures)
+{
+ m2::PointF rulerSize;
+ renderer->AddShapeRenderer(WIDGET_RULER,
+ Ruler(position).Draw(rulerSize, textures));
+ return rulerSize;
+}
+
+m2::PointF LayerCacher::CacheCopyright(Position const & position, ref_ptr renderer,
+ ref_ptr textures)
+{
+ m2::PointF size;
+ renderer->AddShapeRenderer(WIDGET_COPYRIGHT,
+ CopyrightLabel(position).Draw(size, textures));
+
+ return size;
+}
+
+m2::PointF LayerCacher::CacheScaleLabel(Position const & position, ref_ptr renderer, ref_ptr textures)
+{
MutableLabelDrawer::Params params;
params.m_alphabet = "Scale: 1234567890";
params.m_maxLength = 10;
- params.m_anchor = dp::LeftBottom;
+ params.m_anchor = position.m_anchor;
params.m_font = DrapeGui::GetGuiTextFont();
- params.m_pivot = m2::PointF::Zero();
+ params.m_pivot = position.m_pixelPivot;
params.m_handleCreator = [](dp::Anchor, m2::PointF const &)
{
return make_unique_dp();
};
drape_ptr scaleRenderer = make_unique_dp();
- MutableLabelDrawer::Draw(params, textures, bind(&ShapeRenderer::AddShape, scaleRenderer.get(), _1, _2));
+ m2::PointF size = MutableLabelDrawer::Draw(params, textures, bind(&ShapeRenderer::AddShape, scaleRenderer.get(), _1, _2));
- renderer->AddShapeRenderer(Skin::ScaleLabel, move(scaleRenderer));
-#endif
-
- return renderer;
-}
-
-Position LayerCacher::GetPos(Skin::ElementName name)
-{
- return m_skin->ResolvePosition(name);
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-
-LayerRenderer::~LayerRenderer()
-{
- DestroyRenderers();
-}
-
-void LayerRenderer::Build(ref_ptr mng)
-{
- for (TRenderers::value_type & r : m_renderers)
- r.second->Build(mng);
-}
-
-void LayerRenderer::Render(ref_ptr mng, ScreenBase const & screen)
-{
- DrapeGui::Instance().GetRulerHelper().Update(screen);
- for (TRenderers::value_type & r : m_renderers)
- r.second->Render(screen, mng);
-}
-
-void LayerRenderer::Merge(ref_ptr other)
-{
- for (TRenderers::value_type & r : other->m_renderers)
- {
- TRenderers::iterator it = m_renderers.find(r.first);
- if (it != m_renderers.end())
- it->second = move(r.second);
- else
- m_renderers.insert(make_pair(r.first, move(r.second)));
- }
-
- other->m_renderers.clear();
-}
-
-void LayerRenderer::DestroyRenderers()
-{
- m_renderers.clear();
-}
-
-void LayerRenderer::AddShapeRenderer(Skin::ElementName name, drape_ptr && shape)
-{
- if (shape == nullptr)
- return;
-
- VERIFY(m_renderers.insert(make_pair(name, move(shape))).second, ());
-}
-
-bool LayerRenderer::OnTouchDown(m2::RectD const & touchArea)
-{
- for (TRenderers::value_type & r : m_renderers)
- {
- m_activeOverlay = r.second->ProcessTapEvent(touchArea);
- if (m_activeOverlay != nullptr)
- {
- m_activeOverlay->OnTapBegin();
- return true;
- }
- }
-
- return false;
-}
-
-void LayerRenderer::OnTouchUp(m2::RectD const & touchArea)
-{
- if (m_activeOverlay != nullptr)
- {
- if (m_activeOverlay->IsTapped(touchArea))
- m_activeOverlay->OnTap();
-
- m_activeOverlay->OnTapEnd();
- m_activeOverlay = nullptr;
- }
-}
-
-void LayerRenderer::OnTouchCancel(m2::RectD const & touchArea)
-{
- UNUSED_VALUE(touchArea);
- if (m_activeOverlay != nullptr)
- {
- m_activeOverlay->OnTapEnd();
- m_activeOverlay = nullptr;
- }
+ renderer->AddShapeRenderer(WIDGET_SCALE_LABLE, move(scaleRenderer));
+ return size;
}
}
diff --git a/drape_gui/layer_render.hpp b/drape_gui/layer_render.hpp
index ea566ba732..9a48aa1aa8 100644
--- a/drape_gui/layer_render.hpp
+++ b/drape_gui/layer_render.hpp
@@ -29,6 +29,7 @@ public:
void Build(ref_ptr mng);
void Render(ref_ptr mng, ScreenBase const & screen);
void Merge(ref_ptr other);
+ void SetLayout(gui::TWidgetsLayoutInfo const & info);
bool OnTouchDown(m2::RectD const & touchArea);
void OnTouchUp(m2::RectD const & touchArea);
@@ -38,10 +39,10 @@ private:
void DestroyRenderers();
friend class LayerCacher;
- void AddShapeRenderer(Skin::ElementName name, drape_ptr && shape);
+ void AddShapeRenderer(EWidget widget, drape_ptr && shape);
private:
- typedef map > TRenderers;
+ typedef map > TRenderers;
TRenderers m_renderers;
ref_ptr m_activeOverlay;
@@ -50,17 +51,16 @@ private:
class LayerCacher
{
public:
- LayerCacher(string const & deviceType);
-
- void Resize(int w, int h);
- /// @param names - can be combinations of single flags, or equal AllElements
- drape_ptr Recache(Skin::ElementName names, ref_ptr textures);
+ drape_ptr RecacheWidgets(TWidgetsInitInfo const & initInfo,
+ TWidgetsSizeInfo & sizeInfo,
+ ref_ptr textures);
+ drape_ptr RecacheCountryStatus(ref_ptr texMng);
private:
- Position GetPos(Skin::ElementName name);
-
-private:
- unique_ptr m_skin;
+ m2::PointF CacheCompass(Position const & position, ref_ptr renderer, ref_ptr textures);
+ m2::PointF CacheRuler(Position const & position, ref_ptr renderer, ref_ptr textures);
+ m2::PointF CacheCopyright(Position const & position, ref_ptr renderer, ref_ptr textures);
+ m2::PointF CacheScaleLabel(Position const & position, ref_ptr renderer, ref_ptr textures);
};
}
diff --git a/drape_gui/ruler.cpp b/drape_gui/ruler.cpp
index 48599074fb..5bdfb22de4 100644
--- a/drape_gui/ruler.cpp
+++ b/drape_gui/ruler.cpp
@@ -33,26 +33,10 @@ struct RulerVertex
dp::BindingInfo GetBindingInfo()
{
dp::BindingInfo info(3);
- dp::BindingDecl & posDecl = info.GetBindingDecl(0);
- posDecl.m_attributeName = "a_position";
- posDecl.m_componentCount = 2;
- posDecl.m_componentType = gl_const::GLFloatType;
- posDecl.m_offset = 0;
- posDecl.m_stride = sizeof(RulerVertex);
-
- dp::BindingDecl & normalDecl = info.GetBindingDecl(1);
- normalDecl.m_attributeName = "a_normal";
- normalDecl.m_componentCount = 2;
- normalDecl.m_componentType = gl_const::GLFloatType;
- normalDecl.m_offset = sizeof(glsl::vec2);
- normalDecl.m_stride = posDecl.m_stride;
-
- dp::BindingDecl & texDecl = info.GetBindingDecl(2);
- texDecl.m_attributeName = "a_colorTexCoords";
- texDecl.m_componentCount = 2;
- texDecl.m_componentType = gl_const::GLFloatType;
- texDecl.m_offset = 2 * sizeof(glsl::vec2);
- texDecl.m_stride = posDecl.m_stride;
+ uint8_t offset = 0;
+ offset += dp::FillDecl(0, "a_position", info, offset);
+ offset += dp::FillDecl(1, "a_normal", info, offset);
+ offset += dp::FillDecl(2, "a_colorTexCoords", info, offset);
return info;
}
@@ -74,6 +58,7 @@ public:
{
m_size = m2::PointF(helper.GetRulerPixelLength(), 2 * helper.GetRulerHalfHeight());
m_uniforms.SetFloatValue("u_length", helper.GetRulerPixelLength());
+ m_uniforms.SetFloatValue("u_position", m_pivot.x, m_pivot.y);
}
}
};
@@ -101,33 +86,40 @@ public:
TBase::Update(screen);
}
+ void SetPivot(glsl::vec2 const & pivot) override
+ {
+ RulerHelper & helper = DrapeGui::GetRulerHelper();
+ TBase::SetPivot(pivot + glsl::vec2(0.0, helper.GetVerticalTextOffset() - helper.GetRulerHalfHeight()));
+ }
+
private:
bool m_firstUpdate;
};
}
-drape_ptr Ruler::Draw(ref_ptr tex) const
+drape_ptr Ruler::Draw(m2::PointF & size, ref_ptr tex) const
{
ShapeControl control;
- DrawRuler(control, tex);
- DrawText(control, tex);
+ size = m2::PointF::Zero();
+ DrawRuler(size, control, tex);
+ DrawText(size, control, tex);
drape_ptr renderer = make_unique_dp();
renderer->AddShapeControl(move(control));
return renderer;
}
-void Ruler::DrawRuler(ShapeControl & control, ref_ptr tex) const
+void Ruler::DrawRuler(m2::PointF & size, ShapeControl & control, ref_ptr tex) const
{
buffer_vector data;
dp::TextureManager::ColorRegion reg;
tex->GetColorRegion(DrapeGui::GetGuiTextFont().m_color, reg);
- glsl::vec2 pivot = glsl::ToVec2(m_position.m_pixelPivot);
glsl::vec2 texCoord = glsl::ToVec2(reg.GetTexRect().Center());
float h = DrapeGui::GetRulerHelper().GetRulerHalfHeight();
+ size += m2::PointF(DrapeGui::GetRulerHelper().GetMaxRulerPixelLength(), 2.0 * h);
glsl::vec2 normals[] =
{
@@ -141,10 +133,10 @@ void Ruler::DrawRuler(ShapeControl & control, ref_ptr tex) c
else if (anchor & dp::Right)
normals[1] = glsl::vec2(0.0, 0.0);
- data.push_back(RulerVertex(pivot + glsl::vec2(0.0, h), normals[0], texCoord));
- data.push_back(RulerVertex(pivot + glsl::vec2(0.0, -h), normals[0], texCoord));
- data.push_back(RulerVertex(pivot + glsl::vec2(0.0, h), normals[1], texCoord));
- data.push_back(RulerVertex(pivot + glsl::vec2(0.0, -h), normals[1], texCoord));
+ data.push_back(RulerVertex(glsl::vec2(0.0, h), normals[0], texCoord));
+ data.push_back(RulerVertex(glsl::vec2(0.0, -h), normals[0], texCoord));
+ data.push_back(RulerVertex(glsl::vec2(0.0, h), normals[1], texCoord));
+ data.push_back(RulerVertex(glsl::vec2(0.0, -h), normals[1], texCoord));
dp::GLState state(gpu::RULER_PROGRAM, dp::GLState::Gui);
state.SetColorTexture(reg.GetTexture());
@@ -160,7 +152,7 @@ void Ruler::DrawRuler(ShapeControl & control, ref_ptr tex) c
}
}
-void Ruler::DrawText(ShapeControl & control, ref_ptr tex) const
+void Ruler::DrawText(m2::PointF & size, ShapeControl & control, ref_ptr tex) const
{
string alphabet;
size_t maxTextLength;
@@ -179,7 +171,8 @@ void Ruler::DrawText(ShapeControl & control, ref_ptr tex) co
return make_unique_dp(anchor, pivot);
};
- MutableLabelDrawer::Draw(params, tex, bind(&ShapeControl::AddShape, &control, _1, _2));
+ m2::PointF textSize = MutableLabelDrawer::Draw(params, tex, bind(&ShapeControl::AddShape, &control, _1, _2));
+ size.y += (textSize.y + abs(helper.GetVerticalTextOffset()));
}
}
diff --git a/drape_gui/ruler.hpp b/drape_gui/ruler.hpp
index 16a25d603f..1ec7b4d91a 100644
--- a/drape_gui/ruler.hpp
+++ b/drape_gui/ruler.hpp
@@ -9,11 +9,11 @@ class Ruler : public Shape
{
public:
Ruler(gui::Position const & position) : Shape(position) {}
- drape_ptr Draw(ref_ptr tex) const;
+ drape_ptr Draw(m2::PointF & size, ref_ptr tex) const;
private:
- void DrawRuler(ShapeControl & control, ref_ptr tex) const;
- void DrawText(ShapeControl & control, ref_ptr tex) const;
+ void DrawRuler(m2::PointF & size, ShapeControl & control, ref_ptr tex) const;
+ void DrawText(m2::PointF & size, ShapeControl & control, ref_ptr tex) const;
};
}
diff --git a/drape_gui/ruler_helper.cpp b/drape_gui/ruler_helper.cpp
index 383ce30f8e..f7b54c6041 100644
--- a/drape_gui/ruler_helper.cpp
+++ b/drape_gui/ruler_helper.cpp
@@ -149,6 +149,11 @@ float RulerHelper::GetRulerPixelLength() const
return m_pixelLength;
}
+float RulerHelper::GetMaxRulerPixelLength() const
+{
+ return MinPixelWidth * 3.0 / 2.0;
+}
+
int RulerHelper::GetVerticalTextOffset() const
{
return -5 * DrapeGui::Instance().GetScaleFactor();
diff --git a/drape_gui/ruler_helper.hpp b/drape_gui/ruler_helper.hpp
index fd024dac35..338dffaa15 100644
--- a/drape_gui/ruler_helper.hpp
+++ b/drape_gui/ruler_helper.hpp
@@ -17,6 +17,7 @@ public:
float GetRulerHalfHeight() const;
float GetRulerPixelLength() const;
+ float GetMaxRulerPixelLength() const;
int GetVerticalTextOffset() const;
bool IsTextDirty() const;
string const & GetRulerText() const;
diff --git a/drape_gui/shape.cpp b/drape_gui/shape.cpp
index 54d106a308..7c1ef4feec 100644
--- a/drape_gui/shape.cpp
+++ b/drape_gui/shape.cpp
@@ -118,6 +118,15 @@ void ShapeRenderer::AddShapeControl(ShapeControl && control)
m_shapes.push_back(move(control));
}
+void ShapeRenderer::SetPivot(m2::PointF const & pivot)
+{
+ for (ShapeControl & control : m_shapes)
+ {
+ for (ShapeControl::ShapeInfo & info : control.m_shapesInfo)
+ info.m_handle->SetPivot(glsl::ToVec2(pivot));
+ }
+}
+
void ShapeRenderer::ForEachShapeControl(TShapeControlEditFn const & fn)
{
for_each(m_shapes.begin(), m_shapes.end(), fn);
diff --git a/drape_gui/shape.hpp b/drape_gui/shape.hpp
index f9be811c79..3152a19ea3 100644
--- a/drape_gui/shape.hpp
+++ b/drape_gui/shape.hpp
@@ -32,7 +32,7 @@ public:
virtual void GetPixelShape(ScreenBase const & screen, Rects & rects) const override;
m2::PointF GetSize() const { return m_size; }
- void SetPivot(glsl::vec2 const & pivot) { m_pivot = pivot; }
+ virtual void SetPivot(glsl::vec2 const & pivot) { m_pivot = pivot; }
protected:
dp::UniformValuesStorage m_uniforms;
@@ -89,6 +89,8 @@ public:
void AddShape(dp::GLState const & state, drape_ptr && bucket);
void AddShapeControl(ShapeControl && control);
+ void SetPivot(m2::PointF const & pivot);
+
ref_ptr ProcessTapEvent(m2::RectD const & touchArea);
private:
diff --git a/drape_gui/skin.cpp b/drape_gui/skin.cpp
index a606adde99..5d44f296a7 100644
--- a/drape_gui/skin.cpp
+++ b/drape_gui/skin.cpp
@@ -1,5 +1,4 @@
#include "skin.hpp"
-#include "drape_gui.hpp"
#include "platform/platform.hpp"
#include "coding/parse_xml.hpp"
@@ -118,7 +117,7 @@ private:
class SkinLoader
{
public:
- explicit SkinLoader(map > & skin)
+ explicit SkinLoader(map > & skin)
: m_skin(skin) {}
bool Push(string const & element)
@@ -130,13 +129,11 @@ public:
m_inElement = true;
if (element == "ruler")
- m_currentElement = Skin::ElementName::Ruler;
+ m_currentElement = WIDGET_RULER;
else if (element == "compass")
- m_currentElement = Skin::ElementName::Compass;
+ m_currentElement = WIDGET_COMPASS;
else if (element == "copyright")
- m_currentElement = Skin::ElementName::Copyright;
- else if (element == "country_status")
- m_currentElement = Skin::ElementName::CountryStatus;
+ m_currentElement = WIDGET_COPYRIGHT;
else
ASSERT(false, ());
}
@@ -196,10 +193,10 @@ private:
bool m_inConfiguration = false;
bool m_inElement = false;
- Skin::ElementName m_currentElement = Skin::ElementName::Ruler;
+ EWidget m_currentElement = WIDGET_RULER;
ResolverParser m_parser;
- map > & m_skin;
+ map > & m_skin;
};
}
@@ -247,7 +244,8 @@ void PositionResolver::SetOffsetY(float y)
m_offset.y = y;
}
-Skin::Skin(ReaderPtr const & reader)
+Skin::Skin(ReaderPtr const & reader, float visualScale)
+ : m_visualScale(visualScale)
{
SkinLoader loader(m_resolvers);
ReaderSource > source(reader);
@@ -255,13 +253,13 @@ Skin::Skin(ReaderPtr const & reader)
LOG(LERROR, ("Error parsing gui skin"));
}
-Position Skin::ResolvePosition(ElementName name)
+Position Skin::ResolvePosition(EWidget name)
{
// check that name have only one bit
ASSERT((static_cast(name) & (static_cast(name) - 1)) == 0, ());
TResolversPair const & resolvers = m_resolvers[name];
PositionResolver const & resolver = (m_displayWidth < m_displayHeight) ? resolvers.first : resolvers.second;
- return resolver.Resolve(m_displayWidth, m_displayHeight, DrapeGui::Instance().GetScaleFactor());
+ return resolver.Resolve(m_displayWidth, m_displayHeight, m_visualScale);
}
void Skin::Resize(int w, int h)
diff --git a/drape_gui/skin.hpp b/drape_gui/skin.hpp
index 71b701033a..d1f059a417 100644
--- a/drape_gui/skin.hpp
+++ b/drape_gui/skin.hpp
@@ -9,9 +9,23 @@
namespace gui
{
+enum EWidget
+{
+ WIDGET_RULER = 0x1,
+ WIDGET_COMPASS = 0x2,
+ WIDGET_COPYRIGHT = 0x4,
+ WIDGET_SCALE_LABLE = 0x8,
+ /// WIDGET_COUNTRY_STATUS - controlled by rendering kernel. Don't use it in platform code
+ WIDGET_COUNTRY_STATUS = 0x8000
+};
+
struct Position
{
Position() : m_pixelPivot(m2::PointF::Zero()), m_anchor(dp::Center) {}
+ explicit Position(dp::Anchor anchor)
+ : m_pixelPivot(m2::PointF::Zero())
+ , m_anchor(anchor) {}
+
Position(m2::PointF const & pt, dp::Anchor anchor)
: m_pixelPivot(pt)
, m_anchor(anchor) {}
@@ -20,6 +34,13 @@ struct Position
dp::Anchor m_anchor;
};
+/// TWidgetsInitInfo - static information about gui widgets (geometry align)
+using TWidgetsInitInfo = map;
+/// TWidgetsLayoutInfo - dynamic info. Pivot point of each widget in pixel coordinates
+using TWidgetsLayoutInfo = map;
+/// TWidgetsSizeInfo - info about widget pixel sizes
+using TWidgetsSizeInfo = TWidgetsLayoutInfo;
+
class PositionResolver
{
public:
@@ -38,33 +59,30 @@ private:
class Skin
{
public:
- enum ElementName
- {
- CountryStatus = 0x1,
- Ruler = 0x2,
- Compass = 0x4,
- Copyright = 0x8,
- AllElements = CountryStatus | Ruler | Compass | Copyright,
- // It's drawing only in debug and not depend from elements flag. It's not part of "AllElements"
- ScaleLabel = 0x8000
- };
-
- explicit Skin(ReaderPtr const & reader);
+ Skin(ReaderPtr const & reader, float visualScale);
/// @param name - must be single flag, not combination
- Position ResolvePosition(ElementName name);
+ Position ResolvePosition(EWidget name);
void Resize(int w, int h);
int GetWidth() const { return m_displayWidth; }
int GetHeight() const { return m_displayHeight; }
+ template
+ void ForEach(ToDo todo)
+ {
+ for (auto node : m_resolvers)
+ todo(node.first, ResolvePosition(node.first));
+ }
+
private:
/// TResolversPair.first - Portrait (when weight < height)
/// TResolversPair.second - Landscape (when weight >= height)
typedef pair TResolversPair;
- map m_resolvers;
+ map m_resolvers;
int m_displayWidth;
int m_displayHeight;
+ float m_visualScale;
};
ReaderPtr ResolveGuiSkinFile(string const & deviceType);
diff --git a/map/framework.cpp b/map/framework.cpp
index 90bff7cdcf..2b24d4bb99 100644
--- a/map/framework.cpp
+++ b/map/framework.cpp
@@ -1305,7 +1305,7 @@ bool Framework::GetDistanceAndAzimut(m2::PointD const & point,
return (d < 25000.0);
}
-void Framework::CreateDrapeEngine(ref_ptr contextFactory, float vs, int w, int h)
+void Framework::CreateDrapeEngine(ref_ptr contextFactory, DrapeCreationParams && params)
{
using TReadIDsFn = df::MapDataProvider::TReadIDsFn;
using TReadFeaturesFn = df::MapDataProvider::TReadFeaturesFn;
@@ -1347,19 +1347,20 @@ void Framework::CreateDrapeEngine(ref_ptr contextFactory,
df::DrapeEngine::Params p(contextFactory,
make_ref(&m_stringsBundle),
- df::Viewport(0, 0, w, h),
+ df::Viewport(0, 0, params.m_surfaceWidth, params.m_surfaceHeight),
df::MapDataProvider(idReadFn, featureReadFn, updateCountryIndex, isCountryLoadedFn,
downloadMapFn, downloadMapRoutingFn, downloadRetryFn),
- vs);
+ params.m_visualScale,
+ move(params.m_widgetsInitInfo));
- m_drapeEngine = make_unique_dp(p);
+ m_drapeEngine = make_unique_dp(move(p));
AddViewportListener([this](ScreenBase const & screen)
{
m_currentMovelView = screen;
});
m_drapeEngine->SetTapEventInfoListener(bind(&Framework::OnTapEvent, this, _1, _2, _3, _4));
m_drapeEngine->SetUserPositionListener(bind(&Framework::OnUserPositionChanged, this, _1));
- OnSize(w, h);
+ OnSize(params.m_surfaceWidth, params.m_surfaceHeight);
}
ref_ptr Framework::GetDrapeEngine()
@@ -1395,11 +1396,18 @@ void Framework::SetupMeasurementSystem()
Settings::Get("Units", units);
m_routingSession.SetTurnNotificationsUnits(units);
+}
+void Framework::SetWidgetLayout(gui::TWidgetsLayoutInfo && layout)
+{
+ ASSERT(m_drapeEngine != nullptr, ());
+ m_drapeEngine->SetWidgetLayout(move(layout));
+}
- //m_informationDisplay.measurementSystemChanged();
- ///@TODO UVR
- //Invalidate();
+gui::TWidgetsSizeInfo const & Framework::GetWidgetSizes()
+{
+ ASSERT(m_drapeEngine != nullptr, ());
+ return m_drapeEngine->GetWidgetSizes();
}
string Framework::GetCountryCode(m2::PointD const & pt) const
diff --git a/map/framework.hpp b/map/framework.hpp
index 2fef96f2af..868318330f 100644
--- a/map/framework.hpp
+++ b/map/framework.hpp
@@ -11,6 +11,9 @@
#include "drape_frontend/drape_engine.hpp"
#include "drape_frontend/user_event_stream.hpp"
+
+#include "drape_gui/skin.hpp"
+
#include "drape/oglcontextfactory.hpp"
#include "indexer/data_header.hpp"
@@ -264,16 +267,26 @@ private:
//@}
public:
- void CreateDrapeEngine(ref_ptr contextFactory, float vs, int w, int h);
+ struct DrapeCreationParams
+ {
+ float m_visualScale;
+ int m_surfaceWidth;
+ int m_surfaceHeight;
+
+ gui::TWidgetsInitInfo m_widgetsInitInfo;
+ };
+
+ void CreateDrapeEngine(ref_ptr contextFactory, DrapeCreationParams && params);
ref_ptr GetDrapeEngine();
void DestroyDrapeEngine();
void SetMapStyle(MapStyle mapStyle);
MapStyle GetMapStyle() const;
- void PrepareToShutdown();
+ void SetWidgetLayout(gui::TWidgetsLayoutInfo && layout);
+ const gui::TWidgetsSizeInfo & GetWidgetSizes();
- void SetupMeasurementSystem();
+ void PrepareToShutdown();
private:
void InitCountryInfoGetter();
diff --git a/qt/draw_widget.cpp b/qt/draw_widget.cpp
index fe6f517ae5..fccd3e1266 100644
--- a/qt/draw_widget.cpp
+++ b/qt/draw_widget.cpp
@@ -109,7 +109,7 @@ bool IsLocationEmulation(QMouseEvent * e)
void DrawWidget::UpdateAfterSettingsChanged()
{
- m_framework->SetupMeasurementSystem();
+ m_framework->EnterForeground();
}
void DrawWidget::LoadState()
@@ -170,8 +170,21 @@ bool IsLocationEmulation(QMouseEvent * e)
void DrawWidget::CreateEngine()
{
- m_framework->CreateDrapeEngine(make_ref(m_contextFactory), m_ratio,
- m_ratio * width(), m_ratio * height());
+ Framework::DrapeCreationParams p;
+ p.m_surfaceWidth = m_ratio * width();
+ p.m_surfaceHeight = m_ratio * height();
+ p.m_visualScale = m_ratio;
+
+ m_skin.reset(new gui::Skin(gui::ResolveGuiSkinFile("default"), m_ratio));
+ m_skin->Resize(p.m_surfaceWidth, p.m_surfaceHeight);
+ m_skin->ForEach([&p](gui::EWidget widget, gui::Position const & pos)
+ {
+ p.m_widgetsInitInfo[widget] = pos;
+ });
+
+ p.m_widgetsInitInfo[gui::WIDGET_SCALE_LABLE] = gui::Position(dp::LeftBottom);
+
+ m_framework->CreateDrapeEngine(make_ref(m_contextFactory), move(p));
m_framework->AddViewportListener(bind(&DrawWidget::OnViewportChanged, this, _1));
}
@@ -315,7 +328,21 @@ bool IsLocationEmulation(QMouseEvent * e)
void DrawWidget::sizeChanged(int)
{
- m_framework->OnSize(m_ratio * width(), m_ratio * height());
+ float w = m_ratio * width();
+ float h = m_ratio * height();
+ m_framework->OnSize(w, h);
+ if (m_skin)
+ {
+ m_skin->Resize(w, h);
+
+ gui::TWidgetsLayoutInfo layout;
+ m_skin->ForEach([&layout](gui::EWidget w, gui::Position const & pos)
+ {
+ layout[w] = pos.m_pixelPivot;
+ });
+
+ m_framework->SetWidgetLayout(move(layout));
+ }
}
void DrawWidget::SubmitFakeLocationPoint(m2::PointD const & pt)
diff --git a/qt/draw_widget.hpp b/qt/draw_widget.hpp
index 37dd51afdb..35276d9951 100644
--- a/qt/draw_widget.hpp
+++ b/qt/draw_widget.hpp
@@ -5,6 +5,7 @@
#include "map/framework.hpp"
#include "drape_frontend/drape_engine.hpp"
+#include "drape_gui/skin.hpp"
#include "std/unique_ptr.hpp"
@@ -99,5 +100,7 @@ namespace qt
bool m_emulatingLocation;
void InitRenderPolicy();
+
+ unique_ptr m_skin;
};
}
diff --git a/qt/mainwindow.cpp b/qt/mainwindow.cpp
index 841623bd23..446a4195ed 100644
--- a/qt/mainwindow.cpp
+++ b/qt/mainwindow.cpp
@@ -386,7 +386,7 @@ void MainWindow::OnPreferences()
PreferencesDialog dlg(this);
dlg.exec();
- m_pDrawWidget->GetFramework().SetupMeasurementSystem();
+ m_pDrawWidget->GetFramework().EnterForeground();
}
#ifndef NO_DOWNLOADER