Moved zoom limits and area boundaries handling to VIEW.

This commit is contained in:
Maciej Suminski 2015-05-18 13:48:13 +02:00
parent 01c9f09833
commit 4026cb6c58
5 changed files with 86 additions and 96 deletions

View File

@ -42,11 +42,13 @@ using namespace KIGFX;
VIEW::VIEW( bool aIsDynamic ) :
m_enableOrderModifier( true ),
m_scale( 1.0 ),
m_scale( 4.0 ),
m_minScale( 4.0 ), m_maxScale( 15000 ),
m_painter( NULL ),
m_gal( NULL ),
m_dynamic( aIsDynamic )
{
m_boundary.SetMaximum();
m_needsUpdate.reserve( 32768 );
// Redraw everything at the beginning
@ -298,13 +300,19 @@ void VIEW::SetScale( double aScale, const VECTOR2D& aAnchor )
{
VECTOR2D a = ToScreen( aAnchor );
m_gal->SetZoomFactor( aScale );
if( aScale < m_minScale )
m_scale = m_minScale;
else if( aScale > m_maxScale )
m_scale = m_maxScale;
else
m_scale = aScale;
m_gal->SetZoomFactor( m_scale );
m_gal->ComputeWorldScreenMatrix();
VECTOR2D delta = ToWorld( a ) - aAnchor;
SetCenter( m_center - delta );
m_scale = aScale;
// Redraw everything after the viewport has changed
MarkDirty();
@ -315,6 +323,19 @@ void VIEW::SetCenter( const VECTOR2D& aCenter )
{
m_center = aCenter;
if( !m_boundary.Contains( aCenter ) )
{
if( m_center.x < m_boundary.GetLeft() )
m_center.x = m_boundary.GetLeft();
else if( aCenter.x > m_boundary.GetRight() )
m_center.x = m_boundary.GetRight();
if( m_center.y < m_boundary.GetTop() )
m_center.y = m_boundary.GetTop();
else if( m_center.y > m_boundary.GetBottom() )
m_center.y = m_boundary.GetBottom();
}
m_gal->SetLookAtPoint( m_center );
m_gal->ComputeWorldScreenMatrix();

View File

@ -35,38 +35,3 @@ void VIEW_CONTROLS::ShowCursor( bool aEnabled )
m_view->GetGAL()->SetCursorEnabled( aEnabled );
}
void VIEW_CONTROLS::setCenter( const VECTOR2D& aCenter )
{
if( !m_panBoundary.Contains( aCenter ) )
{
VECTOR2D newCenter( aCenter );
if( aCenter.x < m_panBoundary.GetLeft() )
newCenter.x = m_panBoundary.GetLeft();
else if( aCenter.x > m_panBoundary.GetRight() )
newCenter.x = m_panBoundary.GetRight();
if( aCenter.y < m_panBoundary.GetTop() )
newCenter.y = m_panBoundary.GetTop();
else if( aCenter.y > m_panBoundary.GetBottom() )
newCenter.y = m_panBoundary.GetBottom();
m_view->SetCenter( newCenter );
}
else
{
m_view->SetCenter( aCenter );
}
}
void VIEW_CONTROLS::setScale( double aScale, const VECTOR2D& aAnchor )
{
if( aScale < m_minScale )
aScale = m_minScale;
else if( aScale > m_maxScale )
aScale = m_maxScale;
m_view->SetScale( aScale, aAnchor );
}

View File

@ -79,7 +79,7 @@ void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent )
VECTOR2D d = m_dragStartPoint - VECTOR2D( aEvent.GetX(), aEvent.GetY() );
VECTOR2D delta = m_view->ToWorld( d, false );
setCenter( m_lookStartPoint + delta );
m_view->SetCenter( m_lookStartPoint + delta );
aEvent.StopPropagation();
}
else
@ -109,7 +109,7 @@ void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& aEvent )
VECTOR2D delta( aEvent.ControlDown() ? -scrollSpeed : 0.0,
aEvent.ShiftDown() ? -scrollSpeed : 0.0 );
setCenter( m_view->GetCenter() + delta );
m_view->SetCenter( m_view->GetCenter() + delta );
}
else
{
@ -150,7 +150,7 @@ void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& aEvent )
}
VECTOR2D anchor = m_view->ToWorld( VECTOR2D( aEvent.GetX(), aEvent.GetY() ) );
setScale( m_view->GetScale() * zoomScale, anchor );
m_view->SetScale( m_view->GetScale() * zoomScale, anchor );
}
aEvent.Skip();
@ -249,7 +249,7 @@ void WX_VIEW_CONTROLS::onTimer( wxTimerEvent& aEvent )
dir = dir.Resize( borderSize );
dir = m_view->ToWorld( dir, false );
setCenter( m_view->GetCenter() + dir * m_autoPanSpeed );
m_view->SetCenter( m_view->GetCenter() + dir * m_autoPanSpeed );
// Notify tools that the cursor position has changed in the world coordinates
wxMouseEvent moveEvent( EVT_REFRESH_MOUSE );
@ -280,13 +280,14 @@ void WX_VIEW_CONTROLS::onTimer( wxTimerEvent& aEvent )
void WX_VIEW_CONTROLS::onScroll( wxScrollWinEvent& aEvent )
{
VECTOR2D center = m_view->GetCenter();
const BOX2I& boundary = m_view->GetBoundary();
if( aEvent.GetOrientation() == wxHORIZONTAL )
center.x = (double) aEvent.GetPosition() * m_panBoundary.GetWidth() / m_scrollScale.x + m_panBoundary.GetLeft();
center.x = (double) aEvent.GetPosition() * boundary.GetWidth() / m_scrollScale.x + boundary.GetLeft();
else if( aEvent.GetOrientation() == wxVERTICAL )
center.y = (double) aEvent.GetPosition() * m_panBoundary.GetHeight() / m_scrollScale.y + m_panBoundary.GetTop();
center.y = (double) aEvent.GetPosition() * boundary.GetHeight() / m_scrollScale.y + boundary.GetTop();
VIEW_CONTROLS::setCenter( center );
m_view->SetCenter( center );
m_parentPanel->Refresh();
}
@ -391,9 +392,10 @@ bool WX_VIEW_CONTROLS::handleAutoPanning( const wxMouseEvent& aEvent )
void WX_VIEW_CONTROLS::UpdateScrollbars()
{
const BOX2D viewport = m_view->GetViewport();
const BOX2I& boundary = m_view->GetBoundary();
m_scrollScale.x = 2e3 * m_panBoundary.GetWidth() / viewport.GetWidth();
m_scrollScale.y = 2e3 * m_panBoundary.GetHeight() / viewport.GetHeight();
m_scrollScale.x = 2e3 * boundary.GetWidth() / viewport.GetWidth();
m_scrollScale.y = 2e3 * boundary.GetHeight() / viewport.GetHeight();
// Another example of wxWidgets being broken by design: scroll position is determined by the
// left (or top, if vertical) edge of the slider. Fortunately, slider size seems to be constant
@ -405,6 +407,6 @@ void WX_VIEW_CONTROLS::UpdateScrollbars()
#else
m_scrollScale.x, m_scrollScale.y,
#endif
( viewport.Centre().x - m_panBoundary.GetLeft() ) / m_panBoundary.GetWidth() * m_scrollScale.x,
( viewport.Centre().y - m_panBoundary.GetTop() ) / m_panBoundary.GetHeight() * m_scrollScale.y );
( viewport.Centre().x - boundary.GetLeft() ) / boundary.GetWidth() * m_scrollScale.x,
( viewport.Centre().y - boundary.GetTop() ) / boundary.GetHeight() * m_scrollScale.y );
}

View File

@ -130,7 +130,7 @@ public:
* Returns the GAL this view is using to draw graphical primitives.
* @return Pointer to the currently used GAL instance.
*/
GAL* GetGAL() const
inline GAL* GetGAL() const
{
return m_gal;
}
@ -139,7 +139,7 @@ public:
* Function SetPainter()
* Sets the painter object used by the view for drawing VIEW_ITEMS.
*/
void SetPainter( PAINTER* aPainter )
inline void SetPainter( PAINTER* aPainter )
{
m_painter = aPainter;
}
@ -149,7 +149,7 @@ public:
* Returns the painter object used by the view for drawing VIEW_ITEMS.
* @return Pointer to the currently used Painter instance.
*/
PAINTER* GetPainter() const
inline PAINTER* GetPainter() const
{
return m_painter;
}
@ -182,7 +182,7 @@ public:
* (depending on correct GAL unit length & DPI settings).
* @param aScale: the scalefactor
*/
void SetScale( double aScale )
inline void SetScale( double aScale )
{
SetScale( aScale, m_center );
}
@ -198,13 +198,46 @@ public:
/**
* Function GetScale()
* @return Current scalefactor of this VIEW
* @return Current scale factor of this VIEW.
*/
double GetScale() const
inline double GetScale() const
{
return m_scale;
}
/**
* Function SetBoundary()
* Sets limits for view area.
* @param aBoundary is the box that limits view area.
*/
inline void SetBoundary( const BOX2I& aBoundary )
{
m_boundary = aBoundary;
}
/**
* Function GetBoundary()
* @return Current view area boundary.
*/
inline const BOX2I& GetBoundary() const
{
return m_boundary;
}
/**
* Function SetScaleLimits()
* Sets minimum and maximum values for scale.
* @param aMaximum is the maximum value for scale.
* @param aMinimum is the minimum value for scale.
*/
void SetScaleLimits( double aMaximum, double aMinimum )
{
wxASSERT_MSG( aMaximum > aMinimum, wxT( "I guess you passed parameters in wrong order" ) );
m_minScale = aMinimum;
m_maxScale = aMaximum;
}
/**
* Function SetCenter()
* Sets the center point of the VIEW (i.e. the point in world space that will be drawn in the middle
@ -656,6 +689,15 @@ private:
/// Scale of displayed VIEW_ITEMs
double m_scale;
/// View boundaries
BOX2I m_boundary;
/// Scale lower limit
double m_minScale;
/// Scale upper limit
double m_maxScale;
/// PAINTER contains information how do draw items
PAINTER* m_painter;

View File

@ -46,41 +46,16 @@ class VIEW;
class VIEW_CONTROLS
{
public:
VIEW_CONTROLS( VIEW* aView ) : m_view( aView ), m_minScale( 4.0 ), m_maxScale( 15000 ),
VIEW_CONTROLS( VIEW* aView ) : m_view( aView ),
m_forceCursorPosition( false ), m_cursorCaptured( false ), m_snappingEnabled( false ),
m_grabMouse( false ), m_autoPanEnabled( false ), m_autoPanMargin( 0.1 ),
m_autoPanSpeed( 0.15 )
{
m_panBoundary.SetMaximum();
}
virtual ~VIEW_CONTROLS()
{}
/**
* Function SetPanBoundary()
* Sets limits for panning area.
* @param aBoundary is the box that limits panning area.
*/
void SetPanBoundary( const BOX2I& aBoundary )
{
m_panBoundary = aBoundary;
}
/**
* Function SetScaleLimits()
* Sets minimum and maximum values for scale.
* @param aMaximum is the maximum value for scale.
* @param aMinimum is the minimum value for scale.
*/
void SetScaleLimits( double aMaximum, double aMinimum )
{
wxASSERT_MSG( aMaximum > aMinimum, wxT( "I guess you passed parameters in wrong order" ) );
m_minScale = aMinimum;
m_maxScale = aMaximum;
}
/**
* Function SetSnapping()
* Enables/disables snapping cursor to grid.
@ -187,24 +162,9 @@ public:
}
protected:
/// Sets center for VIEW, takes into account panning boundaries.
void setCenter( const VECTOR2D& aCenter );
/// Sets scale for VIEW, takes into account scale limits.
void setScale( double aScale, const VECTOR2D& aAnchor );
/// Pointer to controlled VIEW.
VIEW* m_view;
/// Panning boundaries.
BOX2I m_panBoundary;
/// Scale lower limit.
double m_minScale;
/// Scale upper limit.
double m_maxScale;
/// Current cursor position
VECTOR2D m_cursorPosition;