diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 5c15f9c554..30a480262b 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -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 diff --git a/common/preview_items/arc_assistant.cpp b/common/preview_items/arc_assistant.cpp index 441699bffa..80257a467f 100644 --- a/common/preview_items/arc_assistant.cpp +++ b/common/preview_items/arc_assistant.cpp @@ -23,7 +23,9 @@ #include +#include #include + #include #include #include @@ -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( 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( 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( 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( 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 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 ) ); diff --git a/common/preview_items/draw_context.cpp b/common/preview_items/draw_context.cpp new file mode 100644 index 0000000000..a1ecabec04 --- /dev/null +++ b/common/preview_items/draw_context.cpp @@ -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 + +#include + +#include + +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 ); +} \ No newline at end of file diff --git a/include/preview_items/draw_context.h b/include/preview_items/draw_context.h new file mode 100644 index 0000000000..9b2ef11491 --- /dev/null +++ b/include/preview_items/draw_context.h @@ -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 + +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_