Add a m_forceMarkObstaclesMode warning when violating DRC.
Also adds a modifier combination to commit anyway.
This commit is contained in:
parent
d4f6425523
commit
a523c58530
|
@ -1309,7 +1309,10 @@ void PCB_TUNING_PATTERN::EditPush( GENERATOR_TOOL* aTool, BOARD* aBoard, BOARD_C
|
||||||
|
|
||||||
if( router->RoutingInProgress() )
|
if( router->RoutingInProgress() )
|
||||||
{
|
{
|
||||||
router->FixRoute( m_end, nullptr, true );
|
bool forceFinish = true;
|
||||||
|
bool forceCommit = false;
|
||||||
|
|
||||||
|
router->FixRoute( m_end, nullptr, forceFinish, forceCommit );
|
||||||
router->StopRouting();
|
router->StopRouting();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ set( PCBNEW_PNS_SRCS
|
||||||
pns_via.cpp
|
pns_via.cpp
|
||||||
pns_walkaround.cpp
|
pns_walkaround.cpp
|
||||||
router_preview_item.cpp
|
router_preview_item.cpp
|
||||||
|
router_status_view_item.cpp
|
||||||
router_tool.cpp
|
router_tool.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* KiRouter - a push-and-(sometimes-)shove PCB router
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013-2020 CERN
|
* Copyright (C) 2013-2020 CERN
|
||||||
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2021-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
@ -244,13 +244,13 @@ bool COMPONENT_DRAGGER::Drag( const VECTOR2I& aP )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool COMPONENT_DRAGGER::FixRoute()
|
bool COMPONENT_DRAGGER::FixRoute( bool aForceCommit )
|
||||||
{
|
{
|
||||||
NODE* node = CurrentNode();
|
NODE* node = CurrentNode();
|
||||||
|
|
||||||
if( node )
|
if( node )
|
||||||
{
|
{
|
||||||
if( Settings().AllowDRCViolations() || !node->CheckColliding( m_draggedItems ) )
|
if( Settings().AllowDRCViolations() || aForceCommit || !node->CheckColliding( m_draggedItems ) )
|
||||||
{
|
{
|
||||||
Router()->CommitRouting( node );
|
Router()->CommitRouting( node );
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* KiRouter - a push-and-(sometimes-)shove PCB router
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013-2020 CERN
|
* Copyright (C) 2013-2020 CERN
|
||||||
* Copyright (C) 2013-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2013-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
@ -66,7 +66,7 @@ public:
|
||||||
* and eventually commits it to the world.
|
* and eventually commits it to the world.
|
||||||
* @return true, if dragging finished with success.
|
* @return true, if dragging finished with success.
|
||||||
*/
|
*/
|
||||||
bool FixRoute() override;
|
bool FixRoute( bool aForceCommit ) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function CurrentNode()
|
* Function CurrentNode()
|
||||||
|
@ -110,6 +110,12 @@ public:
|
||||||
return PNS::DM_COMPONENT;
|
return PNS::DM_COMPONENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GetForceMarkObstaclesMode( bool* aDragStatus ) const override
|
||||||
|
{
|
||||||
|
*aDragStatus = m_dragStatus;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct DRAGGED_CONNECTION
|
struct DRAGGED_CONNECTION
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* KiRouter - a push-and-(sometimes-)shove PCB router
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013-2020 CERN
|
* Copyright (C) 2013-2020 CERN
|
||||||
* Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2016-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
@ -86,7 +86,7 @@ public:
|
||||||
* and eventually commits it to the world.
|
* and eventually commits it to the world.
|
||||||
* @return true, if dragging finished with success.
|
* @return true, if dragging finished with success.
|
||||||
*/
|
*/
|
||||||
virtual bool FixRoute() = 0;
|
virtual bool FixRoute( bool aForceCommit ) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function CurrentNode()
|
* Function CurrentNode()
|
||||||
|
@ -120,6 +120,8 @@ public:
|
||||||
|
|
||||||
virtual PNS::DRAG_MODE Mode() const = 0;
|
virtual PNS::DRAG_MODE Mode() const = 0;
|
||||||
|
|
||||||
|
virtual bool GetForceMarkObstaclesMode( bool* aDragStatus ) const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
NODE* m_world;
|
NODE* m_world;
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* KiRouter - a push-and-(sometimes-)shove PCB router
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013-2014 CERN
|
* Copyright (C) 2013-2014 CERN
|
||||||
* Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2016-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
@ -116,7 +116,7 @@ bool DRAGGER::startDragSegment( const VECTOR2D& aP, SEGMENT* aSeg )
|
||||||
if ( m_world->CheckColliding( &m_draggedLine ) )
|
if ( m_world->CheckColliding( &m_draggedLine ) )
|
||||||
{
|
{
|
||||||
// If we're already in a state that violates DRC then there's not much we can do but
|
// If we're already in a state that violates DRC then there's not much we can do but
|
||||||
// switch to mark obstacles mode (and ignore other DRC violation).
|
// switch to mark obstacles mode.
|
||||||
m_forceMarkObstaclesMode = true;
|
m_forceMarkObstaclesMode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ bool DRAGGER::startDragArc( const VECTOR2D& aP, ARC* aArc )
|
||||||
if ( m_world->CheckColliding( &m_draggedLine ) )
|
if ( m_world->CheckColliding( &m_draggedLine ) )
|
||||||
{
|
{
|
||||||
// If we're already in a state that violates DRC then there's not much we can do but
|
// If we're already in a state that violates DRC then there's not much we can do but
|
||||||
// switch to mark obstacles mode (and ignore other DRC violation).
|
// switch to mark obstacles mode.
|
||||||
m_forceMarkObstaclesMode = true;
|
m_forceMarkObstaclesMode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ bool DRAGGER::startDragVia( VIA* aVia )
|
||||||
if ( m_world->CheckColliding( aVia ) )
|
if ( m_world->CheckColliding( aVia ) )
|
||||||
{
|
{
|
||||||
// If we're already in a state that violates DRC then there's not much we can do but
|
// If we're already in a state that violates DRC then there's not much we can do but
|
||||||
// switch to mark obstacles mode (and ignore other DRC violation).
|
// switch to mark obstacles mode.
|
||||||
m_forceMarkObstaclesMode = true;
|
m_forceMarkObstaclesMode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,7 +335,7 @@ bool DRAGGER::dragMarkObstacles( const VECTOR2I& aP )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_forceMarkObstaclesMode || Settings().AllowDRCViolations() )
|
if( Settings().AllowDRCViolations() )
|
||||||
m_dragStatus = true;
|
m_dragStatus = true;
|
||||||
else
|
else
|
||||||
m_dragStatus = !m_lastNode->CheckColliding( m_draggedItems );
|
m_dragStatus = !m_lastNode->CheckColliding( m_draggedItems );
|
||||||
|
@ -704,29 +704,41 @@ bool DRAGGER::dragShove( const VECTOR2I& aP )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool DRAGGER::FixRoute()
|
bool DRAGGER::FixRoute( bool aForceCommit )
|
||||||
{
|
{
|
||||||
NODE* node = CurrentNode();
|
NODE* node = CurrentNode();
|
||||||
|
|
||||||
if( node )
|
if( node )
|
||||||
{
|
{
|
||||||
// If collisions exist, we can fix in shove/smart mode because all tracks to be committed
|
if( m_dragStatus )
|
||||||
// will be in valid positions (even if the current routing solution to the mouse cursor is
|
|
||||||
// invalid). In other modes, we can only commit if "Allow DRC violations" is enabled.
|
|
||||||
if( !m_dragStatus )
|
|
||||||
{
|
{
|
||||||
|
Router()->CommitRouting( node );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if( m_forceMarkObstaclesMode )
|
||||||
|
{
|
||||||
|
if( aForceCommit )
|
||||||
|
{
|
||||||
|
Router()->CommitRouting( node );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If collisions exist, we can fix in shove/smart mode because all tracks to be
|
||||||
|
// committed will be in valid positions (even if the current routing solution to
|
||||||
|
// the mouse cursor is invalid).
|
||||||
Drag( m_lastValidPoint );
|
Drag( m_lastValidPoint );
|
||||||
node = CurrentNode();
|
node = CurrentNode();
|
||||||
|
|
||||||
if( !node )
|
if( node && m_dragStatus )
|
||||||
return false;
|
{
|
||||||
|
Router()->CommitRouting( node );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !m_dragStatus && !Settings().AllowDRCViolations() && !m_forceMarkObstaclesMode )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Router()->CommitRouting( node );
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* KiRouter - a push-and-(sometimes-)shove PCB router
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013-2014 CERN
|
* Copyright (C) 2013-2014 CERN
|
||||||
* Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2016-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
@ -73,7 +73,7 @@ public:
|
||||||
* and eventually commits it to the world.
|
* and eventually commits it to the world.
|
||||||
* @return true, if dragging finished with success.
|
* @return true, if dragging finished with success.
|
||||||
*/
|
*/
|
||||||
bool FixRoute() override;
|
bool FixRoute( bool aForceCommit ) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function CurrentNode()
|
* Function CurrentNode()
|
||||||
|
@ -101,7 +101,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
const LINE& GetOriginalLine()
|
const LINE& GetOriginalLine()
|
||||||
{
|
{
|
||||||
return m_draggedLine;
|
return m_draggedLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,6 +121,12 @@ public:
|
||||||
|
|
||||||
PNS::DRAG_MODE Mode() const override;
|
PNS::DRAG_MODE Mode() const override;
|
||||||
|
|
||||||
|
bool GetForceMarkObstaclesMode( bool* aDragStatus ) const override
|
||||||
|
{
|
||||||
|
*aDragStatus = m_dragStatus;
|
||||||
|
return m_forceMarkObstaclesMode;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const ITEM_SET findViaFanoutByHandle ( NODE *aNode, const VIA_HANDLE& handle );
|
const ITEM_SET findViaFanoutByHandle ( NODE *aNode, const VIA_HANDLE& handle );
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* KiRouter - a push-and-(sometimes-)shove PCB router
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013-2014 CERN
|
* Copyright (C) 2013-2014 CERN
|
||||||
* Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2016-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
@ -557,7 +557,12 @@ bool ROUTER::Finish()
|
||||||
|
|
||||||
// If we've made it, fix the route and we're done
|
// If we've made it, fix the route and we're done
|
||||||
if( moveResultPoint == otherEnd && otherEndLayers.Overlaps( GetCurrentLayer() ) )
|
if( moveResultPoint == otherEnd && otherEndLayers.Overlaps( GetCurrentLayer() ) )
|
||||||
return FixRoute( otherEnd, otherEndItem, false );
|
{
|
||||||
|
bool forceFinish = false;
|
||||||
|
bool allowViolations = false;
|
||||||
|
|
||||||
|
return FixRoute( otherEnd, otherEndItem, forceFinish, allowViolations );
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -848,7 +853,7 @@ void ROUTER::CommitRouting( NODE* aNode )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ROUTER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinish )
|
bool ROUTER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinish, bool aForceCommit )
|
||||||
{
|
{
|
||||||
bool rv = false;
|
bool rv = false;
|
||||||
|
|
||||||
|
@ -863,7 +868,7 @@ bool ROUTER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinish )
|
||||||
|
|
||||||
case DRAG_SEGMENT:
|
case DRAG_SEGMENT:
|
||||||
case DRAG_COMPONENT:
|
case DRAG_COMPONENT:
|
||||||
rv = m_dragger->FixRoute();
|
rv = m_dragger->FixRoute( aForceCommit );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* KiRouter - a push-and-(sometimes-)shove PCB router
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013-2014 CERN
|
* Copyright (C) 2013-2014 CERN
|
||||||
* Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2016-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
@ -149,7 +149,7 @@ public:
|
||||||
bool Move( const VECTOR2I& aP, ITEM* aItem );
|
bool Move( const VECTOR2I& aP, ITEM* aItem );
|
||||||
bool Finish();
|
bool Finish();
|
||||||
bool ContinueFromEnd( ITEM** aNewStartItem );
|
bool ContinueFromEnd( ITEM** aNewStartItem );
|
||||||
bool FixRoute( const VECTOR2I& aP, ITEM* aItem, bool aForceFinish = false );
|
bool FixRoute( const VECTOR2I& aP, ITEM* aItem, bool aForceFinish, bool aForceCommit );
|
||||||
void BreakSegment( ITEM *aItem, const VECTOR2I& aP );
|
void BreakSegment( ITEM *aItem, const VECTOR2I& aP );
|
||||||
|
|
||||||
std::optional<VECTOR2I> UndoLastSegment();
|
std::optional<VECTOR2I> UndoLastSegment();
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 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 <gal/color4d.h>
|
||||||
|
#include <gal/graphics_abstraction_layer.h>
|
||||||
|
#include <kiplatform/ui.h>
|
||||||
|
#include <layer_ids.h>
|
||||||
|
#include <wx/settings.h>
|
||||||
|
|
||||||
|
#include "preview_items/preview_utils.h"
|
||||||
|
#include "router_status_view_item.h"
|
||||||
|
#include "gr_text.h"
|
||||||
|
|
||||||
|
using namespace KIGFX;
|
||||||
|
|
||||||
|
|
||||||
|
const BOX2I ROUTER_STATUS_VIEW_ITEM::ViewBBox() const
|
||||||
|
{
|
||||||
|
BOX2I tmp;
|
||||||
|
|
||||||
|
// this is an edit-time artefact; no reason to try and be smart with the bounding box
|
||||||
|
// (besides, we can't tell the text extents without a view to know what the scale is)
|
||||||
|
tmp.SetMaximum();
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ROUTER_STATUS_VIEW_ITEM::ViewGetLayers( int aLayers[], int& aCount ) const
|
||||||
|
{
|
||||||
|
aLayers[0] = LAYER_UI_START;
|
||||||
|
aLayers[1] = LAYER_UI_START + 1;
|
||||||
|
aCount = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ROUTER_STATUS_VIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
|
||||||
|
{
|
||||||
|
KIGFX::GAL* gal = aView->GetGAL();
|
||||||
|
bool viewFlipped = gal->IsFlippedX();
|
||||||
|
bool drawingDropShadows = ( aLayer == LAYER_UI_START );
|
||||||
|
|
||||||
|
gal->Save();
|
||||||
|
gal->Scale( { 1., 1. } );
|
||||||
|
|
||||||
|
KIGFX::PREVIEW::TEXT_DIMS textDims = KIGFX::PREVIEW::GetConstantGlyphHeight( gal, -1 );
|
||||||
|
KIGFX::PREVIEW::TEXT_DIMS hintDims = KIGFX::PREVIEW::GetConstantGlyphHeight( gal, -2 );
|
||||||
|
KIFONT::FONT* font = KIFONT::FONT::GetFont();
|
||||||
|
const KIFONT::METRICS& fontMetrics = KIFONT::METRICS::Default();
|
||||||
|
TEXT_ATTRIBUTES textAttrs;
|
||||||
|
int textWidth;
|
||||||
|
|
||||||
|
textWidth = std::max( GRTextWidth( m_status, font, textDims.GlyphSize, textDims.StrokeWidth,
|
||||||
|
false, false, fontMetrics ),
|
||||||
|
GRTextWidth( m_hint, font, hintDims.GlyphSize, hintDims.StrokeWidth,
|
||||||
|
false, false, fontMetrics ) );
|
||||||
|
|
||||||
|
VECTOR2I margin( KiROUND( textDims.GlyphSize.x * 0.4 ), KiROUND( textDims.GlyphSize.y * 0.6 ) );
|
||||||
|
VECTOR2I size( textWidth + margin.x, KiROUND( textDims.GlyphSize.y * 1.7 ) );
|
||||||
|
VECTOR2I offset( margin.x * 5, -( size.y + margin.y * 5 ) );
|
||||||
|
|
||||||
|
if( !m_hint.IsEmpty() )
|
||||||
|
size.y += KiROUND( hintDims.GlyphSize.y * 1.2 );
|
||||||
|
|
||||||
|
if( drawingDropShadows )
|
||||||
|
{
|
||||||
|
gal->SetIsFill( true );
|
||||||
|
gal->SetIsStroke( true );
|
||||||
|
gal->SetLineWidth( gal->GetScreenWorldMatrix().GetScale().x * 2 );
|
||||||
|
gal->SetStrokeColor( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNTEXT ) );
|
||||||
|
KIGFX::COLOR4D bgColor( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) );
|
||||||
|
gal->SetFillColor( bgColor.WithAlpha( 0.9 ) );
|
||||||
|
|
||||||
|
gal->DrawRectangle( GetPosition() + offset - margin,
|
||||||
|
GetPosition() + offset + size + margin );
|
||||||
|
gal->Restore();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
COLOR4D bg = wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE );
|
||||||
|
COLOR4D normal = wxSystemSettings::GetColour( wxSYS_COLOUR_BTNTEXT );
|
||||||
|
COLOR4D red;
|
||||||
|
|
||||||
|
if( viewFlipped )
|
||||||
|
textAttrs.m_Halign = GR_TEXT_H_ALIGN_RIGHT;
|
||||||
|
else
|
||||||
|
textAttrs.m_Halign = GR_TEXT_H_ALIGN_LEFT;
|
||||||
|
|
||||||
|
gal->SetIsFill( false );
|
||||||
|
gal->SetIsStroke( true );
|
||||||
|
gal->SetStrokeColor( normal );
|
||||||
|
textAttrs.m_Halign = GR_TEXT_H_ALIGN_LEFT;
|
||||||
|
|
||||||
|
// Prevent text flipping when view is flipped
|
||||||
|
if( gal->IsFlippedX() )
|
||||||
|
{
|
||||||
|
textAttrs.m_Mirrored = true;
|
||||||
|
textAttrs.m_Halign = GR_TEXT_H_ALIGN_RIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
textAttrs.m_Size = textDims.GlyphSize;
|
||||||
|
textAttrs.m_StrokeWidth = textDims.StrokeWidth;
|
||||||
|
|
||||||
|
VECTOR2I textPos = GetPosition() + offset + margin;
|
||||||
|
font->Draw( gal, m_status, textPos, textAttrs, KIFONT::METRICS::Default() );
|
||||||
|
|
||||||
|
if( !m_hint.IsEmpty() )
|
||||||
|
{
|
||||||
|
textAttrs.m_Size = hintDims.GlyphSize;
|
||||||
|
textAttrs.m_StrokeWidth = hintDims.StrokeWidth;
|
||||||
|
|
||||||
|
textPos.y += KiROUND( textDims.GlyphSize.y * 1.6 );
|
||||||
|
font->Draw( gal, m_hint, textPos, textAttrs, KIFONT::METRICS::Default() );
|
||||||
|
}
|
||||||
|
|
||||||
|
gal->Restore();
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ROUTER_STATUS_VIEW_ITEM_H
|
||||||
|
#define ROUTER_STATUS_VIEW_ITEM_H
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
#include <view/view.h>
|
||||||
|
#include <view/view_item.h>
|
||||||
|
#include <view/view_group.h>
|
||||||
|
|
||||||
|
#include <math/vector2d.h>
|
||||||
|
#include <math/box2.h>
|
||||||
|
|
||||||
|
#include <geometry/shape_line_chain.h>
|
||||||
|
#include <geometry/shape_circle.h>
|
||||||
|
|
||||||
|
#include <gal/color4d.h>
|
||||||
|
|
||||||
|
#include <eda_item.h>
|
||||||
|
|
||||||
|
|
||||||
|
class ROUTER_STATUS_VIEW_ITEM : public EDA_ITEM
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ROUTER_STATUS_VIEW_ITEM() :
|
||||||
|
EDA_ITEM( NOT_USED ) // Never added to anything - just a preview
|
||||||
|
{ }
|
||||||
|
|
||||||
|
wxString GetClass() const override { return wxT( "ROUTER_STATUS" ); }
|
||||||
|
|
||||||
|
#if defined(DEBUG)
|
||||||
|
void Show( int nestLevel, std::ostream& os ) const override {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
VECTOR2I GetPosition() const override { return m_pos; }
|
||||||
|
void SetPosition( const VECTOR2I& aPos ) override { m_pos = aPos; };
|
||||||
|
|
||||||
|
void SetMessage( const wxString& aStatus )
|
||||||
|
{
|
||||||
|
m_status = aStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetHint( const wxString& aHint )
|
||||||
|
{
|
||||||
|
m_hint = aHint;
|
||||||
|
}
|
||||||
|
|
||||||
|
const BOX2I ViewBBox() const override;
|
||||||
|
void ViewGetLayers( int aLayers[], int& aCount ) const override;
|
||||||
|
void ViewDraw( int aLayer, KIGFX::VIEW* aView ) const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
VECTOR2I m_pos;
|
||||||
|
wxString m_status;
|
||||||
|
wxString m_hint;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // ROUTER_STATUS_VIEW_ITEM_H
|
|
@ -2,7 +2,7 @@
|
||||||
* KiRouter - a push-and-(sometimes-)shove PCB router
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013-2017 CERN
|
* Copyright (C) 2013-2017 CERN
|
||||||
* Copyright (C) 2017-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2017-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
*
|
*
|
||||||
|
@ -66,13 +66,12 @@ using namespace std::placeholders;
|
||||||
#include <project/project_local_settings.h>
|
#include <project/project_local_settings.h>
|
||||||
|
|
||||||
#include "router_tool.h"
|
#include "router_tool.h"
|
||||||
#include "pns_segment.h"
|
#include "router_status_view_item.h"
|
||||||
#include "pns_router.h"
|
#include "pns_router.h"
|
||||||
#include "pns_itemset.h"
|
#include "pns_itemset.h"
|
||||||
#include "pns_logger.h"
|
#include "pns_logger.h"
|
||||||
#include "pns_placement_algo.h"
|
#include "pns_placement_algo.h"
|
||||||
#include "pns_line_placer.h"
|
#include "pns_drag_algo.h"
|
||||||
#include "pns_topology.h"
|
|
||||||
|
|
||||||
#include "pns_kicad_iface.h"
|
#include "pns_kicad_iface.h"
|
||||||
|
|
||||||
|
@ -1391,13 +1390,16 @@ void ROUTER_TOOL::performRouting()
|
||||||
frame()->ShowInfoBarError( m_router->FailureReason(), true );
|
frame()->ShowInfoBarError( m_router->FailureReason(), true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( evt->IsClick( BUT_LEFT ) || evt->IsDrag( BUT_LEFT ) || evt->IsAction( &PCB_ACTIONS::routeSingleTrack ) )
|
else if( evt->IsClick( BUT_LEFT )
|
||||||
|
|| evt->IsDrag( BUT_LEFT )
|
||||||
|
|| evt->IsAction( &PCB_ACTIONS::routeSingleTrack ) )
|
||||||
{
|
{
|
||||||
updateEndItem( *evt );
|
updateEndItem( *evt );
|
||||||
bool needLayerSwitch = m_router->IsPlacingVia();
|
bool needLayerSwitch = m_router->IsPlacingVia();
|
||||||
bool forceFinish = evt->Modifier( MD_SHIFT );
|
bool forceFinish = evt->Modifier( MD_SHIFT );
|
||||||
|
bool forceCommit = false;
|
||||||
|
|
||||||
if( m_router->FixRoute( m_endSnapPoint, m_endItem, forceFinish ) )
|
if( m_router->FixRoute( m_endSnapPoint, m_endItem, forceFinish, forceCommit ) )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if( needLayerSwitch )
|
if( needLayerSwitch )
|
||||||
|
@ -1437,7 +1439,10 @@ void ROUTER_TOOL::performRouting()
|
||||||
else if( evt->IsAction( &ACTIONS::finishInteractive ) || evt->IsDblClick( BUT_LEFT ) )
|
else if( evt->IsAction( &ACTIONS::finishInteractive ) || evt->IsDblClick( BUT_LEFT ) )
|
||||||
{
|
{
|
||||||
// Stop current routing:
|
// Stop current routing:
|
||||||
m_router->FixRoute( m_endSnapPoint, m_endItem, true );
|
bool forceFinish = true;
|
||||||
|
bool forceCommit = false;
|
||||||
|
|
||||||
|
m_router->FixRoute( m_endSnapPoint, m_endItem, forceFinish, forceCommit );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if( evt->IsCancelInteractive() || evt->IsActivate()
|
else if( evt->IsCancelInteractive() || evt->IsActivate()
|
||||||
|
@ -1848,6 +1853,9 @@ void ROUTER_TOOL::performDragging( int aMode )
|
||||||
{
|
{
|
||||||
m_router->ClearViewDecorations();
|
m_router->ClearViewDecorations();
|
||||||
|
|
||||||
|
view()->ClearPreview();
|
||||||
|
view()->InitPreview();
|
||||||
|
|
||||||
VIEW_CONTROLS* ctls = getViewControls();
|
VIEW_CONTROLS* ctls = getViewControls();
|
||||||
|
|
||||||
if( m_startItem && m_startItem->IsLocked() )
|
if( m_startItem && m_startItem->IsLocked() )
|
||||||
|
@ -1900,10 +1908,36 @@ void ROUTER_TOOL::performDragging( int aMode )
|
||||||
{
|
{
|
||||||
updateEndItem( *evt );
|
updateEndItem( *evt );
|
||||||
m_router->Move( m_endSnapPoint, m_endItem );
|
m_router->Move( m_endSnapPoint, m_endItem );
|
||||||
|
|
||||||
|
if( PNS::DRAG_ALGO* dragger = m_router->GetDragger() )
|
||||||
|
{
|
||||||
|
bool dragStatus;
|
||||||
|
|
||||||
|
if( dragger->GetForceMarkObstaclesMode( &dragStatus ) )
|
||||||
|
{
|
||||||
|
view()->ClearPreview();
|
||||||
|
|
||||||
|
if( !dragStatus )
|
||||||
|
{
|
||||||
|
wxString hint;
|
||||||
|
hint.Printf( _( "(%s to commit anyway.)" ),
|
||||||
|
KeyNameFromKeyCode( MD_CTRL + PSEUDO_WXK_CLICK ) );
|
||||||
|
|
||||||
|
ROUTER_STATUS_VIEW_ITEM* statusItem = new ROUTER_STATUS_VIEW_ITEM();
|
||||||
|
statusItem->SetMessage( _( "Track violates DRC." ) );
|
||||||
|
statusItem->SetHint( hint );
|
||||||
|
statusItem->SetPosition( frame()->GetToolManager()->GetMousePosition() );
|
||||||
|
view()->AddToPreview( statusItem );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( evt->IsClick( BUT_LEFT ) )
|
else if( evt->IsClick( BUT_LEFT ) )
|
||||||
{
|
{
|
||||||
if( m_router->FixRoute( m_endSnapPoint, m_endItem ) )
|
bool forceFinish = false;
|
||||||
|
bool forceCommit = evt->Modifier( MD_CTRL );
|
||||||
|
|
||||||
|
if( m_router->FixRoute( m_endSnapPoint, m_endItem, forceFinish, forceCommit ) )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if( evt->IsClick( BUT_RIGHT ) )
|
else if( evt->IsClick( BUT_RIGHT ) )
|
||||||
|
@ -1959,6 +1993,9 @@ void ROUTER_TOOL::performDragging( int aMode )
|
||||||
handleCommonEvents( *evt );
|
handleCommonEvents( *evt );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
view()->ClearPreview();
|
||||||
|
view()->ShowPreview( false );
|
||||||
|
|
||||||
if( m_router->RoutingInProgress() )
|
if( m_router->RoutingInProgress() )
|
||||||
m_router->StopRouting();
|
m_router->StopRouting();
|
||||||
|
|
||||||
|
@ -2283,13 +2320,13 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
||||||
updateEndItem( *evt );
|
updateEndItem( *evt );
|
||||||
m_router->Move( m_endSnapPoint, m_endItem );
|
m_router->Move( m_endSnapPoint, m_endItem );
|
||||||
|
|
||||||
|
view()->ClearPreview();
|
||||||
|
|
||||||
if( !footprints.empty() )
|
if( !footprints.empty() )
|
||||||
{
|
{
|
||||||
VECTOR2I offset = m_endSnapPoint - p;
|
VECTOR2I offset = m_endSnapPoint - p;
|
||||||
BOARD_ITEM* previewItem;
|
BOARD_ITEM* previewItem;
|
||||||
|
|
||||||
view()->ClearPreview();
|
|
||||||
|
|
||||||
for( FOOTPRINT* footprint : footprints )
|
for( FOOTPRINT* footprint : footprints )
|
||||||
{
|
{
|
||||||
for( BOARD_ITEM* drawing : footprint->GraphicalItems() )
|
for( BOARD_ITEM* drawing : footprint->GraphicalItems() )
|
||||||
|
@ -2347,11 +2384,35 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
||||||
lastOffset = offset;
|
lastOffset = offset;
|
||||||
connectivityData->ComputeLocalRatsnest( dynamicItems, dynamicData.get(), offset );
|
connectivityData->ComputeLocalRatsnest( dynamicItems, dynamicData.get(), offset );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( PNS::DRAG_ALGO* dragger = m_router->GetDragger() )
|
||||||
|
{
|
||||||
|
bool dragStatus;
|
||||||
|
|
||||||
|
if( dragger->GetForceMarkObstaclesMode( &dragStatus ) )
|
||||||
|
{
|
||||||
|
if( !dragStatus )
|
||||||
|
{
|
||||||
|
wxString hint;
|
||||||
|
hint.Printf( _( "(%s to commit anyway.)" ),
|
||||||
|
KeyNameFromKeyCode( MD_CTRL + PSEUDO_WXK_CLICK ) );
|
||||||
|
|
||||||
|
ROUTER_STATUS_VIEW_ITEM* statusItem = new ROUTER_STATUS_VIEW_ITEM();
|
||||||
|
statusItem->SetMessage( _( "Track violates DRC." ) );
|
||||||
|
statusItem->SetHint( hint );
|
||||||
|
statusItem->SetPosition( frame()->GetToolManager()->GetMousePosition() );
|
||||||
|
view()->AddToPreview( statusItem );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( hasMouseMoved && ( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) )
|
else if( hasMouseMoved && ( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) )
|
||||||
{
|
{
|
||||||
|
bool forceFinish = false;
|
||||||
|
bool forceCommit = evt->Modifier( MD_CTRL );
|
||||||
|
|
||||||
updateEndItem( *evt );
|
updateEndItem( *evt );
|
||||||
m_router->FixRoute( m_endSnapPoint, m_endItem );
|
m_router->FixRoute( m_endSnapPoint, m_endItem, forceFinish, forceCommit );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if( evt->IsUndoRedo() )
|
else if( evt->IsUndoRedo() )
|
||||||
|
@ -2407,12 +2468,12 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
|
||||||
view()->Hide( pad, false );
|
view()->Hide( pad, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
view()->ClearPreview();
|
|
||||||
view()->ShowPreview( false );
|
|
||||||
|
|
||||||
connectivityData->ClearLocalRatsnest();
|
connectivityData->ClearLocalRatsnest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
view()->ClearPreview();
|
||||||
|
view()->ShowPreview( false );
|
||||||
|
|
||||||
// Clear temporary COURTYARD_CONFLICT flag and ensure the conflict shadow is cleared
|
// Clear temporary COURTYARD_CONFLICT flag and ensure the conflict shadow is cleared
|
||||||
courtyardClearanceDRC.ClearConflicts( getView() );
|
courtyardClearanceDRC.ClearConflicts( getView() );
|
||||||
|
|
||||||
|
|
|
@ -156,7 +156,7 @@ void PNS_LOG_PLAYER::ReplayLog( PNS_LOG_FILE* aLog, int aStartEventIndex, int aF
|
||||||
m_debugDecorator->NewStage( "fix", 0, PNSLOGINFO );
|
m_debugDecorator->NewStage( "fix", 0, PNSLOGINFO );
|
||||||
m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
|
m_viewTracker->SetStage( m_debugDecorator->GetStageCount() - 1 );
|
||||||
m_debugDecorator->Message( wxString::Format( "fix (%d, %d)", evt.p.x, evt.p.y ) );
|
m_debugDecorator->Message( wxString::Format( "fix (%d, %d)", evt.p.x, evt.p.y ) );
|
||||||
bool rv = m_router->FixRoute( evt.p, ritem );
|
bool rv = m_router->FixRoute( evt.p, ritem, false, false );
|
||||||
printf( " fix -> (%d, %d) ret %d\n", evt.p.x, evt.p.y, rv ? 1 : 0 );
|
printf( " fix -> (%d, %d) ret %d\n", evt.p.x, evt.p.y, rv ? 1 : 0 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue