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->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  m_reverseDrawOrder( false )
272 {
274  m_allItems.reserve( 32768 );
275 
276  // Redraw everything at the beginning
277  MarkDirty();
278 
279  // View uses layers to display EDA_ITEMs (item may be displayed on several layers, for example
280  // pad may be shown on pad, pad hole and solder paste layers). There are usual copper layers
281  // (eg. F.Cu, B.Cu, internal and so on) and layers for displaying objects such as texts,
282  // silkscreen, pads, vias, etc.
283  for( int i = 0; i < VIEW_MAX_LAYERS; i++ )
284  AddLayer( i );
285 }
286 
287 
289 {
290  for( LAYER_MAP::value_type& l : m_layers )
291  delete l.second.items;
292 }
293 
294 
295 void VIEW::AddLayer( int aLayer, bool aDisplayOnly )
296 {
297  if( m_layers.find( aLayer ) == m_layers.end() )
298  {
299  m_layers[aLayer] = VIEW_LAYER();
300  m_layers[aLayer].id = aLayer;
301  m_layers[aLayer].items = new VIEW_RTREE();
302  m_layers[aLayer].renderingOrder = aLayer;
303  m_layers[aLayer].visible = true;
304  m_layers[aLayer].displayOnly = aDisplayOnly;
305  m_layers[aLayer].target = TARGET_CACHED;
306  }
307 
308  sortLayers();
309 }
310 
311 
312 void VIEW::Add( VIEW_ITEM* aItem, int aDrawPriority )
313 {
314  int layers[VIEW_MAX_LAYERS], layers_count;
315 
316  if( aDrawPriority < 0 )
317  aDrawPriority = m_nextDrawPriority++;
318 
319  if( !aItem->m_viewPrivData )
320  aItem->m_viewPrivData = new VIEW_ITEM_DATA;
321 
322  aItem->m_viewPrivData->m_view = this;
323  aItem->m_viewPrivData->m_drawPriority = aDrawPriority;
324 
325  aItem->ViewGetLayers( layers, layers_count );
326  aItem->viewPrivData()->saveLayers( layers, layers_count );
327 
328  m_allItems.push_back( aItem );
329 
330  for( int i = 0; i < layers_count; ++i )
331  {
332  VIEW_LAYER& l = m_layers[layers[i]];
333  l.items->Insert( aItem );
334  MarkTargetDirty( l.target );
335  }
336 
337  SetVisible( aItem, true );
338  Update( aItem, KIGFX::INITIAL_ADD );
339 }
340 
341 
342 void VIEW::Remove( VIEW_ITEM* aItem )
343 {
344  if( !aItem )
345  return;
346 
347  auto viewData = aItem->viewPrivData();
348 
349  if( !viewData )
350  return;
351 
352  wxASSERT( viewData->m_view == this );
353  auto item = std::find( m_allItems.begin(), m_allItems.end(), aItem );
354 
355  if( item != m_allItems.end() )
356  {
357  m_allItems.erase( item );
358  viewData->clearUpdateFlags();
359  }
360 
361  int layers[VIEW::VIEW_MAX_LAYERS], layers_count;
362  viewData->getLayers( layers, layers_count );
363 
364  for( int i = 0; i < layers_count; ++i )
365  {
366  VIEW_LAYER& l = m_layers[layers[i]];
367  l.items->Remove( aItem );
368  MarkTargetDirty( l.target );
369 
370  // Clear the GAL cache
371  int prevGroup = viewData->getGroup( layers[i] );
372 
373  if( prevGroup >= 0 )
374  m_gal->DeleteGroup( prevGroup );
375  }
376 
377  viewData->deleteGroups();
378  viewData->m_view = nullptr;
379 }
380 
381 
382 void VIEW::SetRequired( int aLayerId, int aRequiredId, bool aRequired )
383 {
384  wxASSERT( (unsigned) aLayerId < m_layers.size() );
385  wxASSERT( (unsigned) aRequiredId < m_layers.size() );
386 
387  if( aRequired )
388  m_layers[aLayerId].requiredLayers.insert( aRequiredId );
389  else
390  m_layers[aLayerId].requiredLayers.erase( aRequired );
391 }
392 
393 
394 // stupid C++... python lambda would do this in one line
395 template <class Container>
397 {
398  typedef typename Container::value_type item_type;
399 
400  queryVisitor( Container& aCont, int aLayer ) :
401  m_cont( aCont ), m_layer( aLayer )
402  {
403  }
404 
405  bool operator()( VIEW_ITEM* aItem )
406  {
407  if( aItem->viewPrivData()->getFlags() & VISIBLE )
408  m_cont.push_back( VIEW::LAYER_ITEM_PAIR( aItem, m_layer ) );
409 
410  return true;
411  }
412 
413  Container& m_cont;
414  int m_layer;
415 };
416 
417 
418 int VIEW::Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) const
419 {
420  if( m_orderedLayers.empty() )
421  return 0;
422 
423  std::vector<VIEW_LAYER*>::const_reverse_iterator i;
424 
425  // execute queries in reverse direction, so that items that are on the top of
426  // the rendering stack are returned first.
427  for( i = m_orderedLayers.rbegin(); i != m_orderedLayers.rend(); ++i )
428  {
429  // ignore layers that do not contain actual items (i.e. the selection box, menus, floats)
430  if( ( *i )->displayOnly )
431  continue;
432 
433  queryVisitor<std::vector<LAYER_ITEM_PAIR> > visitor( aResult, ( *i )->id );
434  ( *i )->items->Query( aRect, visitor );
435  }
436 
437  return aResult.size();
438 }
439 
440 
441 VECTOR2D VIEW::ToWorld( const VECTOR2D& aCoord, bool aAbsolute ) const
442 {
443  const MATRIX3x3D& matrix = m_gal->GetScreenWorldMatrix();
444 
445  if( aAbsolute )
446  return VECTOR2D( matrix * aCoord );
447  else
448  return VECTOR2D( matrix.GetScale().x * aCoord.x, matrix.GetScale().y * aCoord.y );
449 }
450 
451 
452 double VIEW::ToWorld( double aSize ) const
453 {
454  const MATRIX3x3D& matrix = m_gal->GetScreenWorldMatrix();
455 
456  return fabs( matrix.GetScale().x * aSize );
457 }
458 
459 
460 VECTOR2D VIEW::ToScreen( const VECTOR2D& aCoord, bool aAbsolute ) const
461 {
462  const MATRIX3x3D& matrix = m_gal->GetWorldScreenMatrix();
463 
464  if( aAbsolute )
465  return VECTOR2D( matrix * aCoord );
466  else
467  return VECTOR2D( matrix.GetScale().x * aCoord.x, matrix.GetScale().y * aCoord.y );
468 }
469 
470 
471 double VIEW::ToScreen( double aSize ) const
472 {
473  const MATRIX3x3D& matrix = m_gal->GetWorldScreenMatrix();
474 
475  return matrix.GetScale().x * aSize;
476 }
477 
478 
479 void VIEW::CopySettings( const VIEW* aOtherView )
480 {
481  wxASSERT_MSG( false, wxT( "This is not implemented" ) );
482 }
483 
484 
485 void VIEW::SetGAL( GAL* aGal )
486 {
487  m_gal = aGal;
488 
489  // clear group numbers, so everything is going to be recached
490  clearGroupCache();
491 
492  // every target has to be refreshed
493  MarkDirty();
494 
495  // force the new GAL to display the current viewport.
496  SetCenter( m_center );
497  SetScale( m_scale );
499 }
500 
501 
503 {
504  BOX2D rect;
505  VECTOR2D screenSize = m_gal->GetScreenPixelSize();
506 
507  rect.SetOrigin( ToWorld( VECTOR2D( 0, 0 ) ) );
508  rect.SetEnd( ToWorld( screenSize ) );
509 
510  return rect.Normalize();
511 }
512 
513 
514 void VIEW::SetViewport( const BOX2D& aViewport )
515 {
516  VECTOR2D ssize = ToWorld( m_gal->GetScreenPixelSize(), false );
517 
518  wxASSERT( ssize.x > 0 && ssize.y > 0 );
519 
520  VECTOR2D centre = aViewport.Centre();
521  VECTOR2D vsize = aViewport.GetSize();
522  double zoom = 1.0 / std::max( fabs( vsize.x / ssize.x ), fabs( vsize.y / ssize.y ) );
523 
524  SetCenter( centre );
525  SetScale( GetScale() * zoom );
526 }
527 
528 
529 void VIEW::SetMirror( bool aMirrorX, bool aMirrorY )
530 {
531  wxASSERT_MSG( !aMirrorY, _( "Mirroring for Y axis is not supported yet" ) );
532 
533  m_mirrorX = aMirrorX;
534  m_mirrorY = aMirrorY;
535  m_gal->SetFlip( aMirrorX, aMirrorY );
536 
537  // Redraw everything
538  MarkDirty();
539 }
540 
541 
542 void VIEW::SetScale( double aScale, const VECTOR2D& aAnchor )
543 {
544  VECTOR2D a = ToScreen( aAnchor );
545 
546  if( aScale < m_minScale )
548  else if( aScale > m_maxScale )
550  else
551  m_scale = aScale;
552 
555 
556  VECTOR2D delta = ToWorld( a ) - aAnchor;
557 
558  SetCenter( m_center - delta );
559 
560  // Redraw everything after the viewport has changed
561  MarkDirty();
562 }
563 
564 
565 void VIEW::SetCenter( const VECTOR2D& aCenter )
566 {
567  m_center = aCenter;
568 
569  if( !m_boundary.Contains( aCenter ) )
570  {
571  if( m_center.x < m_boundary.GetLeft() )
573  else if( aCenter.x > m_boundary.GetRight() )
575 
576  if( m_center.y < m_boundary.GetTop() )
578  else if( m_center.y > m_boundary.GetBottom() )
580  }
581 
584 
585  // Redraw everything after the viewport has changed
586  MarkDirty();
587 }
588 
589 
590 void VIEW::SetLayerOrder( int aLayer, int aRenderingOrder )
591 {
592  m_layers[aLayer].renderingOrder = aRenderingOrder;
593 
594  sortLayers();
595 }
596 
597 
598 int VIEW::GetLayerOrder( int aLayer ) const
599 {
600  return m_layers.at( aLayer ).renderingOrder;
601 }
602 
603 
604 void VIEW::SortLayers( int aLayers[], int& aCount ) const
605 {
606  int maxLay, maxOrd, maxIdx;
607 
608  for( int i = 0; i < aCount; ++i )
609  {
610  maxLay = aLayers[i];
611  maxOrd = GetLayerOrder( maxLay );
612  maxIdx = i;
613 
614  // Look for the max element in the range (j..aCount)
615  for( int j = i; j < aCount; ++j )
616  {
617  if( maxOrd < GetLayerOrder( aLayers[j] ) )
618  {
619  maxLay = aLayers[j];
620  maxOrd = GetLayerOrder( maxLay );
621  maxIdx = j;
622  }
623  }
624 
625  // Swap elements
626  aLayers[maxIdx] = aLayers[i];
627  aLayers[i] = maxLay;
628  }
629 }
630 
631 
633 {
634  updateItemsColor( int aLayer, PAINTER* aPainter, GAL* aGal ) :
635  layer( aLayer ), painter( aPainter ), gal( aGal )
636  {
637  }
638 
639  bool operator()( VIEW_ITEM* aItem )
640  {
641  // Obtain the color that should be used for coloring the item
642  const COLOR4D color = painter->GetSettings()->GetColor( aItem, layer );
643  int group = aItem->viewPrivData()->getGroup( layer );
644 
645  if( group >= 0 )
646  gal->ChangeGroupColor( group, color );
647 
648  return true;
649  }
650 
651  int layer;
654 };
655 
656 
657 void VIEW::UpdateLayerColor( int aLayer )
658 {
659  // There is no point in updating non-cached layers
660  if( !IsCached( aLayer ) )
661  return;
662 
663  BOX2I r;
664 
665  r.SetMaximum();
666 
667  m_gal->BeginUpdate();
668  updateItemsColor visitor( aLayer, m_painter, m_gal );
669  m_layers[aLayer].items->Query( r, visitor );
670  MarkTargetDirty( m_layers[aLayer].target );
671  m_gal->EndUpdate();
672 }
673 
674 
676 {
677  BOX2I r;
678 
679  r.SetMaximum();
680  m_gal->BeginUpdate();
681 
682  for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
683  {
684  VIEW_LAYER* l = &( ( *i ).second );
685 
686  // There is no point in updating non-cached layers
687  if( !IsCached( l->id ) )
688  continue;
689 
690  updateItemsColor visitor( l->id, m_painter, m_gal );
691  l->items->Query( r, visitor );
692  }
693 
694  m_gal->EndUpdate();
695  MarkDirty();
696 }
697 
698 
700 {
701  changeItemsDepth( int aLayer, int aDepth, GAL* aGal ) :
702  layer( aLayer ), depth( aDepth ), gal( aGal )
703  {
704  }
705 
706  bool operator()( VIEW_ITEM* aItem )
707  {
708  int group = aItem->viewPrivData()->getGroup( layer );
709 
710  if( group >= 0 )
711  gal->ChangeGroupDepth( group, depth );
712 
713  return true;
714  }
715 
716  int layer, depth;
718 };
719 
720 
721 int VIEW::GetTopLayer() const
722 {
723  if( m_topLayers.size() == 0 )
724  return 0;
725 
726  return *m_topLayers.begin();
727 }
728 
729 
730 void VIEW::SetTopLayer( int aLayer, bool aEnabled )
731 {
732  if( aEnabled )
733  {
734  if( m_topLayers.count( aLayer ) == 1 )
735  return;
736 
737  m_topLayers.insert( aLayer );
738 
739  // Move the layer closer to front
741  m_layers[aLayer].renderingOrder += TOP_LAYER_MODIFIER;
742  }
743  else
744  {
745  if( m_topLayers.count( aLayer ) == 0 )
746  return;
747 
748  m_topLayers.erase( aLayer );
749 
750  // Restore the previous rendering order
752  m_layers[aLayer].renderingOrder -= TOP_LAYER_MODIFIER;
753  }
754 }
755 
756 
757 void VIEW::EnableTopLayer( bool aEnable )
758 {
759  if( aEnable == m_enableOrderModifier )
760  return;
761 
762  m_enableOrderModifier = aEnable;
763 
764  std::set<unsigned int>::iterator it;
765 
766  if( aEnable )
767  {
768  for( it = m_topLayers.begin(); it != m_topLayers.end(); ++it )
769  m_layers[*it].renderingOrder += TOP_LAYER_MODIFIER;
770  }
771  else
772  {
773  for( it = m_topLayers.begin(); it != m_topLayers.end(); ++it )
774  m_layers[*it].renderingOrder -= TOP_LAYER_MODIFIER;
775  }
776 
779 }
780 
781 
783 {
784  std::set<unsigned int>::iterator it;
785 
787  {
788  // Restore the previous rendering order for layers that were marked as top
789  for( it = m_topLayers.begin(); it != m_topLayers.end(); ++it )
790  m_layers[*it].renderingOrder -= TOP_LAYER_MODIFIER;
791  }
792 
793  m_topLayers.clear();
794 }
795 
796 
798 {
799  BOX2I r;
800  r.SetMaximum();
801 
802  sortLayers();
803  m_gal->BeginUpdate();
804 
805  for( LAYER_MAP::value_type& l : m_layers )
806  {
807  int layer = l.first;
808  changeItemsDepth visitor( layer, l.second.renderingOrder, m_gal );
809  m_layers[layer].items->Query( r, visitor );
810  }
811 
812  m_gal->EndUpdate();
813  MarkDirty();
814 }
815 
816 
818 {
819  drawItem( VIEW* aView, int aLayer, bool aUseDrawPriority, bool aReverseDrawOrder ) :
820  view( aView ), layer( aLayer ),
821  useDrawPriority( aUseDrawPriority ),
822  reverseDrawOrder( aReverseDrawOrder )
823  {
824  }
825 
826  bool operator()( VIEW_ITEM* aItem )
827  {
828  wxASSERT( aItem->viewPrivData() );
829 
830  // Conditions that have to be fulfilled for an item to be drawn
831  bool drawCondition = aItem->viewPrivData()->isRenderable() &&
832  aItem->ViewGetLOD( layer, view ) < view->m_scale;
833  if( !drawCondition )
834  return true;
835 
836  if( useDrawPriority )
837  drawItems.push_back( aItem );
838  else
839  view->draw( aItem, layer );
840 
841  return true;
842  }
843 
845  {
846  if( reverseDrawOrder )
847  std::sort( drawItems.begin(), drawItems.end(),
848  []( VIEW_ITEM* a, VIEW_ITEM* b ) -> bool {
849  return b->viewPrivData()->m_drawPriority < a->viewPrivData()->m_drawPriority;
850  });
851  else
852  std::sort( drawItems.begin(), drawItems.end(),
853  []( VIEW_ITEM* a, VIEW_ITEM* b ) -> bool {
854  return a->viewPrivData()->m_drawPriority < b->viewPrivData()->m_drawPriority;
855  });
856 
857  for( auto item : drawItems )
858  view->draw( item, layer );
859  }
860 
864  std::vector<VIEW_ITEM*> drawItems;
865 };
866 
867 
868 void VIEW::redrawRect( const BOX2I& aRect )
869 {
870  for( VIEW_LAYER* l : m_orderedLayers )
871  {
872  if( l->visible && IsTargetDirty( l->target ) && areRequiredLayersEnabled( l->id ) )
873  {
874  drawItem drawFunc( this, l->id, m_useDrawPriority, m_reverseDrawOrder );
875 
876  m_gal->SetTarget( l->target );
877  m_gal->SetLayerDepth( l->renderingOrder );
878  l->items->Query( aRect, drawFunc );
879 
880  if( m_useDrawPriority )
881  drawFunc.deferredDraw();
882  }
883  }
884 }
885 
886 
887 void VIEW::draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate )
888 {
889  auto viewData = aItem->viewPrivData();
890 
891  if( !viewData )
892  return;
893 
894  if( IsCached( aLayer ) && !aImmediate )
895  {
896  // Draw using cached information or create one
897  int group = viewData->getGroup( aLayer );
898 
899  if( group >= 0 )
900  m_gal->DrawGroup( group );
901  else
902  Update( aItem );
903  }
904  else
905  {
906  // Immediate mode
907  if( !m_painter->Draw( aItem, aLayer ) )
908  aItem->ViewDraw( aLayer, this ); // Alternative drawing method
909  }
910 }
911 
912 
913 void VIEW::draw( VIEW_ITEM* aItem, bool aImmediate )
914 {
915  int layers[VIEW_MAX_LAYERS], layers_count;
916 
917  aItem->ViewGetLayers( layers, layers_count );
918 
919  // Sorting is needed for drawing order dependent GALs (like Cairo)
920  SortLayers( layers, layers_count );
921 
922  for( int i = 0; i < layers_count; ++i )
923  {
924  m_gal->SetLayerDepth( m_layers.at( layers[i] ).renderingOrder );
925  draw( aItem, layers[i], aImmediate );
926  }
927 }
928 
929 
930 void VIEW::draw( VIEW_GROUP* aGroup, bool aImmediate )
931 {
932  for( unsigned int i = 0; i < aGroup->GetSize(); i++)
933  draw( aGroup->GetItem(i), aImmediate );
934 }
935 
936 
938 {
939  recacheItem( VIEW* aView, GAL* aGal, int aLayer ) :
940  view( aView ), gal( aGal ), layer( aLayer )
941  {
942  }
943 
944  bool operator()( VIEW_ITEM* aItem )
945  {
946  auto viewData = aItem->viewPrivData();
947 
948  if( !viewData )
949  return false;
950 
951  // Remove previously cached group
952  int group = viewData->getGroup( layer );
953 
954  if( group >= 0 )
955  gal->DeleteGroup( group );
956 
957  viewData->setGroup( layer, -1 );
958  view->Update( aItem );
959 
960  return true;
961  }
962 
965  int layer;
966 };
967 
968 
970 {
971  BOX2I r;
972  r.SetMaximum();
973  m_allItems.clear();
974 
975  for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
976  i->second.items->RemoveAll();
977 
978  m_nextDrawPriority = 0;
979 
980  m_gal->ClearCache();
981 }
982 
983 
985 {
987  {
988  // TARGET_CACHED and TARGET_NONCACHED have to be redrawn together, as they contain
989  // layers that rely on each other (eg. netnames are noncached, but tracks - are cached)
992 
993  MarkDirty();
994  }
995 
997  {
999  }
1000 }
1001 
1002 
1004 {
1005 #ifdef __WXDEBUG__
1006  PROF_COUNTER totalRealTime;
1007 #endif /* __WXDEBUG__ */
1008 
1009  VECTOR2D screenSize = m_gal->GetScreenPixelSize();
1010  BOX2I rect( ToWorld( VECTOR2D( 0, 0 ) ),
1011  ToWorld( screenSize ) - ToWorld( VECTOR2D( 0, 0 ) ) );
1012  rect.Normalize();
1013 
1014  redrawRect( rect );
1015 
1016  // All targets were redrawn, so nothing is dirty
1020 
1021 #ifdef __WXDEBUG__
1022  totalRealTime.Stop();
1023  wxLogTrace( "GAL_PROFILE", wxT( "VIEW::Redraw(): %.1f ms" ), totalRealTime.msecs() );
1024 #endif /* __WXDEBUG__ */
1025 }
1026 
1027 
1029 {
1030  return m_gal->GetScreenPixelSize();
1031 }
1032 
1033 
1035 {
1036  clearLayerCache( VIEW* aView ) :
1037  view( aView )
1038  {
1039  }
1040 
1041  bool operator()( VIEW_ITEM* aItem )
1042  {
1043  aItem->viewPrivData()->deleteGroups();
1044 
1045  return true;
1046  }
1047 
1049 };
1050 
1051 
1053 {
1054  BOX2I r;
1055 
1056  r.SetMaximum();
1057  clearLayerCache visitor( this );
1058 
1059  for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
1060  {
1061  VIEW_LAYER* l = &( ( *i ).second );
1062  l->items->Query( r, visitor );
1063  }
1064 }
1065 
1066 
1067 void VIEW::invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags )
1068 {
1069  if( aUpdateFlags & INITIAL_ADD )
1070  {
1071  // Don't update layers or bbox, since it was done in VIEW::Add()
1072  // Now that we have initialized, set flags to ALL for the code below
1073  aUpdateFlags = ALL;
1074  }
1075  else
1076  {
1077  // updateLayers updates geometry too, so we do not have to update both of them at the same time
1078  if( aUpdateFlags & LAYERS )
1079  {
1080  updateLayers( aItem );
1081  }
1082  else if( aUpdateFlags & GEOMETRY )
1083  {
1084  updateBbox( aItem );
1085  }
1086  }
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.
Layers have changed.
Definition: view_item.h:59
Item is visible (in general)
Definition: view_item.h:69
virtual int GetTopLayer() const
Definition: view.cpp:721
void deleteGroups()
Function deleteGroups() Removes all of the stored group ids.
Definition: view.cpp:176
VIEW_ITEM_DATA * m_viewPrivData
Definition: view_item.h:155
void SetViewport(const BOX2D &aViewport)
Function SetViewport() Sets the visible area of the VIEW.
Definition: view.cpp:514
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:295
void SetLayerOrder(int aLayer, int aRenderingOrder)
Function SetLayerOrder() Sets rendering order of a particular layer.
Definition: view.cpp:590
void SetRequired(int aLayerId, int aRequiredId, bool aRequired=true)
Function SetRequired() Marks the aRequiredId layer as required for the aLayerId layer.
Definition: view.cpp:382
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:814
Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
Definition: class_module.h:57
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:730
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:418
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:808
void sortLayers()
Definition: view.cpp:1112
queryVisitor(Container &aCont, int aLayer)
Definition: view.cpp:400
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:441
void RecacheAllItems()
Function RecacheAllItems() Rebuilds GAL display lists.
Definition: view.cpp:1253
virtual void Remove(VIEW_ITEM *aItem)
Function Remove() Removes a VIEW_ITEM from the view.
Definition: view.cpp:342
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:798
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:771
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:797
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:529
Class VIEW_ITEM - is an abstract base class for deriving all objects that can be added to a VIEW...
Definition: view_item.h:83
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
Item is being added to the view.
Definition: view_item.h:60
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)
virtual void EnableTopLayer(bool aEnable)
Function EnableTopLayer() Enables or disables display of the top layer.
Definition: view.cpp:757
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:774
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:783
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:944
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:819
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:604
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:398
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:706
clearLayerCache(VIEW *aView)
Definition: view.cpp:1036
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:780
void SetCenter(const VECTOR2D &aCenter)
Function SetCenter() Sets the center point of the VIEW (i.e.
Definition: view.cpp:565
BOX2D GetViewport() const
Function GetViewport() Returns the current viewport visible area rectangle.
Definition: view.cpp:502
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:588
virtual void Redraw()
Function Redraw() Immediately redraws the whole view.
Definition: view.cpp:1003
void MarkTargetDirty(int aTarget)
Function MarkTargetDirty() Sets or clears target 'dirty' flag.
Definition: view.h:568
void Clear()
Function Clear() Removes all items from the view.
Definition: view.cpp:969
int GetLayerOrder(int aLayer) const
Function GetLayerOrder() Returns rendering order of a particular layer.
Definition: view.cpp:598
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:652
bool m_mirrorX
Horizontal flip flag
Definition: view.h:789
void invalidateItem(VIEW_ITEM *aItem, int aUpdateFlags)
Function invalidateItem() Manages dirty flags & redraw queueing when updating an item.
Definition: view.cpp:1067
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:556
int layers[VIEW_MAX_LAYERS]
Definition: view.cpp:862
int id
layer ID
Definition: view.h:662
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:768
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:686
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:795
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
bool m_reverseDrawOrder
Flag to reverse the draw order when using draw priority.
Definition: view.h:820
changeItemsDepth(int aLayer, int aDepth, GAL *aGal)
Definition: view.cpp:701
virtual void Update(VIEW_ITEM *aItem, int aUpdateFlags)
For dynamic VIEWs, informs the associated VIEW that the graphical representation of this item has cha...
Definition: view.cpp: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:817
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:782
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:826
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:669
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:1052
VIEW_ITEM_DATA * viewPrivData() const
Definition: view_item.h:147
double m_maxScale
Scale upper limit.
Definition: view.h:786
void UpdateLayerColor(int aLayer)
Function UpdateLayerColor() Applies the new coloring scheme held by RENDER_SETTINGS in case that it h...
Definition: view.cpp:657
double msecs() const
Definition: profile.h:124
std::vector< VIEW_ITEM * > drawItems
Definition: view.cpp:864
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:405
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:639
void redrawRect(const BOX2I &aRect)
Definition: view.cpp:868
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
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:762
#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:115
std::vector< VIEW_ITEM * > m_allItems
Flat list of all items.
Definition: view.h:811
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:576
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:887
virtual unsigned int ViewGetLOD(int aLayer, VIEW *aView) const
Function ViewGetLOD() Returns the level of detail (LOD) of the item.
Definition: view_item.h:139
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:460
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:1028
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:792
void ClearTargets()
Function ClearTargets() Clears targets that are marked as dirty.
Definition: view.cpp:984
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:479
LAYER_MAP m_layers
Contains set of possible displayed layers and its properties.
Definition: view.h:765
double m_scale
Scale of displayed VIEW_ITEMs.
Definition: view.h:777
Position or shape has changed.
Definition: view_item.h:58
int renderingOrder
rendering order of this layer
Definition: view.h:661
void SetLookAtPoint(const VECTOR2D &aPoint)
Set the Point in world space to look at.
Container & m_cont
Definition: view.cpp:413
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:312
std::pair< int, int > GroupPair
Helper for storing cached items group ids
Definition: view.cpp:96
coord_type GetLeft() const
Definition: box2.h:191
virtual ~VIEW()
Definition: view.cpp:288
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:675
void SetGAL(GAL *aGal)
Function SetGAL() Assigns a rendering device for the VIEW.
Definition: view.cpp:485
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:939
static bool compareRenderingOrder(VIEW_LAYER *aI, VIEW_LAYER *aJ)
Determines rendering order of layers. Used in display order sorting function.
Definition: view.h:753
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:594
updateItemsColor(int aLayer, PAINTER *aPainter, GAL *aGal)
Definition: view.cpp:634
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:660
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:1041
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:663