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