/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2013 CERN * @author Tomasz Wlostowski * * 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 #include #include namespace KiGfx { class PAINTER; class GAL; class VIEW_ITEM; 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 LayerItemPair; /** * Constructor. * @param aIsDynamic decides whether we are creating a static or a dynamic VIEW. * @param aUseGroups tells if items added to the VIEW should be stored in groups. */ 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& aResult ); /** * 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 void AddItems( const T& aItems ); * template 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. */ GAL* GetGAL() const { return m_gal; } /** * Function SetPainter() * Sets the painter object used by the view for drawing VIEW_ITEMS. */ void SetPainter( PAINTER* aPainter ); /** * Function GetPainter() * Returns the painter object used by the view for drawing VIEW_ITEMS. * @return Pointer to the currently used Painter instance. */ PAINTER* GetPainter() const { return m_painter; }; /** * Function SetViewport() * Sets the visible area of the VIEW. * @param aViewport: desired visible area, in world space coordinates. * @param aKeepProportions: when true, the X/Y size proportions are kept. */ void SetViewport( const BOX2D& aViewport, bool aKeepProportions = true ); /** * 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 */ void SetScale( double aScale ); /** * Function SetScale() * Sets the scaling factor, zooming around a given anchor point. * (depending on correct GAL unit length & DPI settings). * @param aScale: the scale factor */ void SetScale( double aScale, const VECTOR2D& aAnchor ); /** * Function GetScale() * @return Current scalefactor of this VIEW */ double GetScale() const { return m_scale; } /** * 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 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 coordinate to a coordinate in screen space coordinates. * @param aCoord: the coordinate to be transformed. * @param aAbsolute: when true, aCoord is treated as a point, otherwise - as a direction (vector) */ double ToScreen( double aCoord, bool aAbsolute = true ) const; /** * Function GetScreenPixelSize() * Returns the size of the our rendering area, in pixels. * @return viewport screen size */ VECTOR2D 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. When ALL_LAYERS constant is given, all layers' * visibility is updated * @param aVisible: the obivous */ inline void SetLayerVisible( int aLayer, bool aVisible = true ) { m_layers[aLayer].enabled = aVisible; } /** * Function SetLayerDynamic() * Turns on or off the dynamic parameter of a particular layer. * @param aLayer: the layer * @param aDynamic: the parameter */ inline void SetLayerCached( int aLayer, bool aCached = true ) { m_layers[aLayer].cached = aCached; } /** * Function SetLayerOrder() * Sets rendering order of a particular layer. * @param aLayer: the layer * @param aRenderingOrder: arbitrary number denoting the rendering order. * Lower values are rendered first. */ void SetLayerOrder( int aLayer, int aRenderingOrder ); /** * 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 ); /** * 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 aEnabled: whether to enable or disable display of the top layer. */ void EnableTopLayer( bool aEnable ); /** * Function Redraw() * Immediately redraws the whole view. */ void Redraw(); /** * Function PartialRedraw() * Redraws only the parts of the view that have been affected by items * for which ViewUpdate() function has been called since last redraw. */ void PartialRedraw(); /** * 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; } static const int VIEW_MAX_LAYERS; ///* maximum number of layers that may be shown static const int TOP_LAYER; ///* layer number for displaying items on the top private: struct VIEW_LAYER { bool enabled; ///* is the layer to be rendered? bool isDirty; ///* does it contain any dirty items (updated since last redraw) bool displayOnly; ///* is the layer display only? bool cached; ///* items on non-cached layers are displayed in ///* immediate mode VIEW_RTREE* items; ///* R-tree indexing all items on this layer. std::vector dirtyItems; ///* set of dirty items collected since last redraw int renderingOrder; ///* rendering order of this layer int id; ///* layer ID BOX2I extents; ///* sum of bboxes of all items on the layer BOX2I dirtyExtents; ///* sum of bboxes of all dirty items on the layer }; // Convenience typedefs typedef boost::unordered_map LayerMap; typedef LayerMap::iterator LayerMapIter; typedef std::vector LayerOrder; typedef std::vector::iterator LayerOrderIter; // Function objects that need to access VIEW/VIEW_ITEM private/protected members struct clearLayerCache; struct recacheLayer; struct drawItem; struct unlinkItem; struct updateItemsColor; struct changeItemsDepth; ///* Saves current top layer settings in order to restore it when it's not top anymore VIEW_LAYER m_topLayer; ///* Whether to use top layer settings or not bool m_enableTopLayer; ///* Redraws contents within rect aRect void redrawRect( const BOX2I& aRect ); ///* Manages dirty flags & redraw queueing when updating an item. Called internally /// via VIEW_ITEM::ViewUpdate() void invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags ); ///* 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(); /// Determines rendering order of layers. Used in display order sorting function. static bool compareRenderingOrder( VIEW_LAYER* i, VIEW_LAYER* j ) { return i->renderingOrder > j->renderingOrder; } /// Checks if every layer stored in aLayers array is enabled. bool isEveryLayerEnabled( const int aLayers[], int aCount ) const; /// Contains set of possible displayed layers and its properties LayerMap m_layers; /// Sorted list of pointers to members of m_layers. LayerOrder m_orderedLayers; /// Center point of the VIEW (the point at which we are looking at) VECTOR2D m_center; /// Scale of displayed VIEW_ITEMs double m_scale; /// 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; }; } // namespace KiGfx #endif