diff options
author | ExMix <rahuba.youri@mapswithme.com> | 2014-03-07 16:05:57 +0400 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 02:12:40 +0300 |
commit | 69f6e406743e9bfa4813989cec71d9465b1524e2 (patch) | |
tree | 98ec8f1e4163bcfced4abafcd37499c51401ccd9 /map/ruler.cpp | |
parent | aa9010fa705edb99280619e9e74e04fbff2b0430 (diff) |
new ruler with chess and poetesses
Diffstat (limited to 'map/ruler.cpp')
-rw-r--r-- | map/ruler.cpp | 374 |
1 files changed, 309 insertions, 65 deletions
diff --git a/map/ruler.cpp b/map/ruler.cpp index fd86543d96..d46c4a59bc 100644 --- a/map/ruler.cpp +++ b/map/ruler.cpp @@ -1,15 +1,20 @@ #include "ruler.hpp" #include "framework.hpp" #include "measurement_utils.hpp" +#include "alfa_animation_task.hpp" + +#include "../anim/controller.hpp" #include "../platform/settings.hpp" #include "../gui/cached_text_view.hpp" #include "../gui/controller.hpp" -#include "../graphics/pen.hpp" +#include "../graphics/glyph.hpp" +#include "../graphics/brush.hpp" #include "../graphics/screen.hpp" #include "../graphics/display_list.hpp" +#include "../graphics/uniforms_holder.hpp" #include "../indexer/mercator.hpp" #include "../geometry/distance_on_sphere.hpp" @@ -85,6 +90,42 @@ namespace } } +void Ruler::AlfaAnimEnded(bool isVisible) +{ + setIsVisible(isVisible); + m_rulerAnim.reset(); +} + +bool Ruler::IsHidingAnim() const +{ + ASSERT(m_rulerAnim != NULL, ()); + AlfaCompassAnim * a = static_cast<AlfaCompassAnim *>(m_rulerAnim.get()); + return a->IsHiding(); +} + +float Ruler::GetCurrentAlfa() const +{ + if (m_rulerAnim) + { + AlfaCompassAnim * a = static_cast<AlfaCompassAnim *>(m_rulerAnim.get()); + return a->GetCurrentAlfa(); + } + + return isVisible() ? 1.0 : 0.0; +} + +void Ruler::CreateAnim(double startAlfa, double endAlfa, double timeInterval, double timeOffset, bool isVisibleAtEnd) +{ + if (m_framework->GetAnimController() == NULL) + return; + + if (m_rulerAnim) + m_rulerAnim->Cancel(); + m_rulerAnim.reset(new AlfaCompassAnim(startAlfa, endAlfa, timeInterval, timeOffset, m_framework)); + m_rulerAnim->AddCallback(anim::Task::EEnded, bind(&Ruler::AlfaAnimEnded, this, isVisibleAtEnd)); + m_framework->GetAnimController()->AddTask(m_rulerAnim); +} + void Ruler::CalcMetresDiff(double v) { UnitValue * arrU; @@ -132,7 +173,7 @@ void Ruler::CalcMetresDiff(double v) } } - m_scaleText->setText(s); + UpdateText(s); } Ruler::Params::Params() @@ -150,13 +191,26 @@ Ruler::Ruler(Params const & p) pp.m_depth = depth(); - m_scaleText.reset(new gui::CachedTextView(pp)); + m_dl = NULL; + memset(m_textDL, 0, ARRAY_SIZE(m_textDL) * sizeof(void *)); +} + +void Ruler::AnimateShow() +{ + if (!isVisible() && (m_rulerAnim == NULL || IsHidingAnim())) + { + setIsVisible(true); + CreateAnim(0.1, 1.0, 0.2, 0.0, true); + } + + if (isVisible() && (m_rulerAnim == NULL || IsHidingAnim())) + CreateAnim(GetCurrentAlfa(), 1.0, 0.2, 0.0, true); } -void Ruler::setController(gui::Controller * controller) +void Ruler::AnimateHide() { - gui::Element::setController(controller); - m_scaleText->setController(controller); + if (isVisible() && (m_rulerAnim == NULL || !IsHidingAnim())) + CreateAnim(1.0, 0.0, 0.3, 1.0, false); } void Ruler::layout() @@ -204,10 +258,242 @@ void Ruler::setMaxMetersWidth(double v) setIsDirtyLayout(true); } +void Ruler::PurgeMainDL() +{ + delete m_dl; + m_dl = NULL; +} + +void Ruler::CacheMainDL() +{ + graphics::Screen * cs = m_controller->GetCacheScreen(); + + PurgeMainDL(); + m_dl = cs->createDisplayList(); + + cs->beginFrame(); + + cs->setDisplayList(m_dl); + + cs->applyVarAlfaStates(); + + double k = visualScale(); + double halfLength = m_cacheLength / 2.0; + + graphics::FontDesc const & f = font(EActive); + graphics::GlyphKey key(strings::LastUniChar("0"), f.m_size, f.m_isMasked, f.m_color); + graphics::Glyph::Info glyphInfo(key, m_controller->GetGlyphCache()); + uint32_t zeroMarkGlyph = cs->mapInfo(glyphInfo); + graphics::Resource const * glyphRes = cs->fromID(zeroMarkGlyph); + + m2::RectI glyphRect(glyphRes->m_texRect); + double glyphHalfW = glyphRect.SizeX() / 2.0; + double glyphHalfH = glyphRect.SizeY() / 2.0; + double zeroMarkOffset = (glyphHalfH + 2) + 5 * k; + + graphics::Brush::Info brushInfo(graphics::Color(3, 3, 3, 255)); + uint32_t brushId = cs->mapInfo(brushInfo); + graphics::Resource const * brushRes = cs->fromID(brushId); + m2::RectU brushRect = brushRes->m_texRect; + + shared_ptr<graphics::gl::BaseTexture> glyphTexture = cs->pipeline(glyphRes->m_pipelineID).texture(); + m2::PointF brushCenter = cs->pipeline(brushRes->m_pipelineID).texture()->mapPixel(brushRect.Center()); + + // 0 1 10 11 18 17 + // -- -- -- + // || || || + // || 3, 6 9||8, 12 16||14 + // 2|--------- -------------| + // | | + // | | + // 4-------------------------- + // 5 7, 13 15 + + m2::PointD coords[] = + { + // Zero mark geometry + /*-4*/ m2::PointD(0.0, -zeroMarkOffset), + /*-3*/ m2::PointD(0.0, -zeroMarkOffset), + /*-2*/ m2::PointD(0.0, -zeroMarkOffset), + /*-1*/ m2::PointD(0.0, -zeroMarkOffset), + // Ruler geometry + /* 0*/ m2::PointD(0.0, -5.0 * k), + /* 1*/ m2::PointD(0.0, -5.0 * k), + /* 2*/ m2::PointD(0.0, -3.0 * k), + /* 3*/ m2::PointD(0.0, -3.0 * k), + /* 4*/ m2::PointD(0.0, 0.0), + /* 5*/ m2::PointD(0.0, 0.0), + /* 6*/ m2::PointD(0.0, -3.0 * k), + /* 7*/ m2::PointD(halfLength - 0.5, 0.0), + /* 8*/ m2::PointD(halfLength - 0.5, -3.0 * k), + /* 9*/ m2::PointD(halfLength - 0.5, -3.0 * k), + /*10*/ m2::PointD(halfLength - 0.5, -7.0 * k), + /*11*/ m2::PointD(halfLength - 0.5, -7.0 * k), + /*12*/ m2::PointD(halfLength - 0.5, -3.0 * k), + /*13*/ m2::PointD(halfLength - 0.5, 0.0 * k), + /*14*/ m2::PointD(m_cacheLength, -3.0 * k), + /*15*/ m2::PointD(m_cacheLength, 0.0 * k), + /*16*/ m2::PointD(m_cacheLength, -3.0 * k), + /*17*/ m2::PointD(m_cacheLength, -5.0 * k), + /*18*/ m2::PointD(m_cacheLength, -5.0 * k) + }; + + m2::PointF normals[] = + { + // Zero mark normals + /*-4*/ m2::PointF(-glyphHalfW + 1, -glyphHalfH), + /*-3*/ m2::PointF(-glyphHalfW + 1, glyphHalfH), + /*-2*/ m2::PointF( glyphHalfW + 1, -glyphHalfH), + /*-1*/ m2::PointF( glyphHalfW + 1, glyphHalfH), + // Ruler normals + /* 0*/ m2::PointF( 0.0 , 0.0), + /* 1*/ m2::PointF( 1.0 * k , 0.0), + /* 2*/ m2::PointF( 0.0 , 0.0), + /* 3*/ m2::PointF( 1.0 * k , 0.0), + /* 4*/ m2::PointF( 0.0 , 0.0), + /* 5*/ m2::PointF( 1.0 * k , 0.0), + /* 6*/ m2::PointF( 1.0 * k , 0.0), + /* 7*/ m2::PointF( 1.0 * k , 0.0), + /* 8*/ m2::PointF( 1.0 * k , 0.0), + /* 9*/ m2::PointF( 0.0 , 0.0), + /*10*/ m2::PointF( 0.0 , 0.0), + /*11*/ m2::PointF( 1.0 * k , 0.0), + /*12*/ m2::PointF( 1.0 * k , 0.0), + /*13*/ m2::PointF( 1.0 * k , 0.0), + /*14*/ m2::PointF( 0.0 , 0.0), + /*15*/ m2::PointF( 0.0 , 0.0), + /*16*/ m2::PointF(-1.0 * k , 0.0), + /*17*/ m2::PointF( 0.0 , 0.0), + /*18*/ m2::PointF(-1.0 * k , 0.0) + }; + + vector<m2::PointF> texCoords(ARRAY_SIZE(normals), brushCenter); + texCoords[0] = glyphTexture->mapPixel(m2::PointF(glyphRect.minX(), glyphRect.minY())); + texCoords[1] = glyphTexture->mapPixel(m2::PointF(glyphRect.minX(), glyphRect.maxY())); + texCoords[2] = glyphTexture->mapPixel(m2::PointF(glyphRect.maxX(), glyphRect.minY())); + texCoords[3] = glyphTexture->mapPixel(m2::PointF(glyphRect.maxX(), glyphRect.maxY())); + + ASSERT(ARRAY_SIZE(coords) == ARRAY_SIZE(normals), ()); + + cs->addTexturedStripStrided(coords, sizeof(m2::PointD), + normals, sizeof(m2::PointF), + &texCoords[0], sizeof(m2::PointF), 4, + depth(), glyphRes->m_pipelineID); + + cs->addTexturedStripStrided(coords + 4, sizeof(m2::PointD), + normals + 4, sizeof(m2::PointF), + &texCoords[4], sizeof(m2::PointF), ARRAY_SIZE(coords) - 4, + depth(), brushRes->m_pipelineID); + + cs->setDisplayList(0); + + cs->applyStates(); + + cs->endFrame(); +} + +void Ruler::PurgeTextDL(int index) +{ + delete m_textDL[index]; + m_textDL[index] = NULL; +} + +void Ruler::UpdateText(const string & text) +{ + ASSERT(!text.empty(), ()); + ASSERT(m_textDL[1] == NULL, ()); + swap(m_textDL[0], m_textDL[1]); + PurgeTextDL(1); + + graphics::Screen * cs = m_controller->GetCacheScreen(); + m_textDL[0] = cs->createDisplayList(); + + cs->beginFrame(); + cs->setDisplayList(m_textDL[0]); + cs->applyVarAlfaStates(); + + strings::UniString uniString = strings::MakeUniString(text); + size_t length = uniString.size(); + buffer_vector<graphics::Glyph::Info, 8> infos(length, graphics::Glyph::Info()); + buffer_vector<graphics::Resource::Info const *, 8> resInfos(length, NULL); + buffer_vector<uint32_t, 8> ids(length, 0); + buffer_vector<graphics::Resource const *, 8> glyphRes(length, NULL); + + graphics::FontDesc const & f = font(EActive); + + for (size_t i = 0; i < uniString.size(); ++i) + { + infos[i] = graphics::Glyph::Info(graphics::GlyphKey(uniString[i], f.m_size, false, f.m_color), + m_controller->GetGlyphCache()); + + resInfos[i] = &infos[i]; + } + + if (cs->mapInfo(resInfos.data(), ids.data(), infos.size())) + { + uint32_t width = 0; + for (size_t i = 0; i < ids.size(); ++i) + { + graphics::Resource const * res = cs->fromID(ids[i]); + width += res->m_texRect.SizeX(); + glyphRes[i] = res; + } + + int32_t pipelineID = glyphRes[0]->m_pipelineID; + shared_ptr<graphics::gl::BaseTexture> texture = cs->pipeline(pipelineID).texture(); + double halfWidth = width / 2.0; + double lengthFromStart = 0.0; + + buffer_vector<m2::PointF, 48> coords; + buffer_vector<m2::PointF, 48> normals; + buffer_vector<m2::PointF, 48> texCoords; + + for (size_t i = 0; i < uniString.size(); ++i) + { + double baseX = lengthFromStart - halfWidth; + coords.push_back(m2::PointD(baseX, 0.0)); + coords.push_back(m2::PointD(baseX, 0.0)); + coords.push_back(m2::PointD(baseX, 0.0)); + + coords.push_back(m2::PointD(baseX, 0.0)); + coords.push_back(m2::PointD(baseX, 0.0)); + coords.push_back(m2::PointD(baseX, 0.0)); + + m2::RectI resourceRect(glyphRes[i]->m_texRect); + double w = resourceRect.SizeX(); + double h = resourceRect.SizeY(); + lengthFromStart += w; + + normals.push_back(m2::PointF(0.0, 0.0)); + normals.push_back(m2::PointF(0.0, -h)); + normals.push_back(m2::PointF(w , 0.0)); + + normals.push_back(m2::PointF(w , 0.0)); + normals.push_back(m2::PointF(0.0, -h)); + normals.push_back(m2::PointF(w , -h)); + + texCoords.push_back(texture->mapPixel(m2::PointF(resourceRect.minX(), resourceRect.maxY()))); + texCoords.push_back(texture->mapPixel(m2::PointF(resourceRect.minX(), resourceRect.minY()))); + texCoords.push_back(texture->mapPixel(m2::PointF(resourceRect.maxX(), resourceRect.maxY()))); + + texCoords.push_back(texture->mapPixel(m2::PointF(resourceRect.maxX(), resourceRect.maxY()))); + texCoords.push_back(texture->mapPixel(m2::PointF(resourceRect.minX(), resourceRect.minY()))); + texCoords.push_back(texture->mapPixel(m2::PointF(resourceRect.maxX(), resourceRect.minY()))); + } + + cs->addTexturedListStrided(coords.data(), sizeof(m2::PointF), + normals.data(), sizeof(m2::PointF), + texCoords.data(), sizeof(m2::PointF), + coords.size(), depth(), pipelineID); + } + + cs->setDisplayList(0); + cs->endFrame(); +} + void Ruler::purge() { - m_scaleText->purge(); - m_dl.reset(); + PurgeMainDL(); } void Ruler::update() @@ -266,36 +552,16 @@ void Ruler::update() m_scalerOrg.y += rulerHeight / 2; m_scaleKoeff = scalerWidthInPx / m_cacheLength; - - if (position() & graphics::EPosLeft) - { - m_scaleText->setPosition(graphics::EPosAboveLeft); - m_scaleText->setPivot(m_scalerOrg + m2::PointD(scalerWidthInPx, 0) + m2::PointD(1 * k, -2 * k)); - } - else - if (position() & graphics::EPosRight) - { - m_scaleText->setPosition(graphics::EPosAboveRight); - m_scaleText->setPivot(m_scalerOrg + m2::PointD(7 * k, -4 * k)); - } - else - { - m_scaleText->setPosition(graphics::EPosAbove); - m_scaleText->setPivot(m_scalerOrg + m2::PointD(scalerWidthInPx / 2.0, 0) + m2::PointD(7 * k, -4 * k)); - } -} - -void Ruler::setFont(gui::Element::EState state, graphics::FontDesc const & f) -{ - gui::Element::setFont(state, f); - m_scaleText->setFont(state, f); } vector<m2::AnyRectD> const & Ruler::boundRects() const { if (isDirtyRect()) { - m_boundRects[0] = m2::AnyRectD(m_scaleText->roughBoundRect()); + // TODO + graphics::FontDesc const & f = font(EActive); + m2::RectD rect(m_scalerOrg, m2::PointD(m_cacheLength * m_scaleKoeff, f.m_size * 2)); + m_boundRects[0] = m2::AnyRectD(rect); setIsDirtyRect(false); } @@ -304,34 +570,7 @@ vector<m2::AnyRectD> const & Ruler::boundRects() const void Ruler::cache() { - graphics::Screen * cs = m_controller->GetCacheScreen(); - - m_dl.reset(); - m_dl.reset(cs->createDisplayList()); - - cs->beginFrame(); - - cs->setDisplayList(m_dl.get()); - - cs->applySharpStates(); - - double k = visualScale(); - - m2::PointD path[2] = { - m2::PointD(0, 0), - m2::PointD(0, 0) + m2::PointD(m_cacheLength, 0) - }; - - cs->drawPath( - path, ARRAY_SIZE(path), 0, - cs->mapInfo(graphics::Pen::Info(graphics::Color(0, 0, 0, 0x99), 4 * k, 0, 0, 0, 0, 0, graphics::Pen::Info::ERoundJoin, graphics::Pen::Info::EButtCap)), - depth()); - - cs->setDisplayList(0); - - cs->applyStates(); - - cs->endFrame(); + CacheMainDL(); } void Ruler::draw(graphics::OverlayRenderer * s, math::Matrix<double, 3, 3> const & m) const @@ -340,11 +579,16 @@ void Ruler::draw(graphics::OverlayRenderer * s, math::Matrix<double, 3, 3> const { checkDirtyLayout(); - s->drawDisplayList(m_dl.get(), - math::Shift( - math::Scale(m, m2::PointD(m_scaleKoeff, 1.0)), - m_scalerOrg)); + graphics::UniformsHolder holder; + holder.insertValue(graphics::ETransparency, GetCurrentAlfa()); + + s->drawDisplayList(m_dl, math::Shift( + math::Scale(m, m2::PointD(m_scaleKoeff, 1.0)), + m_scalerOrg), &holder); - m_scaleText->draw(s, m); + double yOffset = -(2 + 5 * m_controller->GetVisualScale()); + if (m_textDL[0]) + s->drawDisplayList(m_textDL[0], + math::Shift(m, m_scalerOrg + m2::PointF(m_cacheLength * m_scaleKoeff, yOffset))); } } |