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