Make smooth scale control.

This commit is contained in:
vng 2011-06-12 11:39:49 +03:00 committed by Alex Zolotarev
parent c566cde6fc
commit 1f90697f1a
7 changed files with 95 additions and 43 deletions

View file

@ -719,7 +719,7 @@ void FrameWork<TModel>::AddRedrawCommandSure()
}
template <typename TModel>
int FrameWork<TModel>::GetCurrentScale() const
double FrameWork<TModel>::GetCurrentScale() const
{
m2::PointD textureCenter(m_renderQueue.renderState().m_textureWidth / 2,
m_renderQueue.renderState().m_textureHeight / 2);
@ -729,7 +729,7 @@ void FrameWork<TModel>::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<TModel>::AddRedrawCommandSure()
template <typename TModel>
void FrameWork<TModel>::Paint(shared_ptr<PaintEvent> 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<TModel>::AddRedrawCommandSure()
UpdateNow();
}
int const theMetersFactor = 6;
template <typename TModel>
void FrameWork<TModel>::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<TModel>::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<TModel>::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)
{

View file

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

View file

@ -1,12 +1,12 @@
#include "draw_widget.hpp"
#include "proxystyle.hpp"
#include "slider_ctrl.hpp"
#include "../storage/storage.hpp"
#include "../map/settings.hpp"
#include <QtGui/QMouseEvent>
#include <QtGui/QSlider>
#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());
}
}

View file

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

View file

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

View file

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

View file

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