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