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