From 1f90697f1af585087aea489cdb0045e05eca29c2 Mon Sep 17 00:00:00 2001 From: vng Date: Sun, 12 Jun 2011 11:39:49 +0300 Subject: [PATCH] Make smooth scale control. --- map/framework.cpp | 24 ++++++++++++----------- map/framework.hpp | 2 +- qt/draw_widget.cpp | 27 ++++++++----------------- qt/draw_widget.hpp | 8 ++++---- qt/mainwindow.cpp | 4 ++-- qt/slider_ctrl.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++--- qt/slider_ctrl.hpp | 24 ++++++++++++++++++++--- 7 files changed, 95 insertions(+), 43 deletions(-) diff --git a/map/framework.cpp b/map/framework.cpp index c491e424dc..02e4602381 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -719,7 +719,7 @@ void FrameWork::AddRedrawCommandSure() } template - int FrameWork::GetCurrentScale() const + double FrameWork::GetCurrentScale() const { m2::PointD textureCenter(m_renderQueue.renderState().m_textureWidth / 2, m_renderQueue.renderState().m_textureHeight / 2); @@ -729,7 +729,7 @@ void FrameWork::AddRedrawCommandSure() m_navigator.Screen().PtoG(m2::RectD(textureCenter - m2::PointD(scaleEtalonSize / 2, scaleEtalonSize / 2), textureCenter + m2::PointD(scaleEtalonSize / 2, scaleEtalonSize / 2)), glbRect); - return scales::GetScaleLevel(glbRect); + return scales::GetScaleLevelD(glbRect); } /// Actual rendering function. @@ -779,14 +779,14 @@ void FrameWork::AddRedrawCommandSure() template void FrameWork::Paint(shared_ptr e) { - /// Making a copy of actualFrameInfo to compare without synchronizing. -// typename yg::gl::RenderState state = m_renderQueue.CopyState(); + // Making a copy of actualFrameInfo to compare without synchronizing. + //typename yg::gl::RenderState state = m_renderQueue.CopyState(); DrawerYG * pDrawer = e->drawer().get(); m_informationDisplay.setScreen(m_navigator.Screen()); - m_informationDisplay.setDebugInfo(m_renderQueue.renderState().m_duration, GetCurrentScale()); + m_informationDisplay.setDebugInfo(m_renderQueue.renderState().m_duration, my::rounds(GetCurrentScale())); m_informationDisplay.enableRuler(!IsEmptyModel()); @@ -855,11 +855,13 @@ void FrameWork::AddRedrawCommandSure() UpdateNow(); } + int const theMetersFactor = 6; + template void FrameWork::ShowRect(m2::RectD rect) { - double const minSizeX = MercatorBounds::ConvertMetresToX(rect.minX(), 6 * m_metresMinWidth); - double const minSizeY = MercatorBounds::ConvertMetresToY(rect.minY(), 6 * m_metresMinWidth); + double const minSizeX = MercatorBounds::ConvertMetresToX(rect.minX(), theMetersFactor * m_metresMinWidth); + double const minSizeY = MercatorBounds::ConvertMetresToY(rect.minY(), theMetersFactor * m_metresMinWidth); if (rect.SizeX() < minSizeX && rect.SizeY() < minSizeY) rect.SetSizes(minSizeX, minSizeY); @@ -896,9 +898,9 @@ void FrameWork::AddRedrawCommandSure() m2::RectD clipRect = m_navigator.Screen().ClipRect(); - double const xMinSize = 6 * max(m_locationState.ErrorRadius(), + double const xMinSize = theMetersFactor * max(m_locationState.ErrorRadius(), MercatorBounds::ConvertMetresToX(pt.x, m_metresMinWidth)); - double const yMinSize = 6 * max(m_locationState.ErrorRadius(), + double const yMinSize = theMetersFactor * max(m_locationState.ErrorRadius(), MercatorBounds::ConvertMetresToY(pt.y, m_metresMinWidth)); bool needToScale = false; @@ -908,8 +910,8 @@ void FrameWork::AddRedrawCommandSure() else needToScale = clipRect.SizeY() > yMinSize * 3; -/* if ((ClipRect.SizeX() < 3 * errorRadius) || (ClipRect.SizeY() < 3 * errorRadius)) - needToScale = true;*/ + //if ((ClipRect.SizeX() < 3 * errorRadius) || (ClipRect.SizeY() < 3 * errorRadius)) + // needToScale = true; if (needToScale) { diff --git a/map/framework.hpp b/map/framework.hpp index 7d266a3d58..e9156d866a 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -246,7 +246,7 @@ public: /// respond to device orientation changes void SetOrientation(EOrientation orientation); - int GetCurrentScale() const; + double GetCurrentScale() const; /// Actual rendering function. /// Called, as the renderQueue processes RenderCommand diff --git a/qt/draw_widget.cpp b/qt/draw_widget.cpp index 7cd02022e1..a460f458fd 100644 --- a/qt/draw_widget.cpp +++ b/qt/draw_widget.cpp @@ -1,12 +1,12 @@ #include "draw_widget.hpp" #include "proxystyle.hpp" +#include "slider_ctrl.hpp" #include "../storage/storage.hpp" #include "../map/settings.hpp" #include -#include #include "../base/start_mem_debug.hpp" @@ -32,7 +32,7 @@ namespace qt m_framework.PrepareToShutdown(); } - void DrawWidget::SetScaleControl(QSlider * pScale) + void DrawWidget::SetScaleControl(QScaleSlider * pScale) { m_pScale = pScale; @@ -52,12 +52,9 @@ namespace qt m_framework.OnSize(widthAndHeight.first, widthAndHeight.second); - bool res = m_framework.LoadState(); - -// m_framework.UpdateNow(); - - if (!res) + if (!m_framework.LoadState()) return false; + //m_framework.UpdateNow(); UpdateScaleControl(); return true; @@ -154,12 +151,10 @@ namespace qt { if (action != QAbstractSlider::SliderNoAction) { - int const oldV = m_pScale->value(); - int const newV = m_pScale->sliderPosition(); - if (oldV != newV) + double const factor = m_pScale->GetScaleFactor(); + if (factor != 1.0) { - double const factor = 1 << abs(oldV - newV); - m_framework.Scale(newV > oldV ? factor : 1.0 / factor); + m_framework.Scale(factor); emit ViewportChanged(); } } @@ -281,13 +276,7 @@ namespace qt if (m_pScale) { // don't send ScaleChanged - - bool const b = m_pScale->signalsBlocked(); - m_pScale->blockSignals(true); - - m_pScale->setSliderPosition(m_framework.GetCurrentScale()); - - m_pScale->blockSignals(b); + m_pScale->SetPosWithBlockedSignals(m_framework.GetCurrentScale()); } } diff --git a/qt/draw_widget.hpp b/qt/draw_widget.hpp index aaea3b482d..ce50b65ddc 100644 --- a/qt/draw_widget.hpp +++ b/qt/draw_widget.hpp @@ -15,10 +15,10 @@ namespace storage { class Storage; } -class QSlider; - namespace qt { + class QScaleSlider; + /// Replace this to set a draw widget kernel. typedef GLDrawWidget widget_type; @@ -61,7 +61,7 @@ namespace qt public: DrawWidget(QWidget * pParent, storage::Storage & storage); - void SetScaleControl(QSlider * pScale); + void SetScaleControl(QScaleSlider * pScale); void OnEnableMyPosition(LocationRetrievedCallbackT observer); void OnDisableMyPosition(); @@ -101,6 +101,6 @@ namespace qt void UpdateScaleControl(); void StopDragging(QMouseEvent * e); - QSlider * m_pScale; + QScaleSlider * m_pScale; }; } diff --git a/qt/mainwindow.cpp b/qt/mainwindow.cpp index fee6b95de8..0d509c4968 100644 --- a/qt/mainwindow.cpp +++ b/qt/mainwindow.cpp @@ -260,8 +260,8 @@ void MainWindow::CreateNavigationBar() } // add scale slider - QClickSlider * pScale = new QClickSlider(Qt::Vertical, this); - pScale->setRange(3, scales::GetUpperScale()); + QScaleSlider * pScale = new QScaleSlider(Qt::Vertical, this, 20); + pScale->SetRange(2, scales::GetUpperScale()); pScale->setTickPosition(QSlider::TicksRight); pToolBar->addWidget(pScale); diff --git a/qt/slider_ctrl.cpp b/qt/slider_ctrl.cpp index 7113c94c52..12024a7676 100644 --- a/qt/slider_ctrl.cpp +++ b/qt/slider_ctrl.cpp @@ -3,13 +3,19 @@ #include "slider_ctrl.hpp" #include "proxystyle.hpp" +#include "../base/math.hpp" + #include "../base/start_mem_debug.hpp" namespace qt { - QClickSlider::QClickSlider(Qt::Orientation orient, QWidget * pParent) - : QSlider(orient, pParent) + /////////////////////////////////////////////////////////////////////////////////////////////// + // QClickSmoothSlider implementation + /////////////////////////////////////////////////////////////////////////////////////////////// + + QClickSmoothSlider::QClickSmoothSlider(Qt::Orientation orient, QWidget * pParent, int factor) + : base_t(orient, pParent), m_factor(factor) { // this style cause slider to set value exactly to the cursor position (not "page scroll") class MyProxyStyle : public ProxyStyle @@ -29,9 +35,46 @@ namespace qt setStyle(new MyProxyStyle(style())); } - QClickSlider::~QClickSlider() + QClickSmoothSlider::~QClickSmoothSlider() { QStyle * p = style(); delete p; } + + void QClickSmoothSlider::SetRange(int low, int up) + { + setRange(low * m_factor, up * m_factor); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + // QScaleSlider implementation + /////////////////////////////////////////////////////////////////////////////////////////////// + + QScaleSlider::QScaleSlider(Qt::Orientation orient, QWidget * pParent, int factor) + : base_t(orient, pParent, factor) + { + } + + double QScaleSlider::GetScaleFactor() const + { + double const oldV = value(); + double const newV = sliderPosition(); + + if (oldV != newV) + { + double const f = pow(2, fabs(oldV - newV) / m_factor); + return (newV > oldV ? f : 1.0 / f); + } + else return 1.0; + } + + void QScaleSlider::SetPosWithBlockedSignals(double pos) + { + bool const b = signalsBlocked(); + blockSignals(true); + + setSliderPosition(my::rounds(pos * m_factor)); + + blockSignals(b); + } } diff --git a/qt/slider_ctrl.hpp b/qt/slider_ctrl.hpp index d29da6274f..2928535a41 100644 --- a/qt/slider_ctrl.hpp +++ b/qt/slider_ctrl.hpp @@ -4,10 +4,28 @@ namespace qt { - class QClickSlider : public QSlider + class QClickSmoothSlider : public QSlider { + typedef QSlider base_t; + + protected: + int m_factor; + public: - QClickSlider(Qt::Orientation orient, QWidget * pParent); - virtual ~QClickSlider(); + QClickSmoothSlider(Qt::Orientation orient, QWidget * pParent, int factor); + virtual ~QClickSmoothSlider(); + + void SetRange(int low, int up); + }; + + class QScaleSlider : public QClickSmoothSlider + { + typedef QClickSmoothSlider base_t; + + public: + QScaleSlider(Qt::Orientation orient, QWidget * pParent, int factor); + + double GetScaleFactor() const; + void SetPosWithBlockedSignals(double pos); }; }