From cbec733deba13a60968c3316edfea6e9746b8f01 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Tue, 16 Jul 2013 09:26:29 +0200 Subject: [PATCH] Refactored code responsible for high contrast mode. Now it allows to have more than one layer on the top. Selecting layer using the dropdown list on the toolbar influences the layer displayed in high contrast mode. --- common/view/view.cpp | 103 ++++++++++++---------- include/view/view.h | 33 +++++-- include/wxPcbStruct.h | 8 +- pcbnew/basepcbframe.cpp | 4 - pcbnew/class_pcb_layer_widget.cpp | 15 +--- pcbnew/dialogs/dialog_general_options.cpp | 15 +++- pcbnew/pcbframe.cpp | 27 ++++++ 7 files changed, 122 insertions(+), 83 deletions(-) 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() );