1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2013-2016 CERN
5  * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, you may find one here:
21  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22  * or you may search the http://www.gnu.org website for the version 2 license,
23  * or you may write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
25  */
26 
27 #ifndef __VIEW_H
28 #define __VIEW_H
29 
30 #include <vector>
31 #include <set>
32 #include <unordered_map>
33 #include <memory>
34 
35 #include <math/box2.h>
36 #include <gal/definitions.h>
37 
38 #include <view/view_overlay.h>
39 #include <view/view.h>
40 
41 class EDA_ITEM;
42 
43 namespace KIGFX
44 {
45 class PAINTER;
46 class GAL;
47 class VIEW_ITEM;
48 class VIEW_GROUP;
49 class VIEW_RTREE;
50 
51 /**
52  * Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device
53  * provided by the GAL.
54  *
55  * VIEWs can exist in two flavors:
56  * - dynamic - where items can be added, removed or changed anytime, intended for the main
57  *   editing panel. Each VIEW_ITEM can be added to a single dynamic view.
58  * - static - where items are added once at the startup and are not linked with the VIEW.
59  *   Foreseen for preview windows and printing.
60  *
61  * Items in a view are grouped in layers (not to be confused with Kicad's PCB layers). Each
62  * layer is identified by an integer number. Visibility and rendering order can be set
63  * individually for each of the layers. Future versions of the VIEW will also allows one to
64  * assign different layers to different rendering targets, which will be composited at the
65  * final stage by the GAL.  The VIEW class also provides fast methods for finding all visible
66  * objects that are within a given rectangular area, useful for object selection/hit testing.
67  */
68 class VIEW
69 {
70 public:
71     friend class VIEW_ITEM;
72 
73     typedef std::pair<VIEW_ITEM*, int> LAYER_ITEM_PAIR;
74 
75     /**
76      * @param aIsDynamic decides whether we are creating a static or a dynamic VIEW.
77      */
78     VIEW( bool aIsDynamic = true );
79 
80     virtual ~VIEW();
81 
82     /**
83      * Nasty hack, invoked by the destructor of VIEW_ITEM to auto-remove the item
84      * from the owning VIEW if there is any.
85      *
86      * KiCad relies too much on this mechanism.  This is the only linking dependency now
87      * between #EDA_ITEM and VIEW class. In near future I'll replace it with observers.
88      */
89     static void OnDestroy( VIEW_ITEM* aItem );
90 
91     /**
92      * Add a #VIEW_ITEM to the view.
93      *
94      * Set \a aDrawPriority to -1 to assign sequential priorities.
95      *
96      * @param aItem: item to be added. No ownership is given
97      * @param aDrawPriority: priority to draw this item on its layer, lowest first.
98      */
99     virtual void Add( VIEW_ITEM* aItem, int aDrawPriority = -1 );
100 
101     /**
102      * Remove a #VIEW_ITEM from the view.
103      *
104      * @param aItem: item to be removed. Caller must dispose the removed item if necessary
105      */
106     virtual void Remove( VIEW_ITEM* aItem );
107 
108 
109     /**
110      * Find all visible items that touch or are within the rectangle \a aRect.
111      *
112      * @param aRect area to search for items
113      * @param aResult result of the search, containing VIEW_ITEMs associated with their layers.
114      *                Sorted according to the rendering order (items that are on top of the
115      *                rendering stack as first).
116      * @return Number of found items.
117      */
118     virtual int Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) const;
119 
120     /**
121      * Set the item visibility.
122      *
123      * @param aItem: the item to modify.
124      * @param aIsVisible: whether the item is visible (on all layers), or not.
125      */
126     void SetVisible( VIEW_ITEM* aItem, bool aIsVisible = true );
127 
128     /**
129      * Temporarily hide the item in the view (e.g. for overlaying).
130      *
131      * @param aItem: the item to modify.
132      * @param aHide: whether the item is hidden (on all layers), or not.
133      */
134     void Hide( VIEW_ITEM* aItem, bool aHide = true );
135 
136     /**
137      * Return information if the item is visible (or not).
138      *
139      * @param aItem: the item to test.
140      * @return when true, the item is visible (i.e. to be displayed, not visible in the
141      * *current* viewport)
142      */
143     bool IsVisible( const VIEW_ITEM* aItem ) const;
144 
145     /**
146      * For dynamic VIEWs, inform the associated VIEW that the graphical representation of
147      * this item has changed. For static views calling has no effect.
148      *
149      * @param aItem: the item to update.
150      * @param aUpdateFlags: how much the object has changed.
151      */
152     virtual void Update( const VIEW_ITEM* aItem, int aUpdateFlags ) const;
153     virtual void Update( const VIEW_ITEM* aItem ) const;
154 
155     /**
156      * Mark the \a aRequiredId layer as required for the aLayerId layer. In order to display the
157      * layer, all of its required layers have to be enabled.
158      *
159      * @param aLayerId is the id of the layer for which we enable/disable the required layer.
160      * @param aRequiredId is the id of the required layer.
161      * @param aRequired tells if the required layer should be added or removed from the list.
162      */
163     void SetRequired( int aLayerId, int aRequiredId, bool aRequired = true );
164 
165     /**
166      * Copy layers and visibility settings from another view.
167      *
168      * @param aOtherView: view from which settings will be copied.
169      */
170     void CopySettings( const VIEW* aOtherView );
171 
172     /*
173      *  Convenience wrappers for adding multiple items
174      *  template <class T> void AddItems( const T& aItems );
175      *  template <class T> void RemoveItems( const T& aItems );
176      */
177 
178     /**
179      * Assign a rendering device for the VIEW.
180      *
181      * @param aGal: pointer to the GAL output device.
182      */
183     void SetGAL( GAL* aGal );
184 
185     /**
186      * Return the #GAL this view is using to draw graphical primitives.
187      *
188      * @return Pointer to the currently used GAL instance.
189      */
GetGAL()190     inline GAL* GetGAL() const
191     {
192         return m_gal;
193     }
194 
195     /**
196      * Set the painter object used by the view for drawing #VIEW_ITEMS.
197      */
SetPainter(PAINTER * aPainter)198     inline void SetPainter( PAINTER* aPainter )
199     {
200         m_painter = aPainter;
201     }
202 
203     /**
204      * Return the painter object used by the view for drawing #VIEW_ITEMS.
205      *
206      * @return Pointer to the currently used Painter instance.
207      */
GetPainter()208     inline PAINTER* GetPainter() const
209     {
210         return m_painter;
211     }
212 
213     /**
214      * Set the visible area of the VIEW.
215      *
216      * @param aViewport: desired visible area, in world space coordinates.
217      */
218     void SetViewport( const BOX2D& aViewport );
219 
220     /**
221      * Return the current viewport visible area rectangle.
222      *
223      * @return Current viewport rectangle.
224      */
225     BOX2D GetViewport() const;
226 
227     /**
228      * Control the mirroring of the VIEW.
229      *
230      * @param aMirrorX: when true, the X axis is mirrored.
231      * @param aMirrorY: when true, the Y axis is mirrored.
232      */
233     void SetMirror( bool aMirrorX, bool aMirrorY );
234 
235     /**
236      * Return true if view is flipped across the X axis.
237      */
IsMirroredX()238     bool IsMirroredX() const
239     {
240         return m_mirrorX;
241     }
242 
243     /**
244      * Return true if view is flipped across the Y axis.
245      */
IsMirroredY()246     bool IsMirroredY() const
247     {
248         return m_mirrorY;
249     }
250 
251     /**
252      * Set the scaling factor, zooming around a given anchor point.
253      *
254      * (depending on correct GAL unit length & DPI settings).
255      *
256      * @param aAnchor is the zooming  anchor point.
257      * @param aScale is the scale factor.
258      */
259     virtual void SetScale( double aScale, VECTOR2D aAnchor = { 0, 0 } );
260 
261     /**
262      * @return Current scale factor of this VIEW.
263      */
GetScale()264     inline double GetScale() const
265     {
266         return m_scale;
267     }
268 
269     /**
270      * Set limits for view area.
271      *
272      * @param aBoundary is the box that limits view area.
273      */
SetBoundary(const BOX2D & aBoundary)274     inline void SetBoundary( const BOX2D& aBoundary )
275     {
276         m_boundary = aBoundary;
277     }
278 
279      /**
280      * Set limits for view area.
281      *
282      * @param aBoundary is the box that limits view area.
283      */
SetBoundary(const BOX2I & aBoundary)284     inline void SetBoundary( const BOX2I& aBoundary )
285     {
286         m_boundary.SetOrigin( aBoundary.GetOrigin() );
287         m_boundary.SetEnd( aBoundary.GetEnd() );
288     }
289 
290     /**
291      * @return Current view area boundary.
292      */
GetBoundary()293     inline const BOX2D& GetBoundary() const
294     {
295         return m_boundary;
296     }
297 
298     /**
299      * Set minimum and maximum values for scale.
300      *
301      * @param aMaximum is the maximum value for scale.
302      * @param aMinimum is the minimum value for scale.
303      */
SetScaleLimits(double aMaximum,double aMinimum)304     void SetScaleLimits( double aMaximum, double aMinimum )
305     {
306         wxASSERT_MSG( aMaximum > aMinimum, wxT( "I guess you passed parameters in wrong order" ) );
307 
308         m_minScale = aMinimum;
309         m_maxScale = aMaximum;
310     }
311 
312     /**
313      * Set the center point of the VIEW (i.e. the point in world space that will be drawn in
314      * the middle of the screen).
315      *
316      * @param aCenter: the new center point, in world space coordinates.
317      */
318     void SetCenter( const VECTOR2D& aCenter );
319 
320     /**
321      * Set the center point of the VIEW, attempting to avoid \a obscuringScreenRects (for
322      * instance, the screen rect of a modeless dialog in front of the VIEW).
323      *
324      * @param aCenter: the new center point, in world space coordinates.
325      * @param obscuringScreenRects: the obscuring rects, in screen space coordinates.
326      */
327     void SetCenter( const VECTOR2D& aCenter, const std::vector<BOX2D>& obscuringScreenRects );
328 
329     /**
330      * Return the center point of this VIEW (in world space coordinates).
331      *
332      * @return center point of the view
333      */
GetCenter()334     const VECTOR2D& GetCenter() const
335     {
336         return m_center;
337     }
338 
339     /**
340      * Converts a screen space point/vector to a point/vector in world space coordinates.
341      *
342      * @param aCoord is the point/vector to be converted.
343      * @param aAbsolute when true aCoord is treated as a point, otherwise as a direction (vector).
344      */
345     VECTOR2D ToWorld( const VECTOR2D& aCoord, bool aAbsolute = true ) const;
346 
347     /**
348      * Converts a screen space one dimensional size to a one dimensional size in world
349      * space coordinates.
350      *
351      * @param aSize is the size to be converted.
352      */
353     double ToWorld( double aSize ) const;
354 
355     /**
356      * Convert a world space point/vector to a point/vector in screen space coordinates.
357      *
358      * @param aCoord is the point/vector to be converted.
359      * @param aAbsolute when true aCoord is treated as a point, otherwise as a direction (vector).
360      */
361     VECTOR2D ToScreen( const VECTOR2D& aCoord, bool aAbsolute = true ) const;
362 
363     /**
364      * Convert a world space one dimensional size to a one dimensional size in screen space.
365      *
366      * @param aSize: the size to be transformed.
367      */
368     double ToScreen( double aSize ) const;
369 
370     /**
371      * Return the size of the our rendering area in pixels.
372      *
373      * @return viewport screen size.
374      */
375     const VECTOR2I& GetScreenPixelSize() const;
376 
377     /**
378      * Remove all items from the view.
379      */
380     void Clear();
381 
382     /**
383      * Control the visibility of a particular layer.
384      *
385      * @param aLayer is the layer to show/hide.
386      * @param aVisible is the layer visibility state.
387      */
388     inline void SetLayerVisible( int aLayer, bool aVisible = true )
389     {
390         wxCHECK( aLayer < (int) m_layers.size(), /*void*/ );
391 
392         if( m_layers[aLayer].visible != aVisible )
393         {
394             // Target has to be redrawn after changing its visibility
395             MarkTargetDirty( m_layers[aLayer].target );
396             m_layers[aLayer].visible = aVisible;
397         }
398     }
399 
400     /**
401      * Return information about visibility of a particular layer.
402      *
403      * @param aLayer true if the layer is visible, false otherwise.
404      */
IsLayerVisible(int aLayer)405     inline bool IsLayerVisible( int aLayer ) const
406     {
407         wxCHECK( aLayer >= 0, false);
408         wxCHECK( aLayer < (int) m_layers.size(), false );
409 
410         return m_layers.at( aLayer ).visible;
411     }
412 
413     /**
414      * Set the whether the layer should drawn differentially.
415      *
416      * @param aLayer is the layer to set to be draw differentially
417      * @param aDiff is the layer diff'ing state.
418      */
419     inline void SetLayerDiff( int aLayer, bool aDiff = true )
420     {
421         wxCHECK( aLayer < (int) m_layers.size(), /*void*/ );
422 
423         if( m_layers[aLayer].diffLayer != aDiff )
424         {
425             // Target has to be redrawn after changing its layers' diff status
426             MarkTargetDirty( m_layers[aLayer].target );
427             m_layers[aLayer].diffLayer = aDiff;
428         }
429     }
430 
431     /**
432      * Set the status of negatives presense in a particular layer.
433      *
434      * @param aLayer is the layer to set as containing negatives (or not).
435      * @param aNegatives is the layer negatives state.
436      */
437     inline void SetLayerHasNegatives( int aLayer, bool aNegatives = true )
438     {
439         wxCHECK( aLayer < (int) m_layers.size(), /*void*/ );
440 
441         if( m_layers[aLayer].hasNegatives != aNegatives )
442         {
443             // Target has to be redrawn after changing a layers' negatives
444             MarkTargetDirty( m_layers[aLayer].target );
445             m_layers[aLayer].hasNegatives = aNegatives;
446         }
447     }
448 
449     inline void SetLayerDisplayOnly( int aLayer, bool aDisplayOnly = true )
450     {
451         wxCHECK( aLayer < (int) m_layers.size(), /*void*/ );
452         m_layers[aLayer].displayOnly = aDisplayOnly;
453     }
454 
455     /**
456      * Change the rendering target for a particular layer.
457      *
458      * @param aLayer is the layer.
459      * @param aTarget is the rendering target.
460      */
SetLayerTarget(int aLayer,RENDER_TARGET aTarget)461     inline void SetLayerTarget( int aLayer, RENDER_TARGET aTarget )
462     {
463         wxCHECK( aLayer < (int) m_layers.size(), /*void*/ );
464         m_layers[aLayer].target = aTarget;
465     }
466 
467     /**
468      * Set rendering order of a particular layer. Lower values are rendered first.
469      *
470      * @param aLayer is the layer.
471      * @param aRenderingOrder is an arbitrary number denoting the rendering order.
472      */
473     void SetLayerOrder( int aLayer, int aRenderingOrder );
474 
475     /**
476      * Return rendering order of a particular layer. Lower values are rendered first.
477      *
478      * @param aLayer is the layer.
479      * @return Rendering order of a particular layer.
480      */
481     int GetLayerOrder( int aLayer ) const;
482 
483     /**
484      * Change the order of given layer ids, so after sorting the order corresponds to layers
485      * rendering order (descending, ie. order in which layers should be drawn - from the bottom to
486      * the top).
487      *
488      * @param aLayers stores id of layers to be sorted.
489      * @param aCount stores the number of layers.
490      */
491     void SortLayers( int aLayers[], int& aCount ) const;
492 
493     /**
494      * Remap the data between layer ids without invalidating that data.
495      *
496      * Used by GerbView for the "Sort by X2" functionality.
497      *
498      * @param aReorderMap is a mapping of old to new layer ids.
499      */
500     void ReorderLayerData( std::unordered_map<int, int> aReorderMap );
501 
502     /**
503      * Apply the new coloring scheme held by RENDER_SETTINGS in case that it has changed.
504      *
505      * @param aLayer is a number of the layer to be updated.
506      * @see RENDER_SETTINGS
507      */
508     void UpdateLayerColor( int aLayer );
509 
510     /**
511      * Apply the new coloring scheme to all layers. The used scheme is held by #RENDER_SETTINGS.
512      *
513      * @see RENDER_SETTINGS
514      */
515     void UpdateAllLayersColor();
516 
517     /**
518      * Set given layer to be displayed on the top or sets back the default order of layers.
519      *
520      * @param aEnabled = true to display aLayer on the top.
521      * @param aLayer is the layer or -1 in case when no particular layer should be displayed
522      *               on the top.
523      */
524     virtual void SetTopLayer( int aLayer, bool aEnabled = true );
525 
526     /**
527      * Enable or disable display of the top layer.
528      *
529      * When disabled, layers are rendered as usual with no influence from SetTopLayer
530      * function.  Otherwise on the top there is displayed the layer set previously with
531      * SetTopLayer function.
532      *
533      * @param aEnable whether to enable or disable display of the top layer.
534      */
535     virtual void EnableTopLayer( bool aEnable );
536 
537     virtual int GetTopLayer() const;
538 
539     /**
540      * Remove all layers from the on-the-top set (they are no longer displayed over the rest of
541      * layers).
542      */
543     void ClearTopLayers();
544 
545     /**
546      * Do everything that is needed to apply the rendering order of layers.
547      *
548      * It has to be called after modification of renderingOrder field of LAYER.
549      */
550     void UpdateAllLayersOrder();
551 
552     /**
553      * Clear targets that are marked as dirty.
554      */
555     void ClearTargets();
556 
557     /**
558      * Immediately redraws the whole view.
559      */
560     virtual void Redraw();
561 
562     /**
563      * Rebuild GAL display lists.
564      */
565     void RecacheAllItems();
566 
567     /**
568      * Tell if the VIEW is dynamic (ie. can be changed, for example displaying PCBs in a window)
569      * or static (that cannot be modified, eg. displaying image/PDF).
570      */
IsDynamic()571     bool IsDynamic() const
572     {
573         return m_dynamic;
574     }
575 
576     /**
577      * Return true if any of the VIEW layers needs to be refreshened.
578      *
579      * @return True in case if any of layers is marked as dirty.
580      */
IsDirty()581     bool IsDirty() const
582     {
583         for( int i = 0; i < TARGETS_NUMBER; ++i )
584         {
585             if( IsTargetDirty( i ) )
586                 return true;
587         }
588 
589         return false;
590     }
591 
592     /**
593      * Return true if any of layers belonging to the target or the target itself should be
594      * redrawn.
595      *
596      * @return True if the above condition is fulfilled.
597      */
IsTargetDirty(int aTarget)598     bool IsTargetDirty( int aTarget ) const
599     {
600         wxCHECK( aTarget < TARGETS_NUMBER, false );
601         return m_dirtyTargets[aTarget];
602     }
603 
604     /**
605      * Set or clear target 'dirty' flag.
606      *
607      * @param aTarget is the target to set.
608      */
MarkTargetDirty(int aTarget)609     inline void MarkTargetDirty( int aTarget )
610     {
611         wxCHECK( aTarget < TARGETS_NUMBER, /* void */ );
612         m_dirtyTargets[aTarget] = true;
613     }
614 
615     /// Return true if the layer is cached.
IsCached(int aLayer)616     inline bool IsCached( int aLayer ) const
617     {
618         wxCHECK( aLayer < (int) m_layers.size(), false );
619 
620         try
621         {
622             return m_layers.at( aLayer ).target == TARGET_CACHED;
623         }
624         catch( const std::out_of_range& )
625         {
626             return false;
627         }
628     }
629 
630     /**
631      * Force redraw of view on the next rendering.
632      */
MarkDirty()633     void MarkDirty()
634     {
635         for( int i = 0; i < TARGETS_NUMBER; ++i )
636             m_dirtyTargets[i] = true;
637     }
638 
639     /**
640      * Force redraw of view on the next rendering.
641      */
MarkClean()642     void MarkClean()
643     {
644         for( int i = 0; i < TARGETS_NUMBER; ++i )
645             m_dirtyTargets[i] = false;
646     }
647 
648     /**
649      * Iterate through the list of items that asked for updating and updates them.
650      */
651     void UpdateItems();
652 
653     /**
654      * Update all items in the view according to the given flags.
655      *
656      * @param aUpdateFlags is is according to KIGFX::VIEW_UPDATE_FLAGS
657      */
658     void UpdateAllItems( int aUpdateFlags );
659 
660     /**
661      * Update items in the view according to the given flags and condition.
662      *
663      * @param aUpdateFlags is is according to KIGFX::VIEW_UPDATE_FLAGS.
664      * @param aCondition is a function returning true if the item should be updated.
665      */
666     void UpdateAllItemsConditionally( int aUpdateFlags,
667                                       std::function<bool( VIEW_ITEM* )> aCondition );
668 
669     /**
670      * @return true if draw priority is being respected while redrawing.
671      */
IsUsingDrawPriority()672     bool IsUsingDrawPriority() const
673     {
674         return m_useDrawPriority;
675     }
676 
677     /**
678      * @param aFlag is true if draw priority should be respected while redrawing.
679      */
UseDrawPriority(bool aFlag)680     void UseDrawPriority( bool aFlag )
681     {
682         m_useDrawPriority = aFlag;
683     }
684 
685     /**
686      * Only takes effect if UseDrawPriority is true.
687      *
688      * @param aFlag is true if draw order should be reversed
689      */
ReverseDrawOrder(bool aFlag)690     void ReverseDrawOrder( bool aFlag )
691     {
692         m_reverseDrawOrder = aFlag;
693     }
694 
695     std::shared_ptr<VIEW_OVERLAY> MakeOverlay();
696 
697     void InitPreview();
698 
699     void ClearPreview();
700     void AddToPreview( EDA_ITEM* aItem, bool aTakeOwnership = true );
701 
702     void ShowPreview( bool aShow = true );
703 
704     /**
705      * Return a new VIEW object that shares the same set of VIEW_ITEMs and LAYERs.
706      *
707      * GAL, PAINTER and other properties are left uninitialized.
708      */
709     std::unique_ptr<VIEW> DataReference() const;
710 
711     static constexpr int VIEW_MAX_LAYERS = 512;  ///< maximum number of layers that may be shown
712 
713 protected:
714     struct VIEW_LAYER
715     {
716         bool                    visible;         ///< Is the layer to be rendered?
717         bool                    displayOnly;     ///< Is the layer display only?
718         bool                    diffLayer;       ///< Layer should be drawn differentially over lower layers
719         bool                    hasNegatives;    ///< Layer should be drawn separately to not delete lower layers
720         std::shared_ptr<VIEW_RTREE> items;       ///< R-tree indexing all items on this layer.
721         int                     renderingOrder;  ///< Rendering order of this layer.
722         int                     id;              ///< Layer ID.
723         RENDER_TARGET           target;          ///< Where the layer should be rendered.
724         std::set<int>           requiredLayers;  ///< Layers that have to be enabled to show
725                                                  ///< the layer.
726     };
727 
728 
729 
730     VIEW( const VIEW& ) = delete;
731 
732     ///* Redraws contents within rect aRect
733     void redrawRect( const BOX2I& aRect );
734 
markTargetClean(int aTarget)735     inline void markTargetClean( int aTarget )
736     {
737         wxCHECK( aTarget < TARGETS_NUMBER, /* void */ );
738         m_dirtyTargets[aTarget] = false;
739     }
740 
741     /**
742      * Draw an item, but on a specified layers.
743      *
744      * It has to be marked that some of drawing settings are based on the layer on which
745      * an item is drawn.
746      *
747      * @param aItem is the item to be drawn.
748      * @param aLayer is the layer which should be drawn.
749      * @param aImmediate dictates the way of drawing - it allows one to force immediate
750      *                   drawing mode for cached items.
751      */
752     void draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate = false );
753 
754     /**
755      * Draw an item on all layers that the item uses.
756      *
757      * @param aItem is the item to be drawn.
758      * @param aImmediate dictates the way of drawing - it allows one to force immediate
759      *                   drawing mode for cached items.
760      */
761     void draw( VIEW_ITEM* aItem, bool aImmediate = false );
762 
763     /**
764      * Draw a group of items on all layers that those items use.
765      *
766      * @param aGroup is the group to be drawn.
767      * @param aImmediate dictates the way of drawing - it allows one to force immediate
768      *                   drawing mode for cached items.
769      */
770     void draw( VIEW_GROUP* aGroup, bool aImmediate = false );
771 
772     ///< Sort m_orderedLayers when layer rendering order has changed
773     void sortLayers();
774 
775     ///< Clear cached GAL group numbers (*ONLY* numbers stored in VIEW_ITEMs, not group objects
776     ///< used by GAL)
777     void clearGroupCache();
778 
779     /**
780      * Manage dirty flags & redraw queuing when updating an item.
781      *
782      * @param aItem is the item to be updated.
783      * @param aUpdateFlags determines the way an item is refreshed.
784      */
785     void invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags );
786 
787     ///< Update colors that are used for an item to be drawn
788     void updateItemColor( VIEW_ITEM* aItem, int aLayer );
789 
790     ///< Update all information needed to draw an item
791     void updateItemGeometry( VIEW_ITEM* aItem, int aLayer );
792 
793     ///< Update bounding box of an item
794     void updateBbox( VIEW_ITEM* aItem );
795 
796     ///< Update set of layers that an item occupies
797     void updateLayers( VIEW_ITEM* aItem );
798 
799     ///< Determine rendering order of layers. Used in display order sorting function.
compareRenderingOrder(VIEW_LAYER * aI,VIEW_LAYER * aJ)800     static bool compareRenderingOrder( VIEW_LAYER* aI, VIEW_LAYER* aJ )
801     {
802         return aI->renderingOrder > aJ->renderingOrder;
803     }
804 
805     ///< Check if every layer required by the aLayerId layer is enabled.
806     bool areRequiredLayersEnabled( int aLayerId ) const;
807 
808     // Function objects that need to access VIEW/VIEW_ITEM private/protected members
809     struct CLEAR_LAYER_CACHE_VISITOR;
810     struct RECACHE_ITEM_VISITOR;
811     struct DRAW_ITEM_VISITOR;
812     struct UPDATE_COLOR_VISITOR;
813     struct UPDATE_DEPTH_VISITOR;
814 
815     std::unique_ptr<KIGFX::VIEW_GROUP> m_preview;
816     std::vector<EDA_ITEM *>            m_ownedItems;
817 
818     ///< Whether to use rendering order modifier or not.
819     bool                               m_enableOrderModifier;
820 
821     ///< The set of possible displayed layers and its properties.
822     std::vector<VIEW_LAYER>            m_layers;
823 
824     ///< Sorted list of pointers to members of m_layers.
825     std::vector<VIEW_LAYER*>           m_orderedLayers;
826 
827     ///< Flat list of all items.
828     std::shared_ptr<std::vector<VIEW_ITEM*>> m_allItems;
829 
830     ///< The set of layers that are displayed on the top.
831     std::set<unsigned int>             m_topLayers;
832 
833     ///< Center point of the VIEW (the point at which we are looking at).
834     VECTOR2D                           m_center;
835 
836     double                             m_scale;
837     BOX2D                              m_boundary;
838     double                             m_minScale;
839     double                             m_maxScale;
840 
841     bool                               m_mirrorX;
842     bool                               m_mirrorY;
843 
844     ///< PAINTER contains information how do draw items.
845     PAINTER* m_painter;
846 
847     ///< Interface to #PAINTER that is used to draw items.
848     GAL* m_gal;
849 
850     ///< Dynamic VIEW (eg. display PCB in window) allows changes once it is built,
851     ///< static (eg. image/PDF) - does not.
852     bool m_dynamic;
853 
854     ///< Flag to mark targets as dirty so they have to be redrawn on the next refresh event.
855     bool m_dirtyTargets[TARGETS_NUMBER];
856 
857     ///< Rendering order modifier for layers that are marked as top layers.
858     static const int TOP_LAYER_MODIFIER;
859 
860     ///< Flag to respect draw priority when drawing items.
861     bool m_useDrawPriority;
862 
863     ///< The next sequential drawing priority.
864     int m_nextDrawPriority;
865 
866     ///< Flag to reverse the draw order when using draw priority.
867     bool m_reverseDrawOrder;
868 };
869 } // namespace KIGFX
870 
871 #endif
872