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 <gal/definitions.h>
36 #include <painter.h>
37 
38 #ifdef __WXDEBUG__
39 #include <profile.h>
40 #endif /* __WXDEBUG__ */
41 
42 namespace KIGFX {
43 
44 class VIEW;
45 
47 {
48 public:
50  m_view( nullptr ),
51  m_flags( KIGFX::VISIBLE ),
53  m_drawPriority( 0 ),
54  m_groups( nullptr ),
55  m_groupsSize( 0 ) {}
56 
58  {
59  deleteGroups();
60  }
61 
62  int getFlags() const
63  {
64  return m_flags;
65  }
66 
67 private:
68  friend class VIEW;
69 
77  void getLayers( int* aLayers, int& aCount ) const
78  {
79  int* layersPtr = aLayers;
80 
81  for( unsigned int i = 0; i < m_layers.size(); ++i )
82  {
83  if( m_layers[i] )
84  *layersPtr++ = i;
85  }
86 
87  aCount = m_layers.count();
88  }
89 
91  int m_flags;
94 
96  typedef std::pair<int, int> GroupPair;
97 
100  GroupPair* m_groups;
102 
110  int getGroup( int aLayer ) const
111  {
112  for( int i = 0; i < m_groupsSize; ++i )
113  {
114  if( m_groups[i].first == aLayer )
115  return m_groups[i].second;
116  }
117 
118  return -1;
119  }
120 
127  std::vector<int> getAllGroups() const
128  {
129  std::vector<int> groups( m_groupsSize );
130 
131  for( int i = 0; i < m_groupsSize; ++i )
132  {
133  groups[i] = m_groups[i].second;
134  }
135 
136  return groups;
137  }
138 
146  void setGroup( int aLayer, int aGroup )
147  {
148  // Look if there is already an entry for the layer
149  for( int i = 0; i < m_groupsSize; ++i )
150  {
151  if( m_groups[i].first == aLayer )
152  {
153  m_groups[i].second = aGroup;
154  return;
155  }
156  }
157 
158  // If there was no entry for the given layer - create one
159  GroupPair* newGroups = new GroupPair[m_groupsSize + 1];
160 
161  if( m_groupsSize > 0 )
162  {
163  std::copy( m_groups, m_groups + m_groupsSize, newGroups );
164  delete[] m_groups;
165  }
166 
167  m_groups = newGroups;
168  newGroups[m_groupsSize++] = GroupPair( aLayer, aGroup );
169  }
170 
171 
177  {
178  delete[] m_groups;
179  m_groups = nullptr;
180  m_groupsSize = 0;
181  }
182 
183 
190  inline bool storesGroups() const
191  {
192  return m_groupsSize > 0;
193  }
194 
196  std::bitset<VIEW::VIEW_MAX_LAYERS> m_layers;
197 
205  void saveLayers( int* aLayers, int aCount )
206  {
207  m_layers.reset();
208 
209  for( int i = 0; i < aCount; ++i )
210  {
211  // this fires on some eagle board after EAGLE_PLUGIN::Load()
212  wxASSERT( unsigned( aLayers[i] ) <= unsigned( VIEW::VIEW_MAX_LAYERS ) );
213 
214  m_layers.set( aLayers[i] );
215  }
216  }
217 
222  int requiredUpdate() const
223  {
224  return m_requiredUpdate;
225  }
226 
232  {
233  m_requiredUpdate = NONE;
234  }
235 
240  bool isRenderable() const
241  {
242  return m_flags == VISIBLE;
243  }
244 };
245 
246 
248 {
249  auto data = aItem->viewPrivData();
250 
251  if( !data )
252  return;
253 
254  if( data->m_view )
255  data->m_view->Remove( aItem );
256 
257  delete data;
258 }
259 
260 
261 VIEW::VIEW( bool aIsDynamic ) :
262  m_enableOrderModifier( true ),
263  m_scale( 4.0 ),
264  m_minScale( 4.0 ), m_maxScale( 15000 ),
265  m_mirrorX( false ), m_mirrorY( false ),
266  m_painter( NULL ),
267  m_gal( NULL ),
268  m_dynamic( aIsDynamic ),
269  m_useDrawPriority( false ),
270  m_nextDrawPriority( 0 )
271 {
273  m_allItems.reserve( 32768 );
274 
275  // Redraw everything at the beginning
276  MarkDirty();
277 
278  // View uses layers to display EDA_ITEMs (item may be displayed on several layers, for example
279  // pad may be shown on pad, pad hole and solder paste layers). There are usual copper layers
280  // (eg. F.Cu, B.Cu, internal and so on) and layers for displaying objects such as texts,
281  // silkscreen, pads, vias, etc.
282  for( int i = 0; i < VIEW_MAX_LAYERS; i++ )
283  AddLayer( i );
284 }
285 
286 
288 {
289  for( LAYER_MAP::value_type& l : m_layers )
290  delete l.second.items;
291 }
292 
293 
294 void VIEW::AddLayer( int aLayer, bool aDisplayOnly )
295 {
296  if( m_layers.find( aLayer ) == m_layers.end() )
297  {
298  m_layers[aLayer] = VIEW_LAYER();
299  m_layers[aLayer].id = aLayer;
300  m_layers[aLayer].items = new VIEW_RTREE();
301  m_layers[aLayer].renderingOrder = aLayer;
302  m_layers[aLayer].visible = true;
303  m_layers[aLayer].displayOnly = aDisplayOnly;
304  m_layers[aLayer].target = TARGET_CACHED;
305  }
306 
307  sortLayers();
308 }
309 
310 
311 void VIEW::Add( VIEW_ITEM* aItem, int aDrawPriority )
312 {
313  int layers[VIEW_MAX_LAYERS], layers_count;
314 
315  if( aDrawPriority < 0 )
316  aDrawPriority = m_nextDrawPriority++;
317 
318  if( !aItem->m_viewPrivData )
319  aItem->m_viewPrivData = new VIEW_ITEM_DATA;
320 
321  aItem->m_viewPrivData->m_view = this;
322  aItem->m_viewPrivData->m_drawPriority = aDrawPriority;
323 
324  aItem->ViewGetLayers( layers, layers_count );
325  aItem->viewPrivData()->saveLayers( layers, layers_count );
326 
327  m_allItems.push_back( aItem );
328 
329  for( int i = 0; i < layers_count; ++i )
330  {
331  VIEW_LAYER& l = m_layers[layers[i]];
332  l.items->Insert( aItem );
333  MarkTargetDirty( l.target );
334  }
335 
336  SetVisible( aItem, true );
337  Update( aItem, KIGFX::ALL );
338 }
339 
340 
341 void VIEW::Remove( VIEW_ITEM* aItem )
342 {
343  if( !aItem )
344  return;
345 
346  auto viewData = aItem->viewPrivData();
347 
348  if( !viewData )
349  return;
350 
351  wxASSERT( viewData->m_view == this );
352  auto item = std::find( m_allItems.begin(), m_allItems.end(), aItem );
353 
354  if( item != m_allItems.end() )
355  {
356  m_allItems.erase( item );
357  viewData->clearUpdateFlags();
358  }
359 
360  int layers[VIEW::VIEW_MAX_LAYERS], layers_count;
361  viewData->getLayers( layers, layers_count );
362 
363  for( int i = 0; i < layers_count; ++i )
364  {
365  VIEW_LAYER& l = m_layers[layers[i]];
366  l.items->Remove( aItem );
367  MarkTargetDirty( l.target );
368 
369  // Clear the GAL cache
370  int prevGroup = viewData->getGroup( layers[i] );
371 
372  if( prevGroup >= 0 )
373  m_gal->DeleteGroup( prevGroup );
374  }
375 
376  viewData->deleteGroups();
377  viewData->m_view = nullptr;
378 }
379 
380 
381 void VIEW::SetRequired( int aLayerId, int aRequiredId, bool aRequired )
382 {
383  wxASSERT( (unsigned) aLayerId < m_layers.size() );
384  wxASSERT( (unsigned) aRequiredId < m_layers.size() );
385 
386  if( aRequired )
387  m_layers[aLayerId].requiredLayers.insert( aRequiredId );
388  else
389  m_layers[aLayerId].requiredLayers.erase( aRequired );
390 }
391 
392 
393 // stupid C++... python lambda would do this in one line
394 template <class Container>
396 {
397  typedef typename Container::value_type item_type;
398 
399  queryVisitor( Container& aCont, int aLayer ) :
400  m_cont( aCont ), m_layer( aLayer )
401  {
402  }
403 
404  bool operator()( VIEW_ITEM* aItem )
405  {
406  if( aItem->viewPrivData()->getFlags() & VISIBLE )
407  m_cont.push_back( VIEW::LAYER_ITEM_PAIR( aItem, m_layer ) );
408 
409  return true;
410  }
411 
412  Container& m_cont;
413  int m_layer;
414 };
415 
416 
417 int VIEW::Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) const
418 {
419  if( m_orderedLayers.empty() )
420  return 0;
421 
422  std::vector<VIEW_LAYER*>::const_reverse_iterator i;
423 
424  // execute queries in reverse direction, so that items that are on the top of
425  // the rendering stack are returned first.
426  for( i = m_orderedLayers.rbegin(); i != m_orderedLayers.rend(); ++i )
427  {
428  // ignore layers that do not contain actual items (i.e. the selection box, menus, floats)
429  if( ( *i )->displayOnly )
430  continue;
431 
432  queryVisitor<std::vector<LAYER_ITEM_PAIR> > visitor( aResult, ( *i )->id );
433  ( *i )->items->Query( aRect, visitor );
434  }
435 
436  return aResult.size();
437 }
438 
439 
440 VECTOR2D VIEW::ToWorld( const VECTOR2D& aCoord, bool aAbsolute ) const
441 {
442  const MATRIX3x3D& matrix = m_gal->GetScreenWorldMatrix();
443 
444  if( aAbsolute )
445  return VECTOR2D( matrix * aCoord );
446  else
447  return VECTOR2D( matrix.GetScale().x * aCoord.x, matrix.GetScale().y * aCoord.y );
448 }
449 
450 
451 double VIEW::ToWorld( double aSize ) const
452 {
453  const MATRIX3x3D& matrix = m_gal->GetScreenWorldMatrix();
454 
455  return matrix.GetScale().x * aSize;
456 }
457 
458 
459 VECTOR2D VIEW::ToScreen( const VECTOR2D& aCoord, bool aAbsolute ) const
460 {
461  const MATRIX3x3D& matrix = m_gal->GetWorldScreenMatrix();
462 
463  if( aAbsolute )
464  return VECTOR2D( matrix * aCoord );
465  else
466  return VECTOR2D( matrix.GetScale().x * aCoord.x, matrix.GetScale().y * aCoord.y );
467 }
468 
469 
470 double VIEW::ToScreen( double aSize ) const
471 {
472  const MATRIX3x3D& matrix = m_gal->GetWorldScreenMatrix();
473 
474  return matrix.GetScale().x * aSize;
475 }
476 
477 
478 void VIEW::CopySettings( const VIEW* aOtherView )
479 {
480  wxASSERT_MSG( false, wxT( "This is not implemented" ) );
481 }
482 
483 
484 void VIEW::SetGAL( GAL* aGal )
485 {
486  m_gal = aGal;
487 
488  // clear group numbers, so everything is going to be recached
489  clearGroupCache();
490 
491  // every target has to be refreshed
492  MarkDirty();
493 
494  // force the new GAL to display the current viewport.
495  SetCenter( m_center );
496  SetScale( m_scale );
498 }
499 
500 
502 {
503  BOX2D rect;
504  VECTOR2D screenSize = m_gal->GetScreenPixelSize();
505 
506  rect.SetOrigin( ToWorld( VECTOR2D( 0, 0 ) ) );
507  rect.SetEnd( ToWorld( screenSize ) );
508 
509  return rect.Normalize();
510 }
511 
512 
513 void VIEW::SetViewport( const BOX2D& aViewport )
514 {
515  VECTOR2D ssize = ToWorld( m_gal->GetScreenPixelSize(), false );
516 
517  wxASSERT( ssize.x > 0 && ssize.y > 0 );
518 
519  VECTOR2D centre = aViewport.Centre();
520  VECTOR2D vsize = aViewport.GetSize();
521  double zoom = 1.0 / std::max( fabs( vsize.x / ssize.x ), fabs( vsize.y / ssize.y ) );
522 
523  SetCenter( centre );
524  SetScale( GetScale() * zoom );
525 }
526 
527 
528 void VIEW::SetMirror( bool aMirrorX, bool aMirrorY )
529 {
530  wxASSERT_MSG( !aMirrorY, _( "Mirroring for Y axis is not supported yet" ) );
531 
532  m_mirrorX = aMirrorX;
533  m_mirrorY = aMirrorY;
534  m_gal->SetFlip( aMirrorX, aMirrorY );
535 
536  // Redraw everything
537  MarkDirty();
538 }
539 
540 
541 void VIEW::SetScale( double aScale, const VECTOR2D& aAnchor )
542 {
543  VECTOR2D a = ToScreen( aAnchor );
544 
545  if( aScale < m_minScale )
547  else if( aScale > m_maxScale )
549  else
550  m_scale = aScale;
551 
554 
555  VECTOR2D delta = ToWorld( a ) - aAnchor;
556 
557  SetCenter( m_center - delta );
558 
559  // Redraw everything after the viewport has changed
560  MarkDirty();
561 }
562 
563 
564 void VIEW::SetCenter( const VECTOR2D& aCenter )
565 {
566  m_center = aCenter;
567 
568  if( !m_boundary.Contains( aCenter ) )
569  {
570  if( m_center.x < m_boundary.GetLeft() )
572  else if( aCenter.x > m_boundary.GetRight() )
574 
575  if( m_center.y < m_boundary.GetTop() )
577  else if( m_center.y > m_boundary.GetBottom() )
579  }
580 
583 
584  // Redraw everything after the viewport has changed
585  MarkDirty();
586 }
587 
588 
589 void VIEW::SetLayerOrder( int aLayer, int aRenderingOrder )
590 {
591  m_layers[aLayer].renderingOrder = aRenderingOrder;
592 
593  sortLayers();
594 }
595 
596 
597 int VIEW::GetLayerOrder( int aLayer ) const
598 {
599  return m_layers.at( aLayer ).renderingOrder;
600 }
601 
602 
603 void VIEW::SortLayers( int aLayers[], int& aCount ) const
604 {
605  int maxLay, maxOrd, maxIdx;
606 
607  for( int i = 0; i < aCount; ++i )
608  {
609  maxLay = aLayers[i];
610  maxOrd = GetLayerOrder( maxLay );
611  maxIdx = i;
612 
613  // Look for the max element in the range (j..aCount)
614  for( int j = i; j < aCount; ++j )
615  {
616  if( maxOrd < GetLayerOrder( aLayers[j] ) )
617  {
618  maxLay = aLayers[j];
619  maxOrd = GetLayerOrder( maxLay );
620  maxIdx = j;
621  }
622  }
623 
624  // Swap elements
625  aLayers[maxIdx] = aLayers[i];
626  aLayers[i] = maxLay;
627  }
628 }
629 
630 
632 {
633  updateItemsColor( int aLayer, PAINTER* aPainter, GAL* aGal ) :
634  layer( aLayer ), painter( aPainter ), gal( aGal )
635  {
636  }
637 
638  bool operator()( VIEW_ITEM* aItem )
639  {
640  // Obtain the color that should be used for coloring the item
641  const COLOR4D color = painter->GetSettings()->GetColor( aItem, layer );
642  int group = aItem->viewPrivData()->getGroup( layer );
643 
644  if( group >= 0 )
645  gal->ChangeGroupColor( group, color );
646 
647  return true;
648  }
649 
650  int layer;
653 };
654 
655 
656 void VIEW::UpdateLayerColor( int aLayer )
657 {
658  // There is no point in updating non-cached layers
659  if( !IsCached( aLayer ) )
660  return;
661 
662  BOX2I r;
663 
664  r.SetMaximum();
665 
666  m_gal->BeginUpdate();
667  updateItemsColor visitor( aLayer, m_painter, m_gal );
668  m_layers[aLayer].items->Query( r, visitor );
669  MarkTargetDirty( m_layers[aLayer].target );
670  m_gal->EndUpdate();
671 }
672 
673 
675 {
676  BOX2I r;
677 
678  r.SetMaximum();
679  m_gal->BeginUpdate();
680 
681  for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
682  {
683  VIEW_LAYER* l = &( ( *i ).second );
684 
685  // There is no point in updating non-cached layers
686  if( !IsCached( l->id ) )
687  continue;
688 
689  updateItemsColor visitor( l->id, m_painter, m_gal );
690  l->items->Query( r, visitor );
691  }
692 
693  m_gal->EndUpdate();
694  MarkDirty();
695 }
696 
697 
699 {
700  changeItemsDepth( int aLayer, int aDepth, GAL* aGal ) :
701  layer( aLayer ), depth( aDepth ), gal( aGal )
702  {
703  }
704 
705  bool operator()( VIEW_ITEM* aItem )
706  {
707  int group = aItem->viewPrivData()->getGroup( layer );
708 
709  if( group >= 0 )
710  gal->ChangeGroupDepth( group, depth );
711 
712  return true;
713  }
714 
715  int layer, depth;
717 };
718 
719 
720 void VIEW::ChangeLayerDepth( int aLayer, int aDepth )
721 {
722  // There is no point in updating non-cached layers
723  if( !IsCached( aLayer ) )
724  return;
725 
726  BOX2I r;
727 
728  r.SetMaximum();
729 
730  m_gal->BeginUpdate();
731  changeItemsDepth visitor( aLayer, aDepth, m_gal );
732  m_layers[aLayer].items->Query( r, visitor );
733  m_gal->EndUpdate();
734 
735  MarkTargetDirty( m_layers[aLayer].target );
736 }
737 
738 
739 int VIEW::GetTopLayer() const
740 {
741  if( m_topLayers.size() == 0 )
742  return 0;
743 
744  return *m_topLayers.begin();
745 }
746 
747 
748 void VIEW::SetTopLayer( int aLayer, bool aEnabled )
749 {
750  if( aEnabled )
751  {
752  if( m_topLayers.count( aLayer ) == 1 )
753  return;
754 
755  m_topLayers.insert( aLayer );
756 
757  // Move the layer closer to front
759  m_layers[aLayer].renderingOrder += TOP_LAYER_MODIFIER;
760  }
761  else
762  {
763  if( m_topLayers.count( aLayer ) == 0 )
764  return;
765 
766  m_topLayers.erase( aLayer );
767 
768  // Restore the previous rendering order
770  m_layers[aLayer].renderingOrder -= TOP_LAYER_MODIFIER;
771  }
772 }
773 
774 
775 void VIEW::EnableTopLayer( bool aEnable )
776 {
777  if( aEnable == m_enableOrderModifier )
778  return;
779 
780  m_enableOrderModifier = aEnable;
781 
782  std::set<unsigned int>::iterator it;
783 
784  if( aEnable )
785  {
786  for( it = m_topLayers.begin(); it != m_topLayers.end(); ++it )
787  m_layers[*it].renderingOrder += TOP_LAYER_MODIFIER;
788  }
789  else
790  {
791  for( it = m_topLayers.begin(); it != m_topLayers.end(); ++it )
792  m_layers[*it].renderingOrder -= TOP_LAYER_MODIFIER;
793  }
794 
797 }
798 
799 
801 {
802  std::set<unsigned int>::iterator it;
803 
805  {
806  // Restore the previous rendering order for layers that were marked as top
807  for( it = m_topLayers.begin(); it != m_topLayers.end(); ++it )
808  m_layers[*it].renderingOrder -= TOP_LAYER_MODIFIER;
809  }
810 
811  m_topLayers.clear();
812 }
813 
814 
816 {
817  sortLayers();
818 
819  for( LAYER_MAP::value_type& l : m_layers )
820  {
821  ChangeLayerDepth( l.first, l.second.renderingOrder );
822  }
823 
824  MarkDirty();
825 }
826 
827 
829 {
830  drawItem( VIEW* aView, int aLayer, bool aUseDrawPriority ) :
831  view( aView ), layer( aLayer ), useDrawPriority( aUseDrawPriority )
832  {
833  }
834 
835  bool operator()( VIEW_ITEM* aItem )
836  {
837  wxASSERT( aItem->viewPrivData() );
838 
839  // Conditions that have te be fulfilled for an item to be drawn
840  bool drawCondition = aItem->viewPrivData()->isRenderable() &&
841  aItem->ViewGetLOD( layer, view ) < view->m_scale;
842  if( !drawCondition )
843  return true;
844 
845  if( useDrawPriority )
846  drawItems.push_back( aItem );
847  else
848  view->draw( aItem, layer );
849 
850  return true;
851  }
852 
854  {
855  std::sort( drawItems.begin(), drawItems.end(),
856  []( VIEW_ITEM* a, VIEW_ITEM* b ) -> bool {
857  return b->viewPrivData()->m_drawPriority < a->viewPrivData()->m_drawPriority;
858  });
859 
860  for( auto item : drawItems )
861  view->draw( item, layer );
862  }
863 
867  std::vector<VIEW_ITEM*> drawItems;
868 };
869 
870 
871 void VIEW::redrawRect( const BOX2I& aRect )
872 {
873  for( VIEW_LAYER* l : m_orderedLayers )
874  {
875  if( l->visible && IsTargetDirty( l->target ) && areRequiredLayersEnabled( l->id ) )
876  {
877  drawItem drawFunc( this, l->id, m_useDrawPriority );
878 
879  m_gal->SetTarget( l->target );
880  m_gal->SetLayerDepth( l->renderingOrder );
881  l->items->Query( aRect, drawFunc );
882 
883  if( m_useDrawPriority )
884  drawFunc.deferredDraw();
885  }
886  }
887 }
888 
889 
890 void VIEW::draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate )
891 {
892  auto viewData = aItem->viewPrivData();
893 
894  if( !viewData )
895  return;
896 
897  if( IsCached( aLayer ) && !aImmediate )
898  {
899  // Draw using cached information or create one
900  int group = viewData->getGroup( aLayer );
901 
902  if( group >= 0 )
903  {
904  m_gal->DrawGroup( group );
905  }
906  else
907  {
908  group = m_gal->BeginGroup();
909  viewData->setGroup( aLayer, group );
910 
911  if( !m_painter->Draw( aItem, aLayer ) )
912  aItem->ViewDraw( aLayer, this ); // Alternative drawing method
913 
914  m_gal->EndGroup();
915  }
916  }
917  else
918  {
919  // Immediate mode
920  if( !m_painter->Draw( aItem, aLayer ) )
921  aItem->ViewDraw( aLayer, this ); // Alternative drawing method
922  }
923 }
924 
925 
926 void VIEW::draw( VIEW_ITEM* aItem, bool aImmediate )
927 {
928  int layers[VIEW_MAX_LAYERS], layers_count;
929 
930  aItem->ViewGetLayers( layers, layers_count );
931 
932  // Sorting is needed for drawing order dependent GALs (like Cairo)
933  SortLayers( layers, layers_count );
934 
935  for( int i = 0; i < layers_count; ++i )
936  {
937  m_gal->SetLayerDepth( m_layers.at( layers[i] ).renderingOrder );
938  draw( aItem, layers[i], aImmediate );
939  }
940 }
941 
942 
943 void VIEW::draw( VIEW_GROUP* aGroup, bool aImmediate )
944 {
945  for( unsigned int i = 0; i < aGroup->GetSize(); i++)
946  draw( aGroup->GetItem(i), aImmediate );
947 }
948 
949 
951 {
952  recacheItem( VIEW* aView, GAL* aGal, int aLayer ) :
953  view( aView ), gal( aGal ), layer( aLayer )
954  {
955  }
956 
957  bool operator()( VIEW_ITEM* aItem )
958  {
959  auto viewData = aItem->viewPrivData();
960 
961  if( !viewData )
962  return false;
963 
964  // Remove previously cached group
965  int group = viewData->getGroup( layer );
966 
967  if( group >= 0 )
968  gal->DeleteGroup( group );
969 
970  viewData->setGroup( layer, -1 );
971  view->Update( aItem );
972 
973  return true;
974  }
975 
978  int layer;
979 };
980 
981 
983 {
984  BOX2I r;
985  r.SetMaximum();
986  m_allItems.clear();
987 
988  for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
989  i->second.items->RemoveAll();
990 
991  m_nextDrawPriority = 0;
992 
993  m_gal->ClearCache();
994 }
995 
996 
998 {
1000  {
1001  // TARGET_CACHED and TARGET_NONCACHED have to be redrawn together, as they contain
1002  // layers that rely on each other (eg. netnames are noncached, but tracks - are cached)
1005 
1006  MarkDirty();
1007  }
1008 
1009  if( IsTargetDirty( TARGET_OVERLAY ) )
1010  {
1012  }
1013 }
1014 
1015 
1017 {
1018 #ifdef __WXDEBUG__
1019  PROF_COUNTER totalRealTime;
1020 #endif /* __WXDEBUG__ */
1021 
1022  VECTOR2D screenSize = m_gal->GetScreenPixelSize();
1023  BOX2I rect( ToWorld( VECTOR2D( 0, 0 ) ),
1024  ToWorld( screenSize ) - ToWorld( VECTOR2D( 0, 0 ) ) );
1025  rect.Normalize();
1026 
1027  redrawRect( rect );
1028 
1029  // All targets were redrawn, so nothing is dirty
1033 
1034 #ifdef __WXDEBUG__
1035  totalRealTime.Stop();
1036  wxLogTrace( "GAL_PROFILE", wxT( "VIEW::Redraw(): %.1f ms" ), totalRealTime.msecs() );
1037 #endif /* __WXDEBUG__ */
1038 }
1039 
1040 
1042 {
1043  return m_gal->GetScreenPixelSize();
1044 }
1045 
1046 
1048 {
1049  clearLayerCache( VIEW* aView ) :
1050  view( aView )
1051  {
1052  }
1053 
1054  bool operator()( VIEW_ITEM* aItem )
1055  {
1056  aItem->viewPrivData()->deleteGroups();
1057 
1058  return true;
1059  }
1060 
1062 };
1063 
1064 
1066 {
1067  BOX2I r;
1068 
1069  r.SetMaximum();
1070  clearLayerCache visitor( this );
1071 
1072  for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
1073  {
1074  VIEW_LAYER* l = &( ( *i ).second );
1075  l->items->Query( r, visitor );
1076  }
1077 }
1078 
1079 
1080 void VIEW::invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags )
1081 {
1082  // updateLayers updates geometry too, so we do not have to update both of them at the same time
1083  if( aUpdateFlags & LAYERS )
1084  updateLayers( aItem );
1085  else if( aUpdateFlags & GEOMETRY )
1086  updateBbox( aItem );
1087 
1088  int layers[VIEW_MAX_LAYERS], layers_count;
1089  aItem->ViewGetLayers( layers, layers_count );
1090 
1091  // Iterate through layers used by the item and recache it immediately
1092  for( int i = 0; i < layers_count; ++i )
1093  {
1094  int layerId = layers[i];
1095 
1096  if( IsCached( layerId ) )
1097  {
1098  if( aUpdateFlags & ( GEOMETRY | LAYERS ) )
1099  updateItemGeometry( aItem, layerId );
1100  else if( aUpdateFlags & COLOR )
1101  updateItemColor( aItem, layerId );
1102  }
1103 
1104  // Mark those layers as dirty, so the VIEW will be refreshed
1105  MarkTargetDirty( m_layers[layerId].target );
1106  }
1107 
1108  aItem->viewPrivData()->clearUpdateFlags();
1109 }
1110 
1111 
1113 {
1114  int n = 0;
1115 
1116  m_orderedLayers.resize( m_layers.size() );
1117 
1118  for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
1119  m_orderedLayers[n++] = &i->second;
1120 
1121  sort( m_orderedLayers.begin(), m_orderedLayers.end(), compareRenderingOrder );
1122 
1123  MarkDirty();
1124 }
1125 
1126 
1127 void VIEW::updateItemColor( VIEW_ITEM* aItem, int aLayer )
1128 {
1129  auto viewData = aItem->viewPrivData();
1130  wxASSERT( (unsigned) aLayer < m_layers.size() );
1131  wxASSERT( IsCached( aLayer ) );
1132 
1133  if( !viewData )
1134  return;
1135 
1136  // Obtain the color that should be used for coloring the item on the specific layerId
1137  const COLOR4D color = m_painter->GetSettings()->GetColor( aItem, aLayer );
1138  int group = viewData->getGroup( aLayer );
1139 
1140  // Change the color, only if it has group assigned
1141  if( group >= 0 )
1142  m_gal->ChangeGroupColor( group, color );
1143 }
1144 
1145 
1146 void VIEW::updateItemGeometry( VIEW_ITEM* aItem, int aLayer )
1147 {
1148  auto viewData = aItem->viewPrivData();
1149  wxASSERT( (unsigned) aLayer < m_layers.size() );
1150  wxASSERT( IsCached( aLayer ) );
1151 
1152  if( !viewData )
1153  return;
1154 
1155  VIEW_LAYER& l = m_layers.at( aLayer );
1156 
1157  m_gal->SetTarget( l.target );
1159 
1160  // Redraw the item from scratch
1161  int group = viewData->getGroup( aLayer );
1162 
1163  if( group >= 0 )
1164  m_gal->DeleteGroup( group );
1165 
1166  group = m_gal->BeginGroup();
1167  viewData->setGroup( aLayer, group );
1168 
1169  if( !m_painter->Draw( static_cast<EDA_ITEM*>( aItem ), aLayer ) )
1170  aItem->ViewDraw( aLayer, this ); // Alternative drawing method
1171 
1172  m_gal->EndGroup();
1173 }
1174 
1175 
1177 {
1178  int layers[VIEW_MAX_LAYERS], layers_count;
1179 
1180  aItem->ViewGetLayers( layers, layers_count );
1181 
1182  for( int i = 0; i < layers_count; ++i )
1183  {
1184  VIEW_LAYER& l = m_layers[layers[i]];
1185  l.items->Remove( aItem );
1186  l.items->Insert( aItem );
1187  MarkTargetDirty( l.target );
1188  }
1189 }
1190 
1191 
1193 {
1194  auto viewData = aItem->viewPrivData();
1195  int layers[VIEW_MAX_LAYERS], layers_count;
1196 
1197  if( !viewData )
1198  return;
1199 
1200  // Remove the item from previous layer set
1201  viewData->getLayers( layers, layers_count );
1202 
1203  for( int i = 0; i < layers_count; ++i )
1204  {
1205  VIEW_LAYER& l = m_layers[layers[i]];
1206  l.items->Remove( aItem );
1207  MarkTargetDirty( l.target );
1208 
1209  if( IsCached( l.id ) )
1210  {
1211  // Redraw the item from scratch
1212  int prevGroup = viewData->getGroup( layers[i] );
1213 
1214  if( prevGroup >= 0 )
1215  {
1216  m_gal->DeleteGroup( prevGroup );
1217  viewData->setGroup( l.id, -1 );
1218  }
1219  }
1220  }
1221 
1222  // Add the item to new layer set
1223  aItem->ViewGetLayers( layers, layers_count );
1224  viewData->saveLayers( layers, layers_count );
1225 
1226  for( int i = 0; i < layers_count; i++ )
1227  {
1228  VIEW_LAYER& l = m_layers[layers[i]];
1229  l.items->Insert( aItem );
1230  MarkTargetDirty( l.target );
1231  }
1232 }
1233 
1234 
1235 bool VIEW::areRequiredLayersEnabled( int aLayerId ) const
1236 {
1237  wxASSERT( (unsigned) aLayerId < m_layers.size() );
1238 
1239  std::set<int>::const_iterator it, it_end;
1240 
1241  for( it = m_layers.at( aLayerId ).requiredLayers.begin(),
1242  it_end = m_layers.at( aLayerId ).requiredLayers.end(); it != it_end; ++it )
1243  {
1244  // That is enough if just one layer is not enabled
1245  if( !m_layers.at( *it ).visible || !areRequiredLayersEnabled( *it ) )
1246  return false;
1247  }
1248 
1249  return true;
1250 }
1251 
1252 
1254 {
1255  BOX2I r;
1256 
1257  r.SetMaximum();
1258 
1259  for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
1260  {
1261  VIEW_LAYER* l = &( ( *i ).second );
1262 
1263  if( IsCached( l->id ) )
1264  {
1265  recacheItem visitor( this, m_gal, l->id );
1266  l->items->Query( r, visitor );
1267  }
1268  }
1269 }
1270 
1271 
1273 {
1274  m_gal->BeginUpdate();
1275 
1276  for( VIEW_ITEM* item : m_allItems )
1277  {
1278  auto viewData = item->viewPrivData();
1279 
1280  if( !viewData )
1281  continue;
1282 
1283  if( viewData->m_requiredUpdate != NONE )
1284  {
1285  invalidateItem( item, viewData->m_requiredUpdate );
1286  viewData->m_requiredUpdate = NONE;
1287  }
1288  }
1289 
1290  m_gal->EndUpdate();
1291 }
1292 
1293 
1295 {
1297  bool first;
1298 
1300  {
1301  first = true;
1302  }
1303 
1304  bool operator()( VIEW_ITEM* aItem )
1305  {
1306  if( first )
1307  extents = aItem->ViewBBox();
1308  else
1309  extents.Merge( aItem->ViewBBox() );
1310 
1311  return false;
1312  }
1313 };
1314 
1315 
1317 {
1318  extentsVisitor v;
1319  BOX2I fullScene;
1320  fullScene.SetMaximum();
1321 
1322  for( VIEW_LAYER* l : m_orderedLayers )
1323  {
1324  l->items->Query( fullScene, v );
1325  }
1326 
1327  return v.extents;
1328 }
1329 
1330 
1331 void VIEW::SetVisible( VIEW_ITEM* aItem, bool aIsVisible )
1332 {
1333  auto viewData = aItem->viewPrivData();
1334 
1335  if( !viewData )
1336  return;
1337 
1338  bool cur_visible = viewData->m_flags & VISIBLE;
1339 
1340  if( cur_visible != aIsVisible )
1341  {
1342  if( aIsVisible )
1343  viewData->m_flags |= VISIBLE;
1344  else
1345  viewData->m_flags &= ~VISIBLE;
1346 
1347  Update( aItem, APPEARANCE | COLOR );
1348  }
1349 }
1350 
1351 
1352 void VIEW::Hide( VIEW_ITEM* aItem, bool aHide )
1353 {
1354  auto viewData = aItem->viewPrivData();
1355 
1356  if( !viewData )
1357  return;
1358 
1359  if( !( viewData->m_flags & VISIBLE ) )
1360  return;
1361 
1362  if( aHide )
1363  viewData->m_flags |= HIDDEN;
1364  else
1365  viewData->m_flags &= ~HIDDEN;
1366 
1367  Update( aItem, APPEARANCE );
1368 }
1369 
1370 
1371 bool VIEW::IsVisible( const VIEW_ITEM* aItem ) const
1372 {
1373  const auto viewData = aItem->viewPrivData();
1374 
1375  return viewData->m_flags & VISIBLE;
1376 }
1377 
1378 
1379 void VIEW::Update( VIEW_ITEM* aItem )
1380 {
1381  Update( aItem, ALL );
1382 }
1383 
1384 
1385 void VIEW::Update( VIEW_ITEM* aItem, int aUpdateFlags )
1386 {
1387  auto viewData = aItem->viewPrivData();
1388 
1389  if( !viewData )
1390  return;
1391 
1392  assert( aUpdateFlags != NONE );
1393 
1394  viewData->m_requiredUpdate |= aUpdateFlags;
1395 
1396 }
1397 
1398 const int VIEW::TOP_LAYER_MODIFIER = -VIEW_MAX_LAYERS;
1399 
1400 };
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:1352
virtual void DrawGroup(int aGroupNumber)
Draw the stored group.
Item is visible (in general)
Definition: view_item.h:68
int GetTopLayer() const
Definition: view.cpp:739
void deleteGroups()
Function deleteGroups() Removes all of the stored group ids.
Definition: view.cpp:176
VIEW_ITEM_DATA * m_viewPrivData
Definition: view_item.h:149
void SetViewport(const BOX2D &aViewport)
Function SetViewport() Sets the visible area of the VIEW.
Definition: view.cpp:513
void updateLayers(VIEW_ITEM *aItem)
Updates set of layers that an item occupies.
Definition: view.cpp:1192
void AddLayer(int aLayer, bool aDisplayOnly=false)
Function AddLayer() Adds a new layer to the view.
Definition: view.cpp:294
void SetLayerOrder(int aLayer, int aRenderingOrder)
Function SetLayerOrder() Sets rendering order of a particular layer.
Definition: view.cpp:589
void SetRequired(int aLayerId, int aRequiredId, bool aRequired=true)
Function SetRequired() Marks the aRequiredId layer as required for the aLayerId layer.
Definition: view.cpp:381
void updateItemColor(VIEW_ITEM *aItem, int aLayer)
Updates colors that are used for an item to be drawn.
Definition: view.cpp:1127
bool m_useDrawPriority
Flag to respect draw priority when drawing items.
Definition: view.h:803
Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
Definition: class_module.h:58
virtual void DeleteGroup(int aGroupNumber)
Delete the group from the memory.
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:748
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:417
virtual VIEW_ITEM * GetItem(unsigned int aIdx) const
Definition: view_group.cpp:86
static const int TOP_LAYER_MODIFIER
Rendering order modifier for layers that are marked as top layers.
Definition: view.h:797
void sortLayers()
Definition: view.cpp:1112
queryVisitor(Container &aCont, int aLayer)
Definition: view.cpp:399
bool Contains(const Vec &aPoint) const
Function Contains.
Definition: box2.h:139
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:110
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:440
void RecacheAllItems()
Function RecacheAllItems() Rebuilds GAL display lists.
Definition: view.cpp:1253
void Remove(VIEW_ITEM *aItem)
Function Remove() Removes a VIEW_ITEM from the view.
Definition: view.cpp:341
const MATRIX3x3D & GetScreenWorldMatrix() const
Get the screen <-> world transformation matrix.
void SetFlip(bool xAxis, bool yAxis)
Sets flipping of the screen.
virtual void EndUpdate()
Disables item update mode.
GAL * m_gal
Gives interface to PAINTER, that is used to draw items.
Definition: view.h:787
coord_type GetRight() const
Definition: box2.h:187
std::set< unsigned int > m_topLayers
Stores set of layers that are displayed on the top.
Definition: view.h:760
void clearUpdateFlags()
Function clearUpdateFlags() Marks an item as already updated, so it is not going to be redrawn...
Definition: view.cpp:231
void UpdateAllLayersOrder()
Function UpdateLayerOrder() Does everything that is needed to apply the rendering order of layers...
Definition: view.cpp:815
No updates are required.
Definition: view_item.h:55
int requiredUpdate() const
Function viewRequiredUpdate() Returns current update flag for an item.
Definition: view.cpp:222
void Remove(VIEW_ITEM *aItem)
Function Remove() Removes an item from the tree.
Definition: view_rtree.h:63
void SetMirror(bool aMirrorX, bool aMirrorY)
Function SetMirror() Controls the mirroring of the VIEW.
Definition: view.cpp:528
Class VIEW_ITEM - is an abstract base class for deriving all objects that can be added to a VIEW...
Definition: view_item.h:82
Visibility flag has changed.
Definition: view_item.h:56
bool isRenderable() const
Function isRenderable() Returns if the item should be drawn or not.
Definition: view.cpp:240
Layers have changed.
Definition: view_item.h:59
const Vec & GetSize() const
Definition: box2.h:177
virtual void ComputeWorldScreenMatrix()
Compute the world <-> screen transformation matrix.
The class PROF_COUNTER is a small class to help profiling.
Definition: profile.h:45
void SetScale(double aScale)
Function SetScale() Sets the scaling factor.
Definition: view.h:247
virtual void SetLayerDepth(double aLayerDepth)
Set the depth of the layer (position on the z-axis)
void EnableTopLayer(bool aEnable)
Function EnableTopLayer() Enables or disables display of the top layer.
Definition: view.cpp:775
void setGroup(int aLayer, int aGroup)
Function setGroup() Sets a group id for the item and the layer combination.
Definition: view.cpp:146
const MATRIX3x3D & GetWorldScreenMatrix() const
Get the world <-> screen transformation matrix.
coord_type GetTop() const
Definition: box2.h:192
static const int delta[8][2]
Definition: solve.cpp:112
VECTOR2D m_center
Center point of the VIEW (the point at which we are looking at)
Definition: view.h:763
VIEW * m_view
Current dynamic view the item is assigned to.
Definition: view.cpp:90
int getFlags() const
Definition: view.cpp:62
virtual const COLOR4D & GetColor(const VIEW_ITEM *aItem, int aLayer) const =0
Function GetColor Returns the color that should be used to draw the specific VIEW_ITEM on the specifi...
virtual void EndGroup()
End the group.
Auxiliary rendering target (noncached)
Definition: definitions.h:42
void Insert(VIEW_ITEM *aItem)
Function Insert() Inserts an item into the tree.
Definition: view_rtree.h:49
double m_minScale
Scale lower limit.
Definition: view.h:772
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:957
virtual void ChangeGroupColor(int aGroupNumber, const COLOR4D &aNewColor)
Changes the color used to draw the group.
std::vector< int > getAllGroups() const
Function getAllGroups() Returns all group ids for the item (collected from all layers the item occupi...
Definition: view.cpp:127
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:603
Class PAINTER contains all the knowledge about how to draw graphical object onto any particular outpu...
Definition: painter.h:278
Container::value_type item_type
Definition: view.cpp:397
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:705
clearLayerCache(VIEW *aView)
Definition: view.cpp:1049
VIEW_ITEM class definition.
int m_drawPriority
Order to draw this item in a layer, lowest first.
Definition: view.cpp:93
BOX2I m_boundary
View boundaries.
Definition: view.h:769
void SetCenter(const VECTOR2D &aCenter)
Function SetCenter() Sets the center point of the VIEW (i.e.
Definition: view.cpp:564
BOX2D GetViewport() const
Function GetViewport() Returns the current viewport visible area rectangle.
Definition: view.cpp:501
bool storesGroups() const
Function storesGroups() Returns information if the item uses at least one group id (ie...
Definition: view.cpp:190
VECTOR2< double > VECTOR2D
Definition: vector2d.h:589
void Redraw()
Function Redraw() Immediately redraws the whole view.
Definition: view.cpp:1016
void MarkTargetDirty(int aTarget)
Function MarkTargetDirty() Sets or clears target 'dirty' flag.
Definition: view.h:576
void Clear()
Function Clear() Removes all items from the view.
Definition: view.cpp:982
int GetLayerOrder(int aLayer) const
Function GetLayerOrder() Returns rendering order of a particular layer.
Definition: view.cpp:597
drawItem(VIEW *aView, int aLayer, bool aUseDrawPriority)
Definition: view.cpp:830
virtual int BeginGroup()
Begin a group.
const BOX2I CalculateExtents()
Definition: view.cpp:1316
BOX2< Vec > & Normalize()
Function Normalize ensures that the height ant width are positive.
Definition: box2.h:117
virtual void ClearTarget(RENDER_TARGET aTarget)
Clears the target for rendering.
void SetMaximum()
Definition: box2.h:61
virtual void ViewGetLayers(int aLayers[], int &aCount) const =0
Function ViewGetLayers() Returns the all the layers within the VIEW the object is painted on...
static const int VIEW_MAX_LAYERS
maximum number of layers that may be shown
Definition: view.h:641
bool m_mirrorX
Horizontal flip flag
Definition: view.h:778
void invalidateItem(VIEW_ITEM *aItem, int aUpdateFlags)
Function invalidateItem() Manages dirty flags & redraw queueing when updating an item.
Definition: view.cpp:1080
coord_type GetBottom() const
Definition: box2.h:188
Class VIEW_RTREE - Implements an R-tree for fast spatial indexing of VIEW items.
Definition: view_rtree.h:41
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:564
int layers[VIEW_MAX_LAYERS]
Definition: view.cpp:865
int id
layer ID
Definition: view.h:651
Items that may change while the view stays the same (noncached)
Definition: definitions.h:43
virtual void BeginUpdate()
Enables item update mode.
VIEW_GROUP extends VIEW_ITEM by possibility of grouping items into a single object.
LAYER_ORDER m_orderedLayers
Sorted list of pointers to members of m_layers.
Definition: view.h:757
void UpdateItems()
Function UpdateItems() Iterates through the list of items that asked for updating and updates them...
Definition: view.cpp:1272
void markTargetClean(int aTarget)
Definition: view.h:675
GroupPair * m_groups
Indexes of cached GAL display lists corresponding to the item (for every layer it occupies)...
Definition: view.cpp:100
void updateBbox(VIEW_ITEM *aItem)
Updates bounding box of an item.
Definition: view.cpp:1176
PAINTER * m_painter
PAINTER contains information how do draw items.
Definition: view.h:784
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Function Merge modifies the position and size of the rectangle in order to contain aRect...
Definition: box2.h:350
changeItemsDepth(int aLayer, int aDepth, GAL *aGal)
Definition: view.cpp:700
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:1385
void Query(const BOX2I &aBounds, Visitor &aVisitor)
Function Query() Executes a function object aVisitor for each item whose bounding box intersects with...
Definition: view_rtree.h:80
int m_nextDrawPriority
The next sequential drawing priority.
Definition: view.h:806
void saveLayers(int *aLayers, int aCount)
Function saveLayers() Saves layers used by the item.
Definition: view.cpp:205
Vec Centre() const
Definition: box2.h:67
virtual unsigned int GetSize() const
Function GetSize() Returns the number of stored items.
Definition: view_group.cpp:80
void ClearTopLayers()
Function ClearTopLayers() Removes all layers from the on-the-top set (they are no longer displayed ov...
Definition: view.cpp:800
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:835
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...
LAYER_MAP::iterator LAYER_MAP_ITER
Definition: view.h:658
void SetEnd(coord_type x, coord_type y)
Definition: box2.h:213
const VECTOR2I & GetScreenPixelSize() const
Returns GAL canvas size in pixels.
void clearGroupCache()
Definition: view.cpp:1065
VIEW_ITEM_DATA * viewPrivData() const
Definition: view_item.h:141
double m_maxScale
Scale upper limit.
Definition: view.h:775
void UpdateLayerColor(int aLayer)
Function UpdateLayerColor() Applies the new coloring scheme held by RENDER_SETTINGS in case that it h...
Definition: view.cpp:656
double msecs() const
Definition: profile.h:124
std::vector< VIEW_ITEM * > drawItems
Definition: view.cpp:867
virtual RENDER_SETTINGS * GetSettings()=0
Function GetSettings Returns pointer to current settings that are going to be used when drawing items...
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:404
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:638
void redrawRect(const BOX2I &aRect)
Definition: view.cpp:871
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:1304
void updateItemGeometry(VIEW_ITEM *aItem, int aLayer)
Updates all informations needed to draw an item.
Definition: view.cpp:1146
Board layer functions and definitions.
Main rendering target (cached)
Definition: definitions.h:41
void ChangeLayerDepth(int aLayer, int aDepth)
Function ChangeLayerDepth() Changes the depth of items on the given layer.
Definition: view.cpp:720
bool areRequiredLayersEnabled(int aLayerId) const
Checks if every layer required by the aLayerId layer is enabled.
Definition: view.cpp:1235
bool m_enableOrderModifier
Definition: view.h:751
#define max(a, b)
Definition: auxiliary.h:86
static void OnDestroy(VIEW_ITEM *aItem)
Definition: view.cpp:247
virtual void ViewDraw(int aLayer, VIEW *aView) const
Function ViewDraw() Draws the parts of the object belonging to layer aLayer.
Definition: view_item.h:114
std::vector< VIEW_ITEM * > m_allItems
Flat list of all items.
Definition: view.h:800
void getLayers(int *aLayers, int &aCount) const
Function getLayers() Returns layer numbers used by the item.
Definition: view.cpp:77
std::bitset< VIEW::VIEW_MAX_LAYERS > m_layers
Stores layer numbers used by the item.
Definition: view.cpp:196
bool IsCached(int aLayer) const
Returns true if the layer is cached.
Definition: view.h:584
std::pair< VIEW_ITEM *, int > LAYER_ITEM_PAIR
Definition: view.h:63
void draw(VIEW_ITEM *aItem, int aLayer, bool aImmediate=false)
Function draw() Draws an item, but on a specified layers.
Definition: view.cpp:890
virtual unsigned int ViewGetLOD(int aLayer, VIEW *aView) const
Function ViewGetLOD() Returns the level of detail of the item.
Definition: view_item.h:133
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:459
void SetOrigin(const Vec &pos)
Definition: box2.h:198
const VECTOR2I & GetScreenPixelSize() const
Function GetScreenPixelSize() Returns the size of the our rendering area, in pixels.
Definition: view.cpp:1041
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.
bool m_mirrorY
Vertical flip flag
Definition: view.h:781
void ClearTargets()
Function ClearTargets() Clears targets that are marked as dirty.
Definition: view.cpp:997
int m_flags
Visibility flags.
Definition: view.cpp:91
double GetScale() const
Function GetScale()
Definition: view.h:265
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Sets the item visibility.
Definition: view.cpp:1331
void CopySettings(const VIEW *aOtherView)
Function CopySettings() Copies layers and visibility settings from another view.
Definition: view.cpp:478
LAYER_MAP m_layers
Contains set of possible displayed layers and its properties.
Definition: view.h:754
double m_scale
Scale of displayed VIEW_ITEMs.
Definition: view.h:766
Position or shape has changed.
Definition: view_item.h:58
int renderingOrder
rendering order of this layer
Definition: view.h:650
void SetLookAtPoint(const VECTOR2D &aPoint)
Set the Point in world space to look at.
Container & m_cont
Definition: view.cpp:412
void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:311
std::pair< int, int > GroupPair
Helper for storing cached items group ids
Definition: view.cpp:96
coord_type GetLeft() const
Definition: box2.h:191
Basic classes for most KiCad items.
VIEW(bool aIsDynamic=true)
Constructor.
Definition: view.cpp:261
Class VIEW.
Definition: view.h:58
bool IsVisible(const VIEW_ITEM *aItem) const
Returns information if the item is visible (or not).
Definition: view.cpp:1371
void UpdateAllLayersColor()
Function UpdateAllLayersColor() Applies the new coloring scheme to all layers.
Definition: view.cpp:674
void SetGAL(GAL *aGal)
Function SetGAL() Assigns a rendering device for the VIEW.
Definition: view.cpp:484
int m_requiredUpdate
Flag required for updating.
Definition: view.cpp:92
virtual const BOX2I ViewBBox() const =0
Function ViewBBox() returns the bounding box of the item covering all its layers. ...
recacheItem(VIEW *aView, GAL *aGal, int aLayer)
Definition: view.cpp:952
static bool compareRenderingOrder(VIEW_LAYER *aI, VIEW_LAYER *aJ)
Determines rendering order of layers. Used in display order sorting function.
Definition: view.h:742
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:602
updateItemsColor(int aLayer, PAINTER *aPainter, GAL *aGal)
Definition: view.cpp:633
VECTOR2< T > GetScale() const
Get the scale components of the matrix.
Definition: matrix3x3.h:269
Class GAL is the abstract interface for drawing on a 2D-surface.
Color has changed.
Definition: view_item.h:57
VIEW_RTREE * items
R-tree indexing all items on this layer.
Definition: view.h:649
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:1054
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39
RENDER_TARGET target
where the layer should be rendered
Definition: view.h:652