diff --git a/common/view/view.cpp b/common/view/view.cpp index 7528009d6c..b8f72a0f01 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -39,11 +39,6 @@ using namespace KiGfx; -// Static constants -const int VIEW::VIEW_MAX_LAYERS = 64; -// Top layer depth -const int VIEW::TOP_LAYER = -1; - void VIEW::AddLayer( int aLayer, bool aDisplayOnly ) { if( m_layers.find( aLayer ) == m_layers.end() ) @@ -140,14 +135,12 @@ int VIEW::Query( const BOX2I& aRect, std::vector& aResult ) VIEW::VIEW( bool aIsDynamic ) : - m_enableTopLayer( false ), + m_enableOrderModifier( false ), m_scale ( 1.0 ), m_painter( NULL ), m_gal( NULL ), m_dynamic( aIsDynamic ) { - // By default there is no layer on the top - m_topLayer.enabled = false; } @@ -395,63 +388,75 @@ void VIEW::ChangeLayerDepth( int aLayer, int aDepth ) } -void VIEW::SetTopLayer( int aLayer ) +void VIEW::SetTopLayer( int aLayer, bool aEnabled ) { - // Restore previous order - if( m_topLayer.enabled ) + if( aEnabled ) { - m_layers[m_topLayer.id].renderingOrder = m_topLayer.renderingOrder; - ChangeLayerDepth( m_topLayer.id, m_topLayer.renderingOrder ); - } + if( m_topLayers.count( aLayer ) == 1 ) + return; - if( aLayer >= 0 && aLayer < VIEW_MAX_LAYERS ) - { - // Save settings, so it can be restored later - m_topLayer.renderingOrder = m_layers[aLayer].renderingOrder; - m_topLayer.id = m_layers[aLayer].id; + m_topLayers.insert( aLayer ); - // Apply new settings only if the option is enabled - if( m_enableTopLayer ) - { - m_layers[aLayer].renderingOrder = TOP_LAYER; - ChangeLayerDepth( aLayer, TOP_LAYER ); - } - - // Set the flag saying that settings stored in m_topLayer are valid - m_topLayer.enabled = true; + // Move the layer closer to front + if( m_enableOrderModifier ) + m_layers[aLayer].renderingOrder += TOP_LAYER_MODIFIER; } else { - // There are no valid settings in m_topLayer - m_topLayer.enabled = false; - } + if( m_topLayers.count( aLayer ) == 0 ) + return; - sortLayers(); + m_topLayers.erase( aLayer ); + + // Restore the previous rendering order + if( m_enableOrderModifier ) + m_layers[aLayer].renderingOrder -= TOP_LAYER_MODIFIER; + } } void VIEW::EnableTopLayer( bool aEnable ) { - if( aEnable == m_enableTopLayer ) return; + if( aEnable == m_enableOrderModifier ) return; + m_enableOrderModifier = aEnable; - // Use stored settings only if applicable - // (topLayer.enabled == false means there are no valid settings stored) - if( m_topLayer.enabled ) + std::set::iterator it; + if( aEnable ) { - if( aEnable ) - { - m_layers[m_topLayer.id].renderingOrder = TOP_LAYER; - ChangeLayerDepth( m_topLayer.id, TOP_LAYER ); - } - else - { - m_layers[m_topLayer.id].renderingOrder = m_topLayer.renderingOrder; - ChangeLayerDepth( m_topLayer.id, m_topLayer.renderingOrder ); - } + for( it = m_topLayers.begin(); it != m_topLayers.end(); ++it ) + m_layers[*it].renderingOrder += TOP_LAYER_MODIFIER; } + else + { + for( it = m_topLayers.begin(); it != m_topLayers.end(); ++it ) + m_layers[*it].renderingOrder -= TOP_LAYER_MODIFIER; + } +} + + +void VIEW::ClearTopLayers() +{ + std::set::iterator it; + + if( m_enableOrderModifier ) + { + // Restore the previous rendering order for layers that were marked as top + for( it = m_topLayers.begin(); it != m_topLayers.end(); ++it ) + m_layers[*it].renderingOrder -= TOP_LAYER_MODIFIER; + } + + m_topLayers.clear(); +} + + +void VIEW::UpdateAllLayersOrder() +{ sortLayers(); - m_enableTopLayer = aEnable; + BOOST_FOREACH( LayerMap::value_type& l, m_layers ) + { + ChangeLayerDepth( l.first, l.second.renderingOrder ); + } } @@ -513,7 +518,7 @@ void VIEW::redrawRect( const BOX2I& aRect ) { drawItem drawFunc( this, l ); - m_gal->SetLayerDepth( static_cast( l->renderingOrder ) ); + m_gal->SetLayerDepth( l->renderingOrder ); l->items->Query( aRect, drawFunc ); l->isDirty = false; } @@ -703,7 +708,7 @@ void VIEW::RecacheAllItems( bool aImmediately ) if( l->cached ) { - m_gal->SetLayerDepth( (double) l->renderingOrder ); + m_gal->SetLayerDepth( l->renderingOrder ); recacheLayer visitor( this, m_gal, l->id, aImmediately ); l->items->Query( r, visitor ); } diff --git a/include/view/view.h b/include/view/view.h index c13ba6bf52..3f3c0dc459 100644 --- a/include/view/view.h +++ b/include/view/view.h @@ -26,6 +26,7 @@ #define __VIEW_H #include +#include #include #include @@ -305,7 +306,7 @@ public: * @param aLayer: the layer or -1 in case when no particular layer should * be displayed on the top. */ - void SetTopLayer( int aLayer ); + void SetTopLayer( int aLayer, bool aEnabled = true ); /** * Function EnableTopLayer() @@ -316,6 +317,20 @@ public: */ void EnableTopLayer( bool aEnable ); + /** + * Function ClearTopLayers() + * Removes all layers from the on-the-top set (they are no longer displayed over the rest of + * layers). + */ + void ClearTopLayers(); + + /** + * Function UpdateLayerOrder() + * Does everything that is needed to apply the rendering order of layers. It has to be called + * after modification of renderingOrder field of LAYER. + */ + void UpdateAllLayersOrder(); + /** * Function Redraw() * Immediately redraws the whole view. @@ -344,8 +359,7 @@ public: */ bool IsDynamic() const { return m_dynamic; } - static const int VIEW_MAX_LAYERS; ///* maximum number of layers that may be shown - static const int TOP_LAYER; ///* layer number for displaying items on the top + static const int VIEW_MAX_LAYERS = 64; ///* maximum number of layers that may be shown private: struct VIEW_LAYER @@ -377,11 +391,8 @@ private: struct updateItemsColor; struct changeItemsDepth; - ///* Saves current top layer settings in order to restore it when it's not top anymore - VIEW_LAYER m_topLayer; - - ///* Whether to use top layer settings or not - bool m_enableTopLayer; + ///* Whether to use rendering order modifier or not + bool m_enableOrderModifier; ///* Redraws contents within rect aRect void redrawRect( const BOX2I& aRect ); @@ -412,6 +423,9 @@ private: /// Sorted list of pointers to members of m_layers. LayerOrder m_orderedLayers; + /// Stores set of layers that are displayed on the top + std::set m_topLayers; + /// Center point of the VIEW (the point at which we are looking at) VECTOR2D m_center; @@ -427,6 +441,9 @@ private: /// Dynamic VIEW (eg. display PCB in window) allows changes once it is built, /// static (eg. image/PDF) - does not. bool m_dynamic; + + /// Rendering order modifier for layers that are marked as top layers + static const int TOP_LAYER_MODIFIER = -VIEW_MAX_LAYERS; }; } // namespace KiGfx diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 251db833b7..a79e660104 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -133,13 +133,7 @@ protected: * will change the currently active layer to \a aLayer and also * update the PCB_LAYER_WIDGET. */ - void setActiveLayer( LAYER_NUM aLayer, bool doLayerWidgetUpdate = true ) - { - ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer = aLayer; - - if( doLayerWidgetUpdate ) - syncLayerWidgetLayer(); - } + void setActiveLayer( LAYER_NUM aLayer, bool doLayerWidgetUpdate = true ); /** * Function getActiveLayer diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index e8accd2d7f..9fbf01b8dd 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -258,13 +258,9 @@ void PCB_BASE_FRAME::SetBoard( BOARD* aBoard ) view->SetLayerVisible( ITEM_GAL_LAYER( i ), m_Pcb->IsElementVisible( i ) ); } - view->SetTopLayer( m_Pcb->GetLayer() ); - view->RecacheAllItems( true ); if( m_galCanvasActive ) - { m_galCanvas->Refresh(); - } } } diff --git a/pcbnew/class_pcb_layer_widget.cpp b/pcbnew/class_pcb_layer_widget.cpp index dbc070d3df..54fb33d740 100644 --- a/pcbnew/class_pcb_layer_widget.cpp +++ b/pcbnew/class_pcb_layer_widget.cpp @@ -356,21 +356,10 @@ bool PCB_LAYER_WIDGET::OnLayerSelect( LAYER_NUM aLayer ) // false from this function. myframe->setActiveLayer( aLayer, false ); - // Set display settings for high contrast mode - KiGfx::VIEW* view = myframe->GetGalCanvas()->GetView(); - view->GetPainter()->GetSettings()->SetActiveLayer( aLayer ); - view->UpdateAllLayersColor(); - view->SetTopLayer( aLayer ); - if( m_alwaysShowActiveCopperLayer ) OnLayerSelected(); - else if(DisplayOpt.ContrastModeDisplay) - { - if( myframe->IsGalCanvasActive() ) - myframe->GetGalCanvas()->Refresh(); - else - myframe->GetCanvas()->Refresh(); - } + else if( DisplayOpt.ContrastModeDisplay ) + myframe->GetCanvas()->Refresh(); return true; } diff --git a/pcbnew/dialogs/dialog_general_options.cpp b/pcbnew/dialogs/dialog_general_options.cpp index c066e2c3a7..996c0f9e92 100644 --- a/pcbnew/dialogs/dialog_general_options.cpp +++ b/pcbnew/dialogs/dialog_general_options.cpp @@ -232,16 +232,27 @@ void PCB_EDIT_FRAME::OnSelectOptionToolbar( wxCommandEvent& event ) break; case ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE: + { DisplayOpt.ContrastModeDisplay = state; // Apply new display options to the GAL canvas (this is faster than recaching) settings->LoadDisplayOptions( DisplayOpt ); - m_galCanvas->GetView()->EnableTopLayer( state ); - m_galCanvas->GetView()->UpdateAllLayersColor(); + + KiGfx::VIEW* view = m_galCanvas->GetView(); + LAYER_NUM layer = getActiveLayer(); + + view->GetPainter()->GetSettings()->SetActiveLayer( layer ); + view->UpdateAllLayersColor(); + + view->EnableTopLayer( state ); + view->ClearTopLayers(); + view->SetTopLayer( layer ); + view->UpdateAllLayersOrder(); if( !IsGalCanvasActive() ) m_canvas->Refresh(); break; + } case ID_TB_OPTIONS_SHOW_EXTRA_VERTICAL_TOOLBAR_MICROWAVE: m_show_microwave_tools = state; diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 53014d1dcb..a9cafce5cb 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -56,6 +56,8 @@ #include #include #include +#include +#include #if defined(KICAD_SCRIPTING) || defined(KICAD_SCRIPTING_WXPYTHON) @@ -741,6 +743,31 @@ bool PCB_EDIT_FRAME::IsMicroViaAcceptable( void ) } +void PCB_EDIT_FRAME::setActiveLayer( LAYER_NUM aLayer, bool doLayerWidgetUpdate ) +{ + ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer = aLayer; + + // Set display settings for high contrast mode + KiGfx::VIEW* view = m_galCanvas->GetView(); + + if( DisplayOpt.ContrastModeDisplay ) + { + view->GetPainter()->GetSettings()->SetActiveLayer( aLayer ); + view->UpdateAllLayersColor(); + + view->ClearTopLayers(); + view->SetTopLayer( aLayer ); + view->UpdateAllLayersOrder(); + + if( m_galCanvasActive ) + m_galCanvas->Refresh(); + } + + if( doLayerWidgetUpdate ) + syncLayerWidgetLayer(); +} + + void PCB_EDIT_FRAME::syncLayerWidgetLayer() { m_Layers->SelectLayer( getActiveLayer() );