diff --git a/common/drawpanel_gal.cpp b/common/drawpanel_gal.cpp index 8f68332aa3..6df67bb3a0 100644 --- a/common/drawpanel_gal.cpp +++ b/common/drawpanel_gal.cpp @@ -73,15 +73,6 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin m_view->SetPainter( m_painter ); m_view->SetGAL( m_gal ); - // View uses layers to display EDA_ITEMs (item may be displayed on several layers, for example - // pad may be shown on pad, pad hole and solder paste layers). There are usual copper layers - // (eg. F.Cu, B.Cu, internal and so on) and layers for displaying objects such as texts, - // silkscreen, pads, vias, etc. - for( int i = 0; i < TOTAL_LAYER_COUNT; i++ ) - { - m_view->AddLayer( i ); - } - m_viewControls = new KiGfx::WX_VIEW_CONTROLS( m_view, this ); Connect( wxEVT_PAINT, wxPaintEventHandler( EDA_DRAW_PANEL_GAL::onPaint ), NULL, this ); diff --git a/common/view/view.cpp b/common/view/view.cpp index 86333d51c5..4fcd86b9ba 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -50,6 +50,15 @@ VIEW::VIEW( bool aIsDynamic ) : // Redraw everything at the beginning for( int i = 0; i < TARGETS_NUMBER; ++i ) MarkTargetDirty( i ); + + // View uses layers to display EDA_ITEMs (item may be displayed on several layers, for example + // pad may be shown on pad, pad hole and solder paste layers). There are usual copper layers + // (eg. F.Cu, B.Cu, internal and so on) and layers for displaying objects such as texts, + // silkscreen, pads, vias, etc. + for( int i = 0; i < VIEW_MAX_LAYERS; i++ ) + { + AddLayer( i ); + } } @@ -85,6 +94,7 @@ void VIEW::Add( VIEW_ITEM* aItem ) int layers[VIEW_MAX_LAYERS], layers_count; aItem->ViewGetLayers( layers, layers_count ); + aItem->saveLayers( layers, layers_count ); for( int i = 0; i < layers_count; i++ ) { @@ -103,12 +113,14 @@ void VIEW::Remove( VIEW_ITEM* aItem ) if( m_dynamic ) aItem->m_view = NULL; -// fixme: this is so sloooow! - for( LayerMapIter i = m_layers.begin(); i != m_layers.end(); ++i ) + int layers[VIEW::VIEW_MAX_LAYERS], layers_count; + aItem->getLayers( layers, layers_count ); + + for( int i = 0; i < layers_count; ++i ) { - VIEW_LAYER* l = & ( ( *i ).second ); - l->items->Remove( aItem ); - l->isDirty = true; + VIEW_LAYER& l = m_layers[layers[i]]; + l.items->Remove( aItem ); + l.isDirty = true; } } @@ -595,7 +607,9 @@ void VIEW::draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate ) const void VIEW::draw( VIEW_ITEM* aItem, bool aImmediate ) const { int layers[VIEW_MAX_LAYERS], layers_count; - aItem->ViewGetLayers( layers, layers_count ); + + aItem->getLayers( layers, layers_count ); + // Sorting is needed for drawing order dependent GALs (like Cairo) SortLayers( layers, layers_count ); for( int i = 0; i < layers_count; ++i ) @@ -773,26 +787,30 @@ void VIEW::clearGroupCache() void VIEW::invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags ) { int layers[VIEW_MAX_LAYERS], layers_count; - aItem->ViewGetLayers( layers, layers_count ); + aItem->getLayers( layers, layers_count ); // Iterate through layers used by the item and recache it immediately for( int i = 0; i < layers_count; i++ ) { - if( aUpdateFlags == VIEW_ITEM::APPEARANCE ) + int layerId = layers[i]; + + if( aUpdateFlags & VIEW_ITEM::GEOMETRY ) { - updateItemAppearance( aItem, layers[i] ); - } - else if( aUpdateFlags == VIEW_ITEM::GEOMETRY ) - { - // Reinsert item + // Reinsert item in order to update bounding box Remove( aItem ); Add( aItem ); - updateItemGeometry( aItem, layers[i]); /// TODO is it still necessary? + + if( isCached( layerId ) ) + updateItemGeometry( aItem, layerId ); /// TODO is it still necessary? + } + else if( aUpdateFlags & VIEW_ITEM::COLOR ) + { + updateItemColor( aItem, layerId ); } // Mark those layers as dirty, so the VIEW will be refreshed - m_layers[layers[i]].isDirty = true; - MarkTargetDirty( m_layers[layers[i]].target ); // TODO remove? + m_layers[layerId].isDirty = true; + MarkTargetDirty( m_layers[layerId].target ); // TODO remove? } } @@ -812,7 +830,7 @@ void VIEW::sortLayers() } -void VIEW::updateItemAppearance( VIEW_ITEM* aItem, int aLayer ) +void VIEW::updateItemColor( VIEW_ITEM* aItem, int aLayer ) { wxASSERT( (unsigned) aLayer < m_layers.size() ); @@ -875,13 +893,13 @@ void VIEW::RecacheAllItems( bool aImmediately ) { VIEW_LAYER* l = &( ( *i ).second ); - // Obviously, there is only one cached target that has to be recomputed if( isCached( l->id ) ) { m_gal->SetTarget( l->target ); m_gal->SetLayerDepth( l->renderingOrder ); recacheLayer visitor( this, m_gal, l->id, aImmediately ); l->items->Query( r, visitor ); + l->isDirty = false; } } diff --git a/common/view/view_item.cpp b/common/view/view_item.cpp index 3d1fcc1f35..4104d06c1a 100644 --- a/common/view/view_item.cpp +++ b/common/view/view_item.cpp @@ -71,6 +71,20 @@ void VIEW_ITEM::ViewRelease() } +void VIEW_ITEM::getLayers( int* aLayers, int& aCount ) const +{ + int* layersPtr = aLayers; + for( int i = 0; i < m_layers.size(); ++i ) + { + if( m_layers[i] ) + *layersPtr++ = i; + + } + + aCount = m_layers.count(); +} + + int VIEW_ITEM::getGroup( int aLayer ) const { for( int i = 0; i < m_groupsSize; ++i ) diff --git a/include/base_struct.h b/include/base_struct.h index 67e427eae6..b61368e0d1 100644 --- a/include/base_struct.h +++ b/include/base_struct.h @@ -472,13 +472,13 @@ public: inline bool IsHighlighted() const { return m_Flags & HIGHLIGHTED; } inline bool IsBrightened() const { return m_Flags & BRIGHTENED; } - inline void SetSelected() { SetFlags( SELECTED ); ViewUpdate( APPEARANCE ); } - inline void SetHighlighted() { SetFlags( HIGHLIGHTED ); ViewUpdate( APPEARANCE ); } - inline void SetBrightened() { SetFlags( BRIGHTENED ); ViewUpdate( APPEARANCE ); } + inline void SetSelected() { SetFlags( SELECTED ); ViewUpdate( COLOR ); } + inline void SetHighlighted() { SetFlags( HIGHLIGHTED ); ViewUpdate( COLOR ); } + inline void SetBrightened() { SetFlags( BRIGHTENED ); ViewUpdate( COLOR ); } - inline void ClearSelected() { ClearFlags( SELECTED ); ViewUpdate( APPEARANCE ); } - inline void ClearHighlighted() { ClearFlags( HIGHLIGHTED ); ViewUpdate( APPEARANCE ); } - inline void ClearBrightened() { ClearFlags( BRIGHTENED ); ViewUpdate( APPEARANCE ); } + inline void ClearSelected() { ClearFlags( SELECTED ); ViewUpdate( COLOR ); } + inline void ClearHighlighted() { ClearFlags( HIGHLIGHTED ); ViewUpdate( COLOR ); } + inline void ClearBrightened() { ClearFlags( BRIGHTENED ); ViewUpdate( COLOR ); } void SetModified(); diff --git a/include/view/view.h b/include/view/view.h index 3fd1935db6..4ad11828f5 100644 --- a/include/view/view.h +++ b/include/view/view.h @@ -510,7 +510,7 @@ private: void clearGroupCache(); /// Updates colors that are used for an item to be drawn - void updateItemAppearance( VIEW_ITEM* aItem, int aLayer ); + void updateItemColor( VIEW_ITEM* aItem, int aLayer ); /// Updates all informations needed to draw an item void updateItemGeometry( VIEW_ITEM* aItem, int aLayer ); diff --git a/include/view/view_item.h b/include/view/view_item.h index 17325d338b..49f0b7d492 100644 --- a/include/view/view_item.h +++ b/include/view/view_item.h @@ -31,14 +31,16 @@ #define __VIEW_ITEM_H #include +#include #include +#include +#include namespace KiGfx { // Forward declarations class GAL; class PAINTER; -class VIEW; /** * Class VIEW_ITEM - @@ -62,12 +64,14 @@ public: * - ALL: all flags above */ enum ViewUpdateFlags { - APPEARANCE = 0x1, - GEOMETRY = 0x2, - ALL = 0xff + APPEARANCE = 0x01, /// Visibility flag has changed + COLOR = 0x02, /// Color has changed + GEOMETRY = 0x04, /// Position or shape has changed + ALL = 0xff }; - VIEW_ITEM() : m_view( NULL ), m_visible( true ), m_groups( NULL ), m_groupsSize( 0 ) {} + VIEW_ITEM() : m_view( NULL ), m_visible( true ), m_groups( NULL ), + m_groupsSize( 0 ) {} /** * Destructor. For dynamic views, removes the item from the view. @@ -165,6 +169,15 @@ public: protected: friend class VIEW; + /** + * Function getLayers() + * Returns layer numbers used by the item. + * + * @param aLayers[]: output layer index array + * @param aCount: number of layer indices in aLayers[] + */ + virtual void getLayers( int* aLayers, int& aCount ) const; + /** * Function viewAssign() * Assigns the item to a given dynamic VIEW. Called internally by the VIEW. @@ -229,6 +242,25 @@ protected: * @returns true in case it is cached at least for one layer. */ virtual bool storesGroups() const; + + /// Stores layer numbers used by the item. + std::bitset m_layers; + + /** + * Function saveLayers() + * Saves layers used by the item. + * + * @param aLayers is an array containing layer numbers to be saved. + * @param aCount is the size of the array. + */ + virtual void saveLayers( int* aLayers, int aCount ) + { + m_layers.reset(); + + for( int i = 0; i < aCount; ++i ) + m_layers.set(aLayers[i]); + } + }; } // namespace KiGfx