CheckBorders fixes. #closes 168

This commit is contained in:
rachytski 2011-03-31 00:34:32 +03:00 committed by Alex Zolotarev
parent 7080ee4e0b
commit b7942c0c9c
3 changed files with 78 additions and 15 deletions

View file

@ -43,6 +43,7 @@ void ScreenBase::UpdateDependentParameters()
m_GtoP = math::Inverse(m_PtoG);
PtoG(m_PixelRect, m_ClipRect);
PtoG(m_PixelRect, m_GlobalRect);
}
void ScreenBase::SetFromRect(m2::RectD const & GlobalRect)

View file

@ -74,6 +74,56 @@ bool Navigator::LoadState()
void Navigator::OnSize(int x0, int y0, int w, int h)
{
m_Screen.OnSize(x0, y0, w, h);
m2::RectD globalRect = m_Screen.GlobalRect();
m2::RectD tmpRect = globalRect;
/// trying to shift global rect a bit
if (globalRect.minX() < MercatorBounds::minX)
{
globalRect.Offset(m2::PointD(MercatorBounds::minX - globalRect.minX(), 0));
if (globalRect.maxX() > MercatorBounds::maxX)
{
double k = (globalRect.Center().x - MercatorBounds::maxX) / (globalRect.Center().x - globalRect.maxX());
globalRect.Scale(k);
}
}
if (globalRect.maxX() > MercatorBounds::maxX)
{
globalRect.Offset(m2::PointD(MercatorBounds::maxX - globalRect.maxX(), 0));
if (globalRect.minX() < MercatorBounds::minX)
{
double k = (globalRect.Center().x - MercatorBounds::minX) / (globalRect.Center().x - globalRect.minX());
globalRect.Scale(k);
}
}
if (globalRect.minY() < MercatorBounds::minY)
{
globalRect.Offset(m2::PointD(MercatorBounds::minY - globalRect.minY(), 0));
if (globalRect.maxY() > MercatorBounds::maxY)
{
double k = (globalRect.Center().y - MercatorBounds::maxY) / (globalRect.Center().y - globalRect.maxY());
globalRect.Scale(k);
}
}
if (globalRect.maxY() > MercatorBounds::maxY)
{
globalRect.Offset(m2::PointD(MercatorBounds::maxY - globalRect.maxY(), 0));
if (globalRect.minY() < MercatorBounds::minY)
{
double k = (globalRect.Center().y - MercatorBounds::minY) / (globalRect.Center().y - globalRect.minY());
globalRect.Scale(k);
}
}
m_Screen.SetFromRect(globalRect);
if (!m_InAction)
m_StartScreen.OnSize(x0, y0, w, h);
}
@ -94,12 +144,28 @@ void Navigator::DoDrag(m2::PointD const & pt, double /*timeInSec*/)
//m_Screen = m_StartScreen;
ScreenBase tmp = m_StartScreen;
tmp.Move(pt.x - m_StartPt1.x, pt.y - m_StartPt1.y);
int dx = pt.x - m_StartPt1.x;
int dy = pt.y - m_StartPt1.y;
tmp.Move(dx, 0);
if (!CheckBorders(tmp))
dx = 0;
tmp = m_StartScreen;
tmp.Move(0, dy);
if (!CheckBorders(tmp))
dy = 0;
tmp = m_StartScreen;
tmp.Move(dx, dy);
if (CheckBorders(tmp))
{
m_StartScreen = tmp;
m_StartPt1 = pt;
m_LastPt1 = pt;
m_Screen = tmp;
m_LastPt1 = pt;
}
}
void Navigator::StopDrag(m2::PointD const & pt, double timeInSec, bool /*animate*/)
@ -108,7 +174,7 @@ void Navigator::StopDrag(m2::PointD const & pt, double timeInSec, bool /*animate
// Ensure that final pos is reached.
DoDrag(pt, timeInSec);
ASSERT(m_LastPt1 == pt, (m_LastPt1.x, m_LastPt1.y, pt.x, pt.y));
//ASSERT(m_LastPt1 == pt, (m_LastPt1.x, m_LastPt1.y, pt.x, pt.y));
//LOG(LDEBUG, (pt.x, pt.y));
m_InAction = false;
// m_StartScreen = m_Screen;
@ -182,18 +248,17 @@ bool Navigator::CheckMinScale(ScreenBase const & screen)
bool Navigator::CheckBorders(ScreenBase const & screen)
{
m2::RectD WorldBoundsRect(MercatorBounds::minX, MercatorBounds::minY,
MercatorBounds::maxX, MercatorBounds::maxY);
m2::RectD ScreenBounds = screen.GlobalRect();
m2::PointD ScreenCenter = screen.GlobalRect().Center();
m2::PointD WorldCenter = WorldBoundsRect.Center();
m2::RectD WorldBounds(MercatorBounds::minX, MercatorBounds::minY,
MercatorBounds::maxX, MercatorBounds::maxY);
return ScreenCenter.Length(WorldCenter) < WorldBoundsRect.LeftTop().Length(WorldCenter);
return ScreenBounds.IsRectInside(WorldBounds) || WorldBounds.IsRectInside(ScreenBounds);
}
bool Navigator::ScaleImpl(m2::PointD const & newPt1, m2::PointD const & newPt2,
m2::PointD const & oldPt1, m2::PointD const & oldPt2,
bool skipMaxScaleCheck)
bool skipMaxScaleAndBordersCheck)
{
math::Matrix<double, 3, 3> newM = m_Screen.GtoPMatrix() * ScreenBase::CalcTransform(oldPt1, oldPt2, newPt1, newPt2);
@ -201,15 +266,12 @@ bool Navigator::ScaleImpl(m2::PointD const & newPt1, m2::PointD const & newPt2,
tmp.SetGtoPMatrix(newM);
tmp.Rotate(tmp.GetAngle());
if ((!skipMaxScaleCheck) && (!CheckMaxScale(tmp)))
if ((!skipMaxScaleAndBordersCheck) && (!CheckMaxScale(tmp) || !CheckBorders(tmp)))
return false;
if (!CheckMinScale(tmp))
return false;
if (!CheckBorders(tmp))
return false;
m_Screen = tmp;
return true;

View file

@ -94,7 +94,7 @@ private:
// Device orientation
EOrientation m_orientation;
// Used in DoScale and ScaleByPoint
bool ScaleImpl(m2::PointD const & newPt1, m2::PointD const & newPt2, m2::PointD const & oldPt1, m2::PointD const & oldPt2, bool skipMaxScaleCheck);
bool ScaleImpl(m2::PointD const & newPt1, m2::PointD const & newPt2, m2::PointD const & oldPt1, m2::PointD const & oldPt2, bool skipMaxScaleAndBordersCheck);
};
#include "../base/stop_mem_debug.hpp"