forked from organicmaps/organicmaps
Minor refactoring of OverlayElement and it’s inheritors: do not store rough rect and vector of any rects by default.
This commit is contained in:
parent
696fde40b3
commit
7a54c6e080
33 changed files with 290 additions and 496 deletions
|
@ -9,36 +9,18 @@ namespace graphics
|
|||
{}
|
||||
|
||||
CircleElement::CircleElement(Params const & p)
|
||||
: base_t(p),
|
||||
: BaseT(p),
|
||||
m_ci(p.m_ci)
|
||||
{}
|
||||
|
||||
vector<m2::AnyRectD> const & CircleElement::boundRects() const
|
||||
m2::RectD CircleElement::GetBoundRect() const
|
||||
{
|
||||
if (isDirtyRect())
|
||||
{
|
||||
m_boundRects.clear();
|
||||
m_boundRects.push_back(boundRect());
|
||||
setIsDirtyRect(false);
|
||||
}
|
||||
// Skip for one pixel on every border.
|
||||
m2::PointD sz = m_ci.resourceSize();
|
||||
sz -= m2::PointD(2, 2);
|
||||
|
||||
return m_boundRects;
|
||||
}
|
||||
|
||||
m2::AnyRectD const CircleElement::boundRect() const
|
||||
{
|
||||
m2::RectI texRect(m2::PointI(0, 0),
|
||||
m2::PointI(m_ci.resourceSize()));
|
||||
|
||||
texRect.Inflate(-1, -1);
|
||||
|
||||
m2::PointD sz(texRect.SizeX(), texRect.SizeY());
|
||||
|
||||
m2::PointD posPt = computeTopLeft(sz,
|
||||
pivot(),
|
||||
position());
|
||||
|
||||
return m2::AnyRectD(m2::RectD(posPt, posPt + sz));
|
||||
m2::PointD const posPt = computeTopLeft(sz, pivot(), position());
|
||||
return m2::RectD(posPt, posPt + sz);
|
||||
}
|
||||
|
||||
void CircleElement::draw(OverlayRenderer * r, math::Matrix<double, 3, 3> const & m) const
|
||||
|
@ -69,6 +51,6 @@ namespace graphics
|
|||
void CircleElement::setTransformation(const math::Matrix<double, 3, 3> & m)
|
||||
{
|
||||
setPivot(pivot() * getResetMatrix() * m);
|
||||
base_t::setTransformation(m);
|
||||
BaseT::setTransformation(m);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,23 +3,17 @@
|
|||
#include "overlay_element.hpp"
|
||||
#include "circle.hpp"
|
||||
|
||||
|
||||
namespace graphics
|
||||
{
|
||||
class CircleElement : public OverlayElement
|
||||
{
|
||||
private:
|
||||
|
||||
Circle::Info m_ci;
|
||||
|
||||
mutable vector<m2::AnyRectD> m_boundRects;
|
||||
|
||||
m2::AnyRectD const boundRect() const;
|
||||
|
||||
public:
|
||||
typedef OverlayElement BaseT;
|
||||
|
||||
typedef OverlayElement base_t;
|
||||
|
||||
struct Params : public base_t::Params
|
||||
struct Params : public BaseT::Params
|
||||
{
|
||||
Circle::Info m_ci;
|
||||
Params();
|
||||
|
@ -27,7 +21,7 @@ namespace graphics
|
|||
|
||||
CircleElement(Params const & p);
|
||||
|
||||
vector<m2::AnyRectD> const & boundRects() const;
|
||||
virtual m2::RectD GetBoundRect() const;
|
||||
|
||||
void draw(OverlayRenderer * s, math::Matrix<double, 3, 3> const & m) const;
|
||||
|
||||
|
|
|
@ -898,7 +898,7 @@ namespace
|
|||
params.m_logText = strings::MakeUniString("Simplicity is the ultimate sophistication");
|
||||
graphics::StraightTextElement ste(params);
|
||||
|
||||
m2::RectD r = ste.roughBoundRect();
|
||||
m2::RectD const r = ste.GetBoundRect();
|
||||
p->drawRectangle(r, graphics::Color(0, 0, 255, 255), 0);
|
||||
|
||||
base_t::DoDraw(p);
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace graphics
|
|||
|
||||
m2::RectD const OverlayElementTraits::LimitRect(shared_ptr<OverlayElement> const & elem)
|
||||
{
|
||||
return elem->roughBoundRect();
|
||||
return elem->GetBoundRect();
|
||||
}
|
||||
|
||||
void DrawIfNotCancelled(OverlayRenderer * r,
|
||||
|
@ -52,15 +52,19 @@ namespace graphics
|
|||
void offsetTree(Tree & tree, m2::PointD const & offs, m2::RectD const & r)
|
||||
{
|
||||
m2::AnyRectD AnyRect(r);
|
||||
|
||||
typedef typename Tree::elem_t elem_t;
|
||||
vector<elem_t> elems;
|
||||
|
||||
tree.ForEach(MakeBackInsertFunctor(elems));
|
||||
tree.Clear();
|
||||
|
||||
for (typename vector<elem_t>::iterator it = elems.begin(); it != elems.end(); ++it)
|
||||
{
|
||||
(*it)->offset(offs);
|
||||
vector<m2::AnyRectD> const & aaLimitRects = (*it)->boundRects();
|
||||
OverlayElement::RectsT aaLimitRects;
|
||||
(*it)->GetMiniBoundRects(aaLimitRects);
|
||||
|
||||
bool doAppend = false;
|
||||
|
||||
(*it)->setIsNeedRedraw(false);
|
||||
|
@ -69,15 +73,12 @@ namespace graphics
|
|||
bool hasInside = false;
|
||||
bool hasOutside = false;
|
||||
|
||||
for (int i = 0; i < aaLimitRects.size(); ++i)
|
||||
for (size_t i = 0; i < aaLimitRects.size(); ++i)
|
||||
{
|
||||
bool isPartInsideRect = AnyRect.IsRectInside(aaLimitRects[i]);
|
||||
|
||||
if (isPartInsideRect)
|
||||
if (AnyRect.IsRectInside(aaLimitRects[i]))
|
||||
{
|
||||
if (hasOutside)
|
||||
{
|
||||
/// intersecting
|
||||
(*it)->setIsNeedRedraw(true);
|
||||
doAppend = true;
|
||||
break;
|
||||
|
@ -90,25 +91,20 @@ namespace graphics
|
|||
}
|
||||
}
|
||||
|
||||
bool isRectInsidePart = aaLimitRects[i].IsRectInside(AnyRect);
|
||||
|
||||
if (isRectInsidePart)
|
||||
if (aaLimitRects[i].IsRectInside(AnyRect))
|
||||
{
|
||||
doAppend = true;
|
||||
break;
|
||||
}
|
||||
|
||||
bool isPartIntersectRect = AnyRect.IsIntersect(aaLimitRects[i]);
|
||||
|
||||
if (isPartIntersectRect)
|
||||
if (AnyRect.IsIntersect(aaLimitRects[i]))
|
||||
{
|
||||
/// intersecting
|
||||
(*it)->setIsNeedRedraw(true);
|
||||
doAppend = true;
|
||||
break;
|
||||
}
|
||||
|
||||
/// the last case remains here - part rect is outside big rect
|
||||
// the last case remains here - part rect is outside big rect
|
||||
if (hasInside)
|
||||
{
|
||||
(*it)->setIsNeedRedraw(true);
|
||||
|
@ -183,15 +179,12 @@ namespace graphics
|
|||
|
||||
void operator()(shared_ptr<OverlayElement> const & e)
|
||||
{
|
||||
vector<m2::AnyRectD> const & rects = e->boundRects();
|
||||
OverlayElement::RectsT rects;
|
||||
e->GetMiniBoundRects(rects);
|
||||
|
||||
for (vector<m2::AnyRectD>::const_iterator it = rects.begin();
|
||||
it != rects.end();
|
||||
++it)
|
||||
for (size_t i = 0; i < rects.size(); ++i)
|
||||
{
|
||||
m2::AnyRectD const & rect = *it;
|
||||
|
||||
if (m_rect.IsIntersect(rect))
|
||||
if (m_rect.IsIntersect(rects[i]))
|
||||
{
|
||||
m_elements->push_back(e);
|
||||
break;
|
||||
|
@ -200,37 +193,49 @@ namespace graphics
|
|||
}
|
||||
};
|
||||
|
||||
struct DoPreciseIntersect
|
||||
class DoPreciseIntersect
|
||||
{
|
||||
shared_ptr<OverlayElement> m_oe;
|
||||
bool * m_isIntersect;
|
||||
OverlayElement::RectsT m_rects;
|
||||
|
||||
DoPreciseIntersect(shared_ptr<OverlayElement> const & oe, bool * isIntersect)
|
||||
: m_oe(oe),
|
||||
m_isIntersect(isIntersect)
|
||||
{}
|
||||
bool m_isIntersect;
|
||||
|
||||
public:
|
||||
DoPreciseIntersect(shared_ptr<OverlayElement> const & oe)
|
||||
: m_oe(oe), m_isIntersect(false)
|
||||
{
|
||||
m_oe->GetMiniBoundRects(m_rects);
|
||||
}
|
||||
|
||||
m2::RectD GetSearchRect() const
|
||||
{
|
||||
m2::RectD rect;
|
||||
for (size_t i = 0; i < m_rects.size(); ++i)
|
||||
rect.Add(m_rects[i].GetGlobalRect());
|
||||
return rect;
|
||||
}
|
||||
|
||||
void operator()(shared_ptr<OverlayElement> const & e)
|
||||
{
|
||||
if (*m_isIntersect)
|
||||
if (m_isIntersect)
|
||||
return;
|
||||
|
||||
if (m_oe->m_userInfo == e->m_userInfo)
|
||||
return;
|
||||
|
||||
vector<m2::AnyRectD> const & lr = m_oe->boundRects();
|
||||
vector<m2::AnyRectD> const & rr = e->boundRects();
|
||||
OverlayElement::RectsT rects;
|
||||
e->GetMiniBoundRects(rects);
|
||||
|
||||
for (vector<m2::AnyRectD>::const_iterator lit = lr.begin(); lit != lr.end(); ++lit)
|
||||
{
|
||||
for (vector<m2::AnyRectD>::const_iterator rit = rr.begin(); rit != rr.end(); ++rit)
|
||||
for (size_t i = 0; i < m_rects.size(); ++i)
|
||||
for (size_t j = 0; j < rects.size(); ++j)
|
||||
{
|
||||
*m_isIntersect = lit->IsIntersect(*rit);
|
||||
if (*m_isIntersect)
|
||||
m_isIntersect = m_rects[i].IsIntersect(rects[j]);
|
||||
if (m_isIntersect)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IsIntersect() const { return m_isIntersect; }
|
||||
};
|
||||
|
||||
void Overlay::selectOverlayElements(m2::RectD const & rect, list<shared_ptr<OverlayElement> > & res) const
|
||||
|
@ -241,10 +246,10 @@ namespace graphics
|
|||
|
||||
void Overlay::replaceOverlayElement(shared_ptr<OverlayElement> const & oe)
|
||||
{
|
||||
bool isIntersect = false;
|
||||
DoPreciseIntersect fn(oe, &isIntersect);
|
||||
m_tree.ForEachInRect(oe->roughBoundRect(), fn);
|
||||
if (isIntersect)
|
||||
DoPreciseIntersect fn(oe);
|
||||
m_tree.ForEachInRect(fn.GetSearchRect(), bind<void>(ref(fn), _1));
|
||||
|
||||
if (fn.IsIntersect())
|
||||
m_tree.ReplaceIf(oe, &betterOverlayElement);
|
||||
else
|
||||
m_tree.Add(oe);
|
||||
|
@ -321,41 +326,25 @@ namespace graphics
|
|||
m_tree.ForEach(MakeBackInsertFunctor(v));
|
||||
m_tree.Clear();
|
||||
|
||||
//int clippedCnt = 0;
|
||||
//int elemCnt = v.size();
|
||||
|
||||
m2::RectD rd(r);
|
||||
m2::RectD const rd(r);
|
||||
m2::AnyRectD ard(rd);
|
||||
|
||||
for (unsigned i = 0; i < v.size(); ++i)
|
||||
for (size_t i = 0; i < v.size(); ++i)
|
||||
{
|
||||
shared_ptr<OverlayElement> const & e = v[i];
|
||||
|
||||
if (!e->isVisible())
|
||||
{
|
||||
//clippedCnt++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (e->roughBoundRect().IsIntersect(rd))
|
||||
{
|
||||
bool hasIntersection = false;
|
||||
for (unsigned j = 0; j < e->boundRects().size(); ++j)
|
||||
OverlayElement::RectsT rects;
|
||||
e->GetMiniBoundRects(rects);
|
||||
|
||||
for (size_t j = 0; j < rects.size(); ++j)
|
||||
if (ard.IsIntersect(rects[j]))
|
||||
{
|
||||
if (ard.IsIntersect(e->boundRects()[j]))
|
||||
{
|
||||
hasIntersection = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasIntersection)
|
||||
processOverlayElement(e);
|
||||
}
|
||||
//else
|
||||
// clippedCnt++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// LOG(LINFO, ("clipped out", clippedCnt, "elements,", elemCnt, "elements total"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "overlay_element.hpp"
|
||||
#include "overlay_renderer.hpp"
|
||||
|
||||
|
||||
namespace graphics
|
||||
|
@ -50,7 +51,6 @@ namespace graphics
|
|||
void OverlayElement::offset(m2::PointD const & offs)
|
||||
{
|
||||
setPivot(pivot() + offs);
|
||||
setIsDirtyRect(true);
|
||||
}
|
||||
|
||||
m2::PointD const & OverlayElement::pivot() const
|
||||
|
@ -61,7 +61,7 @@ namespace graphics
|
|||
void OverlayElement::setPivot(m2::PointD const & pivot)
|
||||
{
|
||||
m_pivot = pivot;
|
||||
setIsDirtyRect(true);
|
||||
setIsDirtyLayout(true);
|
||||
}
|
||||
|
||||
graphics::EPosition OverlayElement::position() const
|
||||
|
@ -72,7 +72,7 @@ namespace graphics
|
|||
void OverlayElement::setPosition(graphics::EPosition pos)
|
||||
{
|
||||
m_position = pos;
|
||||
setIsDirtyRect(true);
|
||||
setIsDirtyLayout(true);
|
||||
}
|
||||
|
||||
double OverlayElement::depth() const
|
||||
|
@ -123,52 +123,31 @@ namespace graphics
|
|||
void OverlayElement::setIsDirtyLayout(bool flag) const
|
||||
{
|
||||
m_flags[DIRTY_LAYOUT] = flag;
|
||||
if (flag)
|
||||
setIsDirtyRect(true);
|
||||
}
|
||||
|
||||
bool OverlayElement::isDirtyRect() const
|
||||
m2::RectD OverlayElement::GetBoundRect() const
|
||||
{
|
||||
return m_flags[DIRTY_RECT];
|
||||
RectsT rects;
|
||||
GetMiniBoundRects(rects);
|
||||
|
||||
m2::RectD rect;
|
||||
for (size_t i = 0; i < rects.size(); ++i)
|
||||
rect.Add(rects[i].GetGlobalRect());
|
||||
return rect;
|
||||
}
|
||||
|
||||
void OverlayElement::setIsDirtyRect(bool flag) const
|
||||
void OverlayElement::GetMiniBoundRects(RectsT & rects) const
|
||||
{
|
||||
if (flag)
|
||||
m_flags[DIRTY_ROUGH_RECT] = true;
|
||||
m_flags[DIRTY_RECT] = flag;
|
||||
}
|
||||
|
||||
m2::RectD const & OverlayElement::roughBoundRect() const
|
||||
{
|
||||
if (m_flags[DIRTY_ROUGH_RECT])
|
||||
{
|
||||
vector<m2::AnyRectD> const & rects = boundRects();
|
||||
size_t const count = rects.size();
|
||||
if (count == 0)
|
||||
{
|
||||
/// @todo Is it correct use-case?
|
||||
m_roughBoundRect = m2::RectD(pivot(), pivot());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_roughBoundRect = rects[0].GetGlobalRect();
|
||||
for (size_t i = 1; i < count; ++i)
|
||||
m_roughBoundRect.Add(rects[i].GetGlobalRect());
|
||||
}
|
||||
|
||||
m_flags[DIRTY_ROUGH_RECT] = false;
|
||||
}
|
||||
|
||||
return m_roughBoundRect;
|
||||
rects.push_back(m2::AnyRectD(GetBoundRect()));
|
||||
}
|
||||
|
||||
bool OverlayElement::hitTest(m2::PointD const & pt) const
|
||||
{
|
||||
vector<m2::AnyRectD> const & rects = boundRects();
|
||||
RectsT rects;
|
||||
GetMiniBoundRects(rects);
|
||||
|
||||
for (vector<m2::AnyRectD>::const_iterator it = rects.begin(); it != rects.end(); ++it)
|
||||
if (it->IsPointInside(pt))
|
||||
for (size_t i = 0; i < rects.size(); ++i)
|
||||
if (rects[i].IsPointInside(pt))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -184,11 +163,6 @@ namespace graphics
|
|||
m_flags[VALID] = flag;
|
||||
}
|
||||
|
||||
bool OverlayElement::roughHitTest(m2::PointD const & pt) const
|
||||
{
|
||||
return roughBoundRect().IsPointInside(pt);
|
||||
}
|
||||
|
||||
OverlayElement::UserInfo const & OverlayElement::userInfo() const
|
||||
{
|
||||
return m_userInfo;
|
||||
|
@ -200,22 +174,22 @@ namespace graphics
|
|||
/// In general there is no need to store m_roughBoundRect at all.
|
||||
/// It's calculating time is fast, because elements already cache vector<m2::AnyRectD>.
|
||||
|
||||
m2::PointD res = m_roughBoundRect.Center();
|
||||
m2::RectD const rect = GetBoundRect();
|
||||
m2::PointD res = rect.Center();
|
||||
|
||||
if (pos & EPosLeft)
|
||||
res.x = m_roughBoundRect.minX();
|
||||
res.x = rect.minX();
|
||||
if (pos & EPosRight)
|
||||
res.x = m_roughBoundRect.maxX();
|
||||
res.x = rect.maxX();
|
||||
|
||||
if (pos & EPosAbove)
|
||||
res.y = m_roughBoundRect.minY();
|
||||
res.y = rect.minY();
|
||||
if (pos & EPosUnder)
|
||||
res.y = m_roughBoundRect.maxY();
|
||||
res.y = rect.maxY();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
bool OverlayElement::hasSharpGeometry() const
|
||||
{
|
||||
return false;
|
||||
|
@ -240,4 +214,13 @@ namespace graphics
|
|||
{
|
||||
setTransformation(math::Identity<double, 3>());
|
||||
}
|
||||
|
||||
void OverlayElement::DrawRectsDebug(graphics::OverlayRenderer * r, Color color, double depth) const
|
||||
{
|
||||
RectsT rects;
|
||||
GetMiniBoundRects(rects);
|
||||
|
||||
for (size_t i = 0; i < rects.size(); ++i)
|
||||
r->drawRectangle(rects[i], color, depth);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include "defines.hpp"
|
||||
#include "color.hpp"
|
||||
|
||||
#include "../geometry/point2d.hpp"
|
||||
#include "../geometry/any_rect2d.hpp"
|
||||
|
||||
#include "../base/matrix.hpp"
|
||||
#include "../base/buffer_vector.hpp"
|
||||
|
||||
#include "../std/vector.hpp"
|
||||
#include "../std/bitset.hpp"
|
||||
|
||||
|
||||
|
@ -40,13 +41,10 @@ namespace graphics
|
|||
FROZEN,
|
||||
VISIBLE,
|
||||
VALID,
|
||||
DIRTY_RECT,
|
||||
DIRTY_LAYOUT,
|
||||
DIRTY_ROUGH_RECT,
|
||||
FLAGS_COUNT };
|
||||
|
||||
mutable bitset<FLAGS_COUNT> m_flags;
|
||||
mutable m2::RectD m_roughBoundRect;
|
||||
|
||||
math::Matrix<double, 3, 3> m_inverseMatrix;
|
||||
|
||||
|
@ -72,8 +70,13 @@ namespace graphics
|
|||
OverlayElement(Params const & p);
|
||||
virtual ~OverlayElement();
|
||||
|
||||
/// PLEASE, REMEMBER THE REFERENCE!!!
|
||||
virtual vector<m2::AnyRectD> const & boundRects() const = 0;
|
||||
/// @name Getting element boundaries.
|
||||
//@{
|
||||
virtual m2::RectD GetBoundRect() const;
|
||||
typedef buffer_vector<m2::AnyRectD, 4> RectsT;
|
||||
virtual void GetMiniBoundRects(RectsT & rects) const;
|
||||
//@}
|
||||
|
||||
virtual void draw(OverlayRenderer * r, math::Matrix<double, 3, 3> const & m) const = 0;
|
||||
/// Set new transformation ! RELATIVE TO INIT STATE ! for drawing and safe information for reseting
|
||||
/// Need to call base class method
|
||||
|
@ -104,9 +107,6 @@ namespace graphics
|
|||
bool isNeedRedraw() const;
|
||||
void setIsNeedRedraw(bool flag);
|
||||
|
||||
bool isDirtyRect() const;
|
||||
void setIsDirtyRect(bool flag) const;
|
||||
|
||||
bool isDirtyLayout() const;
|
||||
void setIsDirtyLayout(bool flag) const;
|
||||
|
||||
|
@ -122,10 +122,8 @@ namespace graphics
|
|||
UserInfo const & userInfo() const;
|
||||
|
||||
virtual bool hitTest(m2::PointD const & pt) const;
|
||||
virtual bool roughHitTest(m2::PointD const & pt) const;
|
||||
|
||||
m2::RectD const & roughBoundRect() const;
|
||||
|
||||
virtual bool hasSharpGeometry() const;
|
||||
|
||||
void DrawRectsDebug(graphics::OverlayRenderer * r, Color color, double depth) const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace graphics
|
|||
{}
|
||||
|
||||
PathTextElement::PathTextElement(Params const & p)
|
||||
: TextElement(p)
|
||||
: BaseT(p)
|
||||
{
|
||||
strings::UniString visText, auxVisText;
|
||||
(void) p.GetVisibleTexts(visText, auxVisText);
|
||||
|
@ -27,23 +27,23 @@ namespace graphics
|
|||
setIsValid(m_glyphLayout.IsFullVisible());
|
||||
}
|
||||
|
||||
vector<m2::AnyRectD> const & PathTextElement::boundRects() const
|
||||
m2::RectD PathTextElement::GetBoundRect() const
|
||||
{
|
||||
if (isDirtyRect())
|
||||
if (isDirtyLayout())
|
||||
{
|
||||
m_boundRects.clear();
|
||||
m_boundRects.reserve(m_glyphLayout.boundRects().size());
|
||||
|
||||
for (unsigned i = 0; i < m_glyphLayout.boundRects().size(); ++i)
|
||||
m_boundRects.push_back(m_glyphLayout.boundRects()[i]);
|
||||
|
||||
//for (unsigned i = 0; i < m_boundRects.size(); ++i)
|
||||
// m_boundRects[i] = m2::Inflate(m_boundRects[i], m2::PointD(10, 10));
|
||||
//m_boundRects[i].m2::Inflate(m2::PointD(40, 2)); //< to create more sparse street names structure
|
||||
setIsDirtyRect(false);
|
||||
m_boundRect = BaseT::GetBoundRect();
|
||||
setIsDirtyLayout(false);
|
||||
}
|
||||
return m_boundRect;
|
||||
}
|
||||
|
||||
return m_boundRects;
|
||||
void PathTextElement::GetMiniBoundRects(RectsT & rects) const
|
||||
{
|
||||
size_t const count = m_glyphLayout.boundRects().size();
|
||||
rects.reserve(count);
|
||||
copy(m_glyphLayout.boundRects().begin(),
|
||||
m_glyphLayout.boundRects().end(),
|
||||
back_inserter(rects));
|
||||
}
|
||||
|
||||
void PathTextElement::draw(OverlayRenderer * screen, math::Matrix<double, 3, 3> const & m) const
|
||||
|
@ -58,10 +58,9 @@ namespace graphics
|
|||
if (isNeedRedraw())
|
||||
c = graphics::Color(255, 0, 0, 64);
|
||||
|
||||
screen->drawRectangle(roughBoundRect(), graphics::Color(255, 255, 0, 64), depth() + doffs++);
|
||||
screen->drawRectangle(GetBoundRect(), graphics::Color(255, 255, 0, 64), depth() + doffs++);
|
||||
|
||||
for (unsigned i = 0; i < boundRects().size(); ++i)
|
||||
screen->drawRectangle(boundRects()[i], c, depth() + doffs++);
|
||||
DrawRectsDebug(screen, c, depth() + doffs++);
|
||||
}
|
||||
|
||||
if (!isNeedRedraw() || !isVisible() || !isValid())
|
||||
|
@ -81,6 +80,7 @@ namespace graphics
|
|||
void PathTextElement::setPivot(m2::PointD const & pivot)
|
||||
{
|
||||
TextElement::setPivot(pivot);
|
||||
|
||||
m_glyphLayout.setPivot(pivot);
|
||||
}
|
||||
|
||||
|
@ -89,6 +89,7 @@ namespace graphics
|
|||
m_glyphLayout = GlyphLayoutPath(m_glyphLayout, getResetMatrix() * m);
|
||||
TextElement::setPivot(m_glyphLayout.pivot());
|
||||
setIsValid(m_glyphLayout.IsFullVisible());
|
||||
|
||||
TextElement::setTransformation(m);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,13 +8,15 @@ namespace graphics
|
|||
{
|
||||
class PathTextElement : public TextElement
|
||||
{
|
||||
private:
|
||||
typedef TextElement BaseT;
|
||||
|
||||
GlyphLayoutPath m_glyphLayout;
|
||||
|
||||
public:
|
||||
/// Cached bound rect for the fast Overlay tree routine.
|
||||
mutable m2::RectD m_boundRect;
|
||||
|
||||
struct Params : TextElement::Params
|
||||
public:
|
||||
struct Params : BaseT::Params
|
||||
{
|
||||
m2::PointD const * m_pts;
|
||||
size_t m_ptsCount;
|
||||
|
@ -26,7 +28,8 @@ namespace graphics
|
|||
|
||||
PathTextElement(Params const & p);
|
||||
|
||||
vector<m2::AnyRectD> const & boundRects() const;
|
||||
virtual m2::RectD GetBoundRect() const;
|
||||
virtual void GetMiniBoundRects(RectsT & rects) const;
|
||||
|
||||
void draw(OverlayRenderer * r, math::Matrix<double, 3, 3> const & m) const;
|
||||
|
||||
|
|
|
@ -179,20 +179,14 @@ namespace graphics
|
|||
m_offset(0, 0)
|
||||
{}
|
||||
|
||||
vector<m2::AnyRectD> const & StraightTextElement::boundRects() const
|
||||
void StraightTextElement::GetMiniBoundRects(RectsT & rects) const
|
||||
{
|
||||
if (isDirtyRect())
|
||||
for (size_t i = 0; i < m_glyphLayouts.size(); ++i)
|
||||
{
|
||||
m_boundRects.clear();
|
||||
|
||||
for (size_t i = 0; i < m_glyphLayouts.size(); ++i)
|
||||
copy(m_glyphLayouts[i].boundRects().begin(),
|
||||
m_glyphLayouts[i].boundRects().end(),
|
||||
back_inserter(m_boundRects));
|
||||
|
||||
setIsDirtyRect(false);
|
||||
copy(m_glyphLayouts[i].boundRects().begin(),
|
||||
m_glyphLayouts[i].boundRects().end(),
|
||||
back_inserter(rects));
|
||||
}
|
||||
return m_boundRects;
|
||||
}
|
||||
|
||||
void StraightTextElement::draw(OverlayRenderer * screen, math::Matrix<double, 3, 3> const & m) const
|
||||
|
@ -207,14 +201,9 @@ namespace graphics
|
|||
if (isNeedRedraw())
|
||||
c = graphics::Color(255, 0, 0, 64);
|
||||
|
||||
screen->drawRectangle(roughBoundRect(), graphics::Color(255, 255, 0, 64), depth());
|
||||
screen->drawRectangle(GetBoundRect(), graphics::Color(255, 255, 0, 64), depth() + doffs++);
|
||||
|
||||
doffs += 1;
|
||||
|
||||
for (size_t i = 0 ; i < boundRects().size(); ++i)
|
||||
screen->drawRectangle(boundRects()[i], c, depth() + doffs);
|
||||
|
||||
doffs += 1;
|
||||
DrawRectsDebug(screen, c, depth() + doffs++);
|
||||
}
|
||||
|
||||
if (!isNeedRedraw())
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace graphics
|
|||
|
||||
StraightTextElement(Params const & p);
|
||||
|
||||
vector<m2::AnyRectD> const & boundRects() const;
|
||||
virtual void GetMiniBoundRects(RectsT & rects) const;
|
||||
|
||||
void draw(OverlayRenderer * r, math::Matrix<double, 3, 3> const & m) const;
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace graphics
|
|||
{}
|
||||
|
||||
SymbolElement::SymbolElement(Params const & p)
|
||||
: base_t(p),
|
||||
: BaseT(p),
|
||||
m_info(p.m_info),
|
||||
m_symbolRect(0, 0, 0, 0)
|
||||
{
|
||||
|
@ -23,36 +23,20 @@ namespace graphics
|
|||
|
||||
if (res == 0)
|
||||
{
|
||||
LOG(LDEBUG/*LWARNING*/, ("POI", m_info.m_name, "wasn't found on current skin."));
|
||||
LOG(LWARNING, ("POI", m_info.m_name, "wasn't found on current skin."));
|
||||
return;
|
||||
}
|
||||
|
||||
m_symbolRect = res->m_texRect;
|
||||
}
|
||||
|
||||
vector<m2::AnyRectD> const & SymbolElement::boundRects() const
|
||||
m2::RectD SymbolElement::GetBoundRect() const
|
||||
{
|
||||
if (isDirtyRect())
|
||||
{
|
||||
m_boundRects.clear();
|
||||
m_boundRects.push_back(boundRect());
|
||||
setIsDirtyRect(false);
|
||||
}
|
||||
return m_boundRects;
|
||||
}
|
||||
// Skip for one pixel on every border.
|
||||
m2::PointD const sz(m_symbolRect.SizeX() - 2, m_symbolRect.SizeY() - 2);
|
||||
m2::PointD const posPt = computeTopLeft(sz, pivot(), position());
|
||||
|
||||
m2::AnyRectD const SymbolElement::boundRect() const
|
||||
{
|
||||
m2::RectI texRect(m_symbolRect);
|
||||
texRect.Inflate(-1, -1);
|
||||
|
||||
m2::PointD sz(texRect.SizeX(), texRect.SizeY());
|
||||
|
||||
m2::PointD const posPt = computeTopLeft(sz,
|
||||
pivot(),
|
||||
position());
|
||||
|
||||
return m2::AnyRectD(m2::RectD(posPt, posPt + sz));
|
||||
return m2::RectD(posPt, posPt + sz);
|
||||
}
|
||||
|
||||
void SymbolElement::draw(OverlayRenderer * r, math::Matrix<double, 3, 3> const & m) const
|
||||
|
@ -96,7 +80,7 @@ namespace graphics
|
|||
void SymbolElement::setTransformation(const math::Matrix<double, 3, 3> & m)
|
||||
{
|
||||
setPivot(pivot() * getResetMatrix() * m);
|
||||
base_t::setTransformation(m);
|
||||
BaseT::setTransformation(m);
|
||||
}
|
||||
|
||||
bool SymbolElement::hasSharpGeometry() const
|
||||
|
|
|
@ -9,21 +9,13 @@ namespace graphics
|
|||
|
||||
class SymbolElement : public OverlayElement
|
||||
{
|
||||
private:
|
||||
|
||||
Icon::Info m_info;
|
||||
m2::RectU m_symbolRect;
|
||||
|
||||
m2::AnyRectD const boundRect() const;
|
||||
|
||||
protected:
|
||||
mutable vector<m2::AnyRectD> m_boundRects;
|
||||
|
||||
public:
|
||||
typedef OverlayElement BaseT;
|
||||
|
||||
typedef OverlayElement base_t;
|
||||
|
||||
struct Params : public base_t::Params
|
||||
struct Params : public BaseT::Params
|
||||
{
|
||||
Icon::Info m_info;
|
||||
m2::RectU m_symbolRect;
|
||||
|
@ -33,7 +25,8 @@ namespace graphics
|
|||
|
||||
SymbolElement(Params const & p);
|
||||
|
||||
vector<m2::AnyRectD> const & boundRects() const;
|
||||
virtual m2::RectD GetBoundRect() const;
|
||||
|
||||
void draw(OverlayRenderer * s, math::Matrix<double, 3, 3> const & m) const;
|
||||
|
||||
uint32_t resID() const;
|
||||
|
|
|
@ -15,13 +15,9 @@ namespace graphics
|
|||
class TextElement : public OverlayElement
|
||||
{
|
||||
protected:
|
||||
|
||||
FontDesc m_fontDesc, m_auxFontDesc;
|
||||
|
||||
mutable vector<m2::AnyRectD> m_boundRects;
|
||||
|
||||
public:
|
||||
|
||||
struct Params : OverlayElement::Params
|
||||
{
|
||||
FontDesc m_fontDesc;
|
||||
|
|
|
@ -123,7 +123,7 @@ namespace gui
|
|||
cs->setDisplayList(dl.get());
|
||||
|
||||
double const k = visualScale();
|
||||
m2::RectD const rr = roughBoundRect();
|
||||
m2::RectD const rr = GetBoundRect();
|
||||
|
||||
cs->drawRoundedRectangle(m2::RectD(-rr.SizeX() / 2,
|
||||
-rr.SizeY() / 2,
|
||||
|
@ -153,39 +153,33 @@ namespace gui
|
|||
m_textView->setIsDirtyLayout(true);
|
||||
}
|
||||
|
||||
vector<m2::AnyRectD> const & Button::boundRects() const
|
||||
m2::RectD Button::GetBoundRect() const
|
||||
{
|
||||
if (isDirtyRect())
|
||||
{
|
||||
m_boundRects.clear();
|
||||
double k = visualScale();
|
||||
double const k = visualScale();
|
||||
|
||||
m2::RectD tr(m_textView->roughBoundRect());
|
||||
m2::RectD rc(0, 0, tr.SizeX(), tr.SizeY());
|
||||
m2::RectD tr(m_textView->GetBoundRect());
|
||||
m2::RectD rc(0, 0, tr.SizeX(), tr.SizeY());
|
||||
|
||||
rc.Inflate(15 * k, 5 * k);
|
||||
rc.Inflate(15 * k, 5 * k);
|
||||
|
||||
double dx = 0;
|
||||
double dy = 0;
|
||||
double dx = 0;
|
||||
double dy = 0;
|
||||
|
||||
if (rc.SizeX() < m_minWidth * k)
|
||||
dx = (m_minWidth * k - rc.SizeX()) / 2;
|
||||
if (rc.SizeY() < m_minHeight * k)
|
||||
dy = (m_minHeight * k - rc.SizeY()) / 2;
|
||||
if (rc.SizeX() < m_minWidth * k)
|
||||
dx = (m_minWidth * k - rc.SizeX()) / 2;
|
||||
if (rc.SizeY() < m_minHeight * k)
|
||||
dy = (m_minHeight * k - rc.SizeY()) / 2;
|
||||
|
||||
rc.Inflate(dx, dy);
|
||||
rc.Offset(-rc.minX(), -rc.minY());
|
||||
rc.Inflate(dx, dy);
|
||||
rc.Offset(-rc.minX(), -rc.minY());
|
||||
|
||||
m2::PointD pt = computeTopLeft(m2::PointD(rc.SizeX(), rc.SizeY()),
|
||||
pivot(),
|
||||
position());
|
||||
m2::PointD pt = computeTopLeft(m2::PointD(rc.SizeX(), rc.SizeY()),
|
||||
pivot(),
|
||||
position());
|
||||
|
||||
rc.Offset(pt);
|
||||
m_boundRects.push_back(m2::AnyRectD(rc));
|
||||
setIsDirtyRect(false);
|
||||
}
|
||||
rc.Offset(pt);
|
||||
|
||||
return m_boundRects;
|
||||
return rc;
|
||||
}
|
||||
|
||||
void Button::draw(graphics::OverlayRenderer * r, math::Matrix<double, 3, 3> const & m) const
|
||||
|
|
|
@ -25,11 +25,9 @@ namespace gui
|
|||
class Button : public Element
|
||||
{
|
||||
public:
|
||||
|
||||
typedef function<void (Element const *)> TOnClickListener;
|
||||
|
||||
private:
|
||||
|
||||
TOnClickListener m_OnClickListener;
|
||||
|
||||
unsigned m_minWidth;
|
||||
|
@ -40,10 +38,7 @@ namespace gui
|
|||
|
||||
void cacheButtonBody(EState state);
|
||||
|
||||
mutable vector<m2::AnyRectD> m_boundRects;
|
||||
|
||||
public:
|
||||
|
||||
struct Params : Element::Params
|
||||
{
|
||||
unsigned m_minWidth;
|
||||
|
@ -70,7 +65,8 @@ namespace gui
|
|||
|
||||
/// @name Override from graphics::OverlayElement and gui::Element.
|
||||
//@{
|
||||
vector<m2::AnyRectD> const & boundRects() const;
|
||||
virtual m2::RectD GetBoundRect() const;
|
||||
|
||||
void draw(graphics::OverlayRenderer * r, math::Matrix<double, 3, 3> const & m) const;
|
||||
void setPivot(m2::PointD const & pv);
|
||||
|
||||
|
|
|
@ -16,8 +16,7 @@ namespace gui
|
|||
CachedTextView::CachedTextView(Params const & p)
|
||||
: Element(p)
|
||||
{
|
||||
m_text = p.m_text;
|
||||
m_uniText = strings::MakeUniString(p.m_text);
|
||||
setText(p.m_text);
|
||||
|
||||
setFont(EActive, FontDesc(12, Color(0, 0, 0, 255)));
|
||||
setFont(EPressed, FontDesc(12, Color(0, 0, 0, 255)));
|
||||
|
@ -28,10 +27,10 @@ namespace gui
|
|||
|
||||
void CachedTextView::setText(string const & text)
|
||||
{
|
||||
if (m_text != text)
|
||||
strings::UniString const uText = strings::MakeUniString(text);
|
||||
if (uText != m_uniText)
|
||||
{
|
||||
m_text = text;
|
||||
m_uniText = strings::MakeUniString(text);
|
||||
m_uniText = uText;
|
||||
setIsDirtyLayout(true);
|
||||
}
|
||||
}
|
||||
|
@ -42,24 +41,14 @@ namespace gui
|
|||
Element::setFont(state, desc);
|
||||
}
|
||||
|
||||
string const & CachedTextView::text() const
|
||||
void CachedTextView::GetMiniBoundRects(RectsT & rects) const
|
||||
{
|
||||
return m_text;
|
||||
}
|
||||
checkDirtyLayout();
|
||||
|
||||
vector<m2::AnyRectD> const & CachedTextView::boundRects() const
|
||||
{
|
||||
if (isDirtyRect())
|
||||
{
|
||||
const_cast<CachedTextView*>(this)->layout();
|
||||
|
||||
m_boundRects.clear();
|
||||
|
||||
copy(m_layout->boundRects().begin(),
|
||||
m_layout->boundRects().end(),
|
||||
back_inserter(m_boundRects));
|
||||
}
|
||||
return m_boundRects;
|
||||
rects.resize(m_layout->boundRects().size());
|
||||
copy(m_layout->boundRects().begin(),
|
||||
m_layout->boundRects().end(),
|
||||
back_inserter(rects));
|
||||
}
|
||||
|
||||
void CachedTextView::draw(OverlayRenderer *r, math::Matrix<double, 3, 3> const & m) const
|
||||
|
@ -83,8 +72,6 @@ namespace gui
|
|||
|
||||
void CachedTextView::cache()
|
||||
{
|
||||
layout();
|
||||
|
||||
DisplayListCache * dlc = m_controller->GetDisplayListCache();
|
||||
FontDesc fontDesc = font(EActive);
|
||||
|
||||
|
@ -111,6 +98,7 @@ namespace gui
|
|||
|
||||
void CachedTextView::purge()
|
||||
{
|
||||
m_maskedDls.clear();
|
||||
m_dls.clear();
|
||||
}
|
||||
|
||||
|
@ -141,6 +129,7 @@ namespace gui
|
|||
void CachedTextView::setPivot(m2::PointD const & pv)
|
||||
{
|
||||
Element::setPivot(pv);
|
||||
|
||||
if (m_maskedLayout)
|
||||
m_maskedLayout->setPivot(pivot());
|
||||
if (m_layout)
|
||||
|
|
|
@ -20,10 +20,6 @@ namespace gui
|
|||
{
|
||||
class CachedTextView : public Element
|
||||
{
|
||||
private:
|
||||
|
||||
string m_text;
|
||||
|
||||
strings::UniString m_uniText;
|
||||
|
||||
vector<shared_ptr<graphics::DisplayList> > m_dls;
|
||||
|
@ -32,10 +28,7 @@ namespace gui
|
|||
unique_ptr<graphics::GlyphLayout> m_layout;
|
||||
unique_ptr<graphics::GlyphLayout> m_maskedLayout;
|
||||
|
||||
mutable vector<m2::AnyRectD> m_boundRects;
|
||||
|
||||
public:
|
||||
|
||||
struct Params : public Element::Params
|
||||
{
|
||||
string m_text;
|
||||
|
@ -44,9 +37,8 @@ namespace gui
|
|||
CachedTextView(Params const & p);
|
||||
|
||||
void setText(string const & text);
|
||||
string const & text() const;
|
||||
|
||||
vector<m2::AnyRectD> const & boundRects() const;
|
||||
virtual void GetMiniBoundRects(RectsT & rects) const;
|
||||
void draw(graphics::OverlayRenderer * r, math::Matrix<double, 3, 3> const & m) const;
|
||||
|
||||
void cache();
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace gui
|
|||
++it)
|
||||
{
|
||||
shared_ptr<gui::Element> const & e = *it;
|
||||
if ((!onlyVisible || e->isVisible()) && e->roughHitTest(pt) && e->hitTest(pt))
|
||||
if ((!onlyVisible || e->isVisible()) && e->hitTest(pt))
|
||||
l.push_back(e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
#include "element.hpp"
|
||||
#include "controller.hpp"
|
||||
|
||||
#include "../graphics/overlay_renderer.hpp"
|
||||
|
||||
#include "../base/logging.hpp"
|
||||
|
||||
|
||||
namespace gui
|
||||
{
|
||||
Element::Element(Params const & p)
|
||||
|
@ -84,10 +83,9 @@ namespace gui
|
|||
}
|
||||
}
|
||||
|
||||
void Element::draw(graphics::OverlayRenderer *r, math::Matrix<double, 3, 3> const & m) const
|
||||
void Element::draw(graphics::OverlayRenderer * r, math::Matrix<double, 3, 3> const &) const
|
||||
{
|
||||
for (size_t i = 0; i < boundRects().size(); ++i)
|
||||
r->drawRectangle(boundRects()[i], color(state()), depth());
|
||||
DrawRectsDebug(r, color(state()), depth());
|
||||
}
|
||||
|
||||
double Element::priority() const
|
||||
|
|
|
@ -14,8 +14,7 @@ namespace gui
|
|||
{}
|
||||
|
||||
ImageView::ImageView(Params const & p)
|
||||
: base_t(p),
|
||||
m_boundRects(1)
|
||||
: BaseT(p)
|
||||
{
|
||||
m_image = p.m_image;
|
||||
}
|
||||
|
@ -47,23 +46,11 @@ namespace gui
|
|||
m_displayList.reset();
|
||||
}
|
||||
|
||||
vector<m2::AnyRectD> const & ImageView::boundRects() const
|
||||
m2::RectD ImageView::GetBoundRect() const
|
||||
{
|
||||
if (isDirtyRect())
|
||||
{
|
||||
m2::PointD sz(m_image.m_size);
|
||||
|
||||
m2::PointD pt = computeTopLeft(sz,
|
||||
pivot(),
|
||||
position());
|
||||
|
||||
|
||||
m_boundRects[0] = m2::AnyRectD(m2::RectD(pt, pt + sz));
|
||||
|
||||
setIsDirtyRect(false);
|
||||
}
|
||||
|
||||
return m_boundRects;
|
||||
m2::PointD const sz(m_image.m_size);
|
||||
m2::PointD const pt = computeTopLeft(sz, pivot(), position());
|
||||
return m2::RectD(pt, pt + sz);
|
||||
}
|
||||
|
||||
void ImageView::draw(graphics::OverlayRenderer * r,
|
||||
|
|
|
@ -16,10 +16,6 @@ namespace gui
|
|||
{
|
||||
class ImageView : public Element
|
||||
{
|
||||
private:
|
||||
|
||||
mutable vector<m2::AnyRectD> m_boundRects;
|
||||
|
||||
graphics::Image::Info m_image;
|
||||
m2::RectU m_margin;
|
||||
unique_ptr<graphics::DisplayList> m_displayList;
|
||||
|
@ -29,9 +25,9 @@ namespace gui
|
|||
void cache();
|
||||
void purge();
|
||||
|
||||
typedef Element base_t;
|
||||
typedef Element BaseT;
|
||||
|
||||
struct Params : public base_t::Params
|
||||
struct Params : public BaseT::Params
|
||||
{
|
||||
graphics::Image::Info m_image;
|
||||
Params();
|
||||
|
@ -39,7 +35,7 @@ namespace gui
|
|||
|
||||
ImageView(Params const & p);
|
||||
|
||||
vector<m2::AnyRectD> const & boundRects() const;
|
||||
virtual m2::RectD GetBoundRect() const;
|
||||
|
||||
void draw(graphics::OverlayRenderer * r, math::Matrix<double, 3, 3> const & m) const;
|
||||
void setImage(graphics::Image::Info const & info);
|
||||
|
|
|
@ -3,8 +3,11 @@
|
|||
|
||||
#include "../graphics/display_list.hpp"
|
||||
#include "../graphics/screen.hpp"
|
||||
#include "../graphics/straight_text_element.hpp"
|
||||
|
||||
#include "../geometry/transformations.hpp"
|
||||
|
||||
|
||||
namespace gui
|
||||
{
|
||||
TextView::TextView(Params const & p)
|
||||
|
@ -35,7 +38,7 @@ namespace gui
|
|||
|
||||
void TextView::layoutBody(EState state)
|
||||
{
|
||||
shared_ptr<graphics::StraightTextElement> & elem = m_elems[state];
|
||||
unique_ptr<graphics::StraightTextElement> & elem = m_elems[state];
|
||||
|
||||
graphics::StraightTextElement::Params params;
|
||||
|
||||
|
@ -66,7 +69,7 @@ namespace gui
|
|||
{
|
||||
graphics::Screen * cs = m_controller->GetCacheScreen();
|
||||
|
||||
shared_ptr<graphics::DisplayList> & dl = m_dls[state];
|
||||
unique_ptr<graphics::DisplayList> & dl = m_dls[state];
|
||||
|
||||
dl.reset();
|
||||
dl.reset(cs->createDisplayList());
|
||||
|
@ -99,43 +102,21 @@ namespace gui
|
|||
{
|
||||
checkDirtyLayout();
|
||||
|
||||
map<EState, shared_ptr<graphics::DisplayList> >::const_iterator it;
|
||||
it = m_dls.find(state());
|
||||
|
||||
math::Matrix<double, 3, 3> drawM = math::Shift(math::Identity<double, 3>(),
|
||||
pivot());
|
||||
|
||||
if (it != m_dls.end())
|
||||
r->drawDisplayList(it->second.get(), drawM * m);
|
||||
else
|
||||
LOG(LDEBUG/*LWARNING*/, ("m_dls[state()] is not set!"));
|
||||
r->drawDisplayList(m_dls.at(state()).get(), drawM * m);
|
||||
}
|
||||
}
|
||||
|
||||
vector<m2::AnyRectD> const & TextView::boundRects() const
|
||||
void TextView::GetMiniBoundRects(RectsT & rects) const
|
||||
{
|
||||
if (isDirtyRect())
|
||||
{
|
||||
const_cast<TextView*>(this)->layout();
|
||||
m_boundRects.clear();
|
||||
checkDirtyLayout();
|
||||
|
||||
map<EState, shared_ptr<graphics::StraightTextElement> >::const_iterator it;
|
||||
it = m_elems.find(EActive);
|
||||
m2::PointD const pt = pivot();
|
||||
|
||||
m2::PointD pt = pivot();
|
||||
|
||||
if (it != m_elems.end())
|
||||
m_boundRects.push_back(m2::AnyRectD(Offset(it->second->roughBoundRect(), pt)));
|
||||
|
||||
it = m_elems.find(EPressed);
|
||||
|
||||
if (it != m_elems.end())
|
||||
m_boundRects.push_back(m2::AnyRectD(Offset(it->second->roughBoundRect(), pt)));
|
||||
|
||||
setIsDirtyRect(false);
|
||||
}
|
||||
|
||||
return m_boundRects;
|
||||
rects.push_back(m2::AnyRectD(Offset(m_elems.at(EActive)->GetBoundRect(), pt)));
|
||||
rects.push_back(m2::AnyRectD(Offset(m_elems.at(EPressed)->GetBoundRect(), pt)));
|
||||
}
|
||||
|
||||
void TextView::setMaxWidth(unsigned width)
|
||||
|
|
|
@ -1,38 +1,32 @@
|
|||
#pragma once
|
||||
|
||||
#include "../std/vector.hpp"
|
||||
#include "../std/shared_ptr.hpp"
|
||||
|
||||
#include "../geometry/any_rect2d.hpp"
|
||||
|
||||
#include "../graphics/straight_text_element.hpp"
|
||||
#include "../graphics/display_list.hpp"
|
||||
|
||||
#include "element.hpp"
|
||||
|
||||
#include "../std/unique_ptr.hpp"
|
||||
|
||||
|
||||
namespace graphics
|
||||
{
|
||||
class DisplayList;
|
||||
class StraightTextElement;
|
||||
}
|
||||
|
||||
namespace gui
|
||||
{
|
||||
class TextView : public Element
|
||||
{
|
||||
private:
|
||||
map<EState, unique_ptr<graphics::DisplayList> > m_dls;
|
||||
|
||||
map<EState, shared_ptr<graphics::DisplayList> > m_dls;
|
||||
map<EState, shared_ptr<graphics::StraightTextElement> > m_elems;
|
||||
typedef map<EState, unique_ptr<graphics::StraightTextElement> > ElemsMapT;
|
||||
ElemsMapT m_elems;
|
||||
|
||||
string m_text;
|
||||
unsigned m_maxWidth;
|
||||
|
||||
mutable vector<m2::AnyRectD> m_boundRects;
|
||||
|
||||
void cacheBody(EState state);
|
||||
void layoutBody(EState state);
|
||||
|
||||
public:
|
||||
|
||||
void cache();
|
||||
void purge();
|
||||
void layout();
|
||||
|
||||
struct Params : public Element::Params
|
||||
{
|
||||
string m_text;
|
||||
|
@ -44,12 +38,20 @@ namespace gui
|
|||
string const & text() const;
|
||||
void setMaxWidth(unsigned width);
|
||||
|
||||
vector<m2::AnyRectD> const & boundRects() const;
|
||||
/// @name Overrider from graphics::OverlayElement and gui::Element.
|
||||
//@{
|
||||
virtual void GetMiniBoundRects(RectsT & rects) const;
|
||||
|
||||
void draw(graphics::OverlayRenderer * r, math::Matrix<double, 3, 3> const & m) const;
|
||||
|
||||
void cache();
|
||||
void purge();
|
||||
void layout();
|
||||
|
||||
bool onTapStarted(m2::PointD const & pt);
|
||||
bool onTapMoved(m2::PointD const & pt);
|
||||
bool onTapEnded(m2::PointD const & pt);
|
||||
bool onTapCancelled(m2::PointD const & pt);
|
||||
//@}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -19,9 +19,9 @@ CompassArrow::Params::Params()
|
|||
{}
|
||||
|
||||
CompassArrow::CompassArrow(Params const & p)
|
||||
: base_t(p),
|
||||
: BaseT(p),
|
||||
m_pixelSize(-1, -1),
|
||||
m_angle(0),
|
||||
m_boundRects(1),
|
||||
m_framework(p.m_framework)
|
||||
{
|
||||
}
|
||||
|
@ -49,31 +49,25 @@ void CompassArrow::AnimateHide()
|
|||
void CompassArrow::SetAngle(double angle)
|
||||
{
|
||||
m_angle = angle;
|
||||
setIsDirtyRect(true);
|
||||
}
|
||||
|
||||
m2::PointD CompassArrow::GetPixelSize() const
|
||||
m2::PointI CompassArrow::GetPixelSize() const
|
||||
{
|
||||
Resource const * res = GetCompassResource();
|
||||
return m2::PointD(res->m_texRect.SizeX(), res->m_texRect.SizeY());
|
||||
}
|
||||
|
||||
vector<m2::AnyRectD> const & CompassArrow::boundRects() const
|
||||
{
|
||||
if (isDirtyRect())
|
||||
if (m_pixelSize == m2::PointI(-1, -1))
|
||||
{
|
||||
Resource const * res = GetCompassResource();
|
||||
double halfW = res->m_texRect.SizeX() / 2.0;
|
||||
double halfH = res->m_texRect.SizeY() / 2.0;
|
||||
|
||||
m_boundRects[0] = m2::AnyRectD(pivot(),
|
||||
-math::pi / 2 + m_angle,
|
||||
m2::RectD(-halfW, -halfH, halfW, halfH));
|
||||
|
||||
setIsDirtyRect(false);
|
||||
m_pixelSize = m2::PointI(res->m_texRect.SizeX(), res->m_texRect.SizeY());
|
||||
}
|
||||
return m_pixelSize;
|
||||
}
|
||||
|
||||
return m_boundRects;
|
||||
void CompassArrow::GetMiniBoundRects(RectsT & rects) const
|
||||
{
|
||||
double const halfW = m_pixelSize.x / 2.0;
|
||||
double const halfH = m_pixelSize.y / 2.0;
|
||||
|
||||
rects.push_back(m2::AnyRectD(pivot(), -math::pi / 2 + m_angle,
|
||||
m2::RectD(-halfW, -halfH, halfW, halfH)));
|
||||
}
|
||||
|
||||
void CompassArrow::draw(OverlayRenderer * r,
|
||||
|
@ -200,7 +194,7 @@ void CompassArrow::purge()
|
|||
|
||||
bool CompassArrow::isBaseVisible() const
|
||||
{
|
||||
return base_t::isVisible();
|
||||
return BaseT::isVisible();
|
||||
}
|
||||
|
||||
bool CompassArrow::onTapEnded(m2::PointD const & pt)
|
||||
|
|
|
@ -23,9 +23,9 @@ class Framework;
|
|||
/// and rotates screen back to straight orientation when beeing pressed
|
||||
class CompassArrow : public gui::Element
|
||||
{
|
||||
private:
|
||||
typedef gui::Element base_t;
|
||||
typedef gui::Element BaseT;
|
||||
|
||||
mutable m2::PointI m_pixelSize;
|
||||
double m_angle;
|
||||
|
||||
unique_ptr<graphics::DisplayList> m_dl;
|
||||
|
@ -37,16 +37,13 @@ private:
|
|||
float GetCurrentAlfa() const;
|
||||
void CreateAnim(double startAlfa, double endAlfa, double timeInterval, double timeOffset, bool isVisibleAtEnd);
|
||||
|
||||
mutable vector<m2::AnyRectD> m_boundRects;
|
||||
|
||||
Framework * m_framework;
|
||||
graphics::Resource const * GetCompassResource() const;
|
||||
|
||||
bool isBaseVisible() const;
|
||||
|
||||
public:
|
||||
|
||||
struct Params : public base_t::Params
|
||||
struct Params : public BaseT::Params
|
||||
{
|
||||
Framework * m_framework;
|
||||
Params();
|
||||
|
@ -58,11 +55,12 @@ public:
|
|||
void AnimateHide();
|
||||
|
||||
void SetAngle(double angle);
|
||||
m2::PointD GetPixelSize() const;
|
||||
m2::PointI GetPixelSize() const;
|
||||
|
||||
/// @name Override from graphics::Overlayelement and gui::Element.
|
||||
//@{
|
||||
vector<m2::AnyRectD> const & boundRects() const;
|
||||
virtual void GetMiniBoundRects(RectsT & rects) const;
|
||||
|
||||
void draw(graphics::OverlayRenderer * r, math::Matrix<double, 3, 3> const & m) const;
|
||||
bool isVisible() const;
|
||||
bool roughHitTest(m2::PointD const & pt) const;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "../gui/text_view.hpp"
|
||||
|
||||
#include "../graphics/overlay_renderer.hpp"
|
||||
#include "../graphics/display_list.hpp"
|
||||
|
||||
#include "../platform/platform.hpp"
|
||||
|
||||
|
@ -68,7 +69,6 @@ void CountryStatusDisplay::cache()
|
|||
m_downloadButton->setIsVisible(false);
|
||||
m_statusMsg->setIsVisible(false);
|
||||
setIsVisible(false);
|
||||
setIsDirtyRect(true);
|
||||
|
||||
string const dn = displayName();
|
||||
|
||||
|
@ -116,10 +116,6 @@ void CountryStatusDisplay::cache()
|
|||
}
|
||||
|
||||
setIsVisible(m_statusMsg->isVisible() || m_downloadButton->isVisible());
|
||||
|
||||
// Element bound rect is possibly changed,
|
||||
// however it's called in the beginning of the function.
|
||||
setIsDirtyRect(true);
|
||||
}
|
||||
|
||||
void CountryStatusDisplay::CountryStatusChanged(storage::TIndex const & idx)
|
||||
|
@ -268,24 +264,15 @@ void CountryStatusDisplay::draw(graphics::OverlayRenderer *r,
|
|||
m_statusMsg->draw(r, m);
|
||||
}
|
||||
|
||||
vector<m2::AnyRectD> const & CountryStatusDisplay::boundRects() const
|
||||
m2::RectD CountryStatusDisplay::GetBoundRect() const
|
||||
{
|
||||
checkDirtyLayout();
|
||||
|
||||
if (isDirtyRect())
|
||||
{
|
||||
m_boundRects.clear();
|
||||
m2::RectD r(pivot(), pivot());
|
||||
if (m_downloadButton->isVisible())
|
||||
r.Add(m_downloadButton->GetBoundRect());
|
||||
|
||||
m2::RectD r(pivot(), pivot());
|
||||
|
||||
if (m_downloadButton->isVisible())
|
||||
r.Add(m_downloadButton->roughBoundRect());
|
||||
|
||||
m_boundRects.push_back(m2::AnyRectD(r));
|
||||
setIsDirtyRect(false);
|
||||
}
|
||||
|
||||
return m_boundRects;
|
||||
return r;
|
||||
}
|
||||
|
||||
void CountryStatusDisplay::setController(gui::Controller *controller)
|
||||
|
@ -299,10 +286,9 @@ void CountryStatusDisplay::setPivot(m2::PointD const & pv)
|
|||
{
|
||||
if (m_countryStatus == storage::EDownloadFailed)
|
||||
{
|
||||
size_t buttonHeight = m_downloadButton->roughBoundRect().SizeY();
|
||||
size_t statusHeight = m_statusMsg->roughBoundRect().SizeY();
|
||||
|
||||
size_t commonHeight = buttonHeight + statusHeight + 10 * visualScale();
|
||||
size_t const buttonHeight = m_downloadButton->GetBoundRect().SizeY();
|
||||
size_t const statusHeight = m_statusMsg->GetBoundRect().SizeY();
|
||||
size_t const commonHeight = buttonHeight + statusHeight + 10 * visualScale();
|
||||
|
||||
m_downloadButton->setPivot(m2::PointD(pv.x, pv.y + commonHeight / 2 - buttonHeight / 2));
|
||||
m_statusMsg->setPivot(m2::PointD(pv.x, pv.y - commonHeight / 2 + statusHeight / 2));
|
||||
|
|
|
@ -49,8 +49,6 @@ private:
|
|||
|
||||
bool m_notEnoughSpace;
|
||||
|
||||
mutable vector<m2::AnyRectD> m_boundRects;
|
||||
|
||||
string const displayName() const;
|
||||
|
||||
template <class T1, class T2>
|
||||
|
@ -76,9 +74,10 @@ public:
|
|||
|
||||
/// @name Override from graphics::OverlayElement and gui::Element.
|
||||
//@{
|
||||
virtual m2::RectD GetBoundRect() const;
|
||||
|
||||
void setPivot(m2::PointD const & pv);
|
||||
void draw(graphics::OverlayRenderer * r, math::Matrix<double, 3, 3> const & m) const;
|
||||
vector<m2::AnyRectD> const & boundRects() const;
|
||||
|
||||
void cache();
|
||||
void purge();
|
||||
|
|
|
@ -53,8 +53,6 @@ namespace location
|
|||
m_locationAreaColor = p.m_locationAreaColor;
|
||||
m_framework = p.m_framework;
|
||||
|
||||
m_boundRects.resize(1);
|
||||
|
||||
setState(EActive);
|
||||
setIsVisible(false);
|
||||
}
|
||||
|
@ -172,15 +170,9 @@ namespace location
|
|||
invalidate();
|
||||
}
|
||||
|
||||
vector<m2::AnyRectD> const & State::boundRects() const
|
||||
m2::RectD State::GetBoundRect() const
|
||||
{
|
||||
if (isDirtyRect())
|
||||
{
|
||||
m_boundRects[0] = m2::AnyRectD(m_boundRect);
|
||||
setIsDirtyRect(false);
|
||||
}
|
||||
|
||||
return m_boundRects;
|
||||
return m_boundRect;
|
||||
}
|
||||
|
||||
bool State::IsPositionFaultCritical() const
|
||||
|
@ -340,12 +332,7 @@ namespace location
|
|||
pxPosition + m_halfArrowSize);
|
||||
|
||||
newRect.Add(arrowRect);
|
||||
|
||||
if (newRect != m_boundRect)
|
||||
{
|
||||
m_boundRect = newRect;
|
||||
setIsDirtyRect(true);
|
||||
}
|
||||
m_boundRect = newRect;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -81,15 +81,13 @@ namespace location
|
|||
|
||||
Framework * m_framework;
|
||||
|
||||
/// Compass Rendering Parameters
|
||||
/// @{
|
||||
|
||||
/// @nameCompass Rendering Parameters
|
||||
//@{
|
||||
unique_ptr<graphics::DisplayList> m_positionArrow;
|
||||
unique_ptr<graphics::DisplayList> m_locationMarkDL;
|
||||
unique_ptr<graphics::DisplayList> m_positionMarkDL;
|
||||
//@}
|
||||
|
||||
/// @}
|
||||
///
|
||||
void cachePositionArrow();
|
||||
void cacheLocationMark();
|
||||
|
||||
|
@ -97,7 +95,6 @@ namespace location
|
|||
void purge();
|
||||
void update();
|
||||
|
||||
mutable vector<m2::AnyRectD> m_boundRects;
|
||||
m2::RectD m_boundRect;
|
||||
|
||||
void CheckCompassFollowing();
|
||||
|
@ -155,7 +152,8 @@ namespace location
|
|||
|
||||
/// @name Override from graphics::OverlayElement and gui::Element.
|
||||
//@{
|
||||
vector<m2::AnyRectD> const & boundRects() const;
|
||||
virtual m2::RectD GetBoundRect() const;
|
||||
|
||||
void draw(graphics::OverlayRenderer * r, math::Matrix<double, 3, 3> const & m) const;
|
||||
bool roughHitTest(m2::PointD const & pt) const;
|
||||
bool hitTest(m2::PointD const & pt) const;
|
||||
|
|
|
@ -445,8 +445,7 @@ Ruler::Params::Params()
|
|||
{}
|
||||
|
||||
Ruler::Ruler(Params const & p)
|
||||
: base_t(p),
|
||||
m_boundRects(1),
|
||||
: BaseT(p),
|
||||
m_currentRangeIndex(InvalidUnitValue),
|
||||
m_currSystem(0),
|
||||
m_framework(p.m_framework)
|
||||
|
@ -615,20 +614,13 @@ void Ruler::update()
|
|||
frame->SetOrgPoint(orgPt);
|
||||
}
|
||||
|
||||
vector<m2::AnyRectD> const & Ruler::boundRects() const
|
||||
m2::RectD Ruler::GetBoundRect() const
|
||||
{
|
||||
if (isDirtyRect())
|
||||
{
|
||||
FontDesc const & f = font(EActive);
|
||||
RulerFrame * frame = GetMainFrame();
|
||||
m2::PointD org = frame->GetOrgPoint();
|
||||
m2::PointD size = m2::PointD(CacheLength * frame->GetScale(), f.m_size * 2);
|
||||
m2::RectD rect(org - m2::PointD(size.x, 0.0), org + m2::PointD(0.0, size.y));
|
||||
m_boundRects[0] = m2::AnyRectD(rect);
|
||||
setIsDirtyRect(false);
|
||||
}
|
||||
|
||||
return m_boundRects;
|
||||
FontDesc const & f = font(EActive);
|
||||
RulerFrame * frame = GetMainFrame();
|
||||
m2::PointD const org = frame->GetOrgPoint();
|
||||
m2::PointD const size = m2::PointD(CacheLength * frame->GetScale(), f.m_size * 2);
|
||||
return m2::RectD(org - m2::PointD(size.x, 0.0), org + m2::PointD(0.0, size.y));
|
||||
}
|
||||
|
||||
void Ruler::cache()
|
||||
|
|
|
@ -27,9 +27,7 @@ class Framework;
|
|||
|
||||
class Ruler : public gui::Element
|
||||
{
|
||||
typedef gui::Element base_t;
|
||||
|
||||
mutable vector<m2::AnyRectD> m_boundRects;
|
||||
typedef gui::Element BaseT;
|
||||
|
||||
class RulerFrame
|
||||
{
|
||||
|
@ -112,7 +110,8 @@ public:
|
|||
|
||||
/// @name Override from graphics::OverlayElement and gui::Element.
|
||||
//@{
|
||||
vector<m2::AnyRectD> const & boundRects() const;
|
||||
virtual m2::RectD GetBoundRect() const;
|
||||
|
||||
void draw(graphics::OverlayRenderer * r, math::Matrix<double, 3, 3> const & m) const;
|
||||
|
||||
void update();
|
||||
|
|
|
@ -32,17 +32,14 @@ namespace
|
|||
CrossElement(OverlayElement::Params const & params)
|
||||
: OverlayElement(params)
|
||||
{
|
||||
m2::PointD offset(ApiPinLength, ApiPinLength);
|
||||
m2::PointD const & pt = pivot();
|
||||
m2::RectD r(pt - offset, pt + offset);
|
||||
|
||||
m_boundRects.push_back(m2::AnyRectD(r));
|
||||
setIsFrozen(true);
|
||||
}
|
||||
|
||||
vector<m2::AnyRectD> const & boundRects() const
|
||||
virtual m2::RectD GetBoundRect() const
|
||||
{
|
||||
return m_boundRects;
|
||||
m2::PointD const offset(ApiPinLength, ApiPinLength);
|
||||
m2::PointD const & pt = pivot();
|
||||
return m2::RectD(pt - offset, pt + offset);
|
||||
}
|
||||
|
||||
void draw(OverlayRenderer * r, math::Matrix<double, 3, 3> const & m) const
|
||||
|
@ -80,9 +77,6 @@ namespace
|
|||
{
|
||||
OverlayElement::setTransformation(m);
|
||||
}
|
||||
|
||||
private:
|
||||
vector<m2::AnyRectD> m_boundRects;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -360,13 +360,13 @@ template <class ToDo> void Query::ForEachCategoryTypes(ToDo toDo) const
|
|||
for (size_t i = 0; i < tokensCount; ++i)
|
||||
{
|
||||
for (int j = 0; j < localesCount; ++j)
|
||||
m_pCategories->ForEachTypeByName(arrLocales[j], m_tokens[i], bind<void>(toDo, i, _1));
|
||||
m_pCategories->ForEachTypeByName(arrLocales[j], m_tokens[i], bind<void>(ref(toDo), i, _1));
|
||||
}
|
||||
|
||||
if (!m_prefix.empty())
|
||||
{
|
||||
for (int j = 0; j < localesCount; ++j)
|
||||
m_pCategories->ForEachTypeByName(arrLocales[j], m_prefix, bind<void>(toDo, tokensCount, _1));
|
||||
m_pCategories->ForEachTypeByName(arrLocales[j], m_prefix, bind<void>(ref(toDo), tokensCount, _1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue