Pcbnew: break out preview draw helpers

The graphical drawing routines in the arc assistant can be
made more generic for re-use in similar code.
This commit is contained in:
John Beard 2019-05-13 14:17:24 +01:00
parent 041c52c369
commit 6cf7ad68ad
4 changed files with 245 additions and 75 deletions

View File

@ -251,6 +251,7 @@ set( COMMON_PREVIEW_ITEMS_SRCS
preview_items/arc_geom_manager.cpp
preview_items/bright_box.cpp
preview_items/centreline_rect_item.cpp
preview_items/draw_context.cpp
preview_items/polygon_geom_manager.cpp
preview_items/polygon_item.cpp
preview_items/preview_utils.cpp

View File

@ -23,7 +23,9 @@
#include <preview_items/arc_assistant.h>
#include <preview_items/draw_context.h>
#include <preview_items/preview_utils.h>
#include <gal/graphics_abstraction_layer.h>
#include <view/view.h>
#include <pcb_painter.h>
@ -82,80 +84,14 @@ double getNormDeciDegFromRad( double aRadians )
}
static const double ANGLE_EPSILON = 1e-9;
bool angleIsSpecial( double aRadians )
{
return std::fabs( std::remainder( aRadians, M_PI_4 ) ) < ANGLE_EPSILON;
}
static void drawLineWithHilight( KIGFX::VIEW *aView,
const VECTOR2I& aStart, const VECTOR2I& aEnd, bool aDim )
{
auto gal = aView->GetGAL();
auto rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( aView->GetPainter()->GetSettings() );
const auto vec = aEnd - aStart;
COLOR4D strokeColor = rs->GetLayerColor( LAYER_AUX_ITEMS );
if( angleIsSpecial( vec.Angle() ) )
strokeColor = rs->IsBackgroundDark() ? COLOR4D( 0.5, 1.0, 0.5, 1.0 ) : COLOR4D( 0.0, 0.7, 0.0, 1.0 ) ;
gal->SetStrokeColor( strokeColor.WithAlpha( PreviewOverlayDeemphAlpha( aDim ) ) );
gal->DrawLine( aStart, aEnd );
}
static void drawArcWithHilight( KIGFX::VIEW *aView,
const VECTOR2I& aOrigin, double aRad, double aStartAngle,
double aEndAngle )
{
auto gal = aView->GetGAL();
auto rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( aView->GetPainter()->GetSettings() );
auto color = rs->GetLayerColor( LAYER_AUX_ITEMS );
if( angleIsSpecial( aStartAngle - aEndAngle ) )
color = rs->IsBackgroundDark() ? COLOR4D( 0.5, 1.0, 0.5, 1.0 ) : COLOR4D( 0.0, 0.7, 0.0, 1.0 ) ;
gal->SetIsStroke( true );
gal->SetIsFill( true );
gal->SetStrokeColor( color );
gal->SetFillColor( color.WithAlpha( 0.2 ) );
// draw the angle reference arc
gal->DrawArc( aOrigin, aRad, -aStartAngle, -aEndAngle );
}
static void drawCircleGuide( KIGFX::VIEW* aView, const VECTOR2I& aOrigin, double aRad )
{
auto gal = aView->GetGAL();
auto rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( aView->GetPainter()->GetSettings() );
auto color = rs->GetLayerColor( LAYER_AUX_ITEMS );
gal->SetStrokeColor( color.WithAlpha( PreviewOverlayDeemphAlpha( true ) ) );
gal->SetIsStroke( true );
gal->SetIsFill( false );
gal->DrawCircle( aOrigin, aRad );
}
void ARC_ASSISTANT::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
{
auto& gal = *aView->GetGAL();
auto rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( aView->GetPainter()->GetSettings() );
// not in a position to draw anything
if( m_constructMan.IsReset() )
return;
gal.SetLineWidth( 1.0 );
gal.SetIsStroke( true );
gal.SetIsFill( true );
gal.ResetTextAttributes();
// constant text size on screen
@ -166,10 +102,13 @@ void ARC_ASSISTANT::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
const auto origin = m_constructMan.GetOrigin();
KIGFX::PREVIEW::DRAW_CONTEXT preview_ctx( *aView );
// draw first radius line
bool dimFirstLine = m_constructMan.GetStep() > ARC_GEOM_MANAGER::SET_START;
drawLineWithHilight( aView, origin, m_constructMan.GetStartRadiusEnd(), dimFirstLine );
preview_ctx.DrawLineWithAngleHighlight(
origin, m_constructMan.GetStartRadiusEnd(), dimFirstLine );
std::vector<wxString> cursorStrings;
@ -177,18 +116,18 @@ void ARC_ASSISTANT::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
{
// haven't started the angle selection phase yet
auto initAngle = m_constructMan.GetStartAngle();
double initAngle = m_constructMan.GetStartAngle();
const auto angleRefLineEnd = m_constructMan.GetOrigin() + VECTOR2D( innerRad * 1.5, 0.0 );
gal.SetStrokeColor( rs->GetLayerColor( LAYER_AUX_ITEMS ) );
gal.DrawLine( origin, angleRefLineEnd );
// draw the short reference baseline
preview_ctx.DrawLine( origin, angleRefLineEnd, false );
// draw the angle reference arc
drawArcWithHilight( aView, origin, innerRad, initAngle, 0.0 );
preview_ctx.DrawArcWithAngleHighlight( origin, innerRad, initAngle, 0.0 );
// draw the radius guide circle
drawCircleGuide( aView, origin, m_constructMan.GetRadius() );
preview_ctx.DrawCircle( origin, m_constructMan.GetRadius(), true );
double degs = getNormDeciDegFromRad( initAngle );
@ -197,18 +136,18 @@ void ARC_ASSISTANT::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
}
else
{
drawLineWithHilight( aView, origin, m_constructMan.GetEndRadiusEnd(), false );
preview_ctx.DrawLineWithAngleHighlight( origin, m_constructMan.GetEndRadiusEnd(), false );
auto start = m_constructMan.GetStartAngle();
auto subtended = m_constructMan.GetSubtended();
drawArcWithHilight( aView, origin, innerRad, start, start + subtended );
preview_ctx.DrawArcWithAngleHighlight( origin, innerRad, start, start + subtended );
double subtendedDeg = getNormDeciDegFromRad( subtended );
double endAngleDeg = getNormDeciDegFromRad( start + subtended );
// draw dimmed extender line to cursor
drawLineWithHilight( aView, origin, m_constructMan.GetLastPoint(), true );
preview_ctx.DrawLineWithAngleHighlight( origin, m_constructMan.GetLastPoint(), true );
cursorStrings.push_back( DimensionLabel( wxString::FromUTF8( "Δθ" ), subtendedDeg, DEGREES ) );
cursorStrings.push_back( DimensionLabel( wxString::FromUTF8( "θ" ), endAngleDeg, DEGREES ) );

View File

@ -0,0 +1,118 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <preview_items/draw_context.h>
#include <preview_items/preview_utils.h>
#include <view/view.h>
using namespace KIGFX::PREVIEW;
static constexpr double ANGLE_EPSILON = 1e-9;
static bool angleIsSpecial( double aRadians )
{
return std::fabs( std::remainder( aRadians, M_PI_4 ) ) < ANGLE_EPSILON;
}
static COLOR4D deemphasise( const COLOR4D& aColor, bool aDeEmphasised )
{
return aColor.WithAlpha( PreviewOverlayDeemphAlpha( aDeEmphasised ) );
}
DRAW_CONTEXT::DRAW_CONTEXT( KIGFX::VIEW& aView )
: m_gal( *aView.GetGAL() ),
m_render_settings( *aView.GetPainter()->GetSettings() ),
m_currLayer( LAYER_AUX_ITEMS ),
m_lineWidth( 1.0f )
{
}
void DRAW_CONTEXT::DrawCircle( const VECTOR2I& aOrigin, double aRad, bool aDeEmphasised )
{
const COLOR4D& color = m_render_settings.GetLayerColor( m_currLayer );
m_gal.SetLineWidth( m_lineWidth );
m_gal.SetStrokeColor( deemphasise( color, aDeEmphasised ) );
m_gal.SetIsStroke( true );
m_gal.SetIsFill( false );
m_gal.DrawCircle( aOrigin, aRad );
}
void DRAW_CONTEXT::DrawArcWithAngleHighlight(
const VECTOR2I& aOrigin, double aRad, double aStartAngle, double aEndAngle )
{
COLOR4D color = m_render_settings.GetLayerColor( m_currLayer );
if( angleIsSpecial( aStartAngle - aEndAngle ) )
color = getSpecialAngleColour();
m_gal.SetLineWidth( m_lineWidth );
m_gal.SetIsStroke( true );
m_gal.SetIsFill( true );
m_gal.SetStrokeColor( color );
m_gal.SetFillColor( color.WithAlpha( 0.2 ) );
// draw the angle reference arc
m_gal.DrawArc( aOrigin, aRad, -aStartAngle, -aEndAngle );
}
void DRAW_CONTEXT::DrawLine( const VECTOR2I& aStart, const VECTOR2I& aEnd, bool aDeEmphasised )
{
COLOR4D strokeColor = m_render_settings.GetLayerColor( m_currLayer );
m_gal.SetLineWidth( m_lineWidth );
m_gal.SetIsStroke( true );
m_gal.SetStrokeColor( deemphasise( strokeColor, aDeEmphasised ) );
m_gal.DrawLine( aStart, aEnd );
}
void DRAW_CONTEXT::DrawLineWithAngleHighlight(
const VECTOR2I& aStart, const VECTOR2I& aEnd, bool aDeEmphasised )
{
const VECTOR2I vec = aEnd - aStart;
COLOR4D strokeColor = m_render_settings.GetLayerColor( m_currLayer );
if( angleIsSpecial( vec.Angle() ) )
strokeColor = getSpecialAngleColour();
m_gal.SetLineWidth( m_lineWidth );
m_gal.SetIsStroke( true );
m_gal.SetStrokeColor( deemphasise( strokeColor, aDeEmphasised ) );
m_gal.DrawLine( aStart, aEnd );
}
COLOR4D DRAW_CONTEXT::getSpecialAngleColour() const
{
return m_render_settings.IsBackgroundDark() ? COLOR4D( 0.5, 1.0, 0.5, 1.0 ) :
COLOR4D( 0.0, 0.7, 0.0, 1.0 );
}

View File

@ -0,0 +1,112 @@
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2017 Kicad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef PREVIEW_PREVIEW_DRAW_CONTEXT__H_
#define PREVIEW_PREVIEW_DRAW_CONTEXT__H_
#include <painter.h>
namespace KIGFX
{
class GAL;
class VIEW;
namespace PREVIEW
{
/**
* A KIGFX::PREVIEW::DRAW_CONTEXT is a wrapper around a GAL and some other
* settings that makes it easy to draw preview items consistently.
*
* This class provides some graphical items that are often used by preview
* items. Complex items can be composed from these.
*/
class DRAW_CONTEXT
{
public:
DRAW_CONTEXT( KIGFX::VIEW& aView );
/**
* Draw a preview circle on the current layer
*
* @param aOrigin circle origin
* @param aRad circle radius
* @param aDeEmphasised draw the circle de-emphasised
*/
void DrawCircle( const VECTOR2I& aOrigin, double aRad, bool aDeEmphasised );
/**
* Draw a simple line on the current layer.
*
* @param aStart line start point
* @param aEnd line end point
* @param aDeEmphasised draw the line de-emphasised
*/
void DrawLine( const VECTOR2I& aStart, const VECTOR2I& aEnd, bool aDeEmphasised );
/**
* Draw a straight line on the current layer, with a special highlight when
* the line angle is a multiple of 45 degrees.
*
* @param aStart line start point
* @param aEnd line end point
* @param aDeEmphasised draw the line de-emphasised
*/
void DrawLineWithAngleHighlight(
const VECTOR2I& aStart, const VECTOR2I& aEnd, bool aDeEmphasised );
/**
* Draw an arc on the current layer, with a special highlight when
* the line angle is a multiple of 45 degrees.
*
* @param aOrigin the arc centre
* @param aRad the arc radius
* @param aStartAngle the arc start angle
* @param aEndAngle the arc end angle
*/
void DrawArcWithAngleHighlight(
const VECTOR2I& aOrigin, double aRad, double aStartAngle, double aEndAngle );
private:
/**
* @return the colour to use for "special" angles
*/
COLOR4D getSpecialAngleColour() const;
///< The GAL to draw into
KIGFX::GAL& m_gal;
const KIGFX::RENDER_SETTINGS& m_render_settings;
///< The current layer to draw onto
GAL_LAYER_ID m_currLayer;
/// The line width to use for items
float m_lineWidth;
};
} // namespace PREVIEW
} // namespace KIGFX
#endif // PREVIEW_PREVIEW_DRAW_CONTEXT__H_