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>
|
Jeff Young <jeff[at]rokeby-dot-ie>
|
||||||
Kevin Cozens <kevin[at]ve3syb-dot-ca>
|
Kevin Cozens <kevin[at]ve3syb-dot-ca>
|
||||||
Ian McInerney <ian.s.mcinerney[at]ieee-dot-org>
|
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
|
See git repo on GitLab for contributors at
|
||||||
https://gitlab.com/kicad/code/kicad/-/graphs/master
|
https://gitlab.com/kicad/code/kicad/-/graphs/master
|
||||||
|
|
|
@ -240,6 +240,7 @@ set( COMMON_PREVIEW_ITEMS_SRCS
|
||||||
preview_items/ruler_item.cpp
|
preview_items/ruler_item.cpp
|
||||||
preview_items/selection_area.cpp
|
preview_items/selection_area.cpp
|
||||||
preview_items/simple_overlay_item.cpp
|
preview_items/simple_overlay_item.cpp
|
||||||
|
preview_items/two_point_assistant.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set( PLOTTERS_CONTROL_SRCS
|
set( PLOTTERS_CONTROL_SRCS
|
||||||
|
|
|
@ -56,6 +56,7 @@ bool ARC_GEOM_MANAGER::acceptPoint( const VECTOR2I& aPt )
|
||||||
void ARC_GEOM_MANAGER::SetClockwise( bool aCw )
|
void ARC_GEOM_MANAGER::SetClockwise( bool aCw )
|
||||||
{
|
{
|
||||||
m_clockwise = aCw;
|
m_clockwise = aCw;
|
||||||
|
m_directionLocked = true;
|
||||||
setGeometryChanged();
|
setGeometryChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +64,7 @@ void ARC_GEOM_MANAGER::SetClockwise( bool aCw )
|
||||||
void ARC_GEOM_MANAGER::ToggleClockwise()
|
void ARC_GEOM_MANAGER::ToggleClockwise()
|
||||||
{
|
{
|
||||||
m_clockwise = !m_clockwise;
|
m_clockwise = !m_clockwise;
|
||||||
|
m_directionLocked = true;
|
||||||
setGeometryChanged();
|
setGeometryChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,6 +161,25 @@ bool ARC_GEOM_MANAGER::setEnd( const VECTOR2I& aCursor )
|
||||||
while( m_endAngle < 0 )
|
while( m_endAngle < 0 )
|
||||||
m_endAngle += M_PI * 2;
|
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
|
// if the end is the same as the start, this is a bad point
|
||||||
return m_endAngle != m_startAngle;
|
return m_endAngle != m_startAngle;
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,6 +125,7 @@ void KIGFX::PREVIEW::DrawTextNextToCursor( KIGFX::VIEW* aView,
|
||||||
textPos.x -= 15.0 / gal->GetWorldScale();
|
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(
|
gal->SetStrokeColor( rs->GetLayerColor( LAYER_AUX_ITEMS ).WithAlpha(
|
||||||
PreviewOverlayDeemphAlpha( true ) ) );
|
PreviewOverlayDeemphAlpha( true ) ) );
|
||||||
gal->SetIsFill( false );
|
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 <base_struct.h>
|
||||||
#include <preview_items/arc_geom_manager.h>
|
#include <preview_items/arc_geom_manager.h>
|
||||||
|
|
||||||
namespace KIGFX {
|
namespace KIGFX
|
||||||
namespace PREVIEW {
|
{
|
||||||
/**
|
namespace PREVIEW
|
||||||
* SELECTION_AREA
|
|
||||||
*
|
|
||||||
* Represents an assitant draw when interactively drawing an
|
|
||||||
* arc on a canvas.
|
|
||||||
*/
|
|
||||||
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
|
* SELECTION_AREA
|
||||||
|
*
|
||||||
|
* Represents an assistant draw when interactively drawing an
|
||||||
|
* arc on a canvas.
|
||||||
*/
|
*/
|
||||||
void ViewDraw( int aLayer, KIGFX::VIEW* aView ) const override final;
|
class ARC_ASSISTANT : public EDA_ITEM
|
||||||
|
|
||||||
#if defined(DEBUG)
|
|
||||||
void Show( int x, std::ostream& st ) const override
|
|
||||||
{
|
{
|
||||||
}
|
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
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get class name
|
* Get class name
|
||||||
* @return string "ARC_ASSISTANT"
|
* @return string "ARC_ASSISTANT"
|
||||||
*/
|
*/
|
||||||
wxString GetClass() const override
|
wxString GetClass() const override
|
||||||
{
|
{
|
||||||
return "ARC_ASSISTANT";
|
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;
|
#endif // PREVIEW_ITEMS_ARC_ASSISTANT_H
|
||||||
EDA_UNITS m_units;
|
|
||||||
};
|
|
||||||
} // PREVIEW
|
|
||||||
} // KIGFX
|
|
||||||
|
|
||||||
#endif // PREVIEW_ITEMS_ARC_ASSISTANT_H
|
|
||||||
|
|
|
@ -136,6 +136,7 @@ private:
|
||||||
* construction parameters
|
* construction parameters
|
||||||
*/
|
*/
|
||||||
bool m_angleSnap = false;
|
bool m_angleSnap = false;
|
||||||
|
bool m_directionLocked = false;
|
||||||
};
|
};
|
||||||
} // PREVIEW
|
} // PREVIEW
|
||||||
} // KIGFX
|
} // 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 )
|
void SetOrigin( const VECTOR2I& aOrigin )
|
||||||
{
|
{
|
||||||
m_origin = aOrigin;
|
m_origin = aOrigin;
|
||||||
|
m_originSet = true;
|
||||||
|
setGeometryChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
VECTOR2I GetOrigin() const
|
VECTOR2I GetOrigin() const
|
||||||
|
@ -69,6 +71,7 @@ public:
|
||||||
{
|
{
|
||||||
m_end = aEnd;
|
m_end = aEnd;
|
||||||
}
|
}
|
||||||
|
setGeometryChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
VECTOR2I GetEnd() const
|
VECTOR2I GetEnd() const
|
||||||
|
@ -81,10 +84,61 @@ public:
|
||||||
m_angleSnap = aSnap;
|
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:
|
private:
|
||||||
|
|
||||||
VECTOR2I m_origin, m_end;
|
VECTOR2I m_origin, m_end;
|
||||||
bool m_angleSnap = false;
|
bool m_angleSnap = false;
|
||||||
|
|
||||||
|
///> Has the gemotry changed such that a client should redraw?
|
||||||
|
bool m_changed = false;
|
||||||
|
bool m_originSet = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // PREVIEW
|
} // PREVIEW
|
||||||
|
|
|
@ -47,12 +47,14 @@
|
||||||
#include <class_zone.h>
|
#include <class_zone.h>
|
||||||
#include <class_module.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/selection_tool.h>
|
||||||
#include <tools/tool_event_utils.h>
|
#include <tools/tool_event_utils.h>
|
||||||
#include <tools/zone_create_helper.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>;
|
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,
|
bool DRAWING_TOOL::drawSegment( const std::string& aTool, int aShape, DRAWSEGMENT** aGraphic,
|
||||||
OPT<VECTOR2D> aStartingPoint )
|
OPT<VECTOR2D> aStartingPoint )
|
||||||
{
|
{
|
||||||
|
@ -962,9 +980,22 @@ bool DRAWING_TOOL::drawSegment( const std::string& aTool, int aShape, DRAWSEGMEN
|
||||||
|
|
||||||
m_lineWidth = getSegmentWidth( m_frame->GetActiveLayer() );
|
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
|
// Add a VIEW_GROUP that serves as a preview for the new item
|
||||||
PCBNEW_SELECTION preview;
|
PCBNEW_SELECTION preview;
|
||||||
m_view->Add( &preview );
|
m_view->Add( &preview );
|
||||||
|
m_view->Add( &twoPointAsst );
|
||||||
|
|
||||||
m_controls->ShowCursor( true );
|
m_controls->ShowCursor( true );
|
||||||
|
|
||||||
|
@ -1004,19 +1035,24 @@ bool DRAWING_TOOL::drawSegment( const std::string& aTool, int aShape, DRAWSEGMEN
|
||||||
|
|
||||||
if( direction45 )
|
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
|
// get a restricted 45/H/V line from the last fixed point to the cursor
|
||||||
auto newEnd = GetVectorSnapped45( lineVector );
|
auto newEnd = GetVectorSnapped45( lineVector );
|
||||||
graphic->SetEnd( graphic->GetStart() + (wxPoint) newEnd );
|
m_controls->ForceCursorPosition( true, VECTOR2I( twoPointManager.GetEnd() ) );
|
||||||
m_controls->ForceCursorPosition( true, VECTOR2I( graphic->GetEnd() ) );
|
twoPointManager.SetEnd( twoPointManager.GetOrigin() + (wxPoint) newEnd );
|
||||||
|
twoPointManager.SetAngleSnap( true );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
graphic->SetEnd( (wxPoint) cursorPos );
|
twoPointManager.SetEnd( (wxPoint) cursorPos );
|
||||||
|
twoPointManager.SetAngleSnap( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateSegmentFromConstructionMgr( twoPointManager, graphic );
|
||||||
m_view->Update( &preview );
|
m_view->Update( &preview );
|
||||||
|
m_view->Update( &twoPointAsst );
|
||||||
|
|
||||||
frame()->SetMsgPanel( graphic );
|
frame()->SetMsgPanel( graphic );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1092,11 +1128,12 @@ bool DRAWING_TOOL::drawSegment( const std::string& aTool, int aShape, DRAWSEGMEN
|
||||||
// Init the new item attributes
|
// Init the new item attributes
|
||||||
graphic->SetShape( (STROKE_T) aShape );
|
graphic->SetShape( (STROKE_T) aShape );
|
||||||
graphic->SetWidth( m_lineWidth );
|
graphic->SetWidth( m_lineWidth );
|
||||||
graphic->SetStart( (wxPoint) cursorPos );
|
|
||||||
graphic->SetEnd( (wxPoint) cursorPos );
|
|
||||||
graphic->SetLayer( m_frame->GetActiveLayer() );
|
graphic->SetLayer( m_frame->GetActiveLayer() );
|
||||||
grid.SetSkipPoint( cursorPos );
|
grid.SetSkipPoint( cursorPos );
|
||||||
|
|
||||||
|
twoPointManager.SetOrigin( (wxPoint) cursorPos );
|
||||||
|
twoPointManager.SetEnd( (wxPoint) cursorPos );
|
||||||
|
|
||||||
if( !isLocalOriginSet )
|
if( !isLocalOriginSet )
|
||||||
m_frame->GetScreen()->m_LocalOrigin = cursorPos;
|
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->SetAutoPan( true );
|
||||||
m_controls->CaptureCursor( true );
|
m_controls->CaptureCursor( true );
|
||||||
|
|
||||||
|
updateSegmentFromConstructionMgr( twoPointManager, graphic );
|
||||||
|
|
||||||
started = true;
|
started = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto snapItem = dyn_cast<DRAWSEGMENT*>( grid.GetSnapped() );
|
auto snapItem = dyn_cast<DRAWSEGMENT*>( grid.GetSnapped() );
|
||||||
|
|
||||||
if( graphic->GetEnd() == graphic->GetStart()
|
if( twoPointManager.GetOrigin() == twoPointManager.GetEnd()
|
||||||
|| ( evt->IsDblClick( BUT_LEFT ) && aShape == S_SEGMENT )
|
|| ( evt->IsDblClick( BUT_LEFT ) && aShape == S_SEGMENT ) || snapItem )
|
||||||
|| snapItem )
|
|
||||||
// User has clicked twice in the same spot
|
// User has clicked twice in the same spot
|
||||||
// or clicked on the end of an existing segment (closing a path)
|
// 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();
|
preview.Clear();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
twoPointManager.SetEnd( cursorPos );
|
||||||
}
|
}
|
||||||
else if( evt->IsMotion() )
|
else if( evt->IsMotion() )
|
||||||
{
|
{
|
||||||
// 45 degree lines
|
// 45 degree lines
|
||||||
if( direction45 && aShape == S_SEGMENT )
|
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
|
// get a restricted 45/H/V line from the last fixed point to the cursor
|
||||||
auto newEnd = GetVectorSnapped45( lineVector );
|
auto newEnd = GetVectorSnapped45( lineVector );
|
||||||
graphic->SetEnd( graphic->GetStart() + (wxPoint) newEnd );
|
m_controls->ForceCursorPosition( true, VECTOR2I( twoPointManager.GetEnd() ) );
|
||||||
m_controls->ForceCursorPosition( true, VECTOR2I( graphic->GetEnd() ) );
|
twoPointManager.SetEnd( twoPointManager.GetOrigin() + (wxPoint) newEnd );
|
||||||
|
twoPointManager.SetAngleSnap( true );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
graphic->SetEnd( (wxPoint) cursorPos );
|
{
|
||||||
|
twoPointManager.SetEnd( (wxPoint) cursorPos );
|
||||||
|
twoPointManager.SetAngleSnap( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSegmentFromConstructionMgr( twoPointManager, graphic );
|
||||||
m_view->Update( &preview );
|
m_view->Update( &preview );
|
||||||
|
m_view->Update( &twoPointAsst );
|
||||||
|
|
||||||
if( started )
|
if( started )
|
||||||
frame()->SetMsgPanel( graphic );
|
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
|
if( !isLocalOriginSet ) // reset the relative coordinte if it was not set before
|
||||||
m_frame->GetScreen()->m_LocalOrigin = VECTOR2D( 0, 0 );
|
m_frame->GetScreen()->m_LocalOrigin = VECTOR2D( 0, 0 );
|
||||||
|
|
||||||
|
m_view->Remove( &twoPointAsst );
|
||||||
m_view->Remove( &preview );
|
m_view->Remove( &preview );
|
||||||
frame()->SetMsgPanel( board() );
|
frame()->SetMsgPanel( board() );
|
||||||
m_controls->SetAutoPan( false );
|
m_controls->SetAutoPan( false );
|
||||||
|
|
Loading…
Reference in New Issue