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 
193  std::vector<int> m_layers;
194 
202  void saveLayers( int* aLayers, int aCount )
203  {
204  m_layers.clear();
205 
206  for( int i = 0; i < aCount; ++i )
207  {
208  // this fires on some eagle board after EAGLE_PLUGIN::Load()
209  wxASSERT( unsigned( aLayers[i] ) <= unsigned( VIEW::VIEW_MAX_LAYERS ) );
210 
211  m_layers.push_back( aLayers[i] );
212  }
213  }
214 
219  int requiredUpdate() const
220  {
221  return m_requiredUpdate;
222  }
223 
229  {
230  m_requiredUpdate = NONE;
231  }
232 
237  bool isRenderable() const
238  {
239  return m_flags == VISIBLE;
240  }
241 };
242 
243 
245 {
246  auto data = aItem->viewPrivData();
247 
248  if( !data )
249  return;
250 
251  if( data->m_view )
252  data->m_view->VIEW::Remove( aItem );
253 
254  delete data;
255 }
256 
257 
258 VIEW::VIEW( bool aIsDynamic ) :
259  m_enableOrderModifier( true ),
260  m_scale( 4.0 ),
261  m_minScale( 4.0 ), m_maxScale( 15000 ),
262  m_mirrorX( false ), m_mirrorY( false ),
263  m_painter( NULL ),
264  m_gal( NULL ),
265  m_dynamic( aIsDynamic ),
266  m_useDrawPriority( false ),
267  m_nextDrawPriority( 0 ),
268  m_reverseDrawOrder( false )
269 {
271  m_allItems.reserve( 32768 );
272 
273  // Redraw everything at the beginning
274  MarkDirty();
275 
276  // View uses layers to display EDA_ITEMs (item may be displayed on several layers, for example
277  // pad may be shown on pad, pad hole and solder paste layers). There are usual copper layers
278  // (eg. F.Cu, B.Cu, internal and so on) and layers for displaying objects such as texts,
279  // silkscreen, pads, vias, etc.
280  for( int i = 0; i < VIEW_MAX_LAYERS; i++ )
281  AddLayer( i );
282 }
283 
284 
286 {
287  for( LAYER_MAP::value_type& l : m_layers )
288  delete l.second.items;
289 }
290 
291 
292 void VIEW::AddLayer( int aLayer, bool aDisplayOnly )
293 {
294  if( m_layers.find( aLayer ) == m_layers.end() )
295  {
296  m_layers[aLayer] = VIEW_LAYER();
297  m_layers[aLayer].id = aLayer;
298  m_layers[aLayer].items = new VIEW_RTREE();
299  m_layers[aLayer].renderingOrder = aLayer;
300  m_layers[aLayer].visible = true;
301  m_layers[aLayer].displayOnly = aDisplayOnly;
302  m_layers[aLayer].target = TARGET_CACHED;
303  }
304 
305  sortLayers();
306 }
307 
308 
309 void VIEW::Add( VIEW_ITEM* aItem, int aDrawPriority )
310 {
311  int layers[VIEW_MAX_LAYERS], layers_count;
312 
313  if( aDrawPriority < 0 )
314  aDrawPriority = m_nextDrawPriority++;
315 
316  if( !aItem->m_viewPrivData )
317  aItem->m_viewPrivData = new VIEW_ITEM_DATA;
318 
319  aItem->m_viewPrivData->m_view = this;
320  aItem->m_viewPrivData->m_drawPriority = aDrawPriority;
321 
322  aItem->ViewGetLayers( layers, layers_count );
323  aItem->viewPrivData()->saveLayers( layers, layers_count );
324 
325  m_allItems.push_back( aItem );
326 
327  for( int i = 0; i < layers_count; ++i )
328  {
329  VIEW_LAYER& l = m_layers[layers[i]];
330  l.items->Insert( aItem );
331  MarkTargetDirty( l.target );
332  }
333 
334  SetVisible( aItem, true );
335  Update( aItem, KIGFX::INITIAL_ADD );
336 }
337 
338 
339 void VIEW::Remove( VIEW_ITEM* aItem )
340 {
341  if( !aItem )
342  return;
343 
344  auto viewData = aItem->viewPrivData();
345 
346  if( !viewData )
347  return;
348 
349  wxASSERT( viewData->m_view == this );
350  auto item = std::find( m_allItems.begin(), m_allItems.end(), aItem );
351 
352  if( item != m_allItems.end() )
353  {
354  m_allItems.erase( item );
355  viewData->clearUpdateFlags();
356  }
357 
358  int layers[VIEW::VIEW_MAX_LAYERS], layers_count;
359  viewData->getLayers( layers, layers_count );
360 
361  for( int i = 0; i < layers_count; ++i )
362  {
363  VIEW_LAYER& l = m_layers[layers[i]];
364  l.items->Remove( aItem );
365  MarkTargetDirty( l.target );
366 
367  // Clear the GAL cache
368  int prevGroup = viewData->getGroup( layers[i] );
369 
370  if( prevGroup >= 0 )
371  m_gal->DeleteGroup( prevGroup );
372  }
373 
374  viewData->deleteGroups();
375  viewData->m_view = nullptr;
376 }
377 
378 
379 void VIEW::SetRequired( int aLayerId, int aRequiredId, bool aRequired )
380 {
381  wxASSERT( (unsigned) aLayerId < m_layers.size() );
382  wxASSERT( (unsigned) aRequiredId < m_layers.size() );
383 
384  if( aRequired )
385  m_layers[aLayerId].requiredLayers.insert( aRequiredId );
386  else
387  m_layers[aLayerId].requiredLayers.erase( aRequired );
388 }
389 
390 
391 // stupid C++... python lambda would do this in one line
392 template <class Container>
394 {
395  typedef typename Container::value_type item_type;
396 
397  queryVisitor( Container& aCont, int aLayer ) :
398  m_cont( aCont ), m_layer( aLayer )
399  {
400  }
401 
402  bool operator()( VIEW_ITEM* aItem )
403  {
404  if( aItem->viewPrivData()->getFlags() & VISIBLE )
405  m_cont.push_back( VIEW::LAYER_ITEM_PAIR( aItem, m_layer ) );
406 
407  return true;
408  }
409 
410  Container& m_cont;
411  int m_layer;
412 };
413 
414 
415 int VIEW::Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) const
416 {
417  if( m_orderedLayers.empty() )
418  return 0;
419 
420  std::vector<VIEW_LAYER*>::const_reverse_iterator i;
421 
422  // execute queries in reverse direction, so that items that are on the top of
423  // the rendering stack are returned first.
424  for( i = m_orderedLayers.rbegin(); i != m_orderedLayers.rend(); ++i )
425  {
426  // ignore layers that do not contain actual items (i.e. the selection box, menus, floats)
427  if( ( *i )->displayOnly )
428  continue;
429 
430  queryVisitor<std::vector<LAYER_ITEM_PAIR> > visitor( aResult, ( *i )->id );
431  ( *i )->items->Query( aRect, visitor );
432  }
433 
434  return aResult.size();
435 }
436 
437 
438 VECTOR2D VIEW::ToWorld( const VECTOR2D& aCoord, bool aAbsolute ) const
439 {
440  const MATRIX3x3D& matrix = m_gal->GetScreenWorldMatrix();
441 
442  if( aAbsolute )
443  return VECTOR2D( matrix * aCoord );
444  else
445  return VECTOR2D( matrix.GetScale().x * aCoord.x, matrix.GetScale().y * aCoord.y );
446 }
447 
448 
449 double VIEW::ToWorld( double aSize ) const
450 {
451  const MATRIX3x3D& matrix = m_gal->GetScreenWorldMatrix();
452 
453  return fabs( matrix.GetScale().x * aSize );
454 }
455 
456 
457 VECTOR2D VIEW::ToScreen( const VECTOR2D& aCoord, bool aAbsolute ) const
458 {
459  const MATRIX3x3D& matrix = m_gal->GetWorldScreenMatrix();
460 
461  if( aAbsolute )
462  return VECTOR2D( matrix * aCoord );
463  else
464  return VECTOR2D( matrix.GetScale().x * aCoord.x, matrix.GetScale().y * aCoord.y );
465 }
466 
467 
468 double VIEW::ToScreen( double aSize ) const
469 {
470  const MATRIX3x3D& matrix = m_gal->GetWorldScreenMatrix();
471 
472  return matrix.GetScale().x * aSize;
473 }
474 
475 
476 void VIEW::CopySettings( const VIEW* aOtherView )
477 {
478  wxASSERT_MSG( false, wxT( "This is not implemented" ) );
479 }
480 
481 
482 void VIEW::SetGAL( GAL* aGal )
483 {
484  m_gal = aGal;
485 
486  // clear group numbers, so everything is going to be recached
487  clearGroupCache();
488 
489  // every target has to be refreshed
490  MarkDirty();
491 
492  // force the new GAL to display the current viewport.
493  SetCenter( m_center );
494  SetScale( m_scale );
496 }
497 
498 
500 {
501  BOX2D rect;
502  VECTOR2D screenSize = m_gal->GetScreenPixelSize();
503 
504  rect.SetOrigin( ToWorld( VECTOR2D( 0, 0 ) ) );
505  rect.SetEnd( ToWorld( screenSize ) );
506 
507  return rect.Normalize();
508 }
509 
510 
511 void VIEW::SetViewport( const BOX2D& aViewport )
512 {
513  VECTOR2D ssize = ToWorld( m_gal->GetScreenPixelSize(), false );
514 
515  wxASSERT( ssize.x > 0 && ssize.y > 0 );
516 
517  VECTOR2D centre = aViewport.Centre();
518  VECTOR2D vsize = aViewport.GetSize();
519  double zoom = 1.0 / std::max( fabs( vsize.x / ssize.x ), fabs( vsize.y / ssize.y ) );
520 
521  SetCenter( centre );
522  SetScale( GetScale() * zoom );
523 }
524 
525 
526 void VIEW::SetMirror( bool aMirrorX, bool aMirrorY )
527 {
528  wxASSERT_MSG( !aMirrorY, _( "Mirroring for Y axis is not supported yet" ) );
529 
530  m_mirrorX = aMirrorX;
531  m_mirrorY = aMirrorY;
532  m_gal->SetFlip( aMirrorX, aMirrorY );
533 
534  // Redraw everything
535  MarkDirty();
536 }
537 
538 
539 void VIEW::SetScale( double aScale, const VECTOR2D& aAnchor )
540 {
541  VECTOR2D a = ToScreen( aAnchor );
542 
543  if( aScale < m_minScale )
545  else if( aScale > m_maxScale )
547  else
548  m_scale = aScale;
549 
552 
553  VECTOR2D delta = ToWorld( a ) - aAnchor;
554 
555  SetCenter( m_center - delta );
556 
557  // Redraw everything after the viewport has changed
558  MarkDirty();
559 }
560 
561 
562 void VIEW::SetCenter( const VECTOR2D& aCenter )
563 {
564  m_center = aCenter;
565 
566  if( !m_boundary.Contains( aCenter ) )
567  {
568  if( m_center.x < m_boundary.GetLeft() )
570  else if( aCenter.x > m_boundary.GetRight() )
572 
573  if( m_center.y < m_boundary.GetTop() )
575  else if( m_center.y > m_boundary.GetBottom() )
577  }
578 
581 
582  // Redraw everything after the viewport has changed
583  MarkDirty();
584 }
585 
586 
587 void VIEW::SetLayerOrder( int aLayer, int aRenderingOrder )
588 {
589  m_layers[aLayer].renderingOrder = aRenderingOrder;
590 
591  sortLayers();
592 }
593 
594 
595 int VIEW::GetLayerOrder( int aLayer ) const
596 {
597  return m_layers.at( aLayer ).renderingOrder;
598 }
599 
600 
601 void VIEW::SortLayers( int aLayers[], int& aCount ) const
602 {
603  int maxLay, maxOrd, maxIdx;
604 
605  for( int i = 0; i < aCount; ++i )
606  {
607  maxLay = aLayers[i];
608  maxOrd = GetLayerOrder( maxLay );
609  maxIdx = i;
610 
611  // Look for the max element in the range (j..aCount)
612  for( int j = i; j < aCount; ++j )
613  {
614  if( maxOrd < GetLayerOrder( aLayers[j] ) )
615  {
616  maxLay = aLayers[j];
617  maxOrd = GetLayerOrder( maxLay );
618  maxIdx = j;
619  }
620  }
621 
622  // Swap elements
623  aLayers[maxIdx] = aLayers[i];
624  aLayers[i] = maxLay;
625  }
626 }
627 
628 
630 {
631  updateItemsColor( int aLayer, PAINTER* aPainter, GAL* aGal ) :
632  layer( aLayer ), painter( aPainter ), gal( aGal )
633  {
634  }
635 
636  bool operator()( VIEW_ITEM* aItem )
637  {
638  // Obtain the color that should be used for coloring the item
639  const COLOR4D color = painter->GetSettings()->GetColor( aItem, layer );
640  int group = aItem->viewPrivData()->getGroup( layer );
641 
642  if( group >= 0 )
643  gal->ChangeGroupColor( group, color );
644 
645  return true;
646  }
647 
648  int layer;
651 };
652 
653 
654 void VIEW::UpdateLayerColor( int aLayer )
655 {
656  // There is no point in updating non-cached layers
657  if( !IsCached( aLayer ) )
658  return;
659 
660  BOX2I r;
661 
662  r.SetMaximum();
663 
664  m_gal->BeginUpdate();
665  updateItemsColor visitor( aLayer, m_painter, m_gal );
666  m_layers[aLayer].items->Query( r, visitor );
667  MarkTargetDirty( m_layers[aLayer].target );
668  m_gal->EndUpdate();
669 }
670 
671 
673 {
674  BOX2I r;
675 
676  r.SetMaximum();
677  m_gal->BeginUpdate();
678 
679  for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
680  {
681  VIEW_LAYER* l = &( ( *i ).second );
682 
683  // There is no point in updating non-cached layers
684  if( !IsCached( l->id ) )
685  continue;
686 
687  updateItemsColor visitor( l->id, m_painter, m_gal );
688  l->items->Query( r, visitor );
689  }
690 
691  m_gal->EndUpdate();
692  MarkDirty();
693 }
694 
695 
697 {
698  changeItemsDepth( int aLayer, int aDepth, GAL* aGal ) :
699  layer( aLayer ), depth( aDepth ), gal( aGal )
700  {
701  }
702 
703  bool operator()( VIEW_ITEM* aItem )
704  {
705  int group = aItem->viewPrivData()->getGroup( layer );
706 
707  if( group >= 0 )
708  gal->ChangeGroupDepth( group, depth );
709 
710  return true;
711  }
712 
713  int layer, depth;
715 };
716 
717 
718 int VIEW::GetTopLayer() const
719 {
720  if( m_topLayers.size() == 0 )
721  return 0;
722 
723  return *m_topLayers.begin();
724 }
725 
726 
727 void VIEW::SetTopLayer( int aLayer, bool aEnabled )
728 {
729  if( aEnabled )
730  {
731  if( m_topLayers.count( aLayer ) == 1 )
732  return;
733 
734  m_topLayers.insert( aLayer );
735 
736  // Move the layer closer to front
738  m_layers[aLayer].renderingOrder += TOP_LAYER_MODIFIER;
739  }
740  else
741  {
742  if( m_topLayers.count( aLayer ) == 0 )
743  return;
744 
745  m_topLayers.erase( aLayer );
746 
747  // Restore the previous rendering order
749  m_layers[aLayer].renderingOrder -= TOP_LAYER_MODIFIER;
750  }
751 }
752 
753 
754 void VIEW::EnableTopLayer( bool aEnable )
755 {
756  if( aEnable == m_enableOrderModifier )
757  return;
758 
759  m_enableOrderModifier = aEnable;
760 
761  std::set<unsigned int>::iterator it;
762 
763  if( aEnable )
764  {
765  for( it = m_topLayers.begin(); it != m_topLayers.end(); ++it )
766  m_layers[*it].renderingOrder += TOP_LAYER_MODIFIER;
767  }
768  else
769  {
770  for( it = m_topLayers.begin(); it != m_topLayers.end(); ++it )
771  m_layers[*it].renderingOrder -= TOP_LAYER_MODIFIER;
772  }
773 
776 }
777 
778 
780 {
781  std::set<unsigned int>::iterator it;
782 
784  {
785  // Restore the previous rendering order for layers that were marked as top
786  for( it = m_topLayers.begin(); it != m_topLayers.end(); ++it )
787  m_layers[*it].renderingOrder -= TOP_LAYER_MODIFIER;
788  }
789 
790  m_topLayers.clear();
791 }
792 
793 
795 {
796  BOX2I r;
797  r.SetMaximum();
798 
799  sortLayers();
800  m_gal->BeginUpdate();
801 
802  for( LAYER_MAP::value_type& l : m_layers )
803  {
804  int layer = l.first;
805  changeItemsDepth visitor( layer, l.second.renderingOrder, m_gal );
806  m_layers[layer].items->Query( r, visitor );
807  }
808 
809  m_gal->EndUpdate();
810  MarkDirty();
811 }
812 
813 
815 {
816  drawItem( VIEW* aView, int aLayer, bool aUseDrawPriority, bool aReverseDrawOrder ) :
817  view( aView ), layer( aLayer ),
818  useDrawPriority( aUseDrawPriority ),
819  reverseDrawOrder( aReverseDrawOrder )
820  {
821  }
822 
823  bool operator()( VIEW_ITEM* aItem )
824  {
825  wxASSERT( aItem->viewPrivData() );
826 
827  // Conditions that have to be fulfilled for an item to be drawn
828  bool drawCondition = aItem->viewPrivData()->isRenderable() &&
829  aItem->ViewGetLOD( layer, view ) < view->m_scale;
830  if( !drawCondition )
831  return true;
832 
833  if( useDrawPriority )
834  drawItems.push_back( aItem );
835  else
836  view->draw( aItem, layer );
837 
838  return true;
839  }
840 
842  {
843  if( reverseDrawOrder )
844  std::sort( drawItems.begin(), drawItems.end(),
845  []( VIEW_ITEM* a, VIEW_ITEM* b ) -> bool {
846  return b->viewPrivData()->m_drawPriority < a->viewPrivData()->m_drawPriority;
847  });
848  else
849  std::sort( drawItems.begin(), drawItems.end(),
850  []( VIEW_ITEM* a, VIEW_ITEM* b ) -> bool {
851  return a->viewPrivData()->m_drawPriority < b->viewPrivData()->m_drawPriority;
852  });
853 
854  for( auto item : drawItems )
855  view->draw( item, layer );
856  }
857 
859  int layer, layers[VIEW_MAX_LAYERS];
860  bool useDrawPriority, reverseDrawOrder;
861  std::vector<VIEW_ITEM*> drawItems;
862 };
863 
864 
865 void VIEW::redrawRect( const BOX2I& aRect )
866 {
867  for( VIEW_LAYER* l : m_orderedLayers )
868  {
869  if( l->visible && IsTargetDirty( l->target ) && areRequiredLayersEnabled( l->id ) )
870  {
871  drawItem drawFunc( this, l->id, m_useDrawPriority, m_reverseDrawOrder );
872 
873  m_gal->SetTarget( l->target );
874  m_gal->SetLayerDepth( l->renderingOrder );
875  l->items->Query( aRect, drawFunc );
876 
877  if( m_useDrawPriority )
878  drawFunc.deferredDraw();
879  }
880  }
881 }
882 
883 
884 void VIEW::draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate )
885 {
886  auto viewData = aItem->viewPrivData();
887 
888  if( !viewData )
889  return;
890 
891  if( IsCached( aLayer ) && !aImmediate )
892  {
893  // Draw using cached information or create one
894  int group = viewData->getGroup( aLayer );
895 
896  if( group >= 0 )
897  m_gal->DrawGroup( group );
898  else
899  Update( aItem );
900  }
901  else
902  {
903  // Immediate mode
904  if( !m_painter->Draw( aItem, aLayer ) )
905  aItem->ViewDraw( aLayer, this ); // Alternative drawing method
906  }
907 }
908 
909 
910 void VIEW::draw( VIEW_ITEM* aItem, bool aImmediate )
911 {
912  int layers[VIEW_MAX_LAYERS], layers_count;
913 
914  aItem->ViewGetLayers( layers, layers_count );
915 
916  // Sorting is needed for drawing order dependent GALs (like Cairo)
917  SortLayers( layers, layers_count );
918 
919  for( int i = 0; i < layers_count; ++i )
920  {
921  m_gal->SetLayerDepth( m_layers.at( layers[i] ).renderingOrder );
922  draw( aItem, layers[i], aImmediate );
923  }
924 }
925 
926 
927 void VIEW::draw( VIEW_GROUP* aGroup, bool aImmediate )
928 {
929  for( unsigned int i = 0; i < aGroup->GetSize(); i++)
930  draw( aGroup->GetItem(i), aImmediate );
931 }
932 
933 
935 {
936  recacheItem( VIEW* aView, GAL* aGal, int aLayer ) :
937  view( aView ), gal( aGal ), layer( aLayer )
938  {
939  }
940 
941  bool operator()( VIEW_ITEM* aItem )
942  {
943  auto viewData = aItem->viewPrivData();
944 
945  if( !viewData )
946  return false;
947 
948  // Remove previously cached group
949  int group = viewData->getGroup( layer );
950 
951  if( group >= 0 )
952  gal->DeleteGroup( group );
953 
954  viewData->setGroup( layer, -1 );
955  view->Update( aItem );
956 
957  return true;
958  }
959 
962  int layer;
963 };
964 
965 
967 {
968  BOX2I r;
969  r.SetMaximum();
970  m_allItems.clear();
971 
972  for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
973  i->second.items->RemoveAll();
974 
975  m_nextDrawPriority = 0;
976 
977  m_gal->ClearCache();
978 }
979 
980 
982 {
984  {
985  // TARGET_CACHED and TARGET_NONCACHED have to be redrawn together, as they contain
986  // layers that rely on each other (eg. netnames are noncached, but tracks - are cached)
989 
990  MarkDirty();
991  }
992 
994  {
996  }
997 }
998 
999 
1001 {
1002 #ifdef __WXDEBUG__
1003  PROF_COUNTER totalRealTime;
1004 #endif /* __WXDEBUG__ */
1005 
1006  VECTOR2D screenSize = m_gal->GetScreenPixelSize();
1007  BOX2I rect( ToWorld( VECTOR2D( 0, 0 ) ),
1008  ToWorld( screenSize ) - ToWorld( VECTOR2D( 0, 0 ) ) );
1009  rect.Normalize();
1010 
1011  redrawRect( rect );
1012 
1013  // All targets were redrawn, so nothing is dirty
1017 
1018 #ifdef __WXDEBUG__
1019  totalRealTime.Stop();
1020  wxLogTrace( "GAL_PROFILE", wxT( "VIEW::Redraw(): %.1f ms" ), totalRealTime.msecs() );
1021 #endif /* __WXDEBUG__ */
1022 }
1023 
1024 
1026 {
1027  return m_gal->GetScreenPixelSize();
1028 }
1029 
1030 
1032 {
1033  clearLayerCache( VIEW* aView ) :
1034  view( aView )
1035  {
1036  }
1037 
1038  bool operator()( VIEW_ITEM* aItem )
1039  {
1040  aItem->viewPrivData()->deleteGroups();
1041 
1042  return true;
1043  }
1044 
1046 };
1047 
1048 
1050 {
1051  BOX2I r;
1052 
1053  r.SetMaximum();
1054  clearLayerCache visitor( this );
1055 
1056  for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
1057  {
1058  VIEW_LAYER* l = &( ( *i ).second );
1059  l->items->Query( r, visitor );
1060  }
1061 }
1062 
1063 
1064 void VIEW::invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags )
1065 {
1066  if( aUpdateFlags & INITIAL_ADD )
1067  {
1068  // Don't update layers or bbox, since it was done in VIEW::Add()
1069  // Now that we have initialized, set flags to ALL for the code below
1070  aUpdateFlags = ALL;
1071  }
1072  else
1073  {
1074  // updateLayers updates geometry too, so we do not have to update both of them at the same time
1075  if( aUpdateFlags & LAYERS )
1076  {
1077  updateLayers( aItem );
1078  }
1079  else if( aUpdateFlags & GEOMETRY )
1080  {
1081  updateBbox( aItem );
1082  }
1083  }
1084 
1085  int layers[VIEW_MAX_LAYERS], layers_count;
1086  aItem->ViewGetLayers( layers, layers_count );
1087 
1088  // Iterate through layers used by the item and recache it immediately
1089  for( int i = 0; i < layers_count; ++i )
1090  {
1091  int layerId = layers[i];
1092 
1093  if( IsCached( layerId ) )
1094  {
1095  if( aUpdateFlags & ( GEOMETRY | LAYERS ) )
1096  updateItemGeometry( aItem, layerId );
1097  else if( aUpdateFlags & COLOR )
1098  updateItemColor( aItem, layerId );
1099  }
1100 
1101  // Mark those layers as dirty, so the VIEW will be refreshed
1102  MarkTargetDirty( m_layers[layerId].target );
1103  }
1104 
1105  aItem->viewPrivData()->clearUpdateFlags();
1106 }
1107 
1108 
1110 {
1111  int n = 0;
1112 
1113  m_orderedLayers.resize( m_layers.size() );
1114 
1115  for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
1116  m_orderedLayers[n++] = &i->second;
1117 
1118  sort( m_orderedLayers.begin(), m_orderedLayers.end(), compareRenderingOrder );
1119 
1120  MarkDirty();
1121 }
1122 
1123 
1124 void VIEW::updateItemColor( VIEW_ITEM* aItem, int aLayer )
1125 {
1126  auto viewData = aItem->viewPrivData();
1127  wxASSERT( (unsigned) aLayer < m_layers.size() );
1128  wxASSERT( IsCached( aLayer ) );
1129 
1130  if( !viewData )
1131  return;
1132 
1133  // Obtain the color that should be used for coloring the item on the specific layerId
1134  const COLOR4D color = m_painter->GetSettings()->GetColor( aItem, aLayer );
1135  int group = viewData->getGroup( aLayer );
1136 
1137  // Change the color, only if it has group assigned
1138  if( group >= 0 )
1139  m_gal->ChangeGroupColor( group, color );
1140 }
1141 
1142 
1143 void VIEW::updateItemGeometry( VIEW_ITEM* aItem, int aLayer )
1144 {
1145  auto viewData = aItem->viewPrivData();
1146  wxASSERT( (unsigned) aLayer < m_layers.size() );
1147  wxASSERT( IsCached( aLayer ) );
1148 
1149  if( !viewData )
1150  return;
1151 
1152  VIEW_LAYER& l = m_layers.at( aLayer );
1153 
1154  m_gal->SetTarget( l.target );
1156 
1157  // Redraw the item from scratch
1158  int group = viewData->getGroup( aLayer );
1159 
1160  if( group >= 0 )
1161  m_gal->DeleteGroup( group );
1162 
1163  group = m_gal->BeginGroup();
1164  viewData->setGroup( aLayer, group );
1165 
1166  if( !m_painter->Draw( static_cast<EDA_ITEM*>( aItem ), aLayer ) )
1167  aItem->ViewDraw( aLayer, this ); // Alternative drawing method
1168 
1169  m_gal->EndGroup();
1170 }
1171 
1172 
1174 {
1175  int layers[VIEW_MAX_LAYERS], layers_count;
1176 
1177  aItem->ViewGetLayers( layers, layers_count );
1178 
1179  for( int i = 0; i < layers_count; ++i )
1180  {
1181  VIEW_LAYER& l = m_layers[layers[i]];
1182  l.items->Remove( aItem );
1183  l.items->Insert( aItem );
1184  MarkTargetDirty( l.target );
1185  }
1186 }
1187 
1188 
1190 {
1191  auto viewData = aItem->viewPrivData();
1192  int layers[VIEW_MAX_LAYERS], layers_count;
1193 
1194  if( !viewData )
1195  return;
1196 
1197  // Remove the item from previous layer set
1198  viewData->getLayers( layers, layers_count );
1199 
1200  for( int i = 0; i < layers_count; ++i )
1201  {
1202  VIEW_LAYER& l = m_layers[layers[i]];
1203  l.items->Remove( aItem );
1204  MarkTargetDirty( l.target );
1205 
1206  if( IsCached( l.id ) )
1207  {
1208  // Redraw the item from scratch
1209  int prevGroup = viewData->getGroup( layers[i] );
1210 
1211  if( prevGroup >= 0 )
1212  {
1213  m_gal->DeleteGroup( prevGroup );
1214  viewData->setGroup( l.id, -1 );
1215  }
1216  }
1217  }
1218 
1219  // Add the item to new layer set
1220  aItem->ViewGetLayers( layers, layers_count );
1221  viewData->saveLayers( layers, layers_count );
1222 
1223  for( int i = 0; i < layers_count; i++ )
1224  {
1225  VIEW_LAYER& l = m_layers[layers[i]];
1226  l.items->Insert( aItem );
1227  MarkTargetDirty( l.target );
1228  }
1229 }
1230 
1231 
1232 bool VIEW::areRequiredLayersEnabled( int aLayerId ) const
1233 {
1234  wxASSERT( (unsigned) aLayerId < m_layers.size() );
1235 
1236  std::set<int>::const_iterator it, it_end;
1237 
1238  for( it = m_layers.at( aLayerId ).requiredLayers.begin(),
1239  it_end = m_layers.at( aLayerId ).requiredLayers.end(); it != it_end; ++it )
1240  {
1241  // That is enough if just one layer is not enabled
1242  if( !m_layers.at( *it ).visible || !areRequiredLayersEnabled( *it ) )
1243  return false;
1244  }
1245 
1246  return true;
1247 }
1248 
1249 
1251 {
1252  BOX2I r;
1253 
1254  r.SetMaximum();
1255 
1256  for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
1257  {
1258  VIEW_LAYER* l = &( ( *i ).second );
1259 
1260  if( IsCached( l->id ) )
1261  {
1262  recacheItem visitor( this, m_gal, l->id );
1263  l->items->Query( r, visitor );
1264  }
1265  }
1266 }
1267 
1268 
1270 {
1271  m_gal->BeginUpdate();
1272 
1273  for( VIEW_ITEM* item : m_allItems )
1274  {
1275  auto viewData = item->viewPrivData();
1276 
1277  if( !viewData )
1278  continue;
1279 
1280  if( viewData->m_requiredUpdate != NONE )
1281  {
1282  invalidateItem( item, viewData->m_requiredUpdate );
1283  viewData->m_requiredUpdate = NONE;
1284  }
1285  }
1286 
1287  m_gal->EndUpdate();
1288 }
1289 
1290 
1292 {
1294  bool first;
1295 
1297  {
1298  first = true;
1299  }
1300 
1301  bool operator()( VIEW_ITEM* aItem )
1302  {
1303  if( first )
1304  extents = aItem->ViewBBox();
1305  else
1306  extents.Merge( aItem->ViewBBox() );
1307 
1308  return false;
1309  }
1310 };
1311 
1312 
1314 {
1315  extentsVisitor v;
1316  BOX2I fullScene;
1317  fullScene.SetMaximum();
1318 
1319  for( VIEW_LAYER* l : m_orderedLayers )
1320  {
1321  l->items->Query( fullScene, v );
1322  }
1323 
1324  return v.extents;
1325 }
1326 
1327 
1328 void VIEW::SetVisible( VIEW_ITEM* aItem, bool aIsVisible )
1329 {
1330  auto viewData = aItem->viewPrivData();
1331 
1332  if( !viewData )
1333  return;
1334 
1335  bool cur_visible = viewData->m_flags & VISIBLE;
1336 
1337  if( cur_visible != aIsVisible )
1338  {
1339  if( aIsVisible )
1340  viewData->m_flags |= VISIBLE;
1341  else
1342  viewData->m_flags &= ~VISIBLE;
1343 
1344  Update( aItem, APPEARANCE | COLOR );
1345  }
1346 }
1347 
1348 
1349 void VIEW::Hide( VIEW_ITEM* aItem, bool aHide )
1350 {
1351  auto viewData = aItem->viewPrivData();
1352 
1353  if( !viewData )
1354  return;
1355 
1356  if( !( viewData->m_flags & VISIBLE ) )
1357  return;
1358 
1359  if( aHide )
1360  viewData->m_flags |= HIDDEN;
1361  else
1362  viewData->m_flags &= ~HIDDEN;
1363 
1364  Update( aItem, APPEARANCE );
1365 }
1366 
1367 
1368 bool VIEW::IsVisible( const VIEW_ITEM* aItem ) const
1369 {
1370  const auto viewData = aItem->viewPrivData();
1371 
1372  return viewData->m_flags & VISIBLE;
1373 }
1374 
1375 
1376 void VIEW::Update( VIEW_ITEM* aItem )
1377 {
1378  Update( aItem, ALL );
1379 }
1380 
1381 
1382 void VIEW::Update( VIEW_ITEM* aItem, int aUpdateFlags )
1383 {
1384  auto viewData = aItem->viewPrivData();
1385 
1386  if( !viewData )
1387  return;
1388 
1389  assert( aUpdateFlags != NONE );
1390 
1391  viewData->m_requiredUpdate |= aUpdateFlags;
1392 
1393 }
1394 
1396 
1397 }
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:1349
virtual void DrawGroup(int aGroupNumber)
Draw the stored group.
Layers have changed.
Definition: view_item.h:59
Item is visible (in general)
Definition: view_item.h:69
virtual int GetTopLayer() const
Definition: view.cpp:718
void deleteGroups()
Function deleteGroups() Removes all of the stored group ids.
Definition: view.cpp:173
VIEW_ITEM_DATA * m_viewPrivData
Definition: view_item.h:155
void SetViewport(const BOX2D &aViewport)
Function SetViewport() Sets the visible area of the VIEW.
Definition: view.cpp:511
void updateLayers(VIEW_ITEM *aItem)
Updates set of layers that an item occupies.
Definition: view.cpp:1189
void AddLayer(int aLayer, bool aDisplayOnly=false)
Function AddLayer() Adds a new layer to the view.
Definition: view.cpp:292
void SetLayerOrder(int aLayer, int aRenderingOrder)
Function SetLayerOrder() Sets rendering order of a particular layer.
Definition: view.cpp:587
void SetRequired(int aLayerId, int aRequiredId, bool aRequired=true)
Function SetRequired() Marks the aRequiredId layer as required for the aLayerId layer.
Definition: view.cpp:379
void updateItemColor(VIEW_ITEM *aItem, int aLayer)
Updates colors that are used for an item to be drawn.
Definition: view.cpp:1124
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.
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:727
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:415
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:1109
queryVisitor(Container &aCont, int aLayer)
Definition: view.cpp:397
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:438
void RecacheAllItems()
Function RecacheAllItems() Rebuilds GAL display lists.
Definition: view.cpp:1250
virtual void Remove(VIEW_ITEM *aItem)
Function Remove() Removes a VIEW_ITEM from the view.
Definition: view.cpp:339
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:228
void UpdateAllLayersOrder()
Function UpdateLayerOrder() Does everything that is needed to apply the rendering order of layers...
Definition: view.cpp:794
No updates are required.
Definition: view_item.h:55
int requiredUpdate() const
Function viewRequiredUpdate() Returns current update flag for an item.
Definition: view.cpp:219
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:526
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:237
Item is being added to the view.
Definition: view_item.h:60
const Vec & GetSize() const
Definition: box2.h:177
virtual void ComputeWorldScreenMatrix()
Compute the world <-> screen transformation matrix.
The class PROF_COUNTER is a small class to help profiling.
Definition: profile.h:45
void SetScale(double aScale)
Function SetScale() Sets the scaling factor.
Definition: view.h:247
virtual void SetLayerDepth(double aLayerDepth)
Set the depth of the layer (position on the z-axis)
virtual void EnableTopLayer(bool aEnable)
Function EnableTopLayer() Enables or disables display of the top layer.
Definition: view.cpp:754
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:774
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:783
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:941
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:816
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:601
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:395
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:703
clearLayerCache(VIEW *aView)
Definition: view.cpp:1033
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:780
void SetCenter(const VECTOR2D &aCenter)
Function SetCenter() Sets the center point of the VIEW (i.e.
Definition: view.cpp:562
BOX2D GetViewport() const
Function GetViewport() Returns the current viewport visible area rectangle.
Definition: view.cpp:499
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:1000
void MarkTargetDirty(int aTarget)
Function MarkTargetDirty() Sets or clears target &#39;dirty&#39; flag.
Definition: view.h:568
void Clear()
Function Clear() Removes all items from the view.
Definition: view.cpp:966
int GetLayerOrder(int aLayer) const
Function GetLayerOrder() Returns rendering order of a particular layer.
Definition: view.cpp:595
virtual int BeginGroup()
Begin a group.
const BOX2I CalculateExtents()
Definition: view.cpp:1313
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:1064
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 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:1269
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:97
void updateBbox(VIEW_ITEM *aItem)
Updates bounding box of an item.
Definition: view.cpp:1173
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:698
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:1382
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:202
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:779
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:823
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:1049
VIEW_ITEM_DATA * viewPrivData() const
Definition: view_item.h:147
double m_maxScale
Scale upper limit.
Definition: view.h:786
void UpdateLayerColor(int aLayer)
Function UpdateLayerColor() Applies the new coloring scheme held by RENDER_SETTINGS in case that it h...
Definition: view.cpp:654
double msecs() const
Definition: profile.h:124
std::vector< VIEW_ITEM * > drawItems
Definition: view.cpp:861
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:402
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:636
void redrawRect(const BOX2I &aRect)
Definition: view.cpp:865
bool operator()(VIEW_ITEM *aItem)
Definition: view.cpp:1301
void updateItemGeometry(VIEW_ITEM *aItem, int aLayer)
Updates all informations needed to draw an item.
Definition: view.cpp:1143
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:1232
bool m_enableOrderModifier
Definition: view.h:762
#define max(a, b)
Definition: auxiliary.h:86
static void OnDestroy(VIEW_ITEM *aItem)
Definition: view.cpp:244
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
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:884
virtual unsigned int ViewGetLOD(int aLayer, VIEW *aView) const
Function ViewGetLOD() Returns the level of detail (LOD) of the item.
Definition: view_item.h:139
VECTOR2D ToScreen(const VECTOR2D &aCoord, bool aAbsolute=true) const
Function ToScreen() Converts a world space point/vector to a point/vector in screen space coordinates...
Definition: view.cpp:457
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:1025
void SetZoomFactor(double aZoomFactor)
Set the zoom factor of the scene.
bool m_mirrorY
Vertical flip flag
Definition: view.h:792
void ClearTargets()
Function ClearTargets() Clears targets that are marked as dirty.
Definition: view.cpp:981
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:1328
void CopySettings(const VIEW *aOtherView)
Function CopySettings() Copies layers and visibility settings from another view.
Definition: view.cpp:476
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:410
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:309
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:285
Basic classes for most KiCad items.
VIEW(bool aIsDynamic=true)
Constructor.
Definition: view.cpp:258
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:1368
void UpdateAllLayersColor()
Function UpdateAllLayersColor() Applies the new coloring scheme to all layers.
Definition: view.cpp:672
std::vector< int > m_layers
Stores layer numbers used by the item.
Definition: view.cpp:193
void SetGAL(GAL *aGal)
Function SetGAL() Assigns a rendering device for the VIEW.
Definition: view.cpp:482
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:936
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:631
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:1038
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