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:
vng 2014-09-06 19:07:12 +03:00 committed by Alex Zolotarev
parent 696fde40b3
commit 7a54c6e080
33 changed files with 290 additions and 496 deletions

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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);

View file

@ -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"));
}
}

View file

@ -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);
}
}

View file

@ -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;
};
}

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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())

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -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)

View file

@ -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();

View file

@ -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);
}
}

View file

@ -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

View file

@ -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,

View file

@ -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);

View file

@ -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)

View file

@ -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);
//@}
};
}

View file

@ -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)

View file

@ -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;

View file

@ -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));

View file

@ -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();

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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()

View file

@ -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();

View file

@ -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;
};
}

View file

@ -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));
}
}
}