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