diff options
Diffstat (limited to 'include/view')
-rw-r--r-- | include/view/view.h | 721 | ||||
-rw-r--r-- | include/view/view_controls.h | 269 | ||||
-rw-r--r-- | include/view/view_group.h | 205 | ||||
-rw-r--r-- | include/view/view_item.h | 356 | ||||
-rw-r--r-- | include/view/view_rtree.h | 92 | ||||
-rw-r--r-- | include/view/wx_view_controls.h | 153 |
6 files changed, 1796 insertions, 0 deletions
diff --git a/include/view/view.h b/include/view/view.h new file mode 100644 index 0000000..e26562e --- /dev/null +++ b/include/view/view.h @@ -0,0 +1,721 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2013 CERN + * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __VIEW_H +#define __VIEW_H + +#include <vector> +#include <set> +#include <boost/unordered/unordered_map.hpp> + +#include <math/box2.h> +#include <gal/definitions.h> + +namespace KIGFX +{ +class PAINTER; +class GAL; +class VIEW_ITEM; +class VIEW_GROUP; +class VIEW_RTREE; + +/** + * Class VIEW. + * Holds a (potentially large) number of VIEW_ITEMs and renders them on a graphics device + * provided by the GAL. VIEWs can exist in two flavors: + * - dynamic - where items can be added, removed or changed anytime, intended for the main + * editing panel. Each VIEW_ITEM can be added to a single dynamic view. + * - static - where items are added once at the startup and are not linked with the VIEW. + * Foreseen for preview windows and printing. + * Items in a view are grouped in layers (not to be confused with Kicad's PCB layers). Each layer is + * identified by an integer number. Visibility and rendering order can be set individually for each + * of the layers. Future versions of the VIEW will also allow to assign different layers to different + * rendering targets, which will be composited at the final stage by the GAL. + * The VIEW class also provides fast methods for finding all visible objects that are within a given + * rectangular area, useful for object selection/hit testing. + */ +class VIEW +{ +public: + friend class VIEW_ITEM; + + typedef std::pair<VIEW_ITEM*, int> LAYER_ITEM_PAIR; + + /** + * Constructor. + * @param aIsDynamic decides whether we are creating a static or a dynamic VIEW. + */ + VIEW( bool aIsDynamic = true ); + + ~VIEW(); + + /** + * Function Add() + * Adds a VIEW_ITEM to the view. + * @param aItem: item to be added. No ownership is given + */ + void Add( VIEW_ITEM* aItem ); + + /** + * Function Remove() + * Removes a VIEW_ITEM from the view. + * @param aItem: item to be removed. Caller must dispose the removed item if necessary + */ + void Remove( VIEW_ITEM* aItem ); + + /** + * Function Query() + * Finds all visible items that touch or are within the rectangle aRect. + * @param aRect area to search for items + * @param aResult result of the search, containing VIEW_ITEMs associated with their layers. + * Sorted according to the rendering order (items that are on top of the rendering stack as + * first). + * @return Number of found items. + */ + int Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) const; + + /** + * Function SetRequired() + * Marks the aRequiredId layer as required for the aLayerId layer. In order to display the + * layer, all of its required layers have to be enabled. + * @param aLayerId is the id of the layer for which we enable/disable the required layer. + * @param aRequiredId is the id of the required layer. + * @param aRequired tells if the required layer should be added or removed from the list. + */ + void SetRequired( int aLayerId, int aRequiredId, bool aRequired = true ); + + /** + * Function CopySettings() + * Copies layers and visibility settings from another view. + * @param aOtherView: view from which settings will be copied. + */ + void CopySettings( const VIEW* aOtherView ); + + /* + * Convenience wrappers for adding multiple items + * template <class T> void AddItems( const T& aItems ); + * template <class T> void RemoveItems( const T& aItems ); + */ + + /** + * Function SetGAL() + * Assigns a rendering device for the VIEW. + * @param aGal: pointer to the GAL output device + */ + void SetGAL( GAL* aGal ); + + /** + * Function GetGAL() + * Returns the GAL this view is using to draw graphical primitives. + * @return Pointer to the currently used GAL instance. + */ + inline GAL* GetGAL() const + { + return m_gal; + } + + /** + * Function SetPainter() + * Sets the painter object used by the view for drawing VIEW_ITEMS. + */ + inline void SetPainter( PAINTER* aPainter ) + { + m_painter = aPainter; + } + + /** + * Function GetPainter() + * Returns the painter object used by the view for drawing VIEW_ITEMS. + * @return Pointer to the currently used Painter instance. + */ + inline PAINTER* GetPainter() const + { + return m_painter; + } + + /** + * Function SetViewport() + * Sets the visible area of the VIEW. + * @param aViewport: desired visible area, in world space coordinates. + */ + void SetViewport( const BOX2D& aViewport ); + + /** + * Function GetViewport() + * Returns the current viewport visible area rectangle. + * @return Current viewport rectangle + */ + BOX2D GetViewport() const; + + /** + * Function SetMirror() + * Controls the mirroring of the VIEW. + * @param aMirrorX: when true, the X axis is mirrored + * @param aMirrorY: when true, the Y axis is mirrored. + */ + void SetMirror( bool aMirrorX, bool aMirrorY ); + + /** + * Function SetScale() + * Sets the scaling factor. Scale = 1 corresponds to the real world size of the objects + * (depending on correct GAL unit length & DPI settings). + * @param aScale: the scalefactor + */ + inline void SetScale( double aScale ) + { + SetScale( aScale, m_center ); + } + + /** + * Function SetScale() + * Sets the scaling factor, zooming around a given anchor point. + * (depending on correct GAL unit length & DPI settings). + * @param aAnchor: the zooming anchor point + * @param aScale: the scale factor + */ + void SetScale( double aScale, const VECTOR2D& aAnchor ); + + /** + * Function GetScale() + * @return Current scale factor of this VIEW. + */ + 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 + * of the screen). + * @param aCenter: the new center point, in world space coordinates. + */ + void SetCenter( const VECTOR2D& aCenter ); + + /** + * Function GetCenter() + * Returns the center point of this VIEW (in world space coordinates) + * @return center point of the view + */ + const VECTOR2D& GetCenter() const + { + return m_center; + } + + /** + * Function ToWorld() + * Converts a screen space point/vector to a point/vector in world space coordinates. + * @param aCoord: the point/vector to be converted + * @param aAbsolute: when true, aCoord is treated as a point, otherwise - as a direction (vector) + */ + VECTOR2D ToWorld( const VECTOR2D& aCoord, bool aAbsolute = true ) const; + + /** + * Function ToWorld() + * Converts a screen space one dimensional size to a one dimensional size in world + * space coordinates. + * @param aSize : the size to be converted + */ + double ToWorld( double aSize ) const; + + /** + * Function ToScreen() + * Converts a world space point/vector to a point/vector in screen space coordinates. + * @param aCoord: the point/vector to be converted + * @param aAbsolute: when true, aCoord is treated as a point, otherwise - as a direction (vector) + */ + VECTOR2D ToScreen( const VECTOR2D& aCoord, bool aAbsolute = true ) const; + + /** + * Function ToScreen() + * Converts a world space one dimensionsal size to a one dimensional size in screen space. + * @param aCoord: the size to be transformed. + */ + double ToScreen( double aSize ) const; + + /** + * Function GetScreenPixelSize() + * Returns the size of the our rendering area, in pixels. + * @return viewport screen size + */ + const VECTOR2I& GetScreenPixelSize() const; + + /** + * Function AddLayer() + * Adds a new layer to the view. + * @param aLayer: unique ID of the layer to be added. + * @param aDisplayOnly: layer is display-only (example: selection boxes, floating hints/menus). + * Objects belonging to this layer are not taken into account by Query() method. + */ + void AddLayer( int aLayer, bool aDisplayOnly = false ); + + /** + * Function ClearLayer() + * Removes all items from a given layer. + * @param aLayer: ID of the layer to be cleared + */ + void ClearLayer( int aLayer ); + + /** + * Function Clear() + * Removes all items from the view. + */ + void Clear(); + + /** + * Function SetLayerVisible() + * Controls the visibility of a particular layer. + * @param aLayer: the layer to show/hide. + * @param aVisible: the obvious. + */ + inline void SetLayerVisible( int aLayer, bool aVisible = true ) + { + wxASSERT( aLayer < (int) m_layers.size() ); + + if( m_layers[aLayer].visible != aVisible ) + { + // Target has to be redrawn after changing its visibility + MarkTargetDirty( m_layers[aLayer].target ); + m_layers[aLayer].visible = aVisible; + } + } + + /** + * Function IsLayerVisible() + * Returns information about visibility of a particular layer. + * @param aLayer: true if the layer is visible, false otherwise + */ + inline bool IsLayerVisible( int aLayer ) const + { + wxASSERT( aLayer < (int) m_layers.size() ); + + return m_layers.at( aLayer ).visible; + } + + inline void SetLayerDisplayOnly( int aLayer, bool aDisplayOnly = true ) + { + wxASSERT( aLayer < (int) m_layers.size() ); + + m_layers[aLayer].displayOnly = aDisplayOnly; + } + + /** + * Function SetLayerTarget() + * Changes the rendering target for a particular layer. + * @param aLayer is the layer. + * @param aTarget is the rendering target. + */ + inline void SetLayerTarget( int aLayer, RENDER_TARGET aTarget ) + { + wxASSERT( aLayer < (int) m_layers.size() ); + + m_layers[aLayer].target = aTarget; + } + + /** + * Function SetLayerOrder() + * Sets rendering order of a particular layer. Lower values are rendered first. + * @param aLayer: the layer + * @param aRenderingOrder: arbitrary number denoting the rendering order. + */ + void SetLayerOrder( int aLayer, int aRenderingOrder ); + + /** + * Function GetLayerOrder() + * Returns rendering order of a particular layer. Lower values are rendered first. + * @param aLayer: the layer + * @return Rendering order of a particular layer. + */ + int GetLayerOrder( int aLayer ) const; + + /** + * Function SortLayers() + * Changes the order of given layer ids, so after sorting the order corresponds to layers + * rendering order (descending, ie. order in which layers should be drawn - from the bottom to + * the top). + * @param aLayers stores id of layers to be sorted. + * @param aCount stores the number of layers. + */ + void SortLayers( int aLayers[], int& aCount ) const; + + /** + * Function UpdateLayerColor() + * Applies the new coloring scheme held by RENDER_SETTINGS in case that it has changed. + * @param aLayer is a number of the layer to be updated. + * @see RENDER_SETTINGS + */ + void UpdateLayerColor( int aLayer ); + + /** + * Function UpdateAllLayersColor() + * Applies the new coloring scheme to all layers. The used scheme is held by RENDER_SETTINGS. + * @see RENDER_SETTINGS + */ + void UpdateAllLayersColor(); + + /** + * Function ChangeLayerDepth() + * Changes the depth of items on the given layer. + * @param aLayer is a number of the layer to be updated. + * @param aDepth is the new depth. + */ + void ChangeLayerDepth( int aLayer, int aDepth ); + + /** + * Function SetTopLayer() + * Sets given layer to be displayed on the top or sets back the default order of layers. + * @param aLayer: the layer or -1 in case when no particular layer should + * be displayed on the top. + */ + void SetTopLayer( int aLayer, bool aEnabled = true ); + + /** + * Function EnableTopLayer() + * Enables or disables display of the top layer. When disabled - layers are rendered as usual + * with no influence from SetTopLayer function. Otherwise on the top there is displayed the + * layer set previously with SetTopLayer function. + * @param aEnable whether to enable or disable display of the top layer. + */ + void EnableTopLayer( bool aEnable ); + + int GetTopLayer() const; + + /** + * Function ClearTopLayers() + * Removes all layers from the on-the-top set (they are no longer displayed over the rest of + * layers). + */ + void ClearTopLayers(); + + /** + * Function UpdateLayerOrder() + * Does everything that is needed to apply the rendering order of layers. It has to be called + * after modification of renderingOrder field of LAYER. + */ + void UpdateAllLayersOrder(); + + /** + * Function ClearTargets() + * Clears targets that are marked as dirty. + */ + void ClearTargets(); + + /** + * Function Redraw() + * Immediately redraws the whole view. + */ + void Redraw(); + + /** + * Function RecacheAllItems() + * Rebuilds GAL display lists. + * @param aForceNow decides if every item should be instantly recached. Otherwise items are + * going to be recached when they become visible. + */ + void RecacheAllItems( bool aForceNow = false ); + + /** + * Function IsDynamic() + * Tells if the VIEW is dynamic (ie. can be changed, for example displaying PCBs in a window) + * or static (that cannot be modified, eg. displaying image/PDF). + */ + bool IsDynamic() const + { + return m_dynamic; + } + + /** + * Function IsDirty() + * Returns true if any of the VIEW layers needs to be refreshened. + * @return True in case if any of layers is marked as dirty. + */ + bool IsDirty() const + { + for( int i = 0; i < TARGETS_NUMBER; ++i ) + { + if( IsTargetDirty( i ) ) + return true; + } + + return false; + } + + /** + * Function IsTargetDirty() + * Returns true if any of layers belonging to the target or the target itself should be + * redrawn. + * @return True if the above condition is fulfilled. + */ + bool IsTargetDirty( int aTarget ) const + { + wxASSERT( aTarget < TARGETS_NUMBER ); + + return m_dirtyTargets[aTarget]; + } + + /** + * Function MarkTargetDirty() + * Sets or clears target 'dirty' flag. + * @param aTarget is the target to set. + */ + inline void MarkTargetDirty( int aTarget ) + { + wxASSERT( aTarget < TARGETS_NUMBER ); + + m_dirtyTargets[aTarget] = true; + } + + /// Returns true if the layer is cached + inline bool IsCached( int aLayer ) const + { + wxASSERT( aLayer < (int) m_layers.size() ); + + try + { + return m_layers.at( aLayer ).target == TARGET_CACHED; + } + catch( std::out_of_range ) + { + return false; + } + } + + /** + * Function MarkDirty() + * Forces redraw of view on the next rendering. + */ + void MarkDirty() + { + for( int i = 0; i < TARGETS_NUMBER; ++i ) + m_dirtyTargets[i] = true; + } + + /** + * Function MarkForUpdate() + * Adds an item to a list of items that are going to be refreshed upon the next frame rendering. + * @param aItem is the item to be refreshed. + */ + void MarkForUpdate( VIEW_ITEM* aItem ) + { + m_needsUpdate.push_back( aItem ); + } + + /** + * Function UpdateItems() + * Iterates through the list of items that asked for updating and updates them. + */ + void UpdateItems(); + + const BOX2I CalculateExtents() ; + + static const int VIEW_MAX_LAYERS = 256; ///< maximum number of layers that may be shown + +private: + struct VIEW_LAYER + { + bool visible; ///< is the layer to be rendered? + bool displayOnly; ///< is the layer display only? + VIEW_RTREE* items; ///< R-tree indexing all items on this layer. + int renderingOrder; ///< rendering order of this layer + int id; ///< layer ID + RENDER_TARGET target; ///< where the layer should be rendered + std::set<int> requiredLayers; ///< layers that have to be enabled to show the layer + }; + + // Convenience typedefs + typedef boost::unordered_map<int, VIEW_LAYER> LAYER_MAP; + typedef LAYER_MAP::iterator LAYER_MAP_ITER; + typedef std::vector<VIEW_LAYER*> LAYER_ORDER; + typedef std::vector<VIEW_LAYER*>::iterator LAYER_ORDER_ITER; + + // Function objects that need to access VIEW/VIEW_ITEM private/protected members + struct clearLayerCache; + struct recacheItem; + struct drawItem; + struct unlinkItem; + struct updateItemsColor; + struct changeItemsDepth; + struct extentsVisitor; + + + ///* Redraws contents within rect aRect + void redrawRect( const BOX2I& aRect ); + + inline void markTargetClean( int aTarget ) + { + wxASSERT( aTarget < TARGETS_NUMBER ); + + m_dirtyTargets[aTarget] = false; + } + + /** + * Function draw() + * Draws an item, but on a specified layers. It has to be marked that some of drawing settings + * are based on the layer on which an item is drawn. + * + * @param aItem is the item to be drawn. + * @param aLayer is the layer which should be drawn. + * @param aImmediate dictates the way of drawing - it allows to force immediate drawing mode + * for cached items. + */ + void draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate = false ); + + /** + * Function draw() + * Draws an item on all layers that the item uses. + * + * @param aItem is the item to be drawn. + * @param aImmediate dictates the way of drawing - it allows to force immediate drawing mode + * for cached items. + */ + void draw( VIEW_ITEM* aItem, bool aImmediate = false ); + + /** + * Function draw() + * Draws a group of items on all layers that those items use. + * + * @param aGroup is the group to be drawn. + * @param aImmediate dictates the way of drawing - it allows to force immediate drawing mode + * for cached items. + */ + void draw( VIEW_GROUP* aGroup, bool aImmediate = false ); + + ///* Sorts m_orderedLayers when layer rendering order has changed + void sortLayers(); + + ///* Clears cached GAL group numbers (*ONLY* numbers stored in VIEW_ITEMs, not group objects + ///* used by GAL) + void clearGroupCache(); + + /** + * Function invalidateItem() + * Manages dirty flags & redraw queueing when updating an item. + * @param aItem is the item to be updated. + * @param aUpdateFlags determines the way an item is refreshed. + */ + void invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags ); + + /// Updates colors that are used for an item to be drawn + void updateItemColor( VIEW_ITEM* aItem, int aLayer ); + + /// Updates all informations needed to draw an item + void updateItemGeometry( VIEW_ITEM* aItem, int aLayer ); + + /// Updates bounding box of an item + void updateBbox( VIEW_ITEM* aItem ); + + /// Updates set of layers that an item occupies + void updateLayers( VIEW_ITEM* aItem ); + + /// Determines rendering order of layers. Used in display order sorting function. + static bool compareRenderingOrder( VIEW_LAYER* aI, VIEW_LAYER* aJ ) + { + return aI->renderingOrder > aJ->renderingOrder; + } + + /// Checks if every layer required by the aLayerId layer is enabled. + bool areRequiredLayersEnabled( int aLayerId ) const; + + ///* Whether to use rendering order modifier or not + bool m_enableOrderModifier; + + /// Contains set of possible displayed layers and its properties + LAYER_MAP m_layers; + + /// Sorted list of pointers to members of m_layers + LAYER_ORDER m_orderedLayers; + + /// Stores set of layers that are displayed on the top + std::set<unsigned int> m_topLayers; + + /// Center point of the VIEW (the point at which we are looking at) + VECTOR2D m_center; + + /// 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; + + /// Gives interface to PAINTER, that is used to draw items + GAL* m_gal; + + /// Dynamic VIEW (eg. display PCB in window) allows changes once it is built, + /// static (eg. image/PDF) - does not. + bool m_dynamic; + + /// Flags to mark targets as dirty, so they have to be redrawn on the next refresh event + bool m_dirtyTargets[TARGETS_NUMBER]; + + /// Rendering order modifier for layers that are marked as top layers + static const int TOP_LAYER_MODIFIER; + + /// Items to be updated + std::vector<VIEW_ITEM*> m_needsUpdate; +}; +} // namespace KIGFX + +#endif diff --git a/include/view/view_controls.h b/include/view/view_controls.h new file mode 100644 index 0000000..d91a0f2 --- /dev/null +++ b/include/view/view_controls.h @@ -0,0 +1,269 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de + * Copyright (C) 2013 CERN + * Copyright (C) 2013-2016 KiCad Developers, see AUTHORS.txt for contributors. + * + * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +/** + * @file view_controls.h + * @brief VIEW_CONTROLS class definition. + */ + +#ifndef __VIEW_CONTROLS_H +#define __VIEW_CONTROLS_H + +#include <math/box2.h> + +namespace KIGFX +{ +class VIEW; + +/** + * Class VIEW_CONTROLS + * is an interface for classes handling user events controlling the view behaviour + * (such as zooming, panning, mouse grab, etc.) + */ +class VIEW_CONTROLS +{ +public: + 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_warpCursor( false ), m_enableMousewheelPan( false ) + { + } + + virtual ~VIEW_CONTROLS() + {} + + /** + * Function SetSnapping() + * Enables/disables snapping cursor to grid. + * + * @param aEnabled says whether the opion should be enabled or disabled. + */ + virtual void SetSnapping( bool aEnabled ) + { + m_snappingEnabled = aEnabled; + } + + /** + * Function SetGrabMouse + * Turns on/off mouse grabbing. When the mouse is grabbed, it cannot go outside the VIEW. + * @param aEnabled tells if mouse should be grabbed or not. + */ + virtual void SetGrabMouse( bool aEnabled ) + { + m_grabMouse = aEnabled; + } + + /** + * Function SetAutoPan + * Turns on/off auto panning (this feature is used when there is a tool active (eg. drawing a + * track) and user moves mouse to the VIEW edge - then the view can be translated or not). + * @param aEnabled tells if the autopanning should be active. + */ + virtual void SetAutoPan( bool aEnabled ) + { + m_autoPanEnabled = aEnabled; + } + + /** + * Function SetAutoPanSpeed() + * Sets speed of autopanning. + * @param aSpeed is a new speed for autopanning. + */ + virtual void SetAutoPanSpeed( float aSpeed ) + { + m_autoPanSpeed = aSpeed; + } + + /** + * Function SetAutoPanMArgin() + * Sets margin for autopanning (ie. the area when autopanning becomes active). + * @param aMargin is a new margin for autopanning. + */ + virtual void SetAutoPanMargin( float aMargin ) + { + m_autoPanMargin = aMargin; + } + + /** + * Function GetMousePosition() + * Returns the current mouse pointer position in screen coordinates. Note, that it may be + * different from the cursor position if snapping is enabled (@see GetCursorPosition()). + * + * @return The current mouse pointer position in the screen coordinates. + */ + virtual VECTOR2I GetMousePosition() const = 0; + + /** + * Function GetCursorPosition() + * Returns the current cursor position in world coordinates. Note, that it may be + * different from the mouse pointer position if snapping is enabled or cursor position + * is forced to specific point. + * + * @return The current cursor position in world coordinates. + */ + virtual VECTOR2D GetCursorPosition() const = 0; + + /** + * Function ForceCursorPosition() + * Places the cursor immediately at a given point. Mouse movement is ignored. + * @param aEnabled enable forced cursor position + * @param aPosition the position (world coordinates). + */ + virtual void ForceCursorPosition( bool aEnabled, const VECTOR2D& aPosition = VECTOR2D( 0, 0 ) ) + { + m_forcedPosition = aPosition; + m_forceCursorPosition = aEnabled; + } + + /** + * Function ShowCursor() + * Enables or disables display of cursor. + * @param aEnabled decides if the cursor should be shown. + */ + virtual void ShowCursor( bool aEnabled ); + + /** + * Function CaptureCursor() + * Forces the cursor to stay within the drawing panel area. + * @param aEnabled determines if the cursor should be captured. + */ + virtual void CaptureCursor( bool aEnabled ) + { + m_cursorCaptured = aEnabled; + } + + inline bool IsCursorPositionForced() const + { + return m_forceCursorPosition; + } + + /** + * Function WarpCursor() + * If enabled (@see SetEnableCursorWarping(), warps the cursor to the specified position, + * expressed either in the screen coordinates or the world coordinates. + * @param aPosition is the position where the cursor should be warped. + * @param aWorldCoordinates if true treats aPosition as the world coordinates, otherwise it + * uses it as the screen coordinates. + * @param aWarpView determines if the view can be warped too (only matters if the position is + * specified in the world coordinates and its not visible in the current viewport). + */ + virtual void WarpCursor( const VECTOR2D& aPosition, bool aWorldCoordinates = false, + bool aWarpView = false ) const = 0; + + /** + * Function EnableCursorWarping() + * Enables or disables warping the cursor. + * @param aEnabled is true if the cursor is allowed to be warped. + */ + void EnableCursorWarping( bool aEnable ) + { + m_warpCursor = aEnable; + } + + /** + * Function IsCursorWarpingEnabled() + * Returns the current setting for cursor warping. + */ + bool IsCursorWarpingEnabled() const + { + return m_warpCursor; + } + + /** + * Function EnableMousewheelPan() + * Enables or disables mousewheel panning. + * @param aEnabled is true if mouse-wheel panning is enabled. + */ + virtual void EnableMousewheelPan( bool aEnable ) + { + m_enableMousewheelPan = aEnable; + } + + /** + * Function IsMousewheelPanEnabled() + * Returns the current setting for mousewheel panning + */ + virtual bool IsMousewheelPanEnabled() const + { + return m_enableMousewheelPan; + } + + /** + * Function CenterOnCursor() + * Sets the viewport center to the current cursor position and warps the cursor to the + * screen center. + */ + virtual void CenterOnCursor() const = 0; + + /** + * Function Reset() + * Restores the default VIEW_CONTROLS settings. + */ + virtual void Reset(); + +protected: + /// Pointer to controlled VIEW. + VIEW* m_view; + + /// Current cursor position + VECTOR2D m_cursorPosition; + + /// Forced cursor position + VECTOR2D m_forcedPosition; + + /// Is the forced cursor position enabled + bool m_forceCursorPosition; + + /// Should the cursor be locked within the parent window area + bool m_cursorCaptured; + + /// Should the cursor snap to grid or move freely + bool m_snappingEnabled; + + /// Flag for grabbing the mouse cursor + bool m_grabMouse; + + /// Flag for turning on autopanning + bool m_autoPanEnabled; + + /// Distance from cursor to VIEW edge when panning is active + float m_autoPanMargin; + + /// How fast is panning when in auto mode + float m_autoPanSpeed; + + /// If the cursor is allowed to be warped + bool m_warpCursor; + + /// Mousewheel (2-finger touchpad) panning + bool m_enableMousewheelPan; +}; +} // namespace KIGFX + +#endif diff --git a/include/view/view_group.h b/include/view/view_group.h new file mode 100644 index 0000000..2a1ad62 --- /dev/null +++ b/include/view/view_group.h @@ -0,0 +1,205 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2013 CERN + * @author Maciej Suminski <maciej.suminski@cern.ch> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +/** + * @file view_group.h + * @brief VIEW_GROUP extends VIEW_ITEM by possibility of grouping items into a single object. + * VIEW_GROUP does not take over ownership of the held items. The main purpose of this class is + * to group items and draw them on a single layer (in particular the overlay). + */ + +#ifndef VIEW_GROUP_H_ +#define VIEW_GROUP_H_ + +#include <view/view_item.h> +#include <deque> + +namespace KIGFX +{ +class VIEW_GROUP : public VIEW_ITEM +{ +public: + VIEW_GROUP( VIEW* aView = NULL ); + virtual ~VIEW_GROUP(); + + /// Helper typedefs + typedef std::set<VIEW_ITEM*>::const_iterator const_iter; + typedef std::set<VIEW_ITEM*>::iterator iter; + + /** + * Function Add() + * Adds an item to the group. + * + * @param aItem is the item to be added. + */ + virtual void Add( VIEW_ITEM* aItem ); + + /** + * Function Remove() + * Removes an item from the group. + * + * @param aItem is the item to be removed. + */ + virtual void Remove( VIEW_ITEM* aItem ); + + /** + * Function Clear() + * Removes all the stored items from the group. + */ + virtual void Clear(); + + /** + * Function Begin() + * Returns iterator to beginning. + */ + inline const_iter Begin() const + { + return m_items.begin(); + } + + /** + * Function End() + * Returns iterator to end. + */ + inline const_iter End() const + { + return m_items.end(); + } + + /** + * Function GetSize() + * Returns the number of stored items. + * + * @return Number of stored items. + */ + virtual unsigned int GetSize() const; + + /** + * Function ViewBBox() + * Returns the bounding box for all stored items covering all its layers. + * + * @return The current bounding box + */ + virtual const BOX2I ViewBBox() const; + + /** + * Function ViewDraw() + * Draws all the stored items in the group on the given layer. + * + * @param aLayer is the layer which should be drawn. + * @param aGal is the GAL that should be used for drawing. + */ + virtual void ViewDraw( int aLayer, GAL* aGal ) const; + + /** + * Function ViewGetLayers() + * Returns all the layers used by the stored items. + * + * @param aLayers[] is the output layer index array. + * @param aCount is the number of layer indices in aLayers[]. + */ + virtual void ViewGetLayers( int aLayers[], int& aCount ) const; + + /** + * Function SetLayer() + * Sets layer used to draw the group. + * + * @param aLayer is the layer used for drawing. + */ + inline virtual void SetLayer( int aLayer ) + { + m_layer = aLayer; + } + + /** + * Function FreeItems() + * Frees all the items that were added to the group. + */ + void FreeItems(); + + /** + * Function GetView() + * Returns pointer to the VIEW instance used by items. + * + * @return Pointer to the VIEW instance. + */ + KIGFX::VIEW* GetView() const + { + return m_view; + } + + /** + * Function ItemsSetVisibility() + * Sets visibility of items stored in the VIEW_GROUP. + * + * @param aVisible decides if items should be visible or not. + */ + virtual void ItemsSetVisibility( bool aVisible ); + + /** + * Function ItemsViewUpdate() + * Updates items stored in the VIEW_GROUP. + * + * @param aFlags determines the way in which items will be updated. + */ + virtual void ItemsViewUpdate( VIEW_ITEM::VIEW_UPDATE_FLAGS aFlags ); + +protected: + /// These functions cannot be used with VIEW_GROUP as they are intended only to work with + /// singular VIEW_ITEMs (there is only one-to-one relation between item/layer combination and + /// its group). + int getGroup( int aLayer ) const + { + return -1; + } + + std::vector<int> getAllGroups() const + { + return std::vector<int>(); + } + + void setGroup( int aLayer, int aGroup ) + {} + + void deleteGroups() + {} + + bool storesGroups() const + { + return false; + } + + /// Layer on which the group is drawn + int m_layer; + +private: + void updateBbox(); + + /// Container for storing VIEW_ITEMs + std::set<VIEW_ITEM*> m_items; +}; +} // namespace KIGFX + +#endif // VIEW_GROUP_H_ diff --git a/include/view/view_item.h b/include/view/view_item.h new file mode 100644 index 0000000..878c8e7 --- /dev/null +++ b/include/view/view_item.h @@ -0,0 +1,356 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2013 CERN + * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * @file view_item.h + * @brief VIEW_ITEM class definition. + */ + +#ifndef __VIEW_ITEM_H +#define __VIEW_ITEM_H + +#include <vector> +#include <bitset> +#include <math/box2.h> +#include <view/view.h> +#include <gal/definitions.h> + + +namespace KIGFX +{ +// Forward declarations +class GAL; +class PAINTER; + +/** + * Class VIEW_ITEM - + * is an abstract base class for deriving all objects that can be added to a VIEW. + * It's role is to: + * - communicte geometry, appearance and visibility updates to the associated dynamic VIEW, + * - provide a bounding box for redraw area calculation, + * - (optional) draw the object using the GAL API functions for PAINTER-less implementations. + * VIEW_ITEM objects are never owned by a VIEW. A single VIEW_ITEM can belong to any number of + * static VIEWs, but only one dynamic VIEW due to storage of only one VIEW reference. + */ +class VIEW_ITEM +{ +public: + /** + * Enum VIEW_UPDATE_FLAGS. + * Defines the how severely the shape/appearance of the item has been changed: + * - NONE: TODO + * - APPEARANCE: shape or layer set of the item have not been affected, + * only colors or visibility. + * - COLOR: + * - GEOMETRY: shape or layer set of the item have changed, VIEW may need to reindex it. + * - LAYERS: TODO + * - ALL: all the flags above */ + + enum VIEW_UPDATE_FLAGS { + NONE = 0x00, /// No updates are required + APPEARANCE = 0x01, /// Visibility flag has changed + COLOR = 0x02, /// Color has changed + GEOMETRY = 0x04, /// Position or shape has changed + LAYERS = 0x08, /// Layers have changed + ALL = 0xff + }; + + /** + * Enum VIEW_VISIBILITY_FLAGS. + * Defines the visibility of the item (temporarily hidden, invisible, etc). + */ + enum VIEW_VISIBILITY_FLAGS { + VISIBLE = 0x01, /// Item is visible (in general) + HIDDEN = 0x02 /// Item is temporarily hidden (e.g. being used by a tool). Overrides VISIBLE flag. + }; + + VIEW_ITEM() : m_view( NULL ), m_flags( VISIBLE ), m_requiredUpdate( NONE ), + m_groups( NULL ), m_groupsSize( 0 ) {} + + /** + * Destructor. For dynamic views, removes the item from the view. + */ + virtual ~VIEW_ITEM() + { + ViewRelease(); + delete[] m_groups; + } + + /** + * Function ViewBBox() + * returns the bounding box of the item covering all its layers. + * @return BOX2I - the current bounding box + */ + virtual const BOX2I ViewBBox() const = 0; + + /** + * Function ViewDraw() + * Draws the parts of the object belonging to layer aLayer. + * viewDraw() is an alternative way for drawing objects if + * if there is no PAINTER assigned for the view or if the PAINTER + * doesn't know how to paint this particular implementation of + * VIEW_ITEM. The preferred way of drawing is to design an + * appropriate PAINTER object, the method below is intended only + * for quick hacks and debugging purposes. + * + * @param aLayer: current drawing layer + * @param aGal: pointer to the GAL device we are drawing on + */ + virtual void ViewDraw( int aLayer, GAL* aGal ) const + {} + + /** + * Function ViewGetLayers() + * Returns the all the layers within the VIEW the object is painted on. For instance, a D_PAD + * spans zero or more copper layers and a few technical layers. ViewDraw() or PAINTER::Draw() is + * repeatedly called for each of the layers returned by ViewGetLayers(), depending on the + * rendering order. + * @param aLayers[]: output layer index array + * @param aCount: number of layer indices in aLayers[] + */ + virtual void ViewGetLayers( int aLayers[], int& aCount ) const = 0; + + /** + * Function ViewSetVisible() + * Sets the item visibility. + * + * @param aIsVisible: whether the item is visible (on all layers), or not. + */ + void ViewSetVisible( bool aIsVisible = true ) + { + bool cur_visible = m_flags & VISIBLE; + + if( cur_visible != aIsVisible ) + { + if( aIsVisible ) + m_flags |= VISIBLE; + else + m_flags &= ~VISIBLE; + + ViewUpdate( APPEARANCE | COLOR ); + } + } + + /** + * Function ViewHide() + * Temporarily hides the item in the view (e.g. for overlaying) + * + * @param aHide: whether the item is hidden (on all layers), or not. + */ + void ViewHide( bool aHide = true ) + { + if( !( m_flags & VISIBLE ) ) + return; + + if( aHide ) + m_flags |= HIDDEN; + else + m_flags &= ~HIDDEN; + + ViewUpdate( APPEARANCE ); + } + + /** + * Function ViewIsVisible() + * Returns information if the item is visible (or not). + * + * @return when true, the item is visible (i.e. to be displayed, not visible in the + * *current* viewport) + */ + bool ViewIsVisible() const + { + return m_flags & VISIBLE; + } + + /** + * Function ViewGetLOD() + * Returns the level of detail of the item. A level of detail is the minimal VIEW scale that + * is sufficient for an item to be shown on a given layer. + */ + virtual unsigned int ViewGetLOD( int aLayer ) const + { + // By default always show the item + return 0; + } + + /** + * Function ViewUpdate() + * For dynamic VIEWs, informs the associated VIEW that the graphical representation of + * this item has changed. For static views calling has no effect. + * + * @param aUpdateFlags: how much the object has changed. + */ + virtual void ViewUpdate( int aUpdateFlags = ALL ) + { + if( m_view ) + { + assert( aUpdateFlags != NONE ); + + if( m_requiredUpdate == NONE ) + m_view->MarkForUpdate( this ); + + m_requiredUpdate |= aUpdateFlags; + } + } + + /** + * Function ViewRelease() + * Releases the item from an associated dynamic VIEW. For static views calling has no effect. + */ + virtual void ViewRelease(); + +protected: + friend class VIEW; + + /** + * Function getLayers() + * Returns layer numbers used by the item. + * + * @param aLayers[]: output layer index array + * @param aCount: number of layer indices in aLayers[] + */ + virtual void getLayers( int* aLayers, int& aCount ) const; + + /** + * Function viewAssign() + * Assigns the item to a given dynamic VIEW. Called internally by the VIEW. + * + * @param aView[]: dynamic VIEW instance the item is being added to. + */ + virtual void viewAssign( VIEW* aView ) + { + // release the item from a previously assigned dynamic view (if there is any) + ViewRelease(); + m_view = aView; + deleteGroups(); + } + + VIEW* m_view; ///< Current dynamic view the item is assigned to. + int m_flags; ///< Visibility flags + int m_requiredUpdate; ///< Flag required for updating + + ///* Helper for storing cached items group ids + typedef std::pair<int, int> GroupPair; + + ///* Indexes of cached GAL display lists corresponding to the item (for every layer it occupies). + ///* (in the std::pair "first" stores layer number, "second" stores group id). + GroupPair* m_groups; + int m_groupsSize; + + /** + * Function getGroup() + * Returns number of the group id for the given layer, or -1 in case it was not cached before. + * + * @param aLayer is the layer number for which group id is queried. + * @return group id or -1 in case there is no group id (ie. item is not cached). + */ + virtual int getGroup( int aLayer ) const; + + /** + * Function getAllGroups() + * Returns all group ids for the item (collected from all layers the item occupies). + * + * @return vector of group ids. + */ + virtual std::vector<int> getAllGroups() const; + + /** + * Function setGroup() + * Sets a group id for the item and the layer combination. + * + * @param aLayer is the layer numbe. + * @param aGroup is the group id. + */ + virtual void setGroup( int aLayer, int aGroup ); + + /** + * Function deleteGroups() + * Removes all of the stored group ids. Forces recaching of the item. + */ + virtual void deleteGroups(); + + /** + * Function storesGroups() + * Returns information if the item uses at least one group id (ie. if it is cached at all). + * + * @returns true in case it is cached at least for one layer. + */ + inline virtual bool storesGroups() const + { + return m_groupsSize > 0; + } + + /// Stores layer numbers used by the item. + std::bitset<VIEW::VIEW_MAX_LAYERS> m_layers; + + /** + * Function saveLayers() + * Saves layers used by the item. + * + * @param aLayers is an array containing layer numbers to be saved. + * @param aCount is the size of the array. + */ + virtual void saveLayers( int* aLayers, int aCount ) + { + m_layers.reset(); + + for( int i = 0; i < aCount; ++i ) + { + // this fires on some eagle board after EAGLE_PLUGIN::Load() + wxASSERT( unsigned( aLayers[i] ) <= unsigned( VIEW::VIEW_MAX_LAYERS ) ); + + m_layers.set( aLayers[i] ); + } + } + + /** + * Function viewRequiredUpdate() + * Returns current update flag for an item. + */ + virtual int viewRequiredUpdate() const + { + return m_requiredUpdate; + } + + /** + * Function clearUpdateFlags() + * Marks an item as already updated, so it is not going to be redrawn. + */ + void clearUpdateFlags() + { + m_requiredUpdate = NONE; + } + + /** + * Function isRenderable() + * Returns if the item should be drawn or not. + */ + bool isRenderable() const + { + return m_flags == VISIBLE; + } +}; +} // namespace KIGFX + +#endif diff --git a/include/view/view_rtree.h b/include/view/view_rtree.h new file mode 100644 index 0000000..b9ddb58 --- /dev/null +++ b/include/view/view_rtree.h @@ -0,0 +1,92 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2013 CERN + * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __VIEW_RTREE_H +#define __VIEW_RTREE_H + +#include <math/box2.h> + +#include <geometry/rtree.h> + +namespace KIGFX +{ +typedef RTree<VIEW_ITEM*, int, 2, float> VIEW_RTREE_BASE; + +/** + * Class VIEW_RTREE - + * Implements an R-tree for fast spatial indexing of VIEW items. + * Non-owning. + */ +class VIEW_RTREE : public VIEW_RTREE_BASE +{ +public: + + /** + * Function Insert() + * Inserts an item into the tree. Item's bounding box is taken via its ViewBBox() method. + */ + void Insert( VIEW_ITEM* aItem ) + { + const BOX2I& bbox = aItem->ViewBBox(); + const int mmin[2] = { bbox.GetX(), bbox.GetY() }; + const int mmax[2] = { bbox.GetRight(), bbox.GetBottom() }; + + VIEW_RTREE_BASE::Insert( mmin, mmax, aItem ); + } + + /** + * Function Remove() + * Removes an item from the tree. Removal is done by comparing pointers, attepmting to remove a copy + * of the item will fail. + */ + void Remove( VIEW_ITEM* aItem ) + { + // const BOX2I& bbox = aItem->ViewBBox(); + + // FIXME: use cached bbox or ptr_map to speed up pointer <-> node lookups. + const int mmin[2] = { INT_MIN, INT_MIN }; + const int mmax[2] = { INT_MAX, INT_MAX }; + + VIEW_RTREE_BASE::Remove( mmin, mmax, aItem ); + } + + /** + * Function Query() + * Executes a function object aVisitor for each item whose bounding box intersects + * with aBounds. + */ + template <class Visitor> + void Query( const BOX2I& aBounds, Visitor& aVisitor ) // const + { + const int mmin[2] = { aBounds.GetX(), aBounds.GetY() }; + const int mmax[2] = { aBounds.GetRight(), aBounds.GetBottom() }; + + VIEW_RTREE_BASE::Search( mmin, mmax, aVisitor ); + } + +private: +}; +} // namespace KIGFX + +#endif diff --git a/include/view/wx_view_controls.h b/include/view/wx_view_controls.h new file mode 100644 index 0000000..0338e58 --- /dev/null +++ b/include/view/wx_view_controls.h @@ -0,0 +1,153 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de + * Copyright (C) 2013 CERN + * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * @file wx_view_controls.h + * @brief WX_VIEW_CONTROLS class definition. + */ + +#ifndef __WX_VIEW_CONTROLS_H +#define __WX_VIEW_CONTROLS_H + +#include <wx/wx.h> +#include <wx/event.h> + +#include <view/view_controls.h> + +class EDA_DRAW_PANEL_GAL; + +namespace KIGFX +{ +/** + * Class WX_VIEW_CONTROLS + * is a specific implementation of class VIEW_CONTROLS for wxWidgets library. + */ +class WX_VIEW_CONTROLS : public VIEW_CONTROLS, public wxEvtHandler +{ +public: + WX_VIEW_CONTROLS( VIEW* aView, wxScrolledCanvas* aParentPanel ); + ~WX_VIEW_CONTROLS() + {} + + /// Handler functions + void onWheel( wxMouseEvent& aEvent ); + void onMotion( wxMouseEvent& aEvent ); +#ifdef USE_OSX_MAGNIFY_EVENT + void onMagnify( wxMouseEvent& aEvent ); +#endif + void onButton( wxMouseEvent& aEvent ); + void onEnter( wxMouseEvent& WXUNUSED( aEvent ) ); + void onLeave( wxMouseEvent& WXUNUSED( aEvent ) ); + void onTimer( wxTimerEvent& WXUNUSED( aEvent ) ); + void onScroll( wxScrollWinEvent& aEvent ); + + /** + * Function SetGrabMouse() + * Enables/disables mouse cursor grabbing (limits the movement field only to the panel area). + * + * @param aEnabled says whether the option should be enabled or disabled. + */ + void SetGrabMouse( bool aEnabled ); + + /** + * Function SetAutoPan() + * Enables/disables autopanning (panning when mouse cursor reaches the panel border). + * + * @param aEnabled says whether the option should enabled or disabled. + */ + void SetAutoPan( bool aEnabled ) + { + m_autoPanEnabled = aEnabled; + + if( m_state == AUTO_PANNING ) + m_state = IDLE; + } + + /// @copydoc VIEW_CONTROLS::GetMousePosition() + VECTOR2I GetMousePosition() const; + + /// @copydoc VIEW_CONTROLS::GetCursorPosition() + VECTOR2D GetCursorPosition() const; + + /// @copydoc VIEW_CONTROLS::CursorWarp() + void WarpCursor( const VECTOR2D& aPosition, bool aWorldCoordinates = false, + bool aWarpView = false ) const; + + /// @copydoc VIEW_CONTROLS::CenterOnCursor() + void CenterOnCursor() const; + + /// Adjusts the scrollbars position to match the current viewport. + void UpdateScrollbars(); + + /// Event that forces mouse move event in the dispatcher (eg. used in autopanning, when mouse + /// cursor does not move in screen coordinates, but does in world coordinates) + static const wxEventType EVT_REFRESH_MOUSE; + +private: + /// Possible states for WX_VIEW_CONTROLS + enum STATE + { + IDLE = 1, /// Nothing is happening + DRAG_PANNING, /// Panning with mouse button pressed + AUTO_PANNING, /// Panning on approaching borders of the frame + }; + + /** + * Function handleAutoPanning() + * Computes new viewport settings while in autopanning mode. + * + * @param aEvent is an event to be processed and decide if autopanning should happen. + * @return true if it is currently autopanning (ie. autopanning is active and mouse cursor + * is in the area that causes autopanning to happen). + */ + bool handleAutoPanning( const wxMouseEvent& aEvent ); + + /// Current state of VIEW_CONTROLS + STATE m_state; + + /// Panel that is affected by VIEW_CONTROLS + wxScrolledCanvas* m_parentPanel; + + /// Stores information about point where dragging has started + VECTOR2D m_dragStartPoint; + + /// Stores information about the center of viewport when dragging has started + VECTOR2D m_lookStartPoint; + + /// Current direction of panning (only autopanning mode) + VECTOR2D m_panDirection; + + /// Used for determining time intervals between scroll & zoom events + wxLongLong m_timeStamp; + + /// Timer repsonsible for handling autopanning + wxTimer m_panTimer; + + /// Ratio used for scaling world coordinates to scrollbar position. + VECTOR2D m_scrollScale; +}; +} // namespace KIGFX + +#endif |