Improve rendering of tuning status popup

Fixes https://gitlab.com/kicad/code/kicad/-/issues/16304

Add dedicated UI rendering layers

Switch to screen-space rendering to avoid blurriness

Fix a bug in OpenGL GAL that causes layer
ordering to be broken when using Scale

Fix some issues with VIEW_GROUP layer ordering
This commit is contained in:
Jon Evans 2023-12-17 08:46:57 -05:00
parent bf6e6d0e11
commit 1c895fe18c
9 changed files with 86 additions and 36 deletions

View File

@ -1923,7 +1923,7 @@ void OPENGL_GAL::Translate( const VECTOR2D& aVector )
void OPENGL_GAL::Scale( const VECTOR2D& aScale )
{
m_currentManager->Scale( aScale.x, aScale.y, 0.0f );
m_currentManager->Scale( aScale.x, aScale.y, 1.0f );
}

View File

@ -138,6 +138,9 @@ void VIEW_GROUP::ViewDraw( int aLayer, VIEW* aView ) const
for( const std::pair<const int, std::vector<VIEW_ITEM*>>& entry : layer_item_map )
layers[ layers_count++ ] = entry.first;
if( layers_count == 0 )
return;
aView->SortLayers( layers, layers_count );
// Now draw the layers in sorted order

View File

@ -363,8 +363,8 @@ public:
*/
virtual void SetLayerDepth( double aLayerDepth )
{
assert( aLayerDepth <= m_depthRange.y );
assert( aLayerDepth >= m_depthRange.x );
wxCHECK_MSG( aLayerDepth <= m_depthRange.y, /* void */, "SetLayerDepth: below minimum" );
wxCHECK_MSG( aLayerDepth >= m_depthRange.x, /* void */, "SetLayerDepth: above maximum" );
m_layerDepth = aLayerDepth;
}
@ -931,7 +931,7 @@ public:
*/
inline void AdvanceDepth()
{
m_layerDepth -= 0.05;
m_layerDepth -= 0.1;
}
/**

View File

@ -174,6 +174,8 @@ enum NETNAMES_LAYER_ID: int
/// Macro for obtaining netname layer for a given PCB layer
#define NETNAMES_LAYER_INDEX( layer ) ( NETNAMES_LAYER_ID_START + layer )
#define GAL_UI_LAYER_COUNT 10
/**
* GAL layers are "virtual" layers, i.e. not tied into design data.
* Some layers here are shared between applications.
@ -258,6 +260,10 @@ enum GAL_LAYER_ID: int
LAYER_BITMAP_START,
LAYER_BITMAP_END = LAYER_BITMAP_START + PCB_LAYER_ID_COUNT,
// Layers for drawing on-canvas UI
LAYER_UI_START,
LAYER_UI_END = LAYER_UI_START + GAL_UI_LAYER_COUNT,
GAL_LAYER_ID_END
};

View File

@ -129,8 +129,8 @@ public:
void ViewGetLayers( int aLayers[], int& aCount ) const override
{
aLayers[0] = LAYER_SELECT_OVERLAY;
aLayers[1] = LAYER_GP_OVERLAY;
aLayers[0] = LAYER_UI_START;
aLayers[1] = LAYER_UI_START + 1;
aCount = 2;
}
@ -138,19 +138,19 @@ public:
{
KIGFX::GAL* gal = aView->GetGAL();
bool viewFlipped = gal->IsFlippedX();
bool drawingDropShadows = ( aLayer == LAYER_GP_OVERLAY );
bool drawingDropShadows = ( aLayer == LAYER_UI_START );
gal->PushDepth();
gal->SetLayerDepth( gal->GetMinDepth() );
gal->Save();
gal->Scale( { 1., 1. } );
KIGFX::PREVIEW::TEXT_DIMS headerDims = KIGFX::PREVIEW::GetConstantGlyphHeight( gal, -3 );
KIGFX::PREVIEW::TEXT_DIMS textDims = KIGFX::PREVIEW::GetConstantGlyphHeight( gal, -2 );
KIGFX::PREVIEW::TEXT_DIMS headerDims = KIGFX::PREVIEW::GetConstantGlyphHeight( gal, -2 );
KIGFX::PREVIEW::TEXT_DIMS textDims = KIGFX::PREVIEW::GetConstantGlyphHeight( gal, -1 );
KIFONT::FONT* font = KIFONT::FONT::GetFont();
const KIFONT::METRICS& fontMetrics = KIFONT::METRICS::Default();
TEXT_ATTRIBUTES textAttrs;
int glyphWidth = textDims.GlyphSize.x;
VECTOR2I margin( KiROUND( glyphWidth * 0.4 ), KiROUND( glyphWidth * 0.9 ) );
VECTOR2I margin( KiROUND( glyphWidth * 0.4 ), KiROUND( glyphWidth ) );
VECTOR2I size( glyphWidth * 25 + margin.x * 2, headerDims.GlyphSize.y + textDims.GlyphSize.y );
VECTOR2I offset( margin.x * 2, -( size.y + margin.y * 2 ) );
@ -158,13 +158,14 @@ public:
{
gal->SetIsFill( true );
gal->SetIsStroke( true );
gal->SetLineWidth( 1 );
gal->SetLineWidth( gal->GetScreenWorldMatrix().GetScale().x * 2 );
gal->SetStrokeColor( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNTEXT ) );
gal->SetFillColor( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) );
KIGFX::COLOR4D bgColor( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) );
gal->SetFillColor( bgColor.WithAlpha( 0.9 ) );
gal->DrawRectangle( GetPosition() + offset - margin,
GetPosition() + offset + size + margin );
gal->PopDepth();
gal->Restore();
return;
}
@ -221,7 +222,7 @@ public:
gal->SetStrokeColor( m_current > m_max ? red : normal );
font->Draw( gal, m_maxText, textPos, textAttrs, fontMetrics );
gal->PopDepth();
gal->Restore();
}
protected:
@ -2060,7 +2061,9 @@ int DRAWING_TOOL::PlaceTuningPattern( const TOOL_EVENT& aEvent )
m_preview.FreeItems();
for( EDA_ITEM* item : dummyPattern->GetPreviewItems( generatorTool, m_frame ) )
{
m_preview.Add( item );
}
generatorTool->Router()->StopRouting();

View File

@ -57,9 +57,21 @@ using namespace std::placeholders;
const int GAL_LAYER_ORDER[] =
{
LAYER_UI_START + 9,
LAYER_UI_START + 8,
LAYER_UI_START + 7,
LAYER_UI_START + 6,
LAYER_UI_START + 5,
LAYER_UI_START + 4,
LAYER_UI_START + 3,
LAYER_UI_START + 2,
LAYER_UI_START + 1,
LAYER_UI_START,
LAYER_GP_OVERLAY,
LAYER_SELECT_OVERLAY,
LAYER_CONFLICTS_SHADOW,
LAYER_DRC_ERROR, LAYER_DRC_WARNING, LAYER_DRC_EXCLUSION, LAYER_MARKER_SHADOWS,
LAYER_PAD_NETNAMES, LAYER_VIA_NETNAMES,
Dwgs_User, ZONE_LAYER_FOR( Dwgs_User ),
@ -358,6 +370,9 @@ void PCB_DRAW_PANEL_GAL::SetHighContrastLayer( PCB_LAYER_ID aLayer )
for( int i : layers )
rSettings->SetLayerIsHighContrast( i );
for( int i = LAYER_UI_START; i < LAYER_UI_END; ++i )
rSettings->SetLayerIsHighContrast( i );
// Pads should be shown too
if( aLayer == B_Cu )
{
@ -396,6 +411,9 @@ void PCB_DRAW_PANEL_GAL::SetTopLayer( PCB_LAYER_ID aLayer )
for( auto layer : layers )
m_view->SetTopLayer( layer );
for( int i = LAYER_UI_START; i < LAYER_UI_END; i++ )
m_view->SetTopLayer( i );
// Extra layers that are brought to the top if a F.* or B.* is selected
const std::vector<int> frontLayers = {
F_Cu, F_Adhes, F_Paste, F_SilkS, F_Mask, F_Fab, F_CrtYd, LAYER_PADS_SMD_FR,
@ -483,6 +501,9 @@ void PCB_DRAW_PANEL_GAL::SyncLayersVisibility( const BOARD* aBoard )
for( int i = LAYER_BITMAP_START; i < LAYER_BITMAP_END; i++ )
m_view->SetLayerVisible( i, true );
for( int i = LAYER_UI_START; i < LAYER_UI_END; i++ )
m_view->SetLayerVisible( i, true );
// Enable some layers that are GAL specific
m_view->SetLayerVisible( LAYER_PAD_PLATEDHOLES, true );
m_view->SetLayerVisible( LAYER_PAD_HOLEWALLS, true );
@ -583,10 +604,10 @@ void PCB_DRAW_PANEL_GAL::setDefaultLayerOrder()
// MW: Gross hack to make SetTopLayer bring the correct bitmap layer to
// the top of the other bitmaps, but still below all the other layers
if( layer < LAYER_BITMAP_START )
m_view->SetLayerOrder( layer, i );
else
if( layer >= LAYER_BITMAP_START && layer < LAYER_BITMAP_END )
m_view->SetLayerOrder( layer, i - KIGFX::VIEW::TOP_LAYER_MODIFIER );
else
m_view->SetLayerOrder( layer, i );
}
}
@ -705,6 +726,12 @@ void PCB_DRAW_PANEL_GAL::setDefaultLayerDeps()
m_view->SetLayerTarget( LAYER_DRAWINGSHEET, KIGFX::TARGET_NONCACHED );
m_view->SetLayerDisplayOnly( LAYER_DRAWINGSHEET ) ;
m_view->SetLayerDisplayOnly( LAYER_GRID );
for( int i = LAYER_UI_START; i < LAYER_UI_END; ++i )
{
m_view->SetLayerTarget( i, KIGFX::TARGET_OVERLAY );
m_view->SetLayerDisplayOnly( i );
}
}

View File

@ -1694,7 +1694,7 @@ void PNS_KICAD_IFACE::DisplayItem( const PNS::ITEM* aItem, int aClearance, bool
void PNS_KICAD_IFACE::DisplayPathLine( const SHAPE_LINE_CHAIN& aLine, int aImportance )
{
ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( aLine, m_view );
pitem->SetDepth( ROUTER_PREVIEW_ITEM::PathOverlayDepth );
pitem->SetDepth( pitem->GetOriginDepth() - ROUTER_PREVIEW_ITEM::PathOverlayDepth );
COLOR4D color;

View File

@ -69,7 +69,7 @@ ROUTER_PREVIEW_ITEM::ROUTER_PREVIEW_ITEM( const PNS::ITEM* aItem, KIGFX::VIEW* a
// initialize variables, overwritten by Update( aItem ), if aItem != NULL
m_type = PR_SHAPE;
m_width = ( aFlags & PNS_SEMI_SOLID ) ? 1 : 0;
m_depth = 0;
m_depth = m_originDepth = aView->GetLayerOrder( m_originLayer );
if( aItem )
Update( aItem );
@ -86,14 +86,14 @@ ROUTER_PREVIEW_ITEM::ROUTER_PREVIEW_ITEM( const SHAPE& aShape, KIGFX::VIEW* aVie
m_hole = nullptr;
m_clearance = -1;
m_originLayer = m_layer = LAYER_SELECT_OVERLAY ;
m_originLayer = m_layer = LAYER_SELECT_OVERLAY;
m_showClearance = false;
// initialize variables, overwritten by Update( aItem ), if aItem != NULL
m_type = PR_SHAPE;
m_width = 0;
m_depth = 0;
m_depth = m_originDepth = aView->GetLayerOrder( m_originLayer );
}
@ -124,7 +124,7 @@ void ROUTER_PREVIEW_ITEM::Update( const PNS::ITEM* aItem )
m_layer = m_originLayer;
m_color = getLayerColor( m_originLayer );
m_color.a = 0.8;
m_depth = BaseOverlayDepth - aItem->Layers().Start();
m_depth = m_originDepth - ( aItem->Layers().Start() * LayerDepthFactor );
switch( aItem->Kind() )
{
@ -148,7 +148,7 @@ void ROUTER_PREVIEW_ITEM::Update( const PNS::ITEM* aItem )
m_type = PR_SHAPE;
m_width = 0;
m_color = COLOR4D( 0.7, 0.7, 0.7, 0.8 );
m_depth = ViaOverlayDepth;
m_depth = m_originDepth - ( PCB_LAYER_ID_COUNT * LayerDepthFactor );
delete m_shape;
m_shape = nullptr;
@ -477,7 +477,7 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
// N.B. The order of draw here is important
// Cairo doesn't current support z-ordering, so we need
// to draw the clearance first to ensure it is in the background
gal->SetLayerDepth( ClearanceOverlayDepth );
gal->SetLayerDepth( m_originDepth );
//TODO(snh) Add configuration option for the color/alpha here
gal->SetStrokeColor( COLOR4D( DARKDARKGRAY ).WithAlpha( 0.9 ) );
@ -520,7 +520,7 @@ const COLOR4D ROUTER_PREVIEW_ITEM::getLayerColor( int aLayer ) const
}
const int ROUTER_PREVIEW_ITEM::ClearanceOverlayDepth = -VIEW::VIEW_MAX_LAYERS - 10;
const int ROUTER_PREVIEW_ITEM::BaseOverlayDepth = -VIEW::VIEW_MAX_LAYERS - 20;
const int ROUTER_PREVIEW_ITEM::ViaOverlayDepth = -VIEW::VIEW_MAX_LAYERS - 50;
const int ROUTER_PREVIEW_ITEM::PathOverlayDepth = -VIEW::VIEW_MAX_LAYERS - 55;
//const int ROUTER_PREVIEW_ITEM::ClearanceOverlayDepth = -VIEW::VIEW_MAX_LAYERS - 10;
//const int ROUTER_PREVIEW_ITEM::BaseOverlayDepth = -VIEW::VIEW_MAX_LAYERS - 20;
//const int ROUTER_PREVIEW_ITEM::ViaOverlayDepth = -VIEW::VIEW_MAX_LAYERS - 50;
//const int ROUTER_PREVIEW_ITEM::PathOverlayDepth = -VIEW::VIEW_MAX_LAYERS - 55;

View File

@ -61,13 +61,21 @@ public:
PR_SHAPE
};
// fixme: shouldn't this go to VIEW?
static const int ClearanceOverlayDepth;
static const int BaseOverlayDepth;
static const int ViaOverlayDepth;
static const int PathOverlayDepth;
/**
* We draw this item on a single layer, but we stack up all the layers from
* the various components that form this preview item. In order to make this
* work, we need to map that layer stack onto fractional depths that are less
* than 1.0 so that this preview item doesn't draw on top of other overlays
* that are in front of it.
*
* This factor is chosen to be fairly small so that we can fit an entire
* GAL layer stack into the space of one view group sublayer (which is
* currently hard-coded via GAL::AdvanceDepth take a depth of 0.1)
*/
static constexpr double LayerDepthFactor = 0.0001;
static constexpr double PathOverlayDepth = LayerDepthFactor * LAYER_ZONE_END;
ROUTER_PREVIEW_ITEM( const SHAPE& aShape, KIGFX::VIEW* aView = nullptr);
ROUTER_PREVIEW_ITEM( const SHAPE& aShape, KIGFX::VIEW* aView = nullptr );
ROUTER_PREVIEW_ITEM( const PNS::ITEM* aItem = nullptr, KIGFX::VIEW* aView = nullptr,
int aFlags = 0 );
~ROUTER_PREVIEW_ITEM();
@ -81,6 +89,8 @@ public:
void SetClearance( int aClearance ) { m_clearance = aClearance; }
void ShowClearance( bool aEnabled ) { m_showClearance = aEnabled; }
double GetOriginDepth() const { return m_originDepth; }
#if defined(DEBUG)
void Show( int aA, std::ostream& aB ) const override {}
#endif
@ -125,6 +135,7 @@ private:
int m_clearance;
bool m_showClearance;
double m_originDepth;
double m_depth;
KIGFX::COLOR4D m_color;