From 69f6e406743e9bfa4813989cec71d9465b1524e2 Mon Sep 17 00:00:00 2001 From: ExMix Date: Fri, 7 Mar 2014 15:05:57 +0300 Subject: [PATCH] new ruler with chess and poetesses --- map/alfa_animation_task.cpp | 49 +++++ map/alfa_animation_task.hpp | 29 +++ map/compass_arrow.cpp | 66 +------ map/framework.cpp | 2 +- map/information_display.cpp | 21 +- map/information_display.hpp | 1 + map/map.pro | 2 + map/ruler.cpp | 374 +++++++++++++++++++++++++++++------- map/ruler.hpp | 25 ++- 9 files changed, 428 insertions(+), 141 deletions(-) create mode 100644 map/alfa_animation_task.cpp create mode 100644 map/alfa_animation_task.hpp diff --git a/map/alfa_animation_task.cpp b/map/alfa_animation_task.cpp new file mode 100644 index 0000000000..0370758b0c --- /dev/null +++ b/map/alfa_animation_task.cpp @@ -0,0 +1,49 @@ +#include "alfa_animation_task.hpp" + +#include "framework.hpp" + +AlfaCompassAnim::AlfaCompassAnim(double start, double end, double timeInterval, double timeOffset, Framework * f) + : m_start(start) + , m_end(end) + , m_current(start) + , m_timeInterval(timeInterval) + , m_timeOffset(timeOffset) + , m_f(f) +{ +} + +bool AlfaCompassAnim::IsHiding() const +{ + return m_start > m_end; +} + +float AlfaCompassAnim::GetCurrentAlfa() const +{ + return m_current; +} + +void AlfaCompassAnim::OnStart(double ts) +{ + m_timeStart = ts; + base_t::OnStart(ts); + m_f->Invalidate(); +} + +void AlfaCompassAnim::OnStep(double ts) +{ + base_t::OnStep(ts); + double elapsed = ts - (m_timeStart + m_timeOffset); + if (elapsed >= 0.0) + { + double t = elapsed / m_timeInterval; + if (t > 1.0) + { + m_current = m_end; + End(); + } + else + m_current = m_start + t * (m_end - m_start); + } + + m_f->Invalidate(); +} diff --git a/map/alfa_animation_task.hpp b/map/alfa_animation_task.hpp new file mode 100644 index 0000000000..151b1f9c3a --- /dev/null +++ b/map/alfa_animation_task.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include "../anim/task.hpp" + +class Framework; + +class AlfaCompassAnim : public anim::Task +{ + typedef anim::Task base_t; +public: + AlfaCompassAnim(double start, double end, double timeInterval, double timeOffset, Framework * f); + + bool IsHiding() const; + + float GetCurrentAlfa() const; + + virtual void OnStart(double ts); + virtual void OnStep(double ts); + +private: + double m_start; + double m_end; + double m_current; + double m_timeInterval; + double m_timeOffset; + double m_timeStart; + + Framework * m_f; +}; diff --git a/map/compass_arrow.cpp b/map/compass_arrow.cpp index b2f4cbffcf..45d6f60e7d 100644 --- a/map/compass_arrow.cpp +++ b/map/compass_arrow.cpp @@ -1,9 +1,9 @@ #include "compass_arrow.hpp" #include "framework.hpp" +#include "alfa_animation_task.hpp" #include "../anim/controller.hpp" -#include "../anim/task.hpp" #include "../gui/controller.hpp" @@ -17,70 +17,6 @@ using namespace graphics; -namespace -{ - class AlfaCompassAnim : public anim::Task - { - typedef anim::Task base_t; - public: - AlfaCompassAnim(double start, double end, double timeInterval, double timeOffset, Framework * f) - : m_start(start) - , m_end(end) - , m_current(start) - , m_timeInterval(timeInterval) - , m_timeOffset(timeOffset) - , m_f(f) - { - } - - bool IsHiding() const - { - return m_start > m_end; - } - - float GetCurrentAlfa() const - { - return m_current; - } - - virtual void OnStart(double ts) - { - m_timeStart = ts; - base_t::OnStart(ts); - m_f->Invalidate(); - } - - virtual void OnStep(double ts) - { - base_t::OnStep(ts); - double elapsed = ts - (m_timeStart + m_timeOffset); - if (elapsed >= 0.0) - { - double t = elapsed / m_timeInterval; - if (t > 1.0) - { - m_current = m_end; - End(); - } - else - m_current = m_start + t * (m_end - m_start); - } - - m_f->Invalidate(); - } - - private: - double m_start; - double m_end; - double m_current; - double m_timeInterval; - double m_timeOffset; - double m_timeStart; - - Framework * m_f; - }; -} - CompassArrow::Params::Params() : m_framework(0) {} diff --git a/map/framework.cpp b/map/framework.cpp index 8719456763..ed36c3b237 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -794,7 +794,7 @@ void Framework::DrawAdditionalInfo(shared_ptr const & e) m_informationDisplay.setDebugInfo(0, GetDrawScale()); - m_informationDisplay.enableRuler(true); + m_informationDisplay.enableRuler(m_navigator.InAction()); #ifdef DEBUG m_informationDisplay.enableDebugInfo(true); #endif diff --git a/map/information_display.cpp b/map/information_display.cpp index 3ef44fd125..b3ffd59ed2 100644 --- a/map/information_display.cpp +++ b/map/information_display.cpp @@ -29,7 +29,9 @@ namespace { - static int const FONT_SIZE = 10; + static int const RULLER_X_OFFSET = 65; + static int const RULLER_Y_OFFSET = 15; + static int const FONT_SIZE = 14; static int const COMPASS_W_OFFSET = 13; static int const COMPASS_H_OFFSET = 71; } @@ -53,6 +55,7 @@ InformationDisplay::InformationDisplay(Framework * fw) enableBenchmarkInfo(false); enableCountryStatusDisplay(false); m_compassArrow->setIsVisible(false); + m_ruler->setIsVisible(false); for (int i = 0; i < sizeof(m_DebugPts) / sizeof(m2::PointD); ++i) m_DebugPts[i] = m2::PointD(0, 0); @@ -65,7 +68,7 @@ void InformationDisplay::InitRuler(Framework * fw) Ruler::Params p; p.m_depth = graphics::rulerDepth; - p.m_position = graphics::EPosAboveLeft; + p.m_position = graphics::EPosAboveRight; p.m_framework = fw; m_ruler.reset(new Ruler(p)); @@ -156,8 +159,8 @@ void InformationDisplay::setDisplayRect(m2::RectI const & rect) { m_displayRect = rect; - m2::PointD pt(m2::PointD(m_displayRect.maxX() - 30 * m_visualScale, - m_displayRect.maxY() - 10 * m_visualScale)); + m2::PointD pt(m2::PointD(m_displayRect.minX() + RULLER_X_OFFSET * m_visualScale, + m_displayRect.maxY() - RULLER_Y_OFFSET * m_visualScale)); m_ruler->setPivot(pt); @@ -189,7 +192,15 @@ void InformationDisplay::drawDebugPoints(Drawer * pDrawer) void InformationDisplay::enableRuler(bool doEnable) { - m_ruler->setIsVisible(doEnable); + if (doEnable) + m_ruler->AnimateShow(); + else + m_ruler->AnimateHide(); +} + +bool InformationDisplay::isRulerEnabled() const +{ + return m_ruler->isVisible(); } void InformationDisplay::setRulerParams(unsigned pxMinWidth, double metresMinWidth, double metresMaxWidth) diff --git a/map/information_display.hpp b/map/information_display.hpp index af7c833734..1c153c4570 100644 --- a/map/information_display.hpp +++ b/map/information_display.hpp @@ -113,6 +113,7 @@ public: void drawDebugPoints(Drawer * pDrawer); void enableRuler(bool doEnable); + bool isRulerEnabled() const; void setRulerParams(unsigned pxMinWidth, double metresMinWidth, double metresMaxWidth); void enableDebugInfo(bool doEnable); diff --git a/map/map.pro b/map/map.pro index 4e8f59c571..256e396f6e 100644 --- a/map/map.pro +++ b/map/map.pro @@ -63,6 +63,7 @@ HEADERS += \ scales_processor.hpp \ yopme_render_policy.hpp \ track.hpp \ + alfa_animation_task.hpp SOURCES += \ feature_vec_model.cpp \ @@ -113,6 +114,7 @@ SOURCES += \ scales_processor.cpp \ yopme_render_policy.cpp \ track.cpp \ + alfa_animation_task.cpp !iphone*:!bada*:!android* { HEADERS += qgl_render_context.hpp 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(m_rulerAnim.get()); + return a->IsHiding(); +} + +float Ruler::GetCurrentAlfa() const +{ + if (m_rulerAnim) + { + AlfaCompassAnim * a = static_cast(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::setController(gui::Controller * controller) +void Ruler::AnimateShow() { - gui::Element::setController(controller); - m_scaleText->setController(controller); + 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::AnimateHide() +{ + 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 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 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 infos(length, graphics::Glyph::Info()); + buffer_vector resInfos(length, NULL); + buffer_vector ids(length, 0); + buffer_vector 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 texture = cs->pipeline(pipelineID).texture(); + double halfWidth = width / 2.0; + double lengthFromStart = 0.0; + + buffer_vector coords; + buffer_vector normals; + buffer_vector 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 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 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 const & m) const @@ -340,11 +579,16 @@ void Ruler::draw(graphics::OverlayRenderer * s, math::Matrix 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()); - m_scaleText->draw(s, m); + s->drawDisplayList(m_dl, math::Shift( + math::Scale(m, m2::PointD(m_scaleKoeff, 1.0)), + m_scalerOrg), &holder); + + 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))); } } diff --git a/map/ruler.hpp b/map/ruler.hpp index 4e26ae4b9e..81a35e9991 100644 --- a/map/ruler.hpp +++ b/map/ruler.hpp @@ -10,6 +10,11 @@ #include "../graphics/display_list.hpp" +namespace anim +{ + class Task; +} + namespace graphics { namespace gl @@ -29,6 +34,12 @@ class Ruler : public gui::Element { private: + shared_ptr m_rulerAnim; + void AlfaAnimEnded(bool isVisible); + bool IsHidingAnim() const; + float GetCurrentAlfa() const; + void CreateAnim(double startAlfa, double endAlfa, double timeInterval, double timeOffset, bool isVisibleAtEnd); + /// @todo Remove this variables. All this stuff are constants /// (get values from Framework constructor) unsigned m_minPxWidth; @@ -57,8 +68,13 @@ private: int m_currSystem; void CalcMetresDiff(double v); - shared_ptr m_scaleText; - scoped_ptr m_dl; + graphics::DisplayList * m_dl; + void PurgeMainDL(); + void CacheMainDL(); + + graphics::DisplayList * m_textDL[2]; + void PurgeTextDL(int index); + void UpdateText(const string & text); Framework * m_framework; @@ -72,14 +88,13 @@ public: Ruler(Params const & p); - void setController(gui::Controller * controller); + void AnimateShow(); + void AnimateHide(); void setMinPxWidth(unsigned minPxWidth); void setMinMetersWidth(double v); void setMaxMetersWidth(double v); - void setFont(gui::Element::EState state, graphics::FontDesc const & f); - vector const & boundRects() const; void draw(graphics::OverlayRenderer * r, math::Matrix const & m) const;