Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrachytski <siarhei.rachytski@gmail.com>2012-08-20 13:42:03 +0400
committerAlex Zolotarev <alex@maps.me>2015-09-23 01:42:13 +0300
commit9ca2c102b916e7aeb54f8616e8a780eaa28d3642 (patch)
tree27a503b3438f1a1d46d5293f85c092a898b516e7 /map/compass_arrow.cpp
parent378ba050eeb2ec9e761c3409d2c962932508c60e (diff)
added CompassArrow GUI element.
Diffstat (limited to 'map/compass_arrow.cpp')
-rw-r--r--map/compass_arrow.cpp162
1 files changed, 162 insertions, 0 deletions
diff --git a/map/compass_arrow.cpp b/map/compass_arrow.cpp
new file mode 100644
index 0000000000..d24ec374f1
--- /dev/null
+++ b/map/compass_arrow.cpp
@@ -0,0 +1,162 @@
+#include "compass_arrow.hpp"
+#include "framework.hpp"
+#include "rotate_screen_task.hpp"
+
+#include "../anim/controller.hpp"
+
+#include "../gui/controller.hpp"
+
+#include "../geometry/any_rect2d.hpp"
+#include "../geometry/transformations.hpp"
+
+#include "../yg/display_list.hpp"
+#include "../yg/screen.hpp"
+#include "../yg/skin.hpp"
+
+CompassArrow::CompassArrow(Params const & p)
+ : base_t(p),
+ m_boundRects(1)
+{
+ m_arrowWidth = p.m_arrowWidth;
+ m_arrowHeight = p.m_arrowHeight;
+ m_northColor = p.m_northColor;
+ m_southColor = p.m_southColor;
+ m_framework = p.m_framework;
+ m_angle = 0;
+}
+
+void CompassArrow::setAngle(double angle)
+{
+ m_angle = angle;
+ m_drawM = math::Shift(math::Rotate(math::Identity<double, 3>(), m_angle), pivot() * visualScale());
+
+ setIsDirtyRect(true);
+}
+
+vector<m2::AnyRectD> const & CompassArrow::boundRects() const
+{
+ if (isDirtyRect())
+ {
+ double k = visualScale();
+
+ m2::PointD pv = pivot() * k;
+ double halfW = m_arrowWidth / 2.0 * k;
+ double halfH = m_arrowHeight / 2.0 * k;
+
+ m_boundRects[0] = m2::AnyRectD(pv,
+ -math::pi / 2 + m_angle,
+ m2::RectD(-halfW, -halfH, halfW, halfH));
+
+ setIsDirtyRect(false);
+ }
+
+ return m_boundRects;
+}
+
+void CompassArrow::draw(yg::gl::OverlayRenderer * r,
+ math::Matrix<double, 3, 3> const & m) const
+{
+ if (isVisible())
+ {
+ checkDirtyDrawing();
+ m_displayList->draw(m_drawM * m);
+ }
+}
+
+void CompassArrow::cache()
+{
+ yg::gl::Screen * cacheScreen = m_controller->GetCacheScreen();
+
+ m_displayList.reset();
+ m_displayList.reset(cacheScreen->createDisplayList());
+
+ cacheScreen->beginFrame();
+ cacheScreen->setDisplayList(m_displayList.get());
+
+ double k = visualScale();
+
+ double halfW = m_arrowWidth / 2.0 * k;
+ double halfH = m_arrowHeight / 2.0 * k;
+
+ m2::PointF northPts[3] = {
+ m2::PointF(-halfW, 0),
+ m2::PointF(0, -halfH),
+ m2::PointF(halfW, 0)
+ };
+
+ cacheScreen->drawConvexPolygon(northPts, 3, m_northColor, depth());
+
+ m2::PointF southPts[3] = {
+ m2::PointF(-halfW, 0),
+ m2::PointF(halfW, 0),
+ m2::PointF(0, halfH),
+ };
+
+ cacheScreen->drawConvexPolygon(southPts, 3, m_southColor, depth());
+
+ m2::PointD outlinePts[6] = {
+ m2::PointD(-halfW, 0),
+ m2::PointD(0, -halfH),
+ m2::PointD(halfW, 0),
+ m2::PointD(0, halfH),
+ m2::PointD(-halfW, 0),
+ m2::PointD(halfW, 0)
+ };
+
+ yg::PenInfo outlinePenInfo(yg::Color(32, 32, 32, 255), 1, 0, 0, 0);
+
+ cacheScreen->drawPath(outlinePts, sizeof(outlinePts) / sizeof(m2::PointD), 0, cacheScreen->skin()->mapPenInfo(outlinePenInfo), depth());
+
+ m_drawM = math::Shift(math::Rotate(math::Identity<double, 3>(), m_angle), pivot() * k);
+
+ cacheScreen->setDisplayList(0);
+ cacheScreen->endFrame();
+
+ // we should not call cacheScreen->completeCommands
+ // as the gui::Element::cache is called on the GUI thread.
+}
+
+void CompassArrow::purge()
+{
+ m_displayList.reset();
+}
+
+bool CompassArrow::onTapEnded(m2::PointD const & pt)
+{
+ shared_ptr<anim::Controller> animController = m_framework->GetRenderPolicy()->GetAnimController();
+ animController->Lock();
+
+ if (m_rotateScreenTask
+ && !m_rotateScreenTask->IsEnded()
+ && !m_rotateScreenTask->IsCancelled())
+ m_rotateScreenTask->Cancel();
+ m_rotateScreenTask.reset();
+
+ double startAngle = m_framework->GetNavigator().Screen().GetAngle();
+ double endAngle = 0;
+
+ double period = 2 * math::pi;
+
+ startAngle -= floor(startAngle / period) * period;
+ endAngle -= floor(endAngle / period) * period;
+
+ if (fabs(startAngle - endAngle) > math::pi)
+ startAngle -= 2 * math::pi;
+
+ m_rotateScreenTask.reset(new RotateScreenTask(m_framework,
+ startAngle,
+ endAngle,
+ 1));
+ animController->AddTask(m_rotateScreenTask);
+
+ animController->Unlock();
+
+ m_framework->Invalidate();
+
+ return true;
+}
+
+bool CompassArrow::hitTest(m2::PointD const & pt) const
+{
+ return pt.Length(pivot() * visualScale()) < max(m_arrowWidth / 2, m_arrowHeight / 2);
+}