mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-13 17:53:11 +02:00
Add a 90°-only mode for polygon creation
Sometimes, you don't want those 45° corners in your nice, clean zones. This adds an additional mode that can be selected, cycling through free-angle, 45° angle and 90° angle constraints
This commit is contained in:
parent
5375e27415
commit
188ffda029
@ -228,6 +228,20 @@ static SHAPE_LINE_CHAIN build45DegLeader( const VECTOR2I& aEndPoint, const SHAPE
|
||||
return SHAPE_LINE_CHAIN( std::vector<VECTOR2I>{ lastPt, midInt, aEndPoint } );
|
||||
}
|
||||
|
||||
static SHAPE_LINE_CHAIN build90DegLeader( const VECTOR2I& aEndPoint, const SHAPE_LINE_CHAIN& aLastPoints )
|
||||
{
|
||||
if( aLastPoints.PointCount() < 1 )
|
||||
return SHAPE_LINE_CHAIN();
|
||||
|
||||
const VECTOR2I lastPt = aLastPoints.CLastPoint();
|
||||
|
||||
if( lastPt.x == aEndPoint.x || lastPt.y == aEndPoint.y )
|
||||
return SHAPE_LINE_CHAIN( std::vector<VECTOR2I>{ lastPt, aEndPoint } );
|
||||
|
||||
VECTOR2I mid( aEndPoint.x, lastPt.y );
|
||||
return SHAPE_LINE_CHAIN( std::vector<VECTOR2I>{ lastPt, mid, aEndPoint } );
|
||||
}
|
||||
|
||||
|
||||
void POLYGON_GEOM_MANAGER::updateTemporaryLines( const VECTOR2I& aEndPoint, LEADER_MODE aModifier )
|
||||
{
|
||||
@ -242,6 +256,14 @@ void POLYGON_GEOM_MANAGER::updateTemporaryLines( const VECTOR2I& aEndPoint, LEAD
|
||||
m_loopPts = build45DegLeader( aEndPoint, m_lockedPoints.Reverse() ).Reverse();
|
||||
}
|
||||
}
|
||||
else if( m_leaderMode == LEADER_MODE::DEG90 || aModifier == LEADER_MODE::DEG90 )
|
||||
{
|
||||
if( m_lockedPoints.PointCount() > 0 )
|
||||
{
|
||||
m_leaderPts = build90DegLeader( aEndPoint, m_lockedPoints );
|
||||
m_loopPts = build90DegLeader( aEndPoint, m_lockedPoints.Reverse() ).Reverse();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// direct segment
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <settings/cvpcb_settings.h>
|
||||
#include <settings/parameters.h>
|
||||
#include <wx/config.h>
|
||||
#include <geometry/geometry_utils.h>
|
||||
|
||||
|
||||
///! Update the schema version whenever a migration is required
|
||||
@ -54,8 +55,9 @@ CVPCB_SETTINGS::CVPCB_SETTINGS() :
|
||||
m_params.emplace_back( new PARAM<bool>( "footprint_viewer.autozoom",
|
||||
&m_FootprintViewerAutoZoomOnSelect, true ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "footprint_viewer.use_45_limit",
|
||||
&m_ViewersDisplay.m_Use45Limit, true ) );
|
||||
m_params.emplace_back( new PARAM<int>( "footprint_viewer.angle_snap_mode",
|
||||
reinterpret_cast<int*>( &m_ViewersDisplay.m_AngleSnapMode ),
|
||||
static_cast<int>( LEADER_MODE::DEG45 ) ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "footprint_viewer.show_pad_fill",
|
||||
&m_ViewersDisplay.m_DisplayPadFill, true ) );
|
||||
|
@ -93,7 +93,7 @@ bool RULE_AREA_CREATE_HELPER::OnFirstPoint( POLYGON_GEOM_MANAGER& aMgr )
|
||||
|
||||
m_parentView.SetVisible( &m_previewItem, true );
|
||||
|
||||
aMgr.SetLeaderMode( POLYGON_GEOM_MANAGER::LEADER_MODE::DEG45 );
|
||||
aMgr.SetLeaderMode( LEADER_MODE::DEG45 );
|
||||
}
|
||||
|
||||
return m_rule_area != nullptr;
|
||||
@ -138,7 +138,7 @@ void RULE_AREA_CREATE_HELPER::OnComplete( const POLYGON_GEOM_MANAGER& aMgr )
|
||||
|
||||
// In DEG45 mode, we may have intermediate points in the leader that should be included
|
||||
// as they are shown in the preview. These typically maintain the 45 constraint
|
||||
if( aMgr.GetLeaderMode() == POLYGON_GEOM_MANAGER::LEADER_MODE::DEG45 )
|
||||
if( aMgr.GetLeaderMode() == LEADER_MODE::DEG45 || aMgr.GetLeaderMode() == LEADER_MODE::DEG90 )
|
||||
{
|
||||
const SHAPE_LINE_CHAIN leaderPts = aMgr.GetLeaderLinePoints();
|
||||
for( int i = 1; i < leaderPts.PointCount(); i++ )
|
||||
|
@ -2617,8 +2617,8 @@ int SCH_DRAWING_TOOLS::DrawRuleArea( const TOOL_EVENT& aEvent )
|
||||
controls->ForceCursorPosition( true, cursorPos );
|
||||
|
||||
polyGeomMgr.SetLeaderMode( m_frame->eeconfig()->m_Drawing.line_mode == LINE_MODE_FREE
|
||||
? POLYGON_GEOM_MANAGER::LEADER_MODE::DIRECT
|
||||
: POLYGON_GEOM_MANAGER::LEADER_MODE::DEG45 );
|
||||
? LEADER_MODE::DIRECT
|
||||
: LEADER_MODE::DEG45 );
|
||||
|
||||
if( evt->IsCancelInteractive() )
|
||||
{
|
||||
|
@ -286,7 +286,8 @@ int GERBVIEW_INSPECTION_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
|
||||
else if( originSet && ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
|
||||
{
|
||||
// move or drag when origin set updates rules
|
||||
twoPtMgr.SetAngleSnap( evt->Modifier( MD_SHIFT ) );
|
||||
twoPtMgr.SetAngleSnap( evt->Modifier( MD_SHIFT ) ? LEADER_MODE::DEG45
|
||||
: LEADER_MODE::DIRECT );
|
||||
twoPtMgr.SetEnd( cursorPos );
|
||||
|
||||
getView()->SetVisible( &ruler, true );
|
||||
|
@ -74,7 +74,7 @@ public:
|
||||
|
||||
EDA_ANGLE m_RotationAngle;
|
||||
|
||||
bool m_Use45Limit;
|
||||
LEADER_MODE m_AngleSnapMode;
|
||||
|
||||
ARC_EDIT_MODE m_ArcEditMode;
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#define PREVIEW_POLYGON_GEOM_MANAGER__H_
|
||||
|
||||
#include <geometry/shape_line_chain.h>
|
||||
#include <geometry/geometry_utils.h>
|
||||
|
||||
/**
|
||||
* Class that handles the drawing of a polygon, including management of last corner deletion
|
||||
@ -63,15 +64,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The kind of the leader line
|
||||
*/
|
||||
enum class LEADER_MODE
|
||||
{
|
||||
DIRECT, ///< Unconstrained point-to-point
|
||||
DEG45, ///< 45 Degree only
|
||||
};
|
||||
|
||||
/**
|
||||
* @param aClient is the client to pass the results onto
|
||||
*/
|
||||
|
@ -40,7 +40,6 @@ namespace PREVIEW
|
||||
class TWO_POINT_GEOMETRY_MANAGER
|
||||
{
|
||||
public:
|
||||
|
||||
///< Set the origin of the ruler (the fixed end)
|
||||
void SetOrigin( const VECTOR2I& aOrigin )
|
||||
{
|
||||
@ -58,10 +57,12 @@ public:
|
||||
*/
|
||||
void SetEnd( const VECTOR2I& aEnd )
|
||||
{
|
||||
if( m_angleSnap )
|
||||
m_end = GetVectorSnapped45( aEnd - m_origin ) + m_origin;
|
||||
else
|
||||
m_end = aEnd;
|
||||
switch( m_angleSnap )
|
||||
{
|
||||
case LEADER_MODE::DEG45: m_end = GetVectorSnapped45( aEnd - m_origin ) + m_origin; break;
|
||||
case LEADER_MODE::DEG90: m_end = GetVectorSnapped90( aEnd - m_origin ) + m_origin; break;
|
||||
default: m_end = aEnd; break;
|
||||
}
|
||||
}
|
||||
|
||||
VECTOR2I GetEnd() const
|
||||
@ -69,15 +70,9 @@ public:
|
||||
return m_end;
|
||||
}
|
||||
|
||||
void SetAngleSnap( bool aSnap )
|
||||
{
|
||||
m_angleSnap = aSnap;
|
||||
}
|
||||
void SetAngleSnap( LEADER_MODE aSnap ) { m_angleSnap = aSnap; }
|
||||
|
||||
bool GetAngleSnap() const
|
||||
{
|
||||
return m_angleSnap;
|
||||
}
|
||||
LEADER_MODE GetAngleSnap() const { return m_angleSnap; }
|
||||
|
||||
/**
|
||||
* @return true if the manager is in the initial state
|
||||
@ -101,11 +96,10 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
VECTOR2I m_origin;
|
||||
VECTOR2I m_end;
|
||||
bool m_angleSnap = false;
|
||||
bool m_originSet = false;
|
||||
VECTOR2I m_origin;
|
||||
VECTOR2I m_end;
|
||||
LEADER_MODE m_angleSnap = LEADER_MODE::DIRECT;
|
||||
bool m_originSet = false;
|
||||
};
|
||||
|
||||
} // PREVIEW
|
||||
|
@ -39,6 +39,16 @@
|
||||
#include <geometry/shape_simple.h>
|
||||
#include <geometry/shape_compound.h>
|
||||
|
||||
/**
|
||||
* The kind of the leader line
|
||||
*/
|
||||
enum class LEADER_MODE
|
||||
{
|
||||
DIRECT, ///< Unconstrained point-to-point
|
||||
DEG45, ///< 45 Degree only
|
||||
DEG90 ///< 90 Degree only
|
||||
};
|
||||
|
||||
/**
|
||||
* @return the number of segments to approximate a arc by segments
|
||||
* with a given max error (this number is >= 1)
|
||||
@ -131,6 +141,30 @@ VECTOR2<T> GetVectorSnapped45( const VECTOR2<T>& aVec, bool only45 = false )
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Snap a vector onto the nearest horizontal or vertical line.
|
||||
*
|
||||
* The magnitude of the vector is NOT kept; instead one of the coordinates is
|
||||
* set to zero as needed. If the starting vector is on a square grid, the
|
||||
* resulting snapped vector will remain on the same grid.
|
||||
*
|
||||
* @param aVec vector to be snapped
|
||||
* @return the snapped vector
|
||||
*/
|
||||
template <typename T>
|
||||
VECTOR2<T> GetVectorSnapped90( const VECTOR2<T>& aVec )
|
||||
{
|
||||
auto newVec = aVec;
|
||||
const VECTOR2<T> absVec{ std::abs( aVec.x ), std::abs( aVec.y ) };
|
||||
|
||||
if( absVec.x >= absVec.y )
|
||||
newVec.y = 0;
|
||||
else
|
||||
newVec.x = 0;
|
||||
|
||||
return newVec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clamps a vector to values that can be negated, respecting numeric limits
|
||||
* of coordinates data type with specified padding.
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <pcbnew_settings.h>
|
||||
#include <footprint_editor_settings.h>
|
||||
#include <panel_edit_options.h>
|
||||
#include <geometry/geometry_utils.h>
|
||||
|
||||
|
||||
PANEL_EDIT_OPTIONS::PANEL_EDIT_OPTIONS( wxWindow* aParent, UNITS_PROVIDER* aUnitsProvider,
|
||||
@ -104,7 +105,7 @@ static ARC_EDIT_MODE arcEditModeToEnum( int aIndex )
|
||||
|
||||
void PANEL_EDIT_OPTIONS::loadPCBSettings( PCBNEW_SETTINGS* aCfg )
|
||||
{
|
||||
m_cbConstrainHV45Mode->SetValue( aCfg->m_Use45DegreeLimit );
|
||||
m_cbConstrainHV45Mode->SetValue( aCfg->m_AngleSnapMode != LEADER_MODE::DIRECT );
|
||||
m_rotationAngle.SetAngleValue( aCfg->m_RotationAngle );
|
||||
m_arcEditMode->SetSelection( arcEditModeToComboIndex( aCfg->m_ArcEditMode ) );
|
||||
m_trackMouseDragCtrl->SetSelection( (int) aCfg->m_TrackDragAction );
|
||||
@ -150,7 +151,7 @@ void PANEL_EDIT_OPTIONS::loadFPSettings( FOOTPRINT_EDITOR_SETTINGS* aCfg )
|
||||
m_rotationAngle.SetAngleValue( aCfg->m_RotationAngle );
|
||||
m_magneticPads->SetValue( aCfg->m_MagneticItems.pads == MAGNETIC_OPTIONS::CAPTURE_ALWAYS );
|
||||
m_magneticGraphics->SetValue( aCfg->m_MagneticItems.graphics );
|
||||
m_cbConstrainHV45Mode->SetValue( aCfg->m_Use45Limit );
|
||||
m_cbConstrainHV45Mode->SetValue( aCfg->m_AngleSnapMode != LEADER_MODE::DIRECT );
|
||||
m_arcEditMode->SetSelection( arcEditModeToComboIndex( aCfg->m_ArcEditMode ) );
|
||||
}
|
||||
|
||||
@ -178,7 +179,8 @@ bool PANEL_EDIT_OPTIONS::TransferDataFromWindow()
|
||||
: MAGNETIC_OPTIONS::NO_EFFECT;
|
||||
cfg->m_MagneticItems.graphics = m_magneticGraphics->GetValue();
|
||||
|
||||
cfg->m_Use45Limit = m_cbConstrainHV45Mode->GetValue();
|
||||
cfg->m_AngleSnapMode = m_cbConstrainHV45Mode->GetValue() ? LEADER_MODE::DEG45
|
||||
: LEADER_MODE::DIRECT;
|
||||
cfg->m_ArcEditMode = arcEditModeToEnum( m_arcEditMode->GetSelection() );
|
||||
}
|
||||
}
|
||||
@ -190,7 +192,8 @@ bool PANEL_EDIT_OPTIONS::TransferDataFromWindow()
|
||||
cfg->m_Display.m_ShowModuleRatsnest = m_showSelectedRatsnest->GetValue();
|
||||
cfg->m_Display.m_RatsnestThickness = m_ratsnestThickness->GetValue();
|
||||
|
||||
cfg->m_Use45DegreeLimit = m_cbConstrainHV45Mode->GetValue();
|
||||
cfg->m_AngleSnapMode = m_cbConstrainHV45Mode->GetValue() ? LEADER_MODE::DEG45
|
||||
: LEADER_MODE::DIRECT;
|
||||
cfg->m_RotationAngle = m_rotationAngle.GetAngleValue();
|
||||
cfg->m_ArcEditMode = arcEditModeToEnum( m_arcEditMode->GetSelection() );
|
||||
cfg->m_TrackDragAction = (TRACK_DRAG_ACTION) m_trackMouseDragCtrl->GetSelection();
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "tools/pcb_actions.h"
|
||||
#include "tools/pcb_control.h"
|
||||
#include "tools/pcb_picker_tool.h"
|
||||
#include <geometry/geometry_utils.h>
|
||||
#include "tools/align_distribute_tool.h"
|
||||
#include "tools/pcb_point_editor.h"
|
||||
#include "tools/pcb_selection_tool.h"
|
||||
@ -1337,7 +1338,7 @@ void FOOTPRINT_EDIT_FRAME::setupUIConditions()
|
||||
auto constrainedDrawingModeCond =
|
||||
[this]( const SELECTION& )
|
||||
{
|
||||
return GetSettings()->m_Use45Limit;
|
||||
return GetSettings()->m_AngleSnapMode != LEADER_MODE::DIRECT;
|
||||
};
|
||||
|
||||
auto highContrastCond =
|
||||
|
@ -50,7 +50,7 @@ FOOTPRINT_EDITOR_SETTINGS::FOOTPRINT_EDITOR_SETTINGS() :
|
||||
m_DisplayInvertXAxis( false ),
|
||||
m_DisplayInvertYAxis( false ),
|
||||
m_RotationAngle( ANGLE_90 ),
|
||||
m_Use45Limit( true ),
|
||||
m_AngleSnapMode( LEADER_MODE::DEG45 ),
|
||||
m_ArcEditMode( ARC_EDIT_MODE::KEEP_CENTER_ADJUST_ANGLE_RADIUS ),
|
||||
m_LibWidth( 250 ),
|
||||
m_LastExportPath(),
|
||||
@ -138,8 +138,9 @@ FOOTPRINT_EDITOR_SETTINGS::FOOTPRINT_EDITOR_SETTINGS() :
|
||||
},
|
||||
900 ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "editing.fp_use_45_degree_limit",
|
||||
&m_Use45Limit, false ) );
|
||||
m_params.emplace_back( new PARAM<int>( "editing.fp_angle_snap_mode",
|
||||
reinterpret_cast<int*>( &m_AngleSnapMode ),
|
||||
static_cast<int>( LEADER_MODE::DEG45 ) ) );
|
||||
|
||||
m_params.emplace_back( new PARAM_LAYER_PRESET( "pcb_display.layer_presets", &m_LayerPresets ) );
|
||||
|
||||
|
@ -209,7 +209,7 @@ int MICROWAVE_TOOL::drawMicrowaveInductor( const TOOL_EVENT& aEvent )
|
||||
// the end point
|
||||
else if( originSet && ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
|
||||
{
|
||||
tpGeomMgr.SetAngleSnap( Is45Limited() );
|
||||
tpGeomMgr.SetAngleSnap( GetAngleSnapMode() );
|
||||
tpGeomMgr.SetEnd( cursorPos );
|
||||
|
||||
view.SetVisible( &previewRect, true );
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <3d_viewer/eda_3d_viewer_frame.h>
|
||||
#include <api/api_plugin_manager.h>
|
||||
#include <fp_lib_table.h>
|
||||
#include <geometry/geometry_utils.h>
|
||||
#include <bitmaps.h>
|
||||
#include <confirm.h>
|
||||
#include <lset.h>
|
||||
@ -888,7 +889,7 @@ void PCB_EDIT_FRAME::setupUIConditions()
|
||||
auto constrainedDrawingModeCond =
|
||||
[this]( const SELECTION& )
|
||||
{
|
||||
return GetPcbNewSettings()->m_Use45DegreeLimit;
|
||||
return GetPcbNewSettings()->m_AngleSnapMode != LEADER_MODE::DIRECT;
|
||||
};
|
||||
|
||||
auto boardFlippedCond =
|
||||
|
@ -58,7 +58,7 @@ PCBNEW_SETTINGS::PCBNEW_SETTINGS()
|
||||
m_TrackDragAction( TRACK_DRAG_ACTION::DRAG ),
|
||||
m_ArcEditMode( ARC_EDIT_MODE::KEEP_CENTER_ADJUST_ANGLE_RADIUS ),
|
||||
m_CtrlClickHighlight( false ),
|
||||
m_Use45DegreeLimit( false ),
|
||||
m_AngleSnapMode( LEADER_MODE::DIRECT ),
|
||||
m_FlipDirection( FLIP_DIRECTION::TOP_BOTTOM ),
|
||||
m_ESCClearsNetHighlight( true ),
|
||||
m_PolarCoords( false ),
|
||||
@ -190,8 +190,9 @@ PCBNEW_SETTINGS::PCBNEW_SETTINGS()
|
||||
m_params.emplace_back( new PARAM<bool>( "editing.ctrl_click_highlight",
|
||||
&m_CtrlClickHighlight, false ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "editing.pcb_use_45_degree_limit",
|
||||
&m_Use45DegreeLimit, false ) );
|
||||
m_params.emplace_back( new PARAM<int>( "editing.pcb_angle_snap_mode",
|
||||
reinterpret_cast<int*>( &m_AngleSnapMode ),
|
||||
static_cast<int>( LEADER_MODE::DIRECT ) ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<bool>( "editing.auto_fill_zones",
|
||||
&m_AutoRefillZones, false ) );
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include <core/mirror.h> // for FLIP_DIRECTION
|
||||
#include <geometry/eda_angle.h>
|
||||
#include <geometry/geometry_utils.h>
|
||||
#include <settings/app_settings.h>
|
||||
#include <pcb_display_options.h>
|
||||
|
||||
@ -108,7 +109,7 @@ class PCB_VIEWERS_SETTINGS_BASE : public APP_SETTINGS_BASE
|
||||
public:
|
||||
struct VIEWERS_DISPLAY_OPTIONS
|
||||
{
|
||||
bool m_Use45Limit;
|
||||
LEADER_MODE m_AngleSnapMode;
|
||||
bool m_DisplayGraphicsFill;
|
||||
bool m_DisplayTextFill;
|
||||
bool m_DisplayPadNumbers;
|
||||
@ -125,7 +126,7 @@ public:
|
||||
m_FootprintViewerZoom( 1.0 ),
|
||||
m_FootprintViewerAutoZoomOnSelect( true )
|
||||
{
|
||||
m_ViewersDisplay.m_Use45Limit = false;
|
||||
m_ViewersDisplay.m_AngleSnapMode = LEADER_MODE::DIRECT;
|
||||
m_ViewersDisplay.m_DisplayGraphicsFill = true;
|
||||
m_ViewersDisplay.m_DisplayTextFill = true;
|
||||
m_ViewersDisplay.m_DisplayPadNumbers = true;
|
||||
@ -246,7 +247,7 @@ public:
|
||||
|
||||
bool m_CtrlClickHighlight;
|
||||
|
||||
bool m_Use45DegreeLimit; // Constrain tool actions to horizontal, vertical and 45deg
|
||||
LEADER_MODE m_AngleSnapMode; // Constrain tool actions to horizontal/vertical or 45°/90°
|
||||
FLIP_DIRECTION m_FlipDirection;
|
||||
|
||||
bool m_ESCClearsNetHighlight;
|
||||
|
@ -333,7 +333,18 @@ DRAWING_TOOL::MODE DRAWING_TOOL::GetDrawingMode() const
|
||||
void DRAWING_TOOL::UpdateStatusBar() const
|
||||
{
|
||||
if( m_frame )
|
||||
m_frame->DisplayConstraintsMsg( Is45Limited() ? _( "Constrain to H, V, 45" ) : wxString( "" ) );
|
||||
{
|
||||
switch( GetAngleSnapMode() )
|
||||
{
|
||||
case LEADER_MODE::DEG45:
|
||||
m_frame->DisplayConstraintsMsg( _( "Constrain to H, V, 45" ) );
|
||||
break;
|
||||
case LEADER_MODE::DEG90:
|
||||
m_frame->DisplayConstraintsMsg( _( "Constrain to H, V" ) );
|
||||
break;
|
||||
default: m_frame->DisplayConstraintsMsg( wxString( "" ) ); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1407,7 +1418,10 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
|
||||
setCursor();
|
||||
|
||||
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
|
||||
bool is45Limited = Is45Limited() && !evt->Modifier( MD_CTRL );
|
||||
auto angleSnap = GetAngleSnapMode();
|
||||
if( evt->Modifier( MD_CTRL ) )
|
||||
angleSnap = LEADER_MODE::DIRECT;
|
||||
bool constrained = angleSnap != LEADER_MODE::DIRECT;
|
||||
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
|
||||
|
||||
if( step == SET_HEIGHT && t != PCB_DIM_ORTHOGONAL_T )
|
||||
@ -1615,7 +1629,7 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
|
||||
case SET_END:
|
||||
dimension->SetEnd( cursorPos );
|
||||
|
||||
if( is45Limited || t == PCB_DIM_CENTER_T )
|
||||
if( constrained || t == PCB_DIM_CENTER_T )
|
||||
constrainDimension( dimension );
|
||||
|
||||
if( t == PCB_DIM_ORTHOGONAL_T )
|
||||
@ -2187,11 +2201,13 @@ bool DRAWING_TOOL::drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
||||
m_frame->SetMsgPanel( graphic );
|
||||
|
||||
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
|
||||
bool is45Limited = Is45Limited() && !evt->Modifier( MD_CTRL );
|
||||
auto angleSnap = GetAngleSnapMode();
|
||||
if( evt->Modifier( MD_CTRL ) )
|
||||
angleSnap = LEADER_MODE::DIRECT;
|
||||
|
||||
// Rectangular shapes never get 45-degree snapping
|
||||
// Rectangular shapes never get diagonal snapping
|
||||
if( shape == SHAPE_T::RECTANGLE )
|
||||
is45Limited = false;
|
||||
angleSnap = LEADER_MODE::DIRECT;
|
||||
|
||||
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
|
||||
cursorPos = GetClampedCoords(
|
||||
@ -2370,21 +2386,25 @@ bool DRAWING_TOOL::drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
||||
else
|
||||
clampedCursorPos = getClampedDifferenceEnd( twoPointMgr.GetOrigin(), cursorPos );
|
||||
|
||||
// 45 degree lines
|
||||
if( started && is45Limited )
|
||||
// constrained lines
|
||||
if( started && angleSnap != LEADER_MODE::DIRECT )
|
||||
{
|
||||
const VECTOR2I lineVector( clampedCursorPos - VECTOR2I( twoPointMgr.GetOrigin() ) );
|
||||
|
||||
// get a restricted 45/H/V line from the last fixed point to the cursor
|
||||
VECTOR2I newEnd = GetVectorSnapped45( lineVector, ( shape == SHAPE_T::RECTANGLE ) );
|
||||
VECTOR2I newEnd;
|
||||
if( angleSnap == LEADER_MODE::DEG90 )
|
||||
newEnd = GetVectorSnapped90( lineVector );
|
||||
else
|
||||
newEnd = GetVectorSnapped45( lineVector, ( shape == SHAPE_T::RECTANGLE ) );
|
||||
|
||||
m_controls->ForceCursorPosition( true, VECTOR2I( twoPointMgr.GetEnd() ) );
|
||||
twoPointMgr.SetEnd( twoPointMgr.GetOrigin() + newEnd );
|
||||
twoPointMgr.SetAngleSnap( true );
|
||||
twoPointMgr.SetAngleSnap( angleSnap );
|
||||
}
|
||||
else
|
||||
{
|
||||
twoPointMgr.SetEnd( clampedCursorPos );
|
||||
twoPointMgr.SetAngleSnap( false );
|
||||
twoPointMgr.SetAngleSnap( LEADER_MODE::DIRECT );
|
||||
}
|
||||
|
||||
updateSegmentFromGeometryMgr( twoPointMgr, graphic );
|
||||
@ -2580,7 +2600,9 @@ bool DRAWING_TOOL::drawArc( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
||||
graphic->SetLayer( m_layer );
|
||||
|
||||
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
|
||||
bool is45Limited = Is45Limited() && !evt->Modifier( MD_CTRL );
|
||||
auto angleSnap = GetAngleSnapMode();
|
||||
if( evt->Modifier( MD_CTRL ) )
|
||||
angleSnap = LEADER_MODE::DIRECT;
|
||||
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
|
||||
VECTOR2I cursorPos = GetClampedCoords(
|
||||
grid.BestSnapAnchor( m_controls->GetMousePosition(), graphic, GRID_GRAPHICS ),
|
||||
@ -2656,7 +2678,7 @@ bool DRAWING_TOOL::drawArc( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
||||
else if( evt->IsMotion() )
|
||||
{
|
||||
// set angle snap
|
||||
arcManager.SetAngleSnap( is45Limited );
|
||||
arcManager.SetAngleSnap( angleSnap != LEADER_MODE::DIRECT );
|
||||
|
||||
// update, but don't step the manager state
|
||||
arcManager.AddPoint( cursorPos, false );
|
||||
@ -3230,7 +3252,9 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
|
||||
|
||||
LSET layers( { m_frame->GetActiveLayer() } );
|
||||
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
|
||||
bool is45Limited = Is45Limited() && !evt->Modifier( MD_CTRL );
|
||||
auto angleSnap = GetAngleSnapMode();
|
||||
if( evt->Modifier( MD_CTRL ) )
|
||||
angleSnap = LEADER_MODE::DIRECT;
|
||||
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
|
||||
|
||||
VECTOR2I cursorPos = evt->HasPosition() ? evt->Position() : m_controls->GetMousePosition();
|
||||
@ -3239,8 +3263,7 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
|
||||
|
||||
m_controls->ForceCursorPosition( true, cursorPos );
|
||||
|
||||
polyGeomMgr.SetLeaderMode( is45Limited ? POLYGON_GEOM_MANAGER::LEADER_MODE::DEG45
|
||||
: POLYGON_GEOM_MANAGER::LEADER_MODE::DIRECT );
|
||||
polyGeomMgr.SetLeaderMode( angleSnap );
|
||||
|
||||
if( evt->IsCancelInteractive() )
|
||||
{
|
||||
|
@ -1399,8 +1399,8 @@ TOOL_ACTION PCB_ACTIONS::toggleHV45Mode( TOOL_ACTION_ARGS()
|
||||
.Name( "pcbnew.EditorControl.toggle45" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.DefaultHotkey( MD_SHIFT + ' ' )
|
||||
.FriendlyName( _( "Constrain to H, V, 45" ) )
|
||||
.Tooltip( _( "Limit actions to horizontal, vertical, or 45 degrees from the starting point" ) )
|
||||
.FriendlyName( _( "Cycle H/V/45 constraint" ) )
|
||||
.Tooltip( _( "Cycle between no angle constraint, 45 degrees, or horizontal/vertical only" ) )
|
||||
.ToolbarState( TOOLBAR_STATE::TOGGLE )
|
||||
.Icon( BITMAPS::hv45mode ) );
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <pcb_base_frame.h>
|
||||
#include <tool/selection.h>
|
||||
#include <tools/pcb_editor_conditions.h>
|
||||
#include <geometry/geometry_utils.h>
|
||||
|
||||
#include <functional>
|
||||
#include <wx/debug.h>
|
||||
@ -200,11 +201,11 @@ bool PCB_EDITOR_CONDITIONS::zoneDisplayModeFunc( const SELECTION& aSelection, PC
|
||||
bool PCB_EDITOR_CONDITIONS::get45degModeFunc( const SELECTION& aSelection, PCB_BASE_FRAME* aFrame )
|
||||
{
|
||||
if( aFrame->IsType( FRAME_PCB_EDITOR ) )
|
||||
return GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" )->m_Use45DegreeLimit;
|
||||
return GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" )->m_AngleSnapMode != LEADER_MODE::DIRECT;
|
||||
else if( aFrame->IsType( FRAME_FOOTPRINT_EDITOR ) )
|
||||
return GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( "fpedit" )->m_Use45Limit;
|
||||
return GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( "fpedit" )->m_AngleSnapMode != LEADER_MODE::DIRECT;
|
||||
else
|
||||
return aFrame->GetViewerSettingsBase()->m_ViewersDisplay.m_Use45Limit;
|
||||
return aFrame->GetViewerSettingsBase()->m_ViewersDisplay.m_AngleSnapMode != LEADER_MODE::DIRECT;
|
||||
}
|
||||
|
||||
|
||||
|
@ -103,9 +103,9 @@ public:
|
||||
SELECTION_CONDITION ZoneDisplayMode( ZONE_DISPLAY_MODE aMode );
|
||||
|
||||
/**
|
||||
* Create a functor that tests whether only 45 degree lines should be allowed
|
||||
* Create a functor that tests whether angle constraints are enabled
|
||||
*
|
||||
* @return Functor returning true if only 45 degree lines should be allowed
|
||||
* @return Functor returning true if angle constraints are enabled
|
||||
*/
|
||||
SELECTION_CONDITION Get45degMode();
|
||||
|
||||
@ -142,7 +142,7 @@ protected:
|
||||
static bool zoneDisplayModeFunc( const SELECTION& aSelection, PCB_BASE_FRAME* aFrame,
|
||||
ZONE_DISPLAY_MODE aMode );
|
||||
|
||||
///< Helper function used by Line45degMode()
|
||||
///< Helper function used by Get45degMode()
|
||||
static bool get45degModeFunc( const SELECTION& aSelection, PCB_BASE_FRAME* aFrame );
|
||||
|
||||
/// Helper function used by FootprintViewerAutoZoom()
|
||||
|
@ -329,11 +329,21 @@ PCB_SELECTION& PCB_TOOL_BASE::selection()
|
||||
|
||||
|
||||
bool PCB_TOOL_BASE::Is45Limited() const
|
||||
{
|
||||
return GetAngleSnapMode() != LEADER_MODE::DIRECT;
|
||||
}
|
||||
|
||||
bool PCB_TOOL_BASE::Is90Limited() const
|
||||
{
|
||||
return GetAngleSnapMode() == LEADER_MODE::DEG90;
|
||||
}
|
||||
|
||||
LEADER_MODE PCB_TOOL_BASE::GetAngleSnapMode() const
|
||||
{
|
||||
if( frame<PCB_BASE_FRAME>()->IsType( FRAME_PCB_EDITOR ) )
|
||||
return GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" )->m_Use45DegreeLimit;
|
||||
return GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" )->m_AngleSnapMode;
|
||||
else
|
||||
return GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( "fpedit" )->m_Use45Limit;
|
||||
return GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( "fpedit" )->m_AngleSnapMode;
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <pcb_view.h>
|
||||
#include <pcb_draw_panel_gal.h>
|
||||
#include <pcbnew_settings.h>
|
||||
#include <preview_items/two_point_geom_manager.h>
|
||||
#include <functional>
|
||||
#include <tool/tool_menu.h>
|
||||
|
||||
@ -114,6 +115,16 @@ public:
|
||||
*/
|
||||
virtual bool Is45Limited() const;
|
||||
|
||||
/**
|
||||
* Should the tool limit drawing to horizontal and vertical only?
|
||||
*/
|
||||
virtual bool Is90Limited() const;
|
||||
|
||||
/**
|
||||
* Get the current angle snapping mode.
|
||||
*/
|
||||
LEADER_MODE GetAngleSnapMode() const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Options for placing items interactively.
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <kiplatform/ui.h>
|
||||
#include <pcb_base_frame.h>
|
||||
#include <preview_items/ruler_item.h>
|
||||
#include <preview_items/two_point_geom_manager.h>
|
||||
#include <pgm_base.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <tool/actions.h>
|
||||
@ -108,11 +109,38 @@ template<class T> void Flip( T& aValue )
|
||||
int PCB_VIEWER_TOOLS::ToggleHV45Mode( const TOOL_EVENT& toolEvent )
|
||||
{
|
||||
if( frame()->IsType( FRAME_PCB_EDITOR ) )
|
||||
Flip( GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" )->m_Use45DegreeLimit );
|
||||
{
|
||||
PCBNEW_SETTINGS* settings = GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" );
|
||||
|
||||
switch( settings->m_AngleSnapMode )
|
||||
{
|
||||
case LEADER_MODE::DIRECT: settings->m_AngleSnapMode = LEADER_MODE::DEG45; break;
|
||||
case LEADER_MODE::DEG45: settings->m_AngleSnapMode = LEADER_MODE::DEG90; break;
|
||||
default: settings->m_AngleSnapMode = LEADER_MODE::DIRECT; break;
|
||||
}
|
||||
}
|
||||
else if( frame()->IsType( FRAME_FOOTPRINT_EDITOR ) )
|
||||
Flip( GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( "fpedit" )->m_Use45Limit );
|
||||
{
|
||||
FOOTPRINT_EDITOR_SETTINGS* settings = GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( "fpedit" );
|
||||
|
||||
switch( settings->m_AngleSnapMode )
|
||||
{
|
||||
case LEADER_MODE::DIRECT: settings->m_AngleSnapMode = LEADER_MODE::DEG45; break;
|
||||
case LEADER_MODE::DEG45: settings->m_AngleSnapMode = LEADER_MODE::DEG90; break;
|
||||
default: settings->m_AngleSnapMode = LEADER_MODE::DIRECT; break;
|
||||
}
|
||||
}
|
||||
else
|
||||
Flip( frame()->GetViewerSettingsBase()->m_ViewersDisplay.m_Use45Limit );
|
||||
{
|
||||
LEADER_MODE& mode = frame()->GetViewerSettingsBase()->m_ViewersDisplay.m_AngleSnapMode;
|
||||
|
||||
switch( mode )
|
||||
{
|
||||
case LEADER_MODE::DIRECT: mode = LEADER_MODE::DEG45; break;
|
||||
case LEADER_MODE::DEG45: mode = LEADER_MODE::DEG90; break;
|
||||
default: mode = LEADER_MODE::DIRECT; break;
|
||||
}
|
||||
}
|
||||
|
||||
frame()->UpdateStatusBar();
|
||||
|
||||
@ -340,16 +368,22 @@ int PCB_VIEWER_TOOLS::MeasureTool( const TOOL_EVENT& aEvent )
|
||||
// move or drag when origin set updates rules
|
||||
else if( originSet && ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
|
||||
{
|
||||
bool force45Deg;
|
||||
auto snap = LEADER_MODE::DIRECT;
|
||||
|
||||
if( frame()->IsType( FRAME_PCB_EDITOR ) )
|
||||
force45Deg = GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" )->m_Use45DegreeLimit;
|
||||
{
|
||||
snap = GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" )->m_AngleSnapMode;
|
||||
}
|
||||
else if( frame()->IsType( FRAME_FOOTPRINT_EDITOR ) )
|
||||
force45Deg = GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( "fpedit" )->m_Use45Limit;
|
||||
{
|
||||
snap = GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( "fpedit" )->m_AngleSnapMode;
|
||||
}
|
||||
else
|
||||
force45Deg = frame()->GetViewerSettingsBase()->m_ViewersDisplay.m_Use45Limit;
|
||||
{
|
||||
snap = frame()->GetViewerSettingsBase()->m_ViewersDisplay.m_AngleSnapMode;
|
||||
}
|
||||
|
||||
twoPtMgr.SetAngleSnap( force45Deg );
|
||||
twoPtMgr.SetAngleSnap( snap );
|
||||
twoPtMgr.SetEnd( cursorPos );
|
||||
|
||||
view.SetVisible( &ruler, true );
|
||||
|
@ -348,14 +348,18 @@ int POSITION_RELATIVE_TOOL::PositionRelativeInteractively( const TOOL_EVENT& aEv
|
||||
// move or drag when origin set updates rules
|
||||
else if( originSet && ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
|
||||
{
|
||||
bool force45Deg;
|
||||
auto snap = LEADER_MODE::DIRECT;
|
||||
|
||||
if( frame()->IsType( FRAME_PCB_EDITOR ) )
|
||||
force45Deg = GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" )->m_Use45DegreeLimit;
|
||||
{
|
||||
snap = GetAppSettings<PCBNEW_SETTINGS>( "pcbnew" )->m_AngleSnapMode;
|
||||
}
|
||||
else
|
||||
force45Deg = GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( "fpedit" )->m_Use45Limit;
|
||||
{
|
||||
snap = GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>( "fpedit" )->m_AngleSnapMode;
|
||||
}
|
||||
|
||||
twoPtMgr.SetAngleSnap( force45Deg );
|
||||
twoPtMgr.SetAngleSnap( snap );
|
||||
twoPtMgr.SetEnd( cursorPos );
|
||||
|
||||
view.SetVisible( &ruler, true );
|
||||
|
@ -281,8 +281,9 @@ bool ZONE_CREATE_HELPER::OnFirstPoint( POLYGON_GEOM_MANAGER& aMgr )
|
||||
|
||||
m_parentView.SetVisible( &m_previewItem, true );
|
||||
|
||||
aMgr.SetLeaderMode( m_tool.Is45Limited() ? POLYGON_GEOM_MANAGER::LEADER_MODE::DEG45
|
||||
: POLYGON_GEOM_MANAGER::LEADER_MODE::DIRECT );
|
||||
LEADER_MODE mode = m_tool.GetAngleSnapMode();
|
||||
|
||||
aMgr.SetLeaderMode( mode );
|
||||
}
|
||||
}
|
||||
|
||||
@ -328,7 +329,7 @@ void ZONE_CREATE_HELPER::OnComplete( const POLYGON_GEOM_MANAGER& aMgr )
|
||||
|
||||
// In DEG45 mode, we may have intermediate points in the leader that should be included
|
||||
// as they are shown in the preview. These typically maintain the 45 constraint
|
||||
if( aMgr.GetLeaderMode() == POLYGON_GEOM_MANAGER::LEADER_MODE::DEG45 )
|
||||
if( aMgr.GetLeaderMode() == LEADER_MODE::DEG45 || aMgr.GetLeaderMode() == LEADER_MODE::DEG90 )
|
||||
{
|
||||
const SHAPE_LINE_CHAIN leaderPts = aMgr.GetLeaderLinePoints();
|
||||
|
||||
|
@ -60,7 +60,7 @@ public:
|
||||
ZONE* m_sourceZone;
|
||||
|
||||
///< Zone leader mode
|
||||
POLYGON_GEOM_MANAGER::LEADER_MODE m_leaderMode;
|
||||
LEADER_MODE m_leaderMode;
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user