Commit 5ac69977 authored by Maciej Suminski's avatar Maciej Suminski

Revisiting GAL:

- VIEW_ITEM::ViewUpdate() does not update items immediately. Now it marks them to be updated and the real update occurs on the next rendering frame.
- VIEW::InvalidateItem() made private.
- VIEW_LAYER::enabled -> visible
- Some functions moved to header files.
parent 87785441
...@@ -124,17 +124,22 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) ) ...@@ -124,17 +124,22 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) )
{ {
m_drawing = true; m_drawing = true;
m_view->UpdateItems();
m_gal->BeginDrawing(); m_gal->BeginDrawing();
m_gal->SetBackgroundColor( KIGFX::COLOR4D( 0.0, 0.0, 0.0, 1.0 ) );
m_gal->ClearScreen(); m_gal->ClearScreen();
if( m_view->IsDirty() )
{
m_view->ClearTargets(); m_view->ClearTargets();
// Grid has to be redrawn only when the NONCACHED target is redrawn // Grid has to be redrawn only when the NONCACHED target is redrawn
if( m_view->IsTargetDirty( KIGFX::TARGET_NONCACHED ) ) if( m_view->IsTargetDirty( KIGFX::TARGET_NONCACHED ) )
m_gal->DrawGrid(); m_gal->DrawGrid();
m_view->Redraw(); m_view->Redraw();
m_gal->DrawCursor( m_viewControls->GetCursorPosition() ); }
m_gal->DrawCursor( m_viewControls->GetCursorPosition() );
m_gal->EndDrawing(); m_gal->EndDrawing();
m_drawing = false; m_drawing = false;
...@@ -215,6 +220,7 @@ void EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType ) ...@@ -215,6 +220,7 @@ void EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType )
wxSize size = GetClientSize(); wxSize size = GetClientSize();
m_gal->ResizeScreen( size.GetX(), size.GetY() ); m_gal->ResizeScreen( size.GetX(), size.GetY() );
m_gal->SetBackgroundColor( KIGFX::COLOR4D( 0.0, 0.0, 0.0, 1.0 ) );
if( m_painter ) if( m_painter )
m_painter->SetGAL( m_gal ); m_painter->SetGAL( m_gal );
......
...@@ -49,28 +49,24 @@ VIEW::VIEW( bool aIsDynamic ) : ...@@ -49,28 +49,24 @@ VIEW::VIEW( bool aIsDynamic ) :
m_scaleLimits( 15000.0, 1.0 ) m_scaleLimits( 15000.0, 1.0 )
{ {
m_panBoundary.SetMaximum(); m_panBoundary.SetMaximum();
m_needsUpdate.reserve( 32768 );
// Redraw everything at the beginning // Redraw everything at the beginning
for( int i = 0; i < TARGETS_NUMBER; ++i ) MarkDirty();
MarkTargetDirty( i );
// View uses layers to display EDA_ITEMs (item may be displayed on several layers, for example // 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 // 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, // (eg. F.Cu, B.Cu, internal and so on) and layers for displaying objects such as texts,
// silkscreen, pads, vias, etc. // silkscreen, pads, vias, etc.
for( int i = 0; i < VIEW_MAX_LAYERS; i++ ) for( int i = 0; i < VIEW_MAX_LAYERS; i++ )
{
AddLayer( i ); AddLayer( i );
}
} }
VIEW::~VIEW() VIEW::~VIEW()
{ {
BOOST_FOREACH( LAYER_MAP::value_type& l, m_layers ) BOOST_FOREACH( LAYER_MAP::value_type& l, m_layers )
{
delete l.second.items; delete l.second.items;
}
} }
...@@ -82,7 +78,7 @@ void VIEW::AddLayer( int aLayer, bool aDisplayOnly ) ...@@ -82,7 +78,7 @@ void VIEW::AddLayer( int aLayer, bool aDisplayOnly )
m_layers[aLayer].id = aLayer; m_layers[aLayer].id = aLayer;
m_layers[aLayer].items = new VIEW_RTREE(); m_layers[aLayer].items = new VIEW_RTREE();
m_layers[aLayer].renderingOrder = aLayer; m_layers[aLayer].renderingOrder = aLayer;
m_layers[aLayer].enabled = true; m_layers[aLayer].visible = true;
m_layers[aLayer].displayOnly = aDisplayOnly; m_layers[aLayer].displayOnly = aDisplayOnly;
m_layers[aLayer].target = TARGET_CACHED; m_layers[aLayer].target = TARGET_CACHED;
} }
...@@ -172,12 +168,12 @@ struct queryVisitor ...@@ -172,12 +168,12 @@ struct queryVisitor
}; };
int VIEW::Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) int VIEW::Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) const
{ {
if( m_orderedLayers.empty() ) if( m_orderedLayers.empty() )
return 0; return 0;
std::vector<VIEW_LAYER*>::reverse_iterator i; std::vector<VIEW_LAYER*>::const_reverse_iterator i;
// execute queries in reverse direction, so that items that are on the top of // execute queries in reverse direction, so that items that are on the top of
// the rendering stack are returned first. // the rendering stack are returned first.
...@@ -257,12 +253,6 @@ void VIEW::SetGAL( GAL* aGal ) ...@@ -257,12 +253,6 @@ void VIEW::SetGAL( GAL* aGal )
} }
void VIEW::SetPainter( PAINTER* aPainter )
{
m_painter = aPainter;
}
BOX2D VIEW::GetViewport() const BOX2D VIEW::GetViewport() const
{ {
BOX2D rect; BOX2D rect;
...@@ -293,12 +283,6 @@ void VIEW::SetMirror( bool aMirrorX, bool aMirrorY ) ...@@ -293,12 +283,6 @@ void VIEW::SetMirror( bool aMirrorX, bool aMirrorY )
} }
void VIEW::SetScale( double aScale )
{
SetScale( aScale, m_center );
}
void VIEW::SetScale( double aScale, const VECTOR2D& aAnchor ) void VIEW::SetScale( double aScale, const VECTOR2D& aAnchor )
{ {
if( aScale > m_scaleLimits.x ) if( aScale > m_scaleLimits.x )
...@@ -578,8 +562,8 @@ void VIEW::UpdateAllLayersOrder() ...@@ -578,8 +562,8 @@ void VIEW::UpdateAllLayersOrder()
struct VIEW::drawItem struct VIEW::drawItem
{ {
drawItem( VIEW* aView, const VIEW_LAYER* aCurrentLayer ) : drawItem( VIEW* aView, int aLayer ) :
currentLayer( aCurrentLayer ), view( aView ) view( aView ), layer( aLayer )
{ {
} }
...@@ -587,18 +571,17 @@ struct VIEW::drawItem ...@@ -587,18 +571,17 @@ struct VIEW::drawItem
{ {
// Conditions that have te be fulfilled for an item to be drawn // Conditions that have te be fulfilled for an item to be drawn
bool drawCondition = aItem->ViewIsVisible() && bool drawCondition = aItem->ViewIsVisible() &&
aItem->ViewGetLOD( currentLayer->id ) < view->m_scale; aItem->ViewGetLOD( layer ) < view->m_scale;
if( !drawCondition ) if( !drawCondition )
return true; return true;
view->draw( aItem, currentLayer->id ); view->draw( aItem, layer );
return true; return true;
} }
const VIEW_LAYER* currentLayer;
VIEW* view; VIEW* view;
int layersCount, layers[VIEW_MAX_LAYERS]; int layer, layersCount, layers[VIEW_MAX_LAYERS];
}; };
...@@ -606,9 +589,9 @@ void VIEW::redrawRect( const BOX2I& aRect ) ...@@ -606,9 +589,9 @@ void VIEW::redrawRect( const BOX2I& aRect )
{ {
BOOST_FOREACH( VIEW_LAYER* l, m_orderedLayers ) BOOST_FOREACH( VIEW_LAYER* l, m_orderedLayers )
{ {
if( l->enabled && IsTargetDirty( l->target ) && areRequiredLayersEnabled( l->id ) ) if( l->visible && IsTargetDirty( l->target ) && areRequiredLayersEnabled( l->id ) )
{ {
drawItem drawFunc( this, l ); drawItem drawFunc( this, l->id );
m_gal->SetTarget( l->target ); m_gal->SetTarget( l->target );
m_gal->SetLayerDepth( l->renderingOrder ); m_gal->SetLayerDepth( l->renderingOrder );
...@@ -618,7 +601,7 @@ void VIEW::redrawRect( const BOX2I& aRect ) ...@@ -618,7 +601,7 @@ void VIEW::redrawRect( const BOX2I& aRect )
} }
void VIEW::draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate ) const void VIEW::draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate )
{ {
if( IsCached( aLayer ) && !aImmediate ) if( IsCached( aLayer ) && !aImmediate )
{ {
...@@ -649,11 +632,12 @@ void VIEW::draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate ) const ...@@ -649,11 +632,12 @@ void VIEW::draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate ) const
} }
void VIEW::draw( VIEW_ITEM* aItem, bool aImmediate ) const void VIEW::draw( VIEW_ITEM* aItem, bool aImmediate )
{ {
int layers[VIEW_MAX_LAYERS], layers_count; int layers[VIEW_MAX_LAYERS], layers_count;
aItem->ViewGetLayers( layers, layers_count ); aItem->ViewGetLayers( layers, layers_count );
// Sorting is needed for drawing order dependent GALs (like Cairo) // Sorting is needed for drawing order dependent GALs (like Cairo)
SortLayers( layers, layers_count ); SortLayers( layers, layers_count );
...@@ -665,26 +649,12 @@ void VIEW::draw( VIEW_ITEM* aItem, bool aImmediate ) const ...@@ -665,26 +649,12 @@ void VIEW::draw( VIEW_ITEM* aItem, bool aImmediate ) const
} }
void VIEW::draw( VIEW_GROUP* aGroup, bool aImmediate ) const void VIEW::draw( VIEW_GROUP* aGroup, bool aImmediate )
{ {
std::set<VIEW_ITEM*>::const_iterator it; std::set<VIEW_ITEM*>::const_iterator it;
for( it = aGroup->Begin(); it != aGroup->End(); ++it ) for( it = aGroup->Begin(); it != aGroup->End(); ++it )
{
draw( *it, aImmediate ); draw( *it, aImmediate );
}
}
bool VIEW::IsDirty() const
{
for( int i = 0; i < TARGETS_NUMBER; ++i )
{
if( IsTargetDirty( i ) )
return true;
}
return false;
} }
...@@ -709,14 +679,14 @@ struct VIEW::recacheItem ...@@ -709,14 +679,14 @@ struct VIEW::recacheItem
bool operator()( VIEW_ITEM* aItem ) bool operator()( VIEW_ITEM* aItem )
{ {
// Remove previously cached group // Remove previously cached group
int prevGroup = aItem->getGroup( layer ); int group = aItem->getGroup( layer );
if( prevGroup >= 0 ) if( group >= 0 )
gal->DeleteGroup( prevGroup ); gal->DeleteGroup( group );
if( immediately ) if( immediately )
{ {
int group = gal->BeginGroup(); group = gal->BeginGroup();
aItem->setGroup( layer, group ); aItem->setGroup( layer, group );
if( !view->m_painter->Draw( aItem, layer ) ) if( !view->m_painter->Draw( aItem, layer ) )
...@@ -791,13 +761,13 @@ void VIEW::Redraw() ...@@ -791,13 +761,13 @@ void VIEW::Redraw()
redrawRect( rect ); redrawRect( rect );
// All targets were redrawn, so nothing is dirty // All targets were redrawn, so nothing is dirty
clearTargetDirty( TARGET_CACHED ); markTargetClean( TARGET_CACHED );
clearTargetDirty( TARGET_NONCACHED ); markTargetClean( TARGET_NONCACHED );
clearTargetDirty( TARGET_OVERLAY ); markTargetClean( TARGET_OVERLAY );
} }
VECTOR2D VIEW::GetScreenPixelSize() const const VECTOR2D& VIEW::GetScreenPixelSize() const
{ {
return m_gal->GetScreenPixelSize(); return m_gal->GetScreenPixelSize();
} }
...@@ -839,7 +809,7 @@ void VIEW::clearGroupCache() ...@@ -839,7 +809,7 @@ void VIEW::clearGroupCache()
} }
void VIEW::InvalidateItem( VIEW_ITEM* aItem, int aUpdateFlags ) void VIEW::invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags )
{ {
// updateLayers updates geometry too, so we do not have to update both of them at the same time // updateLayers updates geometry too, so we do not have to update both of them at the same time
if( aUpdateFlags & VIEW_ITEM::LAYERS ) if( aUpdateFlags & VIEW_ITEM::LAYERS )
...@@ -851,24 +821,23 @@ void VIEW::InvalidateItem( VIEW_ITEM* aItem, int aUpdateFlags ) ...@@ -851,24 +821,23 @@ void VIEW::InvalidateItem( VIEW_ITEM* aItem, int aUpdateFlags )
aItem->ViewGetLayers( layers, layers_count ); aItem->ViewGetLayers( layers, layers_count );
// Iterate through layers used by the item and recache it immediately // Iterate through layers used by the item and recache it immediately
for( int i = 0; i < layers_count; i++ ) for( int i = 0; i < layers_count; ++i )
{ {
int layerId = layers[i]; int layerId = layers[i];
if( aUpdateFlags & ( VIEW_ITEM::GEOMETRY | VIEW_ITEM::LAYERS ) )
{
// Redraw
if( IsCached( layerId ) ) if( IsCached( layerId ) )
{
if( aUpdateFlags & ( VIEW_ITEM::GEOMETRY | VIEW_ITEM::LAYERS ) )
updateItemGeometry( aItem, layerId ); updateItemGeometry( aItem, layerId );
}
else if( aUpdateFlags & VIEW_ITEM::COLOR ) else if( aUpdateFlags & VIEW_ITEM::COLOR )
{
updateItemColor( aItem, layerId ); updateItemColor( aItem, layerId );
} }
// Mark those layers as dirty, so the VIEW will be refreshed // Mark those layers as dirty, so the VIEW will be refreshed
MarkTargetDirty( m_layers[layerId].target ); MarkTargetDirty( m_layers[layerId].target );
} }
aItem->clearUpdateFlags();
} }
...@@ -890,6 +859,7 @@ void VIEW::sortLayers() ...@@ -890,6 +859,7 @@ void VIEW::sortLayers()
void VIEW::updateItemColor( VIEW_ITEM* aItem, int aLayer ) void VIEW::updateItemColor( VIEW_ITEM* aItem, int aLayer )
{ {
wxASSERT( (unsigned) aLayer < m_layers.size() ); wxASSERT( (unsigned) aLayer < m_layers.size() );
wxASSERT( IsCached( aLayer ) );
// Obtain the color that should be used for coloring the item on the specific layerId // Obtain the color that should be used for coloring the item on the specific layerId
const COLOR4D color = m_painter->GetSettings()->GetColor( aItem, aLayer ); const COLOR4D color = m_painter->GetSettings()->GetColor( aItem, aLayer );
...@@ -904,18 +874,20 @@ void VIEW::updateItemColor( VIEW_ITEM* aItem, int aLayer ) ...@@ -904,18 +874,20 @@ void VIEW::updateItemColor( VIEW_ITEM* aItem, int aLayer )
void VIEW::updateItemGeometry( VIEW_ITEM* aItem, int aLayer ) void VIEW::updateItemGeometry( VIEW_ITEM* aItem, int aLayer )
{ {
wxASSERT( (unsigned) aLayer < m_layers.size() ); wxASSERT( (unsigned) aLayer < m_layers.size() );
wxASSERT( IsCached( aLayer ) );
VIEW_LAYER& l = m_layers.at( aLayer ); VIEW_LAYER& l = m_layers.at( aLayer );
m_gal->SetTarget( l.target ); m_gal->SetTarget( l.target );
m_gal->SetLayerDepth( l.renderingOrder ); m_gal->SetLayerDepth( l.renderingOrder );
// Redraw the item from scratch // Redraw the item from scratch
int prevGroup = aItem->getGroup( aLayer ); int group = aItem->getGroup( aLayer );
if( prevGroup >= 0 ) if( group >= 0 )
m_gal->DeleteGroup( prevGroup ); m_gal->DeleteGroup( group );
int group = m_gal->BeginGroup(); group = m_gal->BeginGroup();
aItem->setGroup( aLayer, group ); aItem->setGroup( aLayer, group );
m_painter->Draw( static_cast<EDA_ITEM*>( aItem ), aLayer ); m_painter->Draw( static_cast<EDA_ITEM*>( aItem ), aLayer );
m_gal->EndGroup(); m_gal->EndGroup();
...@@ -951,11 +923,17 @@ void VIEW::updateLayers( VIEW_ITEM* aItem ) ...@@ -951,11 +923,17 @@ void VIEW::updateLayers( VIEW_ITEM* aItem )
l.items->Remove( aItem ); l.items->Remove( aItem );
MarkTargetDirty( l.target ); MarkTargetDirty( l.target );
if( IsCached( l.id ) )
{
// Redraw the item from scratch // Redraw the item from scratch
int prevGroup = aItem->getGroup( layers[i] ); int prevGroup = aItem->getGroup( layers[i] );
if( prevGroup >= 0 ) if( prevGroup >= 0 )
{
m_gal->DeleteGroup( prevGroup ); m_gal->DeleteGroup( prevGroup );
aItem->setGroup( l.id, -1 );
}
}
} }
// Add the item to new layer set // Add the item to new layer set
...@@ -981,7 +959,7 @@ bool VIEW::areRequiredLayersEnabled( int aLayerId ) const ...@@ -981,7 +959,7 @@ bool VIEW::areRequiredLayersEnabled( int aLayerId ) const
it_end = m_layers.at( aLayerId ).requiredLayers.end(); it != it_end; ++it ) it_end = m_layers.at( aLayerId ).requiredLayers.end(); it != it_end; ++it )
{ {
// That is enough if just one layer is not enabled // That is enough if just one layer is not enabled
if( !m_layers.at( *it ).enabled ) if( !m_layers.at( *it ).visible )
return false; return false;
} }
...@@ -1023,13 +1001,15 @@ void VIEW::RecacheAllItems( bool aImmediately ) ...@@ -1023,13 +1001,15 @@ void VIEW::RecacheAllItems( bool aImmediately )
} }
bool VIEW::IsTargetDirty( int aTarget ) const void VIEW::UpdateItems()
{ {
wxASSERT( aTarget < TARGETS_NUMBER ); // Update items that need this
BOOST_FOREACH( VIEW_ITEM* item, m_needsUpdate )
{
assert( item->viewRequiredUpdate() != VIEW_ITEM::NONE );
// Check the target status invalidateItem( item, item->viewRequiredUpdate() );
if( m_dirtyTargets[aTarget] ) }
return true;
return false; m_needsUpdate.clear();
} }
...@@ -31,25 +31,12 @@ using namespace KIGFX; ...@@ -31,25 +31,12 @@ using namespace KIGFX;
void VIEW_ITEM::ViewSetVisible( bool aIsVisible ) void VIEW_ITEM::ViewSetVisible( bool aIsVisible )
{ {
bool update = false; // update only if the visibility has really changed
if( m_visible != aIsVisible ) if( m_visible != aIsVisible )
update = true; {
m_visible = aIsVisible; m_visible = aIsVisible;
// update only if the visibility has really changed
if( update )
ViewUpdate( APPEARANCE ); ViewUpdate( APPEARANCE );
} }
void VIEW_ITEM::ViewUpdate( int aUpdateFlags )
{
if( !m_view )
return;
m_view->InvalidateItem( this, aUpdateFlags );
} }
......
...@@ -94,7 +94,7 @@ public: ...@@ -94,7 +94,7 @@ public:
* first). * first).
* @return Number of found items. * @return Number of found items.
*/ */
int Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ); int Query( const BOX2I& aRect, std::vector<LAYER_ITEM_PAIR>& aResult ) const;
/** /**
* Function SetRequired() * Function SetRequired()
...@@ -140,7 +140,10 @@ public: ...@@ -140,7 +140,10 @@ public:
* Function SetPainter() * Function SetPainter()
* Sets the painter object used by the view for drawing VIEW_ITEMS. * Sets the painter object used by the view for drawing VIEW_ITEMS.
*/ */
void SetPainter( PAINTER* aPainter ); void SetPainter( PAINTER* aPainter )
{
m_painter = aPainter;
}
/** /**
* Function GetPainter() * Function GetPainter()
...@@ -181,7 +184,10 @@ public: ...@@ -181,7 +184,10 @@ public:
* (depending on correct GAL unit length & DPI settings). * (depending on correct GAL unit length & DPI settings).
* @param aScale: the scalefactor * @param aScale: the scalefactor
*/ */
void SetScale( double aScale ); void SetScale( double aScale )
{
SetScale( aScale, m_center );
}
/** /**
* Function SetScale() * Function SetScale()
...@@ -247,7 +253,7 @@ public: ...@@ -247,7 +253,7 @@ public:
* Returns the size of the our rendering area, in pixels. * Returns the size of the our rendering area, in pixels.
* @return viewport screen size * @return viewport screen size
*/ */
VECTOR2D GetScreenPixelSize() const; const VECTOR2D& GetScreenPixelSize() const;
/** /**
* Function AddLayer() * Function AddLayer()
...@@ -279,11 +285,11 @@ public: ...@@ -279,11 +285,11 @@ public:
*/ */
inline void SetLayerVisible( int aLayer, bool aVisible = true ) inline void SetLayerVisible( int aLayer, bool aVisible = true )
{ {
if( m_layers[aLayer].enabled != aVisible ) if( m_layers[aLayer].visible != aVisible )
{ {
// Target has to be redrawn after changing its visibility // Target has to be redrawn after changing its visibility
MarkTargetDirty( m_layers[aLayer].target ); MarkTargetDirty( m_layers[aLayer].target );
m_layers[aLayer].enabled = aVisible; m_layers[aLayer].visible = aVisible;
} }
} }
...@@ -294,7 +300,7 @@ public: ...@@ -294,7 +300,7 @@ public:
*/ */
inline bool IsLayerVisible( int aLayer ) const inline bool IsLayerVisible( int aLayer ) const
{ {
return m_layers.at( aLayer ).enabled; return m_layers.at( aLayer ).visible;
} }
/** /**
...@@ -402,13 +408,6 @@ public: ...@@ -402,13 +408,6 @@ public:
*/ */
void Redraw(); void Redraw();
/**
* Function PartialRedraw()
* Redraws only the parts of the view that have been affected by items
* for which ViewUpdate() function has been called since last redraw.
*/
void PartialRedraw();
/** /**
* Function RecacheAllItems() * Function RecacheAllItems()
* Rebuilds GAL display lists. * Rebuilds GAL display lists.
...@@ -432,7 +431,16 @@ public: ...@@ -432,7 +431,16 @@ public:
* Returns true if any of the VIEW layers needs to be refreshened. * Returns true if any of the VIEW layers needs to be refreshened.
* @return True in case if any of layers is marked as dirty. * @return True in case if any of layers is marked as dirty.
*/ */
bool IsDirty() const; bool IsDirty() const
{
for( int i = 0; i < TARGETS_NUMBER; ++i )
{
if( IsTargetDirty( i ) )
return true;
}
return false;
}
/** /**
* Function IsTargetDirty() * Function IsTargetDirty()
...@@ -440,7 +448,12 @@ public: ...@@ -440,7 +448,12 @@ public:
* redrawn. * redrawn.
* @return True if the above condition is fulfilled. * @return True if the above condition is fulfilled.
*/ */
bool IsTargetDirty( int aTarget ) const; bool IsTargetDirty( int aTarget ) const
{
wxASSERT( aTarget < TARGETS_NUMBER );
return m_dirtyTargets[aTarget];
}
/** /**
* Function MarkTargetDirty() * Function MarkTargetDirty()
...@@ -470,6 +483,22 @@ public: ...@@ -470,6 +483,22 @@ public:
m_dirtyTargets[i] = true; m_dirtyTargets[i] = true;
} }
/**
* Function MarkForUpdate()
* Adds an item to a list of items that are going to be refreshed upon the next frame rendering.
* @param aItem is the item to be refreshed.
*/
void MarkForUpdate( VIEW_ITEM* aItem )
{
m_needsUpdate.push_back( aItem );
}
/**
* Function UpdateItems()
* Iterates through the list of items that asked for updating and updates them.
*/
void UpdateItems();
/** /**
* Function SetPanBoundary() * Function SetPanBoundary()
* Sets limits for panning area. * Sets limits for panning area.
...@@ -493,26 +522,18 @@ public: ...@@ -493,26 +522,18 @@ public:
m_scaleLimits = VECTOR2D( aMaximum, aMinimum ); m_scaleLimits = VECTOR2D( aMaximum, aMinimum );
} }
/** static const int VIEW_MAX_LAYERS = 128; ///< maximum number of layers that may be shown
* Function InvalidateItem()
* Manages dirty flags & redraw queueing when updating an item.
* @param aItem is the item to be updated.
* @param aUpdateFlags determines the way an item is refreshed.
*/
void InvalidateItem( VIEW_ITEM* aItem, int aUpdateFlags );
static const int VIEW_MAX_LAYERS = 128; ///* maximum number of layers that may be shown
private: private:
struct VIEW_LAYER struct VIEW_LAYER
{ {
bool enabled; ///* is the layer to be rendered? bool visible; ///< is the layer to be rendered?
bool displayOnly; ///* is the layer display only? bool displayOnly; ///< is the layer display only?
VIEW_RTREE* items; ///* R-tree indexing all items on this layer. VIEW_RTREE* items; ///< R-tree indexing all items on this layer.
int renderingOrder; ///* rendering order of this layer int renderingOrder; ///< rendering order of this layer
int id; ///* layer ID int id; ///< layer ID
RENDER_TARGET target; ///* where the layer should be rendered RENDER_TARGET target; ///< where the layer should be rendered
std::set<int> requiredLayers; ///* layers that have to be enabled to show the layer std::set<int> requiredLayers; ///< layers that have to be enabled to show the layer
}; };
// Convenience typedefs // Convenience typedefs
...@@ -532,7 +553,7 @@ private: ...@@ -532,7 +553,7 @@ private:
///* Redraws contents within rect aRect ///* Redraws contents within rect aRect
void redrawRect( const BOX2I& aRect ); void redrawRect( const BOX2I& aRect );
inline void clearTargetDirty( int aTarget ) inline void markTargetClean( int aTarget )
{ {
wxASSERT( aTarget < TARGETS_NUMBER ); wxASSERT( aTarget < TARGETS_NUMBER );
...@@ -549,7 +570,7 @@ private: ...@@ -549,7 +570,7 @@ private:
* @param aImmediate dictates the way of drawing - it allows to force immediate drawing mode * @param aImmediate dictates the way of drawing - it allows to force immediate drawing mode
* for cached items. * for cached items.
*/ */
void draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate = false ) const; void draw( VIEW_ITEM* aItem, int aLayer, bool aImmediate = false );
/** /**
* Function draw() * Function draw()
...@@ -559,7 +580,7 @@ private: ...@@ -559,7 +580,7 @@ private:
* @param aImmediate dictates the way of drawing - it allows to force immediate drawing mode * @param aImmediate dictates the way of drawing - it allows to force immediate drawing mode
* for cached items. * for cached items.
*/ */
void draw( VIEW_ITEM* aItem, bool aImmediate = false ) const; void draw( VIEW_ITEM* aItem, bool aImmediate = false );
/** /**
* Function draw() * Function draw()
...@@ -569,7 +590,7 @@ private: ...@@ -569,7 +590,7 @@ private:
* @param aImmediate dictates the way of drawing - it allows to force immediate drawing mode * @param aImmediate dictates the way of drawing - it allows to force immediate drawing mode
* for cached items. * for cached items.
*/ */
void draw( VIEW_GROUP* aGroup, bool aImmediate = false ) const; void draw( VIEW_GROUP* aGroup, bool aImmediate = false );
///* Sorts m_orderedLayers when layer rendering order has changed ///* Sorts m_orderedLayers when layer rendering order has changed
void sortLayers(); void sortLayers();
...@@ -578,6 +599,14 @@ private: ...@@ -578,6 +599,14 @@ private:
///* used by GAL) ///* used by GAL)
void clearGroupCache(); void clearGroupCache();
/**
* Function InvalidateItem()
* Manages dirty flags & redraw queueing when updating an item.
* @param aItem is the item to be updated.
* @param aUpdateFlags determines the way an item is refreshed.
*/
void invalidateItem( VIEW_ITEM* aItem, int aUpdateFlags );
/// Updates colors that are used for an item to be drawn /// Updates colors that are used for an item to be drawn
void updateItemColor( VIEW_ITEM* aItem, int aLayer ); void updateItemColor( VIEW_ITEM* aItem, int aLayer );
...@@ -638,6 +667,9 @@ private: ...@@ -638,6 +667,9 @@ private:
/// Zoom limits /// Zoom limits
VECTOR2D m_scaleLimits; VECTOR2D m_scaleLimits;
/// Items to be updated
std::vector<VIEW_ITEM*> m_needsUpdate;
}; };
} // namespace KIGFX } // namespace KIGFX
......
...@@ -157,12 +157,16 @@ public: ...@@ -157,12 +157,16 @@ public:
/** /**
* Enum VIEW_UPDATE_FLAGS. * Enum VIEW_UPDATE_FLAGS.
* Defines the how severely the shape/appearance of the item has been changed: * Defines the how severely the shape/appearance of the item has been changed:
* - NONE: TODO
* - APPEARANCE: shape or layer set of the item have not been affected, * - APPEARANCE: shape or layer set of the item have not been affected,
* only colors or visibility. * only colors or visibility.
* - COLOR:
* - GEOMETRY: shape or layer set of the item have changed, VIEW may need to reindex it. * - GEOMETRY: shape or layer set of the item have changed, VIEW may need to reindex it.
* - ALL: all flags above */ * - LAYERS: TODO
* - ALL: all the flags above */
enum VIEW_UPDATE_FLAGS { enum VIEW_UPDATE_FLAGS {
NONE = 0x00, /// No updates are required
APPEARANCE = 0x01, /// Visibility flag has changed APPEARANCE = 0x01, /// Visibility flag has changed
COLOR = 0x02, /// Color has changed COLOR = 0x02, /// Color has changed
GEOMETRY = 0x04, /// Position or shape has changed GEOMETRY = 0x04, /// Position or shape has changed
...@@ -170,7 +174,8 @@ public: ...@@ -170,7 +174,8 @@ public:
ALL = 0xff 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_requiredUpdate( NONE ),
m_groups( NULL ), m_groupsSize( 0 ) {}
/** /**
* Destructor. For dynamic views, removes the item from the view. * Destructor. For dynamic views, removes the item from the view.
...@@ -262,9 +267,15 @@ public: ...@@ -262,9 +267,15 @@ public:
* For dynamic VIEWs, informs the associated VIEW that the graphical representation of * For dynamic VIEWs, informs the associated VIEW that the graphical representation of
* this item has changed. For static views calling has no effect. * this item has changed. For static views calling has no effect.
* *
* @param aUpdateFlags: how much the object has changed * @param aUpdateFlags: how much the object has changed.
*/ */
virtual void ViewUpdate( int aUpdateFlags = ALL ); virtual void ViewUpdate( int aUpdateFlags = ALL )
{
if( m_view && m_requiredUpdate == NONE )
m_view->MarkForUpdate( this );
m_requiredUpdate |= aUpdateFlags;
}
/** /**
* Function ViewRelease() * Function ViewRelease()
...@@ -298,8 +309,9 @@ protected: ...@@ -298,8 +309,9 @@ protected:
deleteGroups(); deleteGroups();
} }
VIEW* m_view; ///* Current dynamic view the item is assigned to. VIEW* m_view; ///< Current dynamic view the item is assigned to.
bool m_visible; ///* Are we visible in the current dynamic VIEW. bool m_visible; ///< Are we visible in the current dynamic VIEW.
int m_requiredUpdate; ///< Flag required for updating
///* Helper for storing cached items group ids ///* Helper for storing cached items group ids
typedef std::pair<int, int> GroupPair; typedef std::pair<int, int> GroupPair;
...@@ -374,6 +386,24 @@ protected: ...@@ -374,6 +386,24 @@ protected:
m_layers.set( aLayers[i] ); m_layers.set( aLayers[i] );
} }
} }
/**
* Function viewRequiredUpdate()
* Returns current update flag for an item.
*/
virtual int viewRequiredUpdate() const
{
return m_requiredUpdate;
}
/**
* Function clearUpdateFlags()
* Marks an item as already updated, so it is not going to be redrawn.
*/
void clearUpdateFlags()
{
m_requiredUpdate = NONE;
}
}; };
} // namespace KIGFX } // namespace KIGFX
......
...@@ -746,20 +746,20 @@ void MODULE::ViewUpdate( int aUpdateFlags ) ...@@ -746,20 +746,20 @@ void MODULE::ViewUpdate( int aUpdateFlags )
if( !m_view ) if( !m_view )
return; return;
// Update the module itself
VIEW_ITEM::ViewUpdate( aUpdateFlags );
// Update pads // Update pads
for( D_PAD* pad = m_Pads.GetFirst(); pad; pad = pad->Next() ) for( D_PAD* pad = m_Pads.GetFirst(); pad; pad = pad->Next() )
m_view->InvalidateItem( pad, aUpdateFlags ); pad->ViewUpdate( aUpdateFlags );
// Update module's drawing (mostly silkscreen) // Update module's drawing (mostly silkscreen)
for( BOARD_ITEM* drawing = m_Drawings.GetFirst(); drawing; drawing = drawing->Next() ) for( BOARD_ITEM* drawing = m_Drawings.GetFirst(); drawing; drawing = drawing->Next() )
m_view->InvalidateItem( drawing, aUpdateFlags ); drawing->ViewUpdate( aUpdateFlags );
// Update module's texts // Update module's texts
m_view->InvalidateItem( m_Reference, aUpdateFlags ); m_Reference->ViewUpdate( aUpdateFlags );
m_view->InvalidateItem( m_Value, aUpdateFlags ); m_Value->ViewUpdate( aUpdateFlags );
// Update the module itself
m_view->InvalidateItem( this, aUpdateFlags );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment