Improve arc geometry manager to choose the direction which makes more sense
As long as the arc angle stays below <60°, it will automatically choose between clockwise and counter clockwise. This allows the user to choose the direction with a simple mouse movement.
This commit is contained in:
parent
0201cb4e7e
commit
7ba6a77c94
|
@ -47,6 +47,7 @@ Seth Hillbrand <hillbrand[at]ucdavis-dot-edu>
|
|||
Jeff Young <jeff[at]rokeby-dot-ie>
|
||||
Kevin Cozens <kevin[at]ve3syb-dot-ca>
|
||||
Ian McInerney <ian.s.mcinerney[at]ieee-dot-org>
|
||||
Thomas Pointhuber <thomas.pointhuber[at]gmx-dot-at>
|
||||
|
||||
See git repo on GitLab for contributors at
|
||||
https://gitlab.com/kicad/code/kicad/-/graphs/master
|
||||
|
|
|
@ -240,6 +240,7 @@ set( COMMON_PREVIEW_ITEMS_SRCS
|
|||
preview_items/ruler_item.cpp
|
||||
preview_items/selection_area.cpp
|
||||
preview_items/simple_overlay_item.cpp
|
||||
preview_items/two_point_assistant.cpp
|
||||
)
|
||||
|
||||
set( PLOTTERS_CONTROL_SRCS
|
||||
|
|
|
@ -56,6 +56,7 @@ bool ARC_GEOM_MANAGER::acceptPoint( const VECTOR2I& aPt )
|
|||
void ARC_GEOM_MANAGER::SetClockwise( bool aCw )
|
||||
{
|
||||
m_clockwise = aCw;
|
||||
m_directionLocked = true;
|
||||
setGeometryChanged();
|
||||
}
|
||||
|
||||
|
@ -63,6 +64,7 @@ void ARC_GEOM_MANAGER::SetClockwise( bool aCw )
|
|||
void ARC_GEOM_MANAGER::ToggleClockwise()
|
||||
{
|
||||
m_clockwise = !m_clockwise;
|
||||
m_directionLocked = true;
|
||||
setGeometryChanged();
|
||||
}
|
||||
|
||||
|
@ -159,6 +161,25 @@ bool ARC_GEOM_MANAGER::setEnd( const VECTOR2I& aCursor )
|
|||
while( m_endAngle < 0 )
|
||||
m_endAngle += M_PI * 2;
|
||||
|
||||
if( !m_directionLocked )
|
||||
{
|
||||
double ccwAngle = m_endAngle - m_startAngle;
|
||||
|
||||
if( m_endAngle <= m_startAngle )
|
||||
ccwAngle += 2 * M_PI;
|
||||
|
||||
double cwAngle = std::abs( ccwAngle - 2 * M_PI );
|
||||
|
||||
if( std::min( ccwAngle, cwAngle ) >= M_PI_2 )
|
||||
m_directionLocked = true;
|
||||
else
|
||||
m_clockwise = cwAngle < ccwAngle;
|
||||
}
|
||||
else if( std::abs( GetSubtended() ) < M_PI_2 )
|
||||
{
|
||||
m_directionLocked = false;
|
||||
}
|
||||
|
||||
// if the end is the same as the start, this is a bad point
|
||||
return m_endAngle != m_startAngle;
|
||||
}
|
||||
|
|
|
@ -125,6 +125,7 @@ void KIGFX::PREVIEW::DrawTextNextToCursor( KIGFX::VIEW* aView,
|
|||
textPos.x -= 15.0 / gal->GetWorldScale();
|
||||
}
|
||||
|
||||
gal->SetLineWidth( 1.0f ); // TODO(ISM): Set to the minimum GAL linewidth for HiDPI compatibility
|
||||
gal->SetStrokeColor( rs->GetLayerColor( LAYER_AUX_ITEMS ).WithAlpha(
|
||||
PreviewOverlayDeemphAlpha( true ) ) );
|
||||
gal->SetIsFill( false );
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020 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/two_point_assistant.h>
|
||||
|
||||
#include <preview_items/draw_context.h>
|
||||
#include <preview_items/preview_utils.h>
|
||||
|
||||
#include <view/view.h>
|
||||
|
||||
#include <common.h>
|
||||
#include <pcb_painter.h>
|
||||
|
||||
using namespace KIGFX::PREVIEW;
|
||||
|
||||
TWO_POINT_ASSISTANT::TWO_POINT_ASSISTANT(
|
||||
const TWO_POINT_GEOMETRY_MANAGER& aManager, EDA_UNITS aUnits, GEOM_SHAPE aShape )
|
||||
: EDA_ITEM( NOT_USED ), m_constructMan( aManager ), m_units( aUnits ), m_shape( aShape )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const BOX2I TWO_POINT_ASSISTANT::ViewBBox() const
|
||||
{
|
||||
BOX2I tmp;
|
||||
|
||||
// no bounding box when no graphic shown
|
||||
if( m_constructMan.IsReset() )
|
||||
return tmp;
|
||||
|
||||
// just enclose the whle circular area
|
||||
auto origin = m_constructMan.GetOrigin();
|
||||
auto end = m_constructMan.GetEnd();
|
||||
|
||||
if( m_shape == GEOM_SHAPE::SEGMENT || m_shape == GEOM_SHAPE::RECT )
|
||||
{
|
||||
tmp.SetOrigin( origin );
|
||||
tmp.SetEnd( end );
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp.SetOrigin( origin + end );
|
||||
tmp.SetEnd( origin - end );
|
||||
}
|
||||
|
||||
tmp.Normalize();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
void TWO_POINT_ASSISTANT::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
|
||||
{
|
||||
auto& gal = *aView->GetGAL();
|
||||
|
||||
// not in a position to draw anything
|
||||
if( m_constructMan.IsReset() )
|
||||
return;
|
||||
|
||||
const auto origin = m_constructMan.GetOrigin();
|
||||
const auto end = m_constructMan.GetEnd();
|
||||
const auto radVec = end - origin;
|
||||
|
||||
if( radVec.x == 0 && radVec.y == 0 )
|
||||
{
|
||||
return; // text next to cursor jumps alot around in this corner case
|
||||
}
|
||||
|
||||
gal.ResetTextAttributes();
|
||||
|
||||
// constant text size on screen
|
||||
SetConstantGlyphHeight( gal, 12.0 );
|
||||
|
||||
std::vector<wxString> cursorStrings;
|
||||
|
||||
if( m_shape == GEOM_SHAPE::SEGMENT )
|
||||
{
|
||||
cursorStrings.push_back( DimensionLabel( "l", radVec.EuclideanNorm(), m_units ) );
|
||||
}
|
||||
else if( m_shape == GEOM_SHAPE::RECT )
|
||||
{
|
||||
cursorStrings.push_back( DimensionLabel( "x", std::abs( radVec.x ), m_units ) );
|
||||
cursorStrings.push_back( DimensionLabel( "y", std::abs( radVec.y ), m_units ) );
|
||||
}
|
||||
else if( m_shape == GEOM_SHAPE::CIRCLE )
|
||||
{
|
||||
KIGFX::PREVIEW::DRAW_CONTEXT preview_ctx( *aView );
|
||||
preview_ctx.DrawLine( origin, end, false );
|
||||
|
||||
cursorStrings.push_back( DimensionLabel( "r", radVec.EuclideanNorm(), m_units ) );
|
||||
}
|
||||
|
||||
// place the text next to cursor, on opposite side from drawing
|
||||
DrawTextNextToCursor( aView, end, origin - end, cursorStrings );
|
||||
}
|
|
@ -27,47 +27,48 @@
|
|||
#include <base_struct.h>
|
||||
#include <preview_items/arc_geom_manager.h>
|
||||
|
||||
namespace KIGFX {
|
||||
namespace PREVIEW {
|
||||
/**
|
||||
* SELECTION_AREA
|
||||
*
|
||||
* Represents an assitant draw when interactively drawing an
|
||||
* arc on a canvas.
|
||||
*/
|
||||
class ARC_ASSISTANT : public EDA_ITEM
|
||||
namespace KIGFX
|
||||
{
|
||||
namespace PREVIEW
|
||||
{
|
||||
public:
|
||||
ARC_ASSISTANT( const ARC_GEOM_MANAGER& aManager, EDA_UNITS aUnits );
|
||||
|
||||
const BOX2I ViewBBox() const override;
|
||||
|
||||
/**
|
||||
* Draw the assistance (with reference to the contstruction manager
|
||||
* SELECTION_AREA
|
||||
*
|
||||
* Represents an assistant draw when interactively drawing an
|
||||
* arc on a canvas.
|
||||
*/
|
||||
void ViewDraw( int aLayer, KIGFX::VIEW* aView ) const override final;
|
||||
|
||||
#if defined(DEBUG)
|
||||
void Show( int x, std::ostream& st ) const override
|
||||
class ARC_ASSISTANT : public EDA_ITEM
|
||||
{
|
||||
}
|
||||
public:
|
||||
ARC_ASSISTANT( const ARC_GEOM_MANAGER& aManager, EDA_UNITS aUnits );
|
||||
|
||||
const BOX2I ViewBBox() const override;
|
||||
|
||||
/**
|
||||
* Draw the assistance (with reference to the contstruction manager
|
||||
*/
|
||||
void ViewDraw( int aLayer, KIGFX::VIEW* aView ) const override final;
|
||||
|
||||
#if defined( DEBUG )
|
||||
void Show( int x, std::ostream& st ) const override
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get class name
|
||||
* @return string "ARC_ASSISTANT"
|
||||
*/
|
||||
wxString GetClass() const override
|
||||
{
|
||||
return "ARC_ASSISTANT";
|
||||
}
|
||||
/**
|
||||
* Get class name
|
||||
* @return string "ARC_ASSISTANT"
|
||||
*/
|
||||
wxString GetClass() const override
|
||||
{
|
||||
return "ARC_ASSISTANT";
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
const ARC_GEOM_MANAGER& m_constructMan;
|
||||
EDA_UNITS m_units;
|
||||
};
|
||||
} // namespace PREVIEW
|
||||
} // namespace KIGFX
|
||||
|
||||
const ARC_GEOM_MANAGER& m_constructMan;
|
||||
EDA_UNITS m_units;
|
||||
};
|
||||
} // PREVIEW
|
||||
} // KIGFX
|
||||
|
||||
#endif // PREVIEW_ITEMS_ARC_ASSISTANT_H
|
||||
#endif // PREVIEW_ITEMS_ARC_ASSISTANT_H
|
||||
|
|
|
@ -136,6 +136,7 @@ private:
|
|||
* construction parameters
|
||||
*/
|
||||
bool m_angleSnap = false;
|
||||
bool m_directionLocked = false;
|
||||
};
|
||||
} // PREVIEW
|
||||
} // KIGFX
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020 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 PREVIEW_ITEMS_TWO_POINT_ASSISTANT_H
|
||||
#define PREVIEW_ITEMS_TWO_POINT_ASSISTANT_H
|
||||
|
||||
#include <base_struct.h>
|
||||
#include <preview_items/two_point_geom_manager.h>
|
||||
|
||||
namespace KIGFX
|
||||
{
|
||||
namespace PREVIEW
|
||||
{
|
||||
|
||||
// TODO: required until STROKE_T is either moved into commons or a better approach is found
|
||||
enum class GEOM_SHAPE
|
||||
{
|
||||
SEGMENT = 0,
|
||||
RECT,
|
||||
CIRCLE,
|
||||
};
|
||||
|
||||
/**
|
||||
* SELECTION_AREA
|
||||
*
|
||||
* Represents an assistant draw when interactively drawing an
|
||||
* line or circle on a canvas.
|
||||
*/
|
||||
class TWO_POINT_ASSISTANT : public EDA_ITEM
|
||||
{
|
||||
public:
|
||||
TWO_POINT_ASSISTANT(
|
||||
const TWO_POINT_GEOMETRY_MANAGER& aManager, EDA_UNITS aUnits, GEOM_SHAPE aShape );
|
||||
|
||||
const BOX2I ViewBBox() const override;
|
||||
|
||||
/**
|
||||
* Draw the assistance (with reference to the contstruction manager
|
||||
*/
|
||||
void ViewDraw( int aLayer, KIGFX::VIEW* aView ) const override final;
|
||||
|
||||
#if defined( DEBUG )
|
||||
void Show( int x, std::ostream& st ) const override
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get class name
|
||||
* @return string "TWO_POINT_ASSISTANT"
|
||||
*/
|
||||
wxString GetClass() const override
|
||||
{
|
||||
return "TWO_POINT_ASSISTANT";
|
||||
}
|
||||
|
||||
private:
|
||||
const TWO_POINT_GEOMETRY_MANAGER& m_constructMan;
|
||||
EDA_UNITS m_units;
|
||||
GEOM_SHAPE m_shape;
|
||||
};
|
||||
} // namespace PREVIEW
|
||||
} // namespace KIGFX
|
||||
|
||||
#endif // PREVIEW_ITEMS_TWO_POINT_ASSISTANT_H
|
|
@ -48,6 +48,8 @@ public:
|
|||
void SetOrigin( const VECTOR2I& aOrigin )
|
||||
{
|
||||
m_origin = aOrigin;
|
||||
m_originSet = true;
|
||||
setGeometryChanged();
|
||||
}
|
||||
|
||||
VECTOR2I GetOrigin() const
|
||||
|
@ -69,6 +71,7 @@ public:
|
|||
{
|
||||
m_end = aEnd;
|
||||
}
|
||||
setGeometryChanged();
|
||||
}
|
||||
|
||||
VECTOR2I GetEnd() const
|
||||
|
@ -81,10 +84,61 @@ public:
|
|||
m_angleSnap = aSnap;
|
||||
}
|
||||
|
||||
bool GetAngleSnap() const
|
||||
{
|
||||
return m_angleSnap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the manager is in the initial state
|
||||
*/
|
||||
bool IsReset() const
|
||||
{
|
||||
return !m_originSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the manager to the initial state
|
||||
*/
|
||||
void Reset()
|
||||
{
|
||||
m_originSet = false;
|
||||
setGeometryChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the geoemtry has changed, eg such that a client
|
||||
* should redraw
|
||||
*/
|
||||
bool HasGeometryChanged() const
|
||||
{
|
||||
return m_changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the geometry changed flag, call after the client code has
|
||||
* updated everything as needed.
|
||||
*/
|
||||
void ClearGeometryChanged()
|
||||
{
|
||||
m_changed = false;
|
||||
}
|
||||
|
||||
protected:
|
||||
///> Mark the geometry as changed for clients to notice
|
||||
void setGeometryChanged()
|
||||
{
|
||||
m_changed = true;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
VECTOR2I m_origin, m_end;
|
||||
bool m_angleSnap = false;
|
||||
|
||||
///> Has the gemotry changed such that a client should redraw?
|
||||
bool m_changed = false;
|
||||
bool m_originSet = false;
|
||||
};
|
||||
|
||||
} // PREVIEW
|
||||
|
|
|
@ -47,12 +47,14 @@
|
|||
#include <class_zone.h>
|
||||
#include <class_module.h>
|
||||
|
||||
#include <preview_items/two_point_assistant.h>
|
||||
#include <preview_items/two_point_geom_manager.h>
|
||||
#include <ratsnest/ratsnest_data.h>
|
||||
#include <tools/grid_helper.h>
|
||||
#include <tools/point_editor.h>
|
||||
#include <tools/selection_tool.h>
|
||||
#include <tools/tool_event_utils.h>
|
||||
#include <tools/zone_create_helper.h>
|
||||
#include <tools/point_editor.h>
|
||||
#include <tools/grid_helper.h>
|
||||
#include <ratsnest/ratsnest_data.h>
|
||||
|
||||
using SCOPED_DRAW_MODE = SCOPED_SET_RESET<DRAWING_TOOL::MODE>;
|
||||
|
||||
|
@ -951,6 +953,22 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update an DRAWSEGMENT from the current state
|
||||
* of an Two POINT Geometry Manager
|
||||
*/
|
||||
static void updateSegmentFromConstructionMgr(
|
||||
const KIGFX::PREVIEW::TWO_POINT_GEOMETRY_MANAGER& aMgr, DRAWSEGMENT* aGraphic )
|
||||
{
|
||||
auto vec = aMgr.GetOrigin();
|
||||
|
||||
aGraphic->SetStart( { vec.x, vec.y } );
|
||||
|
||||
vec = aMgr.GetEnd();
|
||||
aGraphic->SetEnd( { vec.x, vec.y } );
|
||||
}
|
||||
|
||||
|
||||
bool DRAWING_TOOL::drawSegment( const std::string& aTool, int aShape, DRAWSEGMENT** aGraphic,
|
||||
OPT<VECTOR2D> aStartingPoint )
|
||||
{
|
||||
|
@ -962,9 +980,22 @@ bool DRAWING_TOOL::drawSegment( const std::string& aTool, int aShape, DRAWSEGMEN
|
|||
|
||||
m_lineWidth = getSegmentWidth( m_frame->GetActiveLayer() );
|
||||
|
||||
// geometric construction manager
|
||||
KIGFX::PREVIEW::TWO_POINT_GEOMETRY_MANAGER twoPointManager;
|
||||
|
||||
// drawing assistant overlay
|
||||
// TODO: workaround because STROKE_T is not visible from commons.
|
||||
KIGFX::PREVIEW::GEOM_SHAPE geomShape =
|
||||
( aShape == S_SEGMENT ) ? KIGFX::PREVIEW::GEOM_SHAPE::SEGMENT :
|
||||
( aShape == S_CIRCLE ) ? KIGFX::PREVIEW::GEOM_SHAPE::CIRCLE :
|
||||
KIGFX::PREVIEW::GEOM_SHAPE::RECT;
|
||||
KIGFX::PREVIEW::TWO_POINT_ASSISTANT twoPointAsst(
|
||||
twoPointManager, m_frame->GetUserUnits(), geomShape );
|
||||
|
||||
// Add a VIEW_GROUP that serves as a preview for the new item
|
||||
PCBNEW_SELECTION preview;
|
||||
m_view->Add( &preview );
|
||||
m_view->Add( &twoPointAsst );
|
||||
|
||||
m_controls->ShowCursor( true );
|
||||
|
||||
|
@ -1004,19 +1035,24 @@ bool DRAWING_TOOL::drawSegment( const std::string& aTool, int aShape, DRAWSEGMEN
|
|||
|
||||
if( direction45 )
|
||||
{
|
||||
const VECTOR2I lineVector( cursorPos - VECTOR2I( graphic->GetStart() ) );
|
||||
const VECTOR2I lineVector( cursorPos - VECTOR2I( twoPointManager.GetOrigin() ) );
|
||||
|
||||
// get a restricted 45/H/V line from the last fixed point to the cursor
|
||||
auto newEnd = GetVectorSnapped45( lineVector );
|
||||
graphic->SetEnd( graphic->GetStart() + (wxPoint) newEnd );
|
||||
m_controls->ForceCursorPosition( true, VECTOR2I( graphic->GetEnd() ) );
|
||||
m_controls->ForceCursorPosition( true, VECTOR2I( twoPointManager.GetEnd() ) );
|
||||
twoPointManager.SetEnd( twoPointManager.GetOrigin() + (wxPoint) newEnd );
|
||||
twoPointManager.SetAngleSnap( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
graphic->SetEnd( (wxPoint) cursorPos );
|
||||
twoPointManager.SetEnd( (wxPoint) cursorPos );
|
||||
twoPointManager.SetAngleSnap( false );
|
||||
}
|
||||
|
||||
updateSegmentFromConstructionMgr( twoPointManager, graphic );
|
||||
m_view->Update( &preview );
|
||||
m_view->Update( &twoPointAsst );
|
||||
|
||||
frame()->SetMsgPanel( graphic );
|
||||
}
|
||||
|
||||
|
@ -1092,11 +1128,12 @@ bool DRAWING_TOOL::drawSegment( const std::string& aTool, int aShape, DRAWSEGMEN
|
|||
// Init the new item attributes
|
||||
graphic->SetShape( (STROKE_T) aShape );
|
||||
graphic->SetWidth( m_lineWidth );
|
||||
graphic->SetStart( (wxPoint) cursorPos );
|
||||
graphic->SetEnd( (wxPoint) cursorPos );
|
||||
graphic->SetLayer( m_frame->GetActiveLayer() );
|
||||
grid.SetSkipPoint( cursorPos );
|
||||
|
||||
twoPointManager.SetOrigin( (wxPoint) cursorPos );
|
||||
twoPointManager.SetEnd( (wxPoint) cursorPos );
|
||||
|
||||
if( !isLocalOriginSet )
|
||||
m_frame->GetScreen()->m_LocalOrigin = cursorPos;
|
||||
|
||||
|
@ -1105,15 +1142,16 @@ bool DRAWING_TOOL::drawSegment( const std::string& aTool, int aShape, DRAWSEGMEN
|
|||
m_controls->SetAutoPan( true );
|
||||
m_controls->CaptureCursor( true );
|
||||
|
||||
updateSegmentFromConstructionMgr( twoPointManager, graphic );
|
||||
|
||||
started = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto snapItem = dyn_cast<DRAWSEGMENT*>( grid.GetSnapped() );
|
||||
|
||||
if( graphic->GetEnd() == graphic->GetStart()
|
||||
|| ( evt->IsDblClick( BUT_LEFT ) && aShape == S_SEGMENT )
|
||||
|| snapItem )
|
||||
if( twoPointManager.GetOrigin() == twoPointManager.GetEnd()
|
||||
|| ( evt->IsDblClick( BUT_LEFT ) && aShape == S_SEGMENT ) || snapItem )
|
||||
// User has clicked twice in the same spot
|
||||
// or clicked on the end of an existing segment (closing a path)
|
||||
{
|
||||
|
@ -1138,23 +1176,31 @@ bool DRAWING_TOOL::drawSegment( const std::string& aTool, int aShape, DRAWSEGMEN
|
|||
preview.Clear();
|
||||
break;
|
||||
}
|
||||
|
||||
twoPointManager.SetEnd( cursorPos );
|
||||
}
|
||||
else if( evt->IsMotion() )
|
||||
{
|
||||
// 45 degree lines
|
||||
if( direction45 && aShape == S_SEGMENT )
|
||||
{
|
||||
const VECTOR2I lineVector( cursorPos - VECTOR2I( graphic->GetStart() ) );
|
||||
const VECTOR2I lineVector( cursorPos - VECTOR2I( twoPointManager.GetOrigin() ) );
|
||||
|
||||
// get a restricted 45/H/V line from the last fixed point to the cursor
|
||||
auto newEnd = GetVectorSnapped45( lineVector );
|
||||
graphic->SetEnd( graphic->GetStart() + (wxPoint) newEnd );
|
||||
m_controls->ForceCursorPosition( true, VECTOR2I( graphic->GetEnd() ) );
|
||||
m_controls->ForceCursorPosition( true, VECTOR2I( twoPointManager.GetEnd() ) );
|
||||
twoPointManager.SetEnd( twoPointManager.GetOrigin() + (wxPoint) newEnd );
|
||||
twoPointManager.SetAngleSnap( true );
|
||||
}
|
||||
else
|
||||
graphic->SetEnd( (wxPoint) cursorPos );
|
||||
{
|
||||
twoPointManager.SetEnd( (wxPoint) cursorPos );
|
||||
twoPointManager.SetAngleSnap( false );
|
||||
}
|
||||
|
||||
updateSegmentFromConstructionMgr( twoPointManager, graphic );
|
||||
m_view->Update( &preview );
|
||||
m_view->Update( &twoPointAsst );
|
||||
|
||||
if( started )
|
||||
frame()->SetMsgPanel( graphic );
|
||||
|
@ -1186,6 +1232,7 @@ bool DRAWING_TOOL::drawSegment( const std::string& aTool, int aShape, DRAWSEGMEN
|
|||
if( !isLocalOriginSet ) // reset the relative coordinte if it was not set before
|
||||
m_frame->GetScreen()->m_LocalOrigin = VECTOR2D( 0, 0 );
|
||||
|
||||
m_view->Remove( &twoPointAsst );
|
||||
m_view->Remove( &preview );
|
||||
frame()->SetMsgPanel( board() );
|
||||
m_controls->SetAutoPan( false );
|
||||
|
|
Loading…
Reference in New Issue