Add drawing priority support to VIEW

Call UseDrawPriority( true ) after creating GAL to enable.

VIEW::Add() gets a new optional argument to specify the draw order
when adding an item.  If the new argument is left default, the draw
order will increment with each call of VIEW::Add().

Fix std::bind calls after change to VIEW::Add
This commit is contained in:
Jon Evans 2017-02-27 18:40:27 -05:00 committed by Tomasz Włostowski
parent be10de8d28
commit 0afb249447
7 changed files with 69 additions and 15 deletions

View File

@ -89,6 +89,7 @@ private:
VIEW* m_view; ///< Current dynamic view the item is assigned to.
int m_flags; ///< Visibility flags
int m_requiredUpdate; ///< Flag required for updating
int m_drawPriority; ///< Order to draw this item in a layer, lowest first
///> Helper for storing cached items group ids
typedef std::pair<int, int> GroupPair;
@ -260,7 +261,9 @@ VIEW::VIEW( bool aIsDynamic ) :
m_mirrorX( false ), m_mirrorY( false ),
m_painter( NULL ),
m_gal( NULL ),
m_dynamic( aIsDynamic )
m_dynamic( aIsDynamic ),
m_useDrawPriority( false ),
m_nextDrawPriority( 0 )
{
m_boundary.SetMaximum();
m_allItems.reserve( 32768 );
@ -301,12 +304,16 @@ void VIEW::AddLayer( int aLayer, bool aDisplayOnly )
}
void VIEW::Add( VIEW_ITEM* aItem )
void VIEW::Add( VIEW_ITEM* aItem, int aDrawPriority )
{
int layers[VIEW_MAX_LAYERS], layers_count;
if( aDrawPriority < 0 )
aDrawPriority = m_nextDrawPriority++;
aItem->m_viewPrivData = new VIEW_ITEM_DATA;
aItem->m_viewPrivData->m_view = this;
aItem->m_viewPrivData->m_drawPriority = aDrawPriority;
aItem->ViewGetLayers( layers, layers_count );
aItem->viewPrivData()->saveLayers( layers, layers_count );
@ -812,8 +819,8 @@ void VIEW::UpdateAllLayersOrder()
struct VIEW::drawItem
{
drawItem( VIEW* aView, int aLayer ) :
view( aView ), layer( aLayer )
drawItem( VIEW* aView, int aLayer, bool aUseDrawPriority ) :
view( aView ), layer( aLayer ), useDrawPriority( aUseDrawPriority )
{
}
@ -827,13 +834,29 @@ struct VIEW::drawItem
if( !drawCondition )
return true;
if( useDrawPriority )
drawItems.push_back( aItem );
else
view->draw( aItem, layer );
return true;
}
void deferredDraw()
{
std::sort( drawItems.begin(), drawItems.end(),
[]( VIEW_ITEM* a, VIEW_ITEM* b ) -> bool {
return b->viewPrivData()->m_drawPriority < a->viewPrivData()->m_drawPriority;
});
for( auto item : drawItems )
view->draw( item, layer );
}
VIEW* view;
int layer, layers[VIEW_MAX_LAYERS];
bool useDrawPriority;
std::vector<VIEW_ITEM*> drawItems;
};
@ -843,11 +866,14 @@ void VIEW::redrawRect( const BOX2I& aRect )
{
if( l->visible && IsTargetDirty( l->target ) && areRequiredLayersEnabled( l->id ) )
{
drawItem drawFunc( this, l->id );
drawItem drawFunc( this, l->id, m_useDrawPriority );
m_gal->SetTarget( l->target );
m_gal->SetLayerDepth( l->renderingOrder );
l->items->Query( aRect, drawFunc );
if( m_useDrawPriority )
drawFunc.deferredDraw();
}
}
}
@ -955,6 +981,8 @@ void VIEW::Clear()
for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
i->second.items->RemoveAll();
m_nextDrawPriority = 0;
m_gal->ClearCache();
}

View File

@ -79,9 +79,11 @@ public:
/**
* Function Add()
* Adds a VIEW_ITEM to the view.
* Set aDrawPriority to -1 to assign sequential priorities.
* @param aItem: item to be added. No ownership is given
* @param aDrawPriority: priority to draw this item on its layer, lowest first.
*/
void Add( VIEW_ITEM* aItem );
void Add( VIEW_ITEM* aItem, int aDrawPriority = -1 );
/**
* Function Remove()
@ -617,6 +619,24 @@ public:
const BOX2I CalculateExtents() ;
/**
* Function IsUsingDrawPriority()
* @return true if draw priority is being respected while redrawing.
*/
bool IsUsingDrawPriority() const
{
return m_useDrawPriority;
}
/**
* Function UseDrawPriority()
* @param aFlag is true if draw priority should be respected while redrawing.
*/
void UseDrawPriority( bool aFlag )
{
m_useDrawPriority = aFlag;
}
static const int VIEW_MAX_LAYERS = 256; ///< maximum number of layers that may be shown
private:
@ -776,6 +796,12 @@ private:
/// Flat list of all items
std::vector<VIEW_ITEM*> m_allItems;
/// Flag to respect draw priority when drawing items
bool m_useDrawPriority;
/// The next sequential drawing priority
int m_nextDrawPriority;
};
} // namespace KIGFX

View File

@ -117,7 +117,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
if( boardItem->Type() == PCB_MODULE_T )
{
MODULE* mod = static_cast<MODULE*>( boardItem );
mod->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1 ) );
mod->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1, -1 ) );
}
}
else
@ -327,7 +327,7 @@ void BOARD_COMMIT::Revert()
{
MODULE* newModule = static_cast<MODULE*>( item );
newModule->RunOnChildren( std::bind( &EDA_ITEM::ClearFlags, _1, SELECTED ) );
newModule->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1 ) );
newModule->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1, -1 ) );
}
view->Add( item );
@ -355,7 +355,7 @@ void BOARD_COMMIT::Revert()
{
MODULE* newModule = static_cast<MODULE*>( item );
newModule->RunOnChildren( std::bind( &EDA_ITEM::ClearFlags, _1, SELECTED ) );
newModule->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1 ) );
newModule->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1, -1 ) );
}
view->Add( item );

View File

@ -202,7 +202,7 @@ void FOOTPRINT_PREVIEW_PANEL::renderFootprint( MODULE *module )
Freeze();
GetView()->Clear();
module->SetParent ( &*m_dummyBoard );
module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, GetView(), _1 ) );
module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, GetView(), _1, -1 ) );
GetView()->Add ( module );

View File

@ -158,7 +158,7 @@ void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName,
// Reload modules
for( MODULE* module = board->m_Modules; module; module = module->Next() )
{
module->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1 ) );
module->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1, -1 ) );
view->Add( module );
}

View File

@ -150,7 +150,7 @@ void PCB_DRAW_PANEL_GAL::DisplayBoard( const BOARD* aBoard )
// Load modules and its additional elements
for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
{
module->RunOnChildren( std::bind( &KIGFX::VIEW::Add, m_view, _1 ) );
module->RunOnChildren( std::bind( &KIGFX::VIEW::Add, m_view, _1, -1 ) );
m_view->Add( module );
}

View File

@ -477,7 +477,7 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
if( item->Type() == PCB_MODULE_T )
{
MODULE* newModule = static_cast<MODULE*>( item );
newModule->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1 ) );
newModule->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1, -1 ) );
newModule->RunOnChildren( std::bind( &BOARD_ITEM::ClearFlags, _1, EDA_ITEM_ALL_FLAGS ));
}
@ -508,7 +508,7 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
if( item->Type() == PCB_MODULE_T )
{
MODULE* module = static_cast<MODULE*>( item );
module->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1) );
module->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1, -1 ) );
}
view->Add( item );