KiCad PCB EDA Suite
view.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2013-2017 CERN
5  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
6  * @author Maciej Suminski <maciej.suminski@cern.ch>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 
27 #include <base_struct.h>
29 
30 #include <view/view.h>
31 #include <view/view_group.h>
32 #include <view/view_item.h>
33 #include <view/view_rtree.h>
34 #include <view/view_overlay.h>
35 
36 #include <gal/definitions.h>
38 #include <painter.h>
39 
40 #ifdef __WXDEBUG__
41 #include <profile.h>
42 #endif /* __WXDEBUG__ */
43 
44 namespace KIGFX {
45 
46 class VIEW;
47 
49 {
50 public:
52  m_view( nullptr ),
53  m_flags( KIGFX::VISIBLE ),
55  m_drawPriority( 0 ),
56  m_groups( nullptr ),
57  m_groupsSize( 0 ) {}
58 
60  {
61  deleteGroups();
62  }
63 
64  int getFlags() const
65  {
66  return m_flags;
67  }
68 
69 private:
70  friend class VIEW;
71 
79  void getLayers( int* aLayers, int& aCount ) const
80  {
81  int* layersPtr = aLayers;
82 
83  for( auto layer : m_layers )
84  *layersPtr++ = layer;
85 
86  aCount = m_layers.size();
87  }
88 
90  int m_flags;
93 
95  typedef std::pair<int, int> GroupPair;
96 
101 
109  int getGroup( int aLayer ) const
110  {
111  for( int i = 0; i < m_groupsSize; ++i )
112  {
113  if( m_groups[i].first == aLayer )
114  return m_groups[i].second;
115  }
116 
117  return -1;
118  }
119 
126  std::vector<int> getAllGroups() const
127  {
128  std::vector<int> groups( m_groupsSize );
129 
130  for( int i = 0; i < m_groupsSize; ++i )
131  {
132  groups[i] = m_groups[i].second;
133  }
134 
135  return groups;
136  }
137 
145  void setGroup( int aLayer, int aGroup )
146  {
147  // Look if there is already an entry for the layer
148  for( int i = 0; i < m_groupsSize; ++i )
149  {
150  if( m_groups[i].first == aLayer )
151  {
152  m_groups[i].second = aGroup;
153  return;
154  }
155  }
156 
157  // If there was no entry for the given layer - create one
158  GroupPair* newGroups = new GroupPair[m_groupsSize + 1];
159 
160  if( m_groupsSize > 0 )
161  {
162  std::copy( m_groups, m_groups + m_groupsSize, newGroups );
163  delete[] m_groups;
164  }
165 
166  m_groups = newGroups;
167  newGroups[m_groupsSize++] = GroupPair( aLayer, aGroup );
168  }
169 
170 
176  {
177  delete[] m_groups;
178  m_groups = nullptr;
179  m_groupsSize = 0;
180  }
181 
182 
189  inline bool storesGroups() const
190  {
191  return m_groupsSize > 0;
192  }
193 
194 
201  void reorderGroups( std::unordered_map<int, int> aReorderMap )
202  {
203  for( int i = 0; i < m_groupsSize; ++i )
204  {
205  int orig_layer = m_groups[i].first;
206  int new_layer = orig_layer;
207 
208  try
209  {
210  new_layer = aReorderMap.at( orig_layer );
211  }
212  catch( const std::out_of_range& ) {}
213 
214  m_groups[i].first = new_layer;
215  }
216  }
217 
218 
220  std::vector<int> m_layers;
221 
229  void saveLayers( int* aLayers, int aCount )
230  {
231  m_layers.clear();
232 
233  for( int i = 0; i < aCount; ++i )
234  {
235  // this fires on some eagle board after EAGLE_PLUGIN::Load()
236  wxASSERT( unsigned( aLayers[i] ) <= unsigned( VIEW::VIEW_MAX_LAYERS ) );
237 
238  m_layers.push_back( aLayers[i] );
239  }
240  }
241 
246  int requiredUpdate() const
247  {
248  return m_requiredUpdate;
249  }
250 
256  {
258  }
259 
264  bool isRenderable() const
265  {
266  return m_flags == VISIBLE;
267  }
268 };
269 
270 
272 {
273  auto data = aItem->viewPrivData();
274 
275  if( !data )
276  return;
277 
278  if( data->m_view )
279  data->m_view->VIEW::Remove( aItem );
280 
281  delete data;
282  aItem->ClearViewPrivData();
283 }
284 
285 
286 VIEW::VIEW( bool aIsDynamic ) :
287  m_enableOrderModifier( true ),
288  m_scale( 4.0 ),
289  m_minScale( 0.2 ), m_maxScale( 25000.0 ),
290  m_mirrorX( false ), m_mirrorY( false ),
291  m_painter( NULL ),
292  m_gal( NULL ),
293  m_dynamic( aIsDynamic ),
294  m_useDrawPriority( false ),
295  m_nextDrawPriority( 0 ),
296  m_reverseDrawOrder( false )
297 {
298  // Set m_boundary to define the max area size. The default area size
299  // is defined here as the max value of a int.
300  // this is a default value acceptable for Pcbnew and Gerbview, but too large for Eeschema.
301  // So in eeschema a call to SetBoundary() with a smaller value will be needed.
302  typedef std::numeric_limits<int> coord_limits;
303  double pos = coord_limits::lowest() / 2 + coord_limits::epsilon();
304  double size = coord_limits::max() - coord_limits::epsilon();
305  m_boundary.SetOrigin( pos, pos );
306  m_boundary.SetSize( size, size );
307  SetPrintMode( 0 );
308 
309  m_allItems.reset( new std::vector<VIEW_ITEM*> );
310  m_allItems->reserve( 32768 );
311 
312  // Redraw everything at the beginning
313  MarkDirty();
314 
315  m_layers.reserve( VIEW_MAX_LAYERS );
316 
317  // View uses layers to display EDA_ITEMs (item may be displayed on several layers, for example
318  // pad may be shown on pad, pad hole and solder paste layers). There are usual copper layers
319  // (eg. F.Cu, B.Cu, internal and so on) and layers for displaying objects such as texts,
320  // silkscreen, pads, vias, etc.
321  for( int ii = 0; ii < VIEW_MAX_LAYERS; ++ii )
322  {
323  m_layers.emplace_back();
324  m_layers[ii].items = std::make_shared<VIEW_RTREE>();
325  m_layers[ii].id = ii;
326  m_layers[ii].renderingOrder = ii;
327  m_layers[ii].visible = true;
328  m_layers[ii].displayOnly = false;
329  m_layers[ii].target = TARGET_CACHED;
330  }
331 
332  sortLayers();
333 
334  m_preview.reset( new KIGFX::VIEW_GROUP() );
335  Add( m_preview.get() );
336 }
337 
338 
340 {
341  Remove( m_preview.get() );
342 }
343 
344 
345 void VIEW::Add( VIEW_ITEM* aItem, int aDrawPriority )
346 {
347  int layers[VIEW_MAX_LAYERS], layers_count;
348 
349  if( aDrawPriority < 0 )
350  aDrawPriority = m_nextDrawPriority++;
351 
352  if( !aItem->m_viewPrivData )
353  aItem->m_viewPrivData = new VIEW_ITEM_DATA;
354 
355  aItem->m_viewPrivData->m_view = this;
356  aItem->m_viewPrivData->m_drawPriority = aDrawPriority;
357 
358  aItem->ViewGetLayers( layers, layers_count );
359  aItem->viewPrivData()->saveLayers( layers, layers_count );
360 
361  m_allItems->push_back( aItem );
362 
363  for( int i = 0; i < layers_count; ++i )
364  {
365  VIEW_LAYER& l = m_layers[layers[i]];
366  l.items->Insert( aItem );
367  MarkTargetDirty( l.target );
368  }
369 
370  SetVisible( aItem, true );
371  Update( aItem, KIGFX::INITIAL_ADD );
372 }
373 
374 
375 void VIEW::Remove( VIEW_ITEM* aItem )
376 {
377  if( !aItem )
378  return;
379 
380  auto viewData = aItem->viewPrivData();
381 
382  if( !viewData )
383  return;
384 
385  wxCHECK( viewData->m_view == this, /*void*/ );
386  auto item = std::find( m_allItems->begin(), m_allItems->end(), aItem );
387 
388  if( item != m_allItems->end() )
389  {
390  m_allItems->erase( item );
391  viewData->clearUpdateFlags();
392  }
393 
394  int layers[VIEW::VIEW_MAX_LAYERS], layers_count;
395  viewData->getLayers( layers, layers_count );
396 
397  for( int i = 0; i < layers_count; ++i )
398  {
399  VIEW_LAYER& l = m_layers[layers[i]];
400  l.items->Remove( aItem );
401  MarkTargetDirty( l.target );
402 
403  // Clear the GAL cache
404  int prevGroup = viewData->getGroup( layers[i] );
405 
406  if( prevGroup >= 0 )
407  m_gal->DeleteGroup( prevGroup );
408  }
409 
410  viewData->deleteGroups();
411  viewData->m_view = nullptr;
412 }
413 
414 
415 void VIEW::SetRequired( int aLayerId, int aRequiredId, bool aRequired )
416 {
417  wxCHECK( (unsigned) aLayerId < m_layers.size(), /*void*/ );
418  wxCHECK( (unsigned) aRequiredId < m_layers.size(), /*void*/ );
419 
420  if( aRequired )
421  m_layers[aLayerId].requiredLayers.insert( aRequiredId );
422  else
423  m_layers[aLayerId].requiredLayers.erase( aRequired );
424 }
425 
426 
427 // stupid C++... python lambda would do this in one line
428 template <class Container>
430 {
431  typedef typename Container::value_type item_type;
432 
433  queryVisitor( Container& aCont, int aLayer ) :
434  m_cont( aCont ), m_layer( aLayer )
435  {
436  }
437 
438  bool operator()( VIEW_ITEM* aItem )
439  {
440  if( aItem->viewPrivData()->getFlags() & VISIBLE )
441  m_cont.push_back( VIEW::LAYER_ITEM_PAIR( aItem, m_layer ) );
442 
443  return true;
444  }
445 
446  Container& m_cont;
447  int m_layer;
448 };
449 
450 
451 int VIEW::Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) const
452 {
453  if( m_orderedLayers.empty() )
454  return 0;
455 
456  std::vector<VIEW_LAYER*>::const_reverse_iterator i;
457 
458  // execute queries in reverse direction, so that items that are on the top of
459  // the rendering stack are returned first.
460  for( i = m_orderedLayers.rbegin(); i != m_orderedLayers.rend(); ++i )
461  {
462  // ignore layers that do not contain actual items (i.e. the selection box, menus, floats)
463  if( ( *i )->displayOnly || !( *i )->visible )
464  continue;
465 
466  queryVisitor<std::vector<LAYER_ITEM_PAIR> > visitor( aResult, ( *i )->id );
467  ( *i )->items->Query( aRect, visitor );
468  }
469 
470  return aResult.size();
471 }
472 
473 
474 VECTOR2D VIEW::ToWorld( const VECTOR2D& aCoord, bool aAbsolute ) const
475 {
476  const MATRIX3x3D& matrix = m_gal->GetScreenWorldMatrix();
477 
478  if( aAbsolute )
479  return VECTOR2D( matrix * aCoord );
480  else
481  return VECTOR2D( matrix.GetScale().x * aCoord.x, matrix.GetScale().y * aCoord.y );
482 }
483 
484 
485 double VIEW::ToWorld( double aSize ) const
486 {
487  const MATRIX3x3D& matrix = m_gal->GetScreenWorldMatrix();
488 
489  return fabs( matrix.GetScale().x * aSize );
490 }
491 
492 
493 VECTOR2D VIEW::ToScreen( const VECTOR2D& aCoord, bool aAbsolute ) const
494 {
495  const MATRIX3x3D& matrix = m_gal->GetWorldScreenMatrix();
496 
497  if( aAbsolute )
498  return VECTOR2D( matrix * aCoord );
499  else
500  return VECTOR2D( matrix.GetScale().x * aCoord.x, matrix.GetScale().y * aCoord.y );
501 }
502 
503 
504 double VIEW::ToScreen( double aSize ) const
505 {
506  const MATRIX3x3D& matrix = m_gal->GetWorldScreenMatrix();
507 
508  return matrix.GetScale().x * aSize;
509 }
510 
511 
512 void VIEW::CopySettings( const VIEW* aOtherView )
513 {
514  wxASSERT_MSG( false, wxT( "This is not implemented" ) );
515 }
516 
517 
518 void VIEW::SetGAL( GAL* aGal )
519 {
520  bool recacheGroups = ( m_gal != nullptr ); // recache groups only if GAL is reassigned
521  m_gal = aGal;
522 
523  // clear group numbers, so everything is going to be recached
524  if( recacheGroups )
525  clearGroupCache();
526 
527  // every target has to be refreshed
528  MarkDirty();
529 
530  // force the new GAL to display the current viewport.
531  SetCenter( m_center );
532  SetScale( m_scale );
534 }
535 
536 
538 {
539  BOX2D rect;
540  VECTOR2D screenSize = m_gal->GetScreenPixelSize();
541 
542  rect.SetOrigin( ToWorld( VECTOR2D( 0, 0 ) ) );
543  rect.SetEnd( ToWorld( screenSize ) );
544 
545  return rect.Normalize();
546 }
547 
548 
549 void VIEW::SetViewport( const BOX2D& aViewport )
550 {
551  VECTOR2D ssize = ToWorld( m_gal->GetScreenPixelSize(), false );
552 
553  wxCHECK( ssize.x > 0 && ssize.y > 0, /*void*/ );
554 
555  VECTOR2D centre = aViewport.Centre();
556  VECTOR2D vsize = aViewport.GetSize();
557  double zoom = 1.0 / std::max( fabs( vsize.x / ssize.x ), fabs( vsize.y / ssize.y ) );
558 
559  SetCenter( centre );
560  SetScale( GetScale() * zoom );
561 }
562 
563 
564 void VIEW::SetMirror( bool aMirrorX, bool aMirrorY )
565 {
566  wxASSERT_MSG( !aMirrorY, _( "Mirroring for Y axis is not supported yet" ) );
567 
568  m_mirrorX = aMirrorX;
569  m_mirrorY = aMirrorY;
570  m_gal->SetFlip( aMirrorX, aMirrorY );
571 
572  // Redraw everything
573  MarkDirty();
574 }
575 
576 
577 void VIEW::SetScale( double aScale, VECTOR2D aAnchor )
578 {
579  if( aAnchor == VECTOR2D( 0, 0 ) )
580  aAnchor = m_center;
581 
582  VECTOR2D a = ToScreen( aAnchor );
583 
584  if( aScale < m_minScale )
586  else if( aScale > m_maxScale )
588  else
589  m_scale = aScale;
590 
593 
594  VECTOR2D delta = ToWorld( a ) - aAnchor;
595 
596  SetCenter( m_center - delta );
597 
598  // Redraw everything after the viewport has changed
599  MarkDirty();
600 }
601 
602 
603 void VIEW::SetCenter( const VECTOR2D& aCenter )
604 {
605  m_center = aCenter;
606 
607  if( !m_boundary.Contains( aCenter ) )
608  {
609  if( m_center.x < m_boundary.GetLeft() )
611  else if( aCenter.x > m_boundary.GetRight() )
613 
614  if( m_center.y < m_boundary.GetTop() )
616  else if( m_center.y > m_boundary.GetBottom() )
618  }
619 
622 
623  // Redraw everything after the viewport has changed
624  MarkDirty();
625 }
626 
627 
628 void VIEW::SetCenter( VECTOR2D aCenter, const BOX2D& occultingScreenRect )
629 {
630  BOX2D screenRect( VECTOR2D( 0, 0 ), m_gal->GetScreenPixelSize() );
631 
632  if( !screenRect.Intersects( occultingScreenRect ) )
633  {
634  SetCenter( aCenter );
635  return;
636  }
637 
638  BOX2D occultedRect = screenRect.Intersect( occultingScreenRect );
639  double topExposed = occultedRect.GetTop() - screenRect.GetTop();
640  double bottomExposed = screenRect.GetBottom() - occultedRect.GetBottom();
641  double leftExposed = occultedRect.GetLeft() - screenRect.GetLeft();
642  double rightExposed = screenRect.GetRight() - occultedRect.GetRight();
643 
644  if( std::max( topExposed, bottomExposed ) > std::max( leftExposed, rightExposed ) )
645  {
646  if( topExposed > bottomExposed )
647  aCenter.y += ToWorld( screenRect.GetHeight() / 2 - topExposed / 2 );
648  else
649  aCenter.y -= ToWorld( screenRect.GetHeight() / 2 - bottomExposed / 2 );
650  }
651  else
652  {
653  if( leftExposed > rightExposed )
654  aCenter.x += ToWorld( screenRect.GetWidth() / 2 - leftExposed / 2 );
655  else
656  aCenter.x -= ToWorld( screenRect.GetWidth() / 2 - rightExposed / 2 );
657  }
658 
659  SetCenter( aCenter );
660 }
661 
662 
663 void VIEW::SetLayerOrder( int aLayer, int aRenderingOrder )
664 {
665  m_layers[aLayer].renderingOrder = aRenderingOrder;
666 
667  sortLayers();
668 }
669 
670 
671 int VIEW::GetLayerOrder( int aLayer ) const
672 {
673  return m_layers.at( aLayer ).renderingOrder;
674 }
675 
676 
677 void VIEW::SortLayers( int aLayers[], int& aCount ) const
678 {
679  int maxLay, maxOrd, maxIdx;
680 
681  for( int i = 0; i < aCount; ++i )
682  {
683  maxLay = aLayers[i];
684  maxOrd = GetLayerOrder( maxLay );
685  maxIdx = i;
686 
687  // Look for the max element in the range (j..aCount)
688  for( int j = i; j < aCount; ++j )
689  {
690  if( maxOrd < GetLayerOrder( aLayers[j] ) )
691  {
692  maxLay = aLayers[j];
693  maxOrd = GetLayerOrder( maxLay );
694  maxIdx = j;
695  }
696  }
697 
698  // Swap elements
699  aLayers[maxIdx] = aLayers[i];
700  aLayers[i] = maxLay;
701  }
702 }
703 
704 
705 void VIEW::ReorderLayerData( std::unordered_map<int, int> aReorderMap )
706 {
707  std::vector<VIEW_LAYER> new_map;
708  new_map.reserve( m_layers.size() );
709 
710  for( int ii = 0; ii < VIEW_MAX_LAYERS; ++ii )
711  new_map.emplace_back();
712 
713  for( const VIEW_LAYER& layer : m_layers )
714  {
715  int orig_idx = layer.id;
716  int new_idx = orig_idx;
717 
718  if( aReorderMap.count( orig_idx ) )
719  new_idx = aReorderMap.at( orig_idx );
720 
721  new_map[new_idx] = layer;
722  new_map[new_idx].id = new_idx;
723  }
724 
725  m_layers = new_map;
726 
727  for( VIEW_ITEM* item : *m_allItems )
728  {
729  auto viewData = item->viewPrivData();
730 
731  if( !viewData )
732  continue;
733 
734  int layers[VIEW::VIEW_MAX_LAYERS], layers_count;
735 
736  item->ViewGetLayers( layers, layers_count );
737  viewData->saveLayers( layers, layers_count );
738 
739  viewData->reorderGroups( aReorderMap );
740 
741  viewData->m_requiredUpdate |= COLOR;
742  }
743 
744  UpdateItems();
745 }
746 
747 
749 {
750  updateItemsColor( int aLayer, PAINTER* aPainter, GAL* aGal ) :
751  layer( aLayer ), painter( aPainter ), gal( aGal )
752  {
753  }
754 
755  bool operator()( VIEW_ITEM* aItem )
756  {
757  // Obtain the color that should be used for coloring the item
758  const COLOR4D color = painter->GetSettings()->GetColor( aItem, layer );
759  int group = aItem->viewPrivData()->getGroup( layer );
760 
761  if( group >= 0 )
762  gal->ChangeGroupColor( group, color );
763 
764  return true;
765  }
766 
767  int layer;
770 };
771 
772 
773 void VIEW::UpdateLayerColor( int aLayer )
774 {
775  // There is no point in updating non-cached layers
776  if( !IsCached( aLayer ) )
777  return;
778 
779  BOX2I r;
780 
781  r.SetMaximum();
782 
783  if( m_gal->IsVisible() )
784  {
785  GAL_UPDATE_CONTEXT ctx( m_gal );
786 
787  updateItemsColor visitor( aLayer, m_painter, m_gal );
788  m_layers[aLayer].items->Query( r, visitor );
789  MarkTargetDirty( m_layers[aLayer].target );
790  }
791 }
792 
793 
795 {
796  if( m_gal->IsVisible() )
797  {
798  GAL_UPDATE_CONTEXT ctx( m_gal );
799 
800  for( VIEW_ITEM* item : *m_allItems )
801  {
802  auto viewData = item->viewPrivData();
803 
804  if( !viewData )
805  continue;
806 
807  int layers[VIEW::VIEW_MAX_LAYERS], layers_count;
808  viewData->getLayers( layers, layers_count );
809 
810  for( int i = 0; i < layers_count; ++i )
811  {
812  const COLOR4D color = m_painter->GetSettings()->GetColor( item, layers[i] );
813  int group = viewData->getGroup( layers[i] );
814 
815  if( group >= 0 )
816  m_gal->ChangeGroupColor( group, color );
817  }
818  }
819  }
820 
821  MarkDirty();
822 }
823 
824 
826 {
827  changeItemsDepth( int aLayer, int aDepth, GAL* aGal ) :
828  layer( aLayer ), depth( aDepth ), gal( aGal )
829  {
830  }
831 
832  bool operator()( VIEW_ITEM* aItem )
833  {
834  int group = aItem->viewPrivData()->getGroup( layer );
835 
836  if( group >= 0 )
837  gal->ChangeGroupDepth( group, depth );
838 
839  return true;
840  }
841 
842  int layer, depth;
844 };
845 
846 
847 int VIEW::GetTopLayer() const
848 {
849  if( m_topLayers.size() == 0 )
850  return 0;
851 
852  return *m_topLayers.begin();
853 }
854 
855 
856 void VIEW::SetTopLayer( int aLayer, bool aEnabled )
857 {
858  if( aEnabled )
859  {
860  if( m_topLayers.count( aLayer ) == 1 )
861  return;
862 
863  m_topLayers.insert( aLayer );
864 
865  // Move the layer closer to front
867  m_layers[aLayer].renderingOrder += TOP_LAYER_MODIFIER;
868  }
869  else
870  {
871  if( m_topLayers.count( aLayer ) == 0 )
872  return;
873 
874  m_topLayers.erase( aLayer );
875 
876  // Restore the previous rendering order
878  m_layers[aLayer].renderingOrder -= TOP_LAYER_MODIFIER;
879  }
880 }
881 
882 
883 void VIEW::EnableTopLayer( bool aEnable )
884 {
885  if( aEnable == m_enableOrderModifier )
886  return;
887 
888  m_enableOrderModifier = aEnable;
889 
890  std::set<unsigned int>::iterator it;
891 
892  if( aEnable )
893  {
894  for( it = m_topLayers.begin(); it != m_topLayers.end(); ++it )
895  m_layers[*it].renderingOrder += TOP_LAYER_MODIFIER;
896  }
897  else
898  {
899  for( it = m_topLayers.begin(); it != m_topLayers.end(); ++it )
900  m_layers[*it].renderingOrder -= TOP_LAYER_MODIFIER;
901  }
902 
905 }
906 
907 
909 {
910  std::set<unsigned int>::iterator it;
911 
913  {
914  // Restore the previous rendering order for layers that were marked as top
915  for( it = m_topLayers.begin(); it != m_topLayers.end(); ++it )
916  m_layers[*it].renderingOrder -= TOP_LAYER_MODIFIER;
917  }
918 
919  m_topLayers.clear();
920 }
921 
922 
924 {
925  sortLayers();
926 
927  if( m_gal->IsVisible() )
928  {
929  GAL_UPDATE_CONTEXT ctx( m_gal );
930 
931  for( VIEW_ITEM* item : *m_allItems )
932  {
933  auto viewData = item->viewPrivData();
934 
935  if( !viewData )
936  continue;
937 
938  int layers[VIEW::VIEW_MAX_LAYERS], layers_count;
939  viewData->getLayers( layers, layers_count );
940 
941  for( int i = 0; i < layers_count; ++i )
942  {
943  int group = viewData->getGroup( layers[i] );
944 
945  if( group >= 0 )
946  m_gal->ChangeGroupDepth( group, m_layers[layers[i]].renderingOrder );
947  }
948  }
949  }
950 
951  MarkDirty();
952 }
953 
954 
956 {
957  drawItem( VIEW* aView, int aLayer, bool aUseDrawPriority, bool aReverseDrawOrder ) :
958  view( aView ), layer( aLayer ),
959  useDrawPriority( aUseDrawPriority ),
960  reverseDrawOrder( aReverseDrawOrder )
961  {
962  }
963 
964  bool operator()( VIEW_ITEM* aItem )
965  {
966  wxCHECK( aItem->viewPrivData(), false );
967 
968  // Conditions that have to be fulfilled for an item to be drawn
969  bool drawCondition = aItem->viewPrivData()->isRenderable() &&
970  aItem->ViewGetLOD( layer, view ) < view->m_scale;
971  if( !drawCondition )
972  return true;
973 
974  if( useDrawPriority )
975  drawItems.push_back( aItem );
976  else
977  view->draw( aItem, layer );
978 
979  return true;
980  }
981 
983  {
984  if( reverseDrawOrder )
985  std::sort( drawItems.begin(), drawItems.end(),
986  []( VIEW_ITEM* a, VIEW_ITEM* b ) -> bool {
987  return b->viewPrivData()->m_drawPriority < a->viewPrivData()->m_drawPriority;
988  });
989  else
990  std::sort( drawItems.begin(), drawItems.end(),
991  []( VIEW_ITEM* a, VIEW_ITEM* b ) -> bool {
992  return a->viewPrivData()->m_drawPriority < b->viewPrivData()->m_drawPriority;
993  });
994 
995  for( auto item : drawItems )
996  view->draw( item, layer );
997  }
998 
1002  std::vector<VIEW_ITEM*> drawItems;
1003 };
1004 
1005 
1006 void VIEW::redrawRect( const BOX2I& aRect )
1007 {
1008  for( VIEW_LAYER* l : m_orderedLayers )
1009  {
1010  if( l->visible && IsTargetDirty( l->target ) && areRequiredLayersEnabled( l->id ) )
1011  {
1012  drawItem drawFunc( this, l->id, m_useDrawPriority, m_reverseDrawOrder );
1013 
1014  m_gal->SetTarget( l->target );
1015  m_gal->SetLayerDepth( l->renderingOrder );
1016  l->items->Query( aRect, drawFunc );
1017 
1018  if( m_useDrawPriority )
1019  drawFunc.deferredDraw();
1020  }
1021  }
1022 }
1023 
1024 
1025 void VIEW::draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate )
1026 {
1027  auto viewData = aItem->viewPrivData();
1028 
1029  if( !viewData )
1030  return;
1031 
1032  if( IsCached( aLayer ) && !aImmediate )
1033  {
1034  // Draw using cached information or create one
1035  int group = viewData->getGroup( aLayer );
1036 
1037  if( group >= 0 )
1038  m_gal->DrawGroup( group );
1039  else
1040  Update( aItem );
1041  }
1042  else
1043  {
1044  // Immediate mode
1045  if( !m_painter->Draw( aItem, aLayer ) )
1046  aItem->ViewDraw( aLayer, this ); // Alternative drawing method
1047  }
1048 }
1049 
1050 
1051 void VIEW::draw( VIEW_ITEM* aItem, bool aImmediate )
1052 {
1053  int layers[VIEW_MAX_LAYERS], layers_count;
1054 
1055  aItem->ViewGetLayers( layers, layers_count );
1056 
1057  // Sorting is needed for drawing order dependent GALs (like Cairo)
1058  SortLayers( layers, layers_count );
1059 
1060  for( int i = 0; i < layers_count; ++i )
1061  {
1062  m_gal->SetLayerDepth( m_layers.at( layers[i] ).renderingOrder );
1063  draw( aItem, layers[i], aImmediate );
1064  }
1065 }
1066 
1067 
1068 void VIEW::draw( VIEW_GROUP* aGroup, bool aImmediate )
1069 {
1070  for( unsigned int i = 0; i < aGroup->GetSize(); i++)
1071  draw( aGroup->GetItem(i), aImmediate );
1072 }
1073 
1074 
1076 {
1077  recacheItem( VIEW* aView, GAL* aGal, int aLayer ) :
1078  view( aView ), gal( aGal ), layer( aLayer )
1079  {
1080  }
1081 
1082  bool operator()( VIEW_ITEM* aItem )
1083  {
1084  auto viewData = aItem->viewPrivData();
1085 
1086  if( !viewData )
1087  return false;
1088 
1089  // Remove previously cached group
1090  int group = viewData->getGroup( layer );
1091 
1092  if( group >= 0 )
1093  gal->DeleteGroup( group );
1094 
1095  viewData->setGroup( layer, -1 );
1096  view->Update( aItem );
1097 
1098  return true;
1099  }
1100 
1103  int layer;
1104 };
1105 
1106 
1108 {
1109  BOX2I r;
1110  r.SetMaximum();
1111  m_allItems->clear();
1112 
1113  for( VIEW_LAYER& layer : m_layers )
1114  layer.items->RemoveAll();
1115 
1116  m_nextDrawPriority = 0;
1117 
1118  m_gal->ClearCache();
1119 }
1120 
1121 
1123 {
1125  {
1126  // TARGET_CACHED and TARGET_NONCACHED have to be redrawn together, as they contain
1127  // layers that rely on each other (eg. netnames are noncached, but tracks - are cached)
1130 
1131  MarkDirty();
1132  }
1133 
1134  if( IsTargetDirty( TARGET_OVERLAY ) )
1135  {
1137  }
1138 }
1139 
1140 
1142 {
1143 #ifdef __WXDEBUG__
1144  PROF_COUNTER totalRealTime;
1145 #endif /* __WXDEBUG__ */
1146 
1147  VECTOR2D screenSize = m_gal->GetScreenPixelSize();
1148  BOX2D rect( ToWorld( VECTOR2D( 0, 0 ) ),
1149  ToWorld( screenSize ) - ToWorld( VECTOR2D( 0, 0 ) ) );
1150 
1151  rect.Normalize();
1152  BOX2I recti( rect.GetPosition(), rect.GetSize() );
1153 
1154  // The view rtree uses integer positions. Large screens can overflow
1155  // this size so in this case, simply set the rectangle to the full rtree
1156  if( rect.GetWidth() > std::numeric_limits<int>::max() ||
1157  rect.GetHeight() > std::numeric_limits<int>::max() )
1158  recti.SetMaximum();
1159 
1160  redrawRect( recti );
1161  // All targets were redrawn, so nothing is dirty
1165 
1166 #ifdef __WXDEBUG__
1167  totalRealTime.Stop();
1168  wxLogTrace( "GAL_PROFILE", "VIEW::Redraw(): %.1f ms", totalRealTime.msecs() );
1169 #endif /* __WXDEBUG__ */
1170 }
1171 
1172 
1174 {
1175  return m_gal->GetScreenPixelSize();
1176 }
1177 
1178 
1180 {
1181  clearLayerCache( VIEW* aView ) :
1182  view( aView )
1183  {
1184  }
1185 
1186  bool operator()( VIEW_ITEM* aItem )
1187  {
1188  aItem->viewPrivData()->deleteGroups();
1189 
1190  return true;
1191  }
1192 
1194 };
1195 
1196 
1198 {
1199  BOX2I r;
1200 
1201  r.SetMaximum();
1202  clearLayerCache visitor( this );
1203 
1204  for( VIEW_LAYER& layer : m_layers )
1205  layer.items->Query( r, visitor );
1206 }
1207 
1208 
1209 void VIEW::invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags )
1210 {
1211  if( aUpdateFlags & INITIAL_ADD )
1212  {
1213  // Don't update layers or bbox, since it was done in VIEW::Add()
1214  // Now that we have initialized, set flags to ALL for the code below
1215  aUpdateFlags = ALL;
1216  }
1217  else
1218  {
1219  // updateLayers updates geometry too, so we do not have to update both of them at the same time
1220  if( aUpdateFlags & LAYERS )
1221  {
1222  updateLayers( aItem );
1223  }
1224  else if( aUpdateFlags & GEOMETRY )
1225  {
1226  updateBbox( aItem );
1227  }
1228  }
1229 
1230  int layers[VIEW_MAX_LAYERS], layers_count;
1231  aItem->ViewGetLayers( layers, layers_count );
1232 
1233  // Iterate through layers used by the item and recache it immediately
1234  for( int i = 0; i < layers_count; ++i )
1235  {
1236  int layerId = layers[i];
1237 
1238  if( IsCached( layerId ) )
1239  {
1240  if( aUpdateFlags & ( GEOMETRY | LAYERS | REPAINT ) )
1241  updateItemGeometry( aItem, layerId );
1242  else if( aUpdateFlags & COLOR )
1243  updateItemColor( aItem, layerId );
1244  }
1245 
1246  // Mark those layers as dirty, so the VIEW will be refreshed
1247  MarkTargetDirty( m_layers[layerId].target );
1248  }
1249 
1250  aItem->viewPrivData()->clearUpdateFlags();
1251 }
1252 
1253 
1255 {
1256  int n = 0;
1257 
1258  m_orderedLayers.resize( m_layers.size() );
1259 
1260  for( VIEW_LAYER& layer : m_layers )
1261  m_orderedLayers[n++] = &layer;
1262 
1263  sort( m_orderedLayers.begin(), m_orderedLayers.end(), compareRenderingOrder );
1264 
1265  MarkDirty();
1266 }
1267 
1268 
1269 void VIEW::updateItemColor( VIEW_ITEM* aItem, int aLayer )
1270 {
1271  auto viewData = aItem->viewPrivData();
1272  wxCHECK( (unsigned) aLayer < m_layers.size(), /*void*/ );
1273  wxCHECK( IsCached( aLayer ), /*void*/ );
1274 
1275  if( !viewData )
1276  return;
1277 
1278  // Obtain the color that should be used for coloring the item on the specific layerId
1279  const COLOR4D color = m_painter->GetSettings()->GetColor( aItem, aLayer );
1280  int group = viewData->getGroup( aLayer );
1281 
1282  // Change the color, only if it has group assigned
1283  if( group >= 0 )
1284  m_gal->ChangeGroupColor( group, color );
1285 }
1286 
1287 
1288 void VIEW::updateItemGeometry( VIEW_ITEM* aItem, int aLayer )
1289 {
1290  auto viewData = aItem->viewPrivData();
1291  wxCHECK( (unsigned) aLayer < m_layers.size(), /*void*/ );
1292  wxCHECK( IsCached( aLayer ), /*void*/ );
1293 
1294  if( !viewData )
1295  return;
1296 
1297  VIEW_LAYER& l = m_layers.at( aLayer );
1298 
1299  m_gal->SetTarget( l.target );
1301 
1302  // Redraw the item from scratch
1303  int group = viewData->getGroup( aLayer );
1304 
1305  if( group >= 0 )
1306  m_gal->DeleteGroup( group );
1307 
1308  group = m_gal->BeginGroup();
1309  viewData->setGroup( aLayer, group );
1310 
1311  if( !m_painter->Draw( static_cast<EDA_ITEM*>( aItem ), aLayer ) )
1312  aItem->ViewDraw( aLayer, this ); // Alternative drawing method
1313 
1314  m_gal->EndGroup();
1315 }
1316 
1317 
1319 {
1320  int layers[VIEW_MAX_LAYERS], layers_count;
1321 
1322  aItem->ViewGetLayers( layers, layers_count );
1323 
1324  for( int i = 0; i < layers_count; ++i )
1325  {
1326  VIEW_LAYER& l = m_layers[layers[i]];
1327  l.items->Remove( aItem );
1328  l.items->Insert( aItem );
1329  MarkTargetDirty( l.target );
1330  }
1331 }
1332 
1333 
1335 {
1336  auto viewData = aItem->viewPrivData();
1337  int layers[VIEW_MAX_LAYERS], layers_count;
1338 
1339  if( !viewData )
1340  return;
1341 
1342  // Remove the item from previous layer set
1343  viewData->getLayers( layers, layers_count );
1344 
1345  for( int i = 0; i < layers_count; ++i )
1346  {
1347  VIEW_LAYER& l = m_layers[layers[i]];
1348  l.items->Remove( aItem );
1349  MarkTargetDirty( l.target );
1350 
1351  if( IsCached( l.id ) )
1352  {
1353  // Redraw the item from scratch
1354  int prevGroup = viewData->getGroup( layers[i] );
1355 
1356  if( prevGroup >= 0 )
1357  {
1358  m_gal->DeleteGroup( prevGroup );
1359  viewData->setGroup( l.id, -1 );
1360  }
1361  }
1362  }
1363 
1364  // Add the item to new layer set
1365  aItem->ViewGetLayers( layers, layers_count );
1366  viewData->saveLayers( layers, layers_count );
1367 
1368  for( int i = 0; i < layers_count; i++ )
1369  {
1370  VIEW_LAYER& l = m_layers[layers[i]];
1371  l.items->Insert( aItem );
1372  MarkTargetDirty( l.target );
1373  }
1374 }
1375 
1376 
1377 bool VIEW::areRequiredLayersEnabled( int aLayerId ) const
1378 {
1379  wxCHECK( (unsigned) aLayerId < m_layers.size(), false );
1380 
1381  std::set<int>::const_iterator it, it_end;
1382 
1383  for( it = m_layers.at( aLayerId ).requiredLayers.begin(),
1384  it_end = m_layers.at( aLayerId ).requiredLayers.end(); it != it_end; ++it )
1385  {
1386  // That is enough if just one layer is not enabled
1387  if( !m_layers.at( *it ).visible || !areRequiredLayersEnabled( *it ) )
1388  return false;
1389  }
1390 
1391  return true;
1392 }
1393 
1394 
1396 {
1397  BOX2I r;
1398 
1399  r.SetMaximum();
1400 
1401  for( const VIEW_LAYER& l : m_layers )
1402  {
1403  if( IsCached( l.id ) )
1404  {
1405  recacheItem visitor( this, m_gal, l.id );
1406  l.items->Query( r, visitor );
1407  }
1408  }
1409 }
1410 
1411 
1413 {
1414  if( m_gal->IsVisible() )
1415  {
1416  GAL_UPDATE_CONTEXT ctx( m_gal );
1417 
1418  for( VIEW_ITEM* item : *m_allItems )
1419  {
1420  auto viewData = item->viewPrivData();
1421 
1422  if( !viewData )
1423  continue;
1424 
1425  if( viewData->m_requiredUpdate != NONE )
1426  {
1427  invalidateItem( item, viewData->m_requiredUpdate );
1428  viewData->m_requiredUpdate = NONE;
1429  }
1430  }
1431  }
1432 }
1433 
1434 
1435 void VIEW::UpdateAllItems( int aUpdateFlags )
1436 {
1437  for( VIEW_ITEM* item : *m_allItems )
1438  {
1439  auto viewData = item->viewPrivData();
1440 
1441  if( !viewData )
1442  continue;
1443 
1444  viewData->m_requiredUpdate |= aUpdateFlags;
1445  }
1446 }
1447 
1448 
1449 void VIEW::UpdateAllItemsConditionally( int aUpdateFlags,
1450  std::function<bool( VIEW_ITEM* )> aCondition )
1451 {
1452  for( VIEW_ITEM* item : *m_allItems )
1453  {
1454  if( aCondition( item ) )
1455  {
1456  auto viewData = item->viewPrivData();
1457 
1458  if( !viewData )
1459  continue;
1460 
1461  viewData->m_requiredUpdate |= aUpdateFlags;
1462  }
1463  }
1464 }
1465 
1466 
1467 std::unique_ptr<VIEW> VIEW::DataReference() const
1468 {
1469  auto ret = std::make_unique<VIEW>();
1470  ret->m_allItems = m_allItems;
1471  ret->m_layers = m_layers;
1472  ret->sortLayers();
1473  return ret;
1474 }
1475 
1476 
1477 void VIEW::SetVisible( VIEW_ITEM* aItem, bool aIsVisible )
1478 {
1479  auto viewData = aItem->viewPrivData();
1480 
1481  if( !viewData )
1482  return;
1483 
1484  bool cur_visible = viewData->m_flags & VISIBLE;
1485 
1486  if( cur_visible != aIsVisible )
1487  {
1488  if( aIsVisible )
1489  viewData->m_flags |= VISIBLE;
1490  else
1491  viewData->m_flags &= ~VISIBLE;
1492 
1493  Update( aItem, APPEARANCE | COLOR );
1494  }
1495 }
1496 
1497 
1498 void VIEW::Hide( VIEW_ITEM* aItem, bool aHide )
1499 {
1500  auto viewData = aItem->viewPrivData();
1501 
1502  if( !viewData )
1503  return;
1504 
1505  if( !( viewData->m_flags & VISIBLE ) )
1506  return;
1507 
1508  if( aHide )
1509  viewData->m_flags |= HIDDEN;
1510  else
1511  viewData->m_flags &= ~HIDDEN;
1512 
1513  Update( aItem, APPEARANCE );
1514 }
1515 
1516 
1517 bool VIEW::IsVisible( const VIEW_ITEM* aItem ) const
1518 {
1519  const auto viewData = aItem->viewPrivData();
1520 
1521  return viewData && ( viewData->m_flags & VISIBLE );
1522 }
1523 
1524 
1525 void VIEW::Update( VIEW_ITEM* aItem )
1526 {
1527  Update( aItem, ALL );
1528 }
1529 
1530 
1531 void VIEW::Update( VIEW_ITEM* aItem, int aUpdateFlags )
1532 {
1533  VIEW_ITEM_DATA* viewData = aItem->viewPrivData();
1534 
1535  if( !viewData )
1536  return;
1537 
1538  assert( aUpdateFlags != NONE );
1539 
1540  viewData->m_requiredUpdate |= aUpdateFlags;
1541 }
1542 
1543 
1544 std::shared_ptr<VIEW_OVERLAY> VIEW::MakeOverlay()
1545 {
1546  std::shared_ptr<VIEW_OVERLAY> overlay( new VIEW_OVERLAY );
1547 
1548  Add( overlay.get() );
1549  return overlay;
1550 }
1551 
1552 
1554 {
1555  m_preview->Clear();
1556 
1557  for( EDA_ITEM* item : m_ownedItems )
1558  delete item;
1559 
1560  m_ownedItems.clear();
1561  Update( m_preview.get() );
1562 }
1563 
1564 
1566 {
1567  m_preview.reset( new KIGFX::VIEW_GROUP() );
1568  Add( m_preview.get() );
1569 }
1570 
1571 
1572 void VIEW::AddToPreview( EDA_ITEM* aItem, bool aTakeOwnership )
1573 {
1574  Hide( aItem, false );
1575  m_preview->Add( aItem );
1576 
1577  if( aTakeOwnership )
1578  m_ownedItems.push_back( aItem );
1579 
1580  SetVisible( m_preview.get(), true );
1581  Hide( m_preview.get(), false );
1582  Update( m_preview.get() );
1583 }
1584 
1585 
1586 void VIEW::ShowPreview( bool aShow )
1587 {
1588  SetVisible( m_preview.get(), aShow );
1589 }
1590 
1591 
1592 const int VIEW::TOP_LAYER_MODIFIER = -VIEW_MAX_LAYERS;
1593 
1595 {
1596  // To be implemented by subclasses.
1597  return BOX2I();
1598 }
1599 
1600 } // namespace KIGFX
void Stop()
save the time when this function was called, and set the counter stane to stop
Definition: profile.h:82
void Hide(VIEW_ITEM *aItem, bool aHide=true)
Temporarily hides the item in the view (e.g.
Definition: view.cpp:1498
virtual void DrawGroup(int aGroupNumber)
Draw the stored group.
Layers have changed.
Definition: view_item.h:61
Item is visible (in general)
Definition: view_item.h:72
int requiredUpdate() const
Function viewRequiredUpdate() Returns current update flag for an item.
Definition: view.cpp:246
BOX2< VECTOR2I > BOX2I
Definition: box2.h:522
void deleteGroups()
Function deleteGroups() Removes all of the stored group ids.
Definition: view.cpp:175
BOX2D GetViewport() const
Function GetViewport() Returns the current viewport visible area rectangle.
Definition: view.cpp:537
VIEW_ITEM_DATA * m_viewPrivData
Definition: view_item.h:162
void SetViewport(const BOX2D &aViewport)
Function SetViewport() Sets the visible area of the VIEW.
Definition: view.cpp:549
void updateLayers(VIEW_ITEM *aItem)
Updates set of layers that an item occupies.
Definition: view.cpp:1334
void UpdateAllItemsConditionally(int aUpdateFlags, std::function< bool(VIEW_ITEM *)> aCondition)
Updates items in the view according to the given flags and condition.
Definition: view.cpp:1449
void SetLayerOrder(int aLayer, int aRenderingOrder)
Function SetLayerOrder() Sets rendering order of a particular layer.
Definition: view.cpp:663
void SetRequired(int aLayerId, int aRequiredId, bool aRequired=true)
Function SetRequired() Marks the aRequiredId layer as required for the aLayerId layer.
Definition: view.cpp:415
void updateItemColor(VIEW_ITEM *aItem, int aLayer)
Updates colors that are used for an item to be drawn.
Definition: view.cpp:1269
bool m_useDrawPriority
Flat list of all items Flag to respect draw priority when drawing items.
Definition: view.h:854
std::unique_ptr< KIGFX::VIEW_GROUP > m_preview
Definition: view.h:718
Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:175
virtual void DeleteGroup(int aGroupNumber)
Delete the group from the memory.
virtual void SetTopLayer(int aLayer, bool aEnabled=true)
Function SetTopLayer() Sets given layer to be displayed on the top or sets back the default order of ...
Definition: view.cpp:856
std::vector< int > getAllGroups() const
Function getAllGroups() Returns all group ids for the item (collected from all layers the item occupi...
Definition: view.cpp:126
static const int TOP_LAYER_MODIFIER
Rendering order modifier for layers that are marked as top layers.
Definition: view.h:850
const MATRIX3x3D & GetScreenWorldMatrix() const
Get the screen <-> world transformation matrix.
void sortLayers()
Definition: view.cpp:1254
int getFlags() const
Definition: view.cpp:64
VECTOR2D ToWorld(const VECTOR2D &aCoord, bool aAbsolute=true) const
Function ToWorld() Converts a screen space point/vector to a point/vector in world space coordinates.
Definition: view.cpp:474
double msecs(bool aSinceLast=false)
Definition: profile.h:143
coord_type GetTop() const
Definition: box2.h:204
queryVisitor(Container &aCont, int aLayer)
Definition: view.cpp:433
void AddToPreview(EDA_ITEM *aItem, bool aTakeOwnership=true)
Definition: view.cpp:1572
int color
Definition: DXF_plotter.cpp:61
void RecacheAllItems()
Function RecacheAllItems() Rebuilds GAL display lists.
Definition: view.cpp:1395
void UpdateAllItems(int aUpdateFlags)
Updates all items in the view according to the given flags.
Definition: view.cpp:1435
virtual void Remove(VIEW_ITEM *aItem)
Function Remove() Removes a VIEW_ITEM from the view.
Definition: view.cpp:375
void SetFlip(bool xAxis, bool yAxis)
Sets flipping of the screen.
void InitPreview()
Definition: view.cpp:1565
GAL * m_gal
Gives interface to PAINTER, that is used to draw items.
Definition: view.h:840
bool areRequiredLayersEnabled(int aLayerId) const
Checks if every layer required by the aLayerId layer is enabled.
Definition: view.cpp:1377
coord_type GetRight() const
Definition: box2.h:199
std::set< unsigned int > m_topLayers
Stores set of layers that are displayed on the top.
Definition: view.h:813
void SetSize(const Vec &size)
Definition: box2.h:212
void clearUpdateFlags()
Function clearUpdateFlags() Marks an item as already updated, so it is not going to be redrawn.
Definition: view.cpp:255
void UpdateAllLayersOrder()
Function UpdateLayerOrder() Does everything that is needed to apply the rendering order of layers.
Definition: view.cpp:923
No updates are required.
Definition: view_item.h:57
coord_type GetBottom() const
Definition: box2.h:200
void SetMirror(bool aMirrorX, bool aMirrorY)
Function SetMirror() Controls the mirroring of the VIEW.
Definition: view.cpp:564
VIEW_ITEM - is an abstract base class for deriving all objects that can be added to a VIEW.
Definition: view_item.h:85
Visibility flag has changed.
Definition: view_item.h:58
Item needs to be redrawn.
Definition: view_item.h:63
virtual void ComputeWorldScreenMatrix()
Compute the world <-> screen transformation matrix.
The class PROF_COUNTER is a small class to help profiling.
Definition: profile.h:44
virtual VIEW_ITEM * GetItem(unsigned int aIdx) const
Definition: view_group.cpp:86
virtual void SetLayerDepth(double aLayerDepth)
Set the depth of the layer (position on the z-axis)
std::shared_ptr< VIEW_OVERLAY > MakeOverlay()
Definition: view.cpp:1544
bool storesGroups() const
Function storesGroups() Returns information if the item uses at least one group id (ie.
Definition: view.cpp:189
virtual void EnableTopLayer(bool aEnable)
Function EnableTopLayer() Enables or disables display of the top layer.
Definition: view.cpp:883
void setGroup(int aLayer, int aGroup)
Function setGroup() Sets a group id for the item and the layer combination.
Definition: view.cpp:145
VECTOR2< T > GetScale() const
Get the scale components of the matrix.
Definition: matrix3x3.h:269
VECTOR2D m_center
Center point of the VIEW (the point at which we are looking at)
Definition: view.h:816
VIEW * m_view
Current dynamic view the item is assigned to.
Definition: view.cpp:89
static constexpr int VIEW_MAX_LAYERS
maximum number of layers that may be shown
Definition: view.h:697
virtual void EndGroup()
End the group.
Auxiliary rendering target (noncached)
Definition: definitions.h:49
std::shared_ptr< std::vector< VIEW_ITEM * > > m_allItems
Flat list of all items.
Definition: view.h:810
void SortLayers(int aLayers[], int &aCount) const
Function SortLayers() Changes the order of given layer ids, so after sorting the order corresponds to...
Definition: view.cpp:677
int getGroup(int aLayer) const
Function getGroup() Returns number of the group id for the given layer, or -1 in case it was not cach...
Definition: view.cpp:109
void ShowPreview(bool aShow=true)
Definition: view.cpp:1586
double m_minScale
Scale lower limit.
Definition: view.h:825
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:1082
virtual void ChangeGroupColor(int aGroupNumber, const COLOR4D &aNewColor)
Changes the color used to draw the group.
virtual const BOX2I GetItemsExtents() const
Return BBox of all items on screen except page and border.
Definition: view.cpp:1594
drawItem(VIEW *aView, int aLayer, bool aUseDrawPriority, bool aReverseDrawOrder)
Definition: view.cpp:957
const VECTOR2I & GetScreenPixelSize() const
Returns GAL canvas size in pixels.
virtual unsigned int GetSize() const
Function GetSize() Returns the number of stored items.
Definition: view_group.cpp:80
void SetPrintMode(int aPrintMode)
Set the printing mode.
Definition: view.h:695
PAINTER contains all the knowledge about how to draw graphical object onto any particular output devi...
Definition: painter.h:58
Container::value_type item_type
Definition: view.cpp:431
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:832
clearLayerCache(VIEW *aView)
Definition: view.cpp:1181
Item is being added to the view.
Definition: view_item.h:62
VIEW_ITEM class definition.
int m_drawPriority
Order to draw this item in a layer, lowest first.
Definition: view.cpp:92
void SetCenter(const VECTOR2D &aCenter)
Function SetCenter() Sets the center point of the VIEW (i.e.
Definition: view.cpp:603
#define NULL
VECTOR2< double > VECTOR2D
Definition: vector2d.h:593
virtual void Redraw()
Function Redraw() Immediately redraws the whole view.
Definition: view.cpp:1141
void MarkTargetDirty(int aTarget)
Function MarkTargetDirty() Sets or clears target 'dirty' flag.
Definition: view.h:574
bool IsTargetDirty(int aTarget) const
Function IsTargetDirty() Returns true if any of layers belonging to the target or the target itself s...
Definition: view.h:563
void Clear()
Function Clear() Removes all items from the view.
Definition: view.cpp:1107
bool IsVisible(const VIEW_ITEM *aItem) const
Returns information if the item is visible (or not).
Definition: view.cpp:1517
VIEW_ITEM_DATA * viewPrivData() const
Definition: view_item.h:149
virtual int GetTopLayer() const
Definition: view.cpp:847
coord_type GetWidth() const
Definition: box2.h:197
virtual int BeginGroup()
Begin a group.
BOX2< Vec > & Normalize()
Function Normalize ensures that the height ant width are positive.
Definition: box2.h:129
bool Contains(const Vec &aPoint) const
Function Contains.
Definition: box2.h:151
virtual void ClearTarget(RENDER_TARGET aTarget)
Clears the target for rendering.
void SetMaximum()
Definition: box2.h:73
virtual void ViewGetLayers(int aLayers[], int &aCount) const =0
Function ViewGetLayers() Returns the all the layers within the VIEW the object is painted on.
bool m_mirrorX
Horizontal flip flag
Definition: view.h:831
void invalidateItem(VIEW_ITEM *aItem, int aUpdateFlags)
Function invalidateItem() Manages dirty flags & redraw queueing when updating an item.
Definition: view.cpp:1209
void ClearPreview()
Definition: view.cpp:1553
const VECTOR2I & GetScreenPixelSize() const
Function GetScreenPixelSize() Returns the size of the our rendering area, in pixels.
Definition: view.cpp:1173
void reorderGroups(std::unordered_map< int, int > aReorderMap)
Reorders the stored groups (to facilitate reordering of layers)
Definition: view.cpp:201
int layers[VIEW_MAX_LAYERS]
Definition: view.cpp:1000
int id
layer ID
Definition: view.h:706
Items that may change while the view stays the same (noncached)
Definition: definitions.h:50
VIEW_GROUP extends VIEW_ITEM by possibility of grouping items into a single object.
void ReorderLayerData(std::unordered_map< int, int > aReorderMap)
Remaps the data between layer ids without invalidating that data.
Definition: view.cpp:705
void UpdateItems()
Function UpdateItems() Iterates through the list of items that asked for updating and updates them.
Definition: view.cpp:1412
void markTargetClean(int aTarget)
Definition: view.h:726
GroupPair * m_groups
Indexes of cached GAL display lists corresponding to the item (for every layer it occupies).
Definition: view.cpp:99
void updateBbox(VIEW_ITEM *aItem)
Updates bounding box of an item.
Definition: view.cpp:1318
PAINTER * m_painter
PAINTER contains information how do draw items.
Definition: view.h:837
bool m_reverseDrawOrder
Flag to reverse the draw order when using draw priority.
Definition: view.h:860
changeItemsDepth(int aLayer, int aDepth, GAL *aGal)
Definition: view.cpp:827
virtual void Update(VIEW_ITEM *aItem, int aUpdateFlags)
For dynamic VIEWs, informs the associated VIEW that the graphical representation of this item has cha...
Definition: view.cpp:1531
int m_nextDrawPriority
The next sequential drawing priority.
Definition: view.h:857
VECTOR2D ToScreen(const VECTOR2D &aCoord, bool aAbsolute=true) const
Function ToScreen() Converts a world space point/vector to a point/vector in screen space coordinates...
Definition: view.cpp:493
void saveLayers(int *aLayers, int aCount)
Function saveLayers() Saves layers used by the item.
Definition: view.cpp:229
std::vector< VIEW_LAYER > m_layers
Contains set of possible displayed layers and its properties.
Definition: view.h:804
void ClearTopLayers()
Function ClearTopLayers() Removes all layers from the on-the-top set (they are no longer displayed ov...
Definition: view.cpp:908
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:964
virtual bool Draw(const VIEW_ITEM *aItem, int aLayer)=0
Function Draw Takes an instance of VIEW_ITEM and passes it to a function that know how to draw the it...
void SetEnd(coord_type x, coord_type y)
Definition: box2.h:225
const Vec & GetPosition() const
Definition: box2.h:194
virtual void SetScale(double aScale, VECTOR2D aAnchor={ 0, 0 })
Function SetScale() Sets the scaling factor, zooming around a given anchor point.
Definition: view.cpp:577
void clearGroupCache()
Definition: view.cpp:1197
double m_maxScale
Scale upper limit.
Definition: view.h:828
void UpdateLayerColor(int aLayer)
Function UpdateLayerColor() Applies the new coloring scheme held by RENDER_SETTINGS in case that it h...
Definition: view.cpp:773
std::unique_ptr< VIEW > DataReference() const
Returns a new VIEW object that shares the same set of VIEW_ITEMs and LAYERs.
Definition: view.cpp:1467
virtual COLOR4D GetColor(const VIEW_ITEM *aItem, int aLayer) const =0
Returns the color that should be used to draw the specific VIEW_ITEM on the specific layer using curr...
std::vector< VIEW_ITEM * > drawItems
Definition: view.cpp:1002
virtual RENDER_SETTINGS * GetSettings()=0
Function GetAdapter Returns pointer to current settings that are going to be used when drawing items.
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:438
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:755
void redrawRect(const BOX2I &aRect)
Definition: view.cpp:1006
bool isRenderable() const
Function isRenderable() Returns if the item should be drawn or not.
Definition: view.cpp:264
std::vector< EDA_ITEM * > m_ownedItems
Definition: view.h:721
void updateItemGeometry(VIEW_ITEM *aItem, int aLayer)
Updates all informations needed to draw an item.
Definition: view.cpp:1288
Board layer functions and definitions.
Main rendering target (cached)
Definition: definitions.h:48
Vec Centre() const
Definition: box2.h:79
bool m_enableOrderModifier
Definition: view.h:801
static void OnDestroy(VIEW_ITEM *aItem)
Definition: view.cpp:271
#define _(s)
Definition: 3d_actions.cpp:33
BOX2D m_boundary
View boundaries.
Definition: view.h:822
std::vector< VIEW_LAYER * > m_orderedLayers
Sorted list of pointers to members of m_layers.
Definition: view.h:807
std::pair< VIEW_ITEM *, int > LAYER_ITEM_PAIR
Definition: view.h:66
int GetLayerOrder(int aLayer) const
Function GetLayerOrder() Returns rendering order of a particular layer.
Definition: view.cpp:671
void draw(VIEW_ITEM *aItem, int aLayer, bool aImmediate=false)
Function draw() Draws an item, but on a specified layers.
Definition: view.cpp:1025
bool IsCached(int aLayer) const
Returns true if the layer is cached.
Definition: view.h:581
void SetOrigin(const Vec &pos)
Definition: box2.h:210
virtual bool IsVisible() const
Returns true if the GAL canvas is visible on the screen.
void SetZoomFactor(double aZoomFactor)
Set the zoom factor of the scene.
virtual void ChangeGroupDepth(int aGroupNumber, int aDepth)
Changes the depth (Z-axis position) of the group.
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:159
bool m_mirrorY
Vertical flip flag
Definition: view.h:834
void ClearTargets()
Function ClearTargets() Clears targets that are marked as dirty.
Definition: view.cpp:1122
coord_type GetHeight() const
Definition: box2.h:198
int m_flags
Visibility flags.
Definition: view.cpp:90
void ClearViewPrivData()
Definition: view_item.h:154
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Sets the item visibility.
Definition: view.cpp:1477
void CopySettings(const VIEW *aOtherView)
Function CopySettings() Copies layers and visibility settings from another view.
Definition: view.cpp:512
double m_scale
Scale of displayed VIEW_ITEMs.
Definition: view.h:819
Position or shape has changed.
Definition: view_item.h:60
int renderingOrder
rendering order of this layer
Definition: view.h:705
void SetLookAtPoint(const VECTOR2D &aPoint)
Set the Point in world space to look at.
Container & m_cont
Definition: view.cpp:446
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:345
std::pair< int, int > GroupPair
Helper for storing cached items group ids
Definition: view.cpp:95
const Vec & GetSize() const
Definition: box2.h:189
virtual int Query(const BOX2I &aRect, std::vector< LAYER_ITEM_PAIR > &aResult) const
Function Query() Finds all visible items that touch or are within the rectangle aRect.
Definition: view.cpp:451
coord_type GetLeft() const
Definition: box2.h:203
virtual ~VIEW()
Definition: view.cpp:339
VIEW(bool aIsDynamic=true)
Constructor.
Definition: view.cpp:286
VIEW.
Definition: view.h:61
const MATRIX3x3D & GetWorldScreenMatrix() const
Get the world <-> screen transformation matrix.
void UpdateAllLayersColor()
Function UpdateAllLayersColor() Applies the new coloring scheme to all layers.
Definition: view.cpp:794
double GetScale() const
Function GetScale()
Definition: view.h:257
std::vector< int > m_layers
Stores layer numbers used by the item.
Definition: view.cpp:220
void SetGAL(GAL *aGal)
Function SetGAL() Assigns a rendering device for the VIEW.
Definition: view.cpp:518
int m_requiredUpdate
Flag required for updating.
Definition: view.cpp:91
recacheItem(VIEW *aView, GAL *aGal, int aLayer)
Definition: view.cpp:1077
static bool compareRenderingOrder(VIEW_LAYER *aI, VIEW_LAYER *aJ)
Determines rendering order of layers. Used in display order sorting function.
Definition: view.h:792
virtual void ClearCache()
Delete all data created during caching of graphic items.
virtual void SetTarget(RENDER_TARGET aTarget)
Sets the target for rendering.
void MarkDirty()
Function MarkDirty() Forces redraw of view on the next rendering.
Definition: view.h:599
updateItemsColor(int aLayer, PAINTER *aPainter, GAL *aGal)
Definition: view.cpp:750
virtual double ViewGetLOD(int aLayer, VIEW *aView) const
Function ViewGetLOD() Returns the level of detail (LOD) of the item.
Definition: view_item.h:141
void getLayers(int *aLayers, int &aCount) const
Function getLayers() Returns layer numbers used by the item.
Definition: view.cpp:79
Class GAL is the abstract interface for drawing on a 2D-surface.
Color has changed.
Definition: view_item.h:59
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:1186
virtual void ViewDraw(int aLayer, VIEW *aView) const
Function ViewDraw() Draws the parts of the object belonging to layer aLayer.
Definition: view_item.h:117
COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:99
BOX2< Vec > Intersect(const BOX2< Vec > &aRect)
Function Intersect Returns the intersection of this with another rectangle.
Definition: box2.h:268
RENDER_TARGET target
where the layer should be rendered
Definition: view.h:707
std::shared_ptr< VIEW_RTREE > items
R-tree indexing all items on this layer.
Definition: view.h:704