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