Add a ruler tool to pcbnew GAL
This allows to measure between features on a PCB. It uses a preview EDA_ITEM in common, but due to the use of the IDs, it's currently Pcbnew/Modedit only. This also adds several "utils" for graphical functons useful when drawing preview items on GAL canvases. Fixes: lp:1467313 * https://bugs.launchpad.net/kicad/+bug/1467313
This commit is contained in:
parent
9c08873210
commit
8c3b8ee693
|
@ -339,6 +339,7 @@ set( BMAPS_MID
|
|||
load_module_lib
|
||||
local_ratsnest
|
||||
locked
|
||||
measurement
|
||||
mirepcb
|
||||
mirror_h
|
||||
mirror_v
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
/* Do not modify this file, it was automatically generated by the
|
||||
* PNG2cpp CMake script, using a *.png file as input.
|
||||
*/
|
||||
|
||||
#include <bitmaps.h>
|
||||
|
||||
static const unsigned char png[] = {
|
||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
|
||||
0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1a, 0x08, 0x04, 0x00, 0x00, 0x00, 0x03, 0x43, 0x84,
|
||||
0x45, 0x00, 0x00, 0x00, 0x76, 0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, 0x63, 0x60, 0x18, 0x2a, 0x20,
|
||||
0x35, 0x01, 0x3b, 0x1b, 0x2f, 0x48, 0xfb, 0x92, 0xaa, 0x0d, 0xd5, 0xa2, 0x9d, 0xf6, 0x85, 0x58,
|
||||
0x4d, 0xff, 0xd3, 0xae, 0xc6, 0x72, 0x33, 0x30, 0xc4, 0x72, 0xa7, 0x5d, 0x4d, 0xfb, 0x4f, 0xbc,
|
||||
0xa6, 0xff, 0xe9, 0xf3, 0x19, 0x18, 0xd2, 0xe7, 0x83, 0x58, 0x24, 0x68, 0x02, 0x29, 0x86, 0xd1,
|
||||
0x78, 0x81, 0xdd, 0x25, 0xe3, 0xff, 0xa4, 0x41, 0xa0, 0x26, 0xe3, 0xff, 0x17, 0x49, 0x84, 0x50,
|
||||
0x4d, 0xc8, 0x1a, 0x09, 0xb3, 0x51, 0x34, 0x11, 0x4b, 0x92, 0xab, 0xc9, 0xf6, 0x1a, 0x19, 0x01,
|
||||
0x81, 0x3d, 0x90, 0x09, 0x06, 0xfc, 0x70, 0xd4, 0x94, 0x5e, 0x8e, 0x43, 0x53, 0x3d, 0xde, 0xf4,
|
||||
0x07, 0xd2, 0x86, 0xa1, 0xa9, 0x9e, 0x61, 0x14, 0xe0, 0x07, 0x00, 0x55, 0x88, 0x33, 0x29, 0x9a,
|
||||
0xe8, 0x0b, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
|
||||
};
|
||||
|
||||
const BITMAP_OPAQUE measurement_xpm[1] = {{ png, sizeof( png ), "measurement_xpm" }};
|
||||
|
||||
//EOF
|
|
@ -0,0 +1,140 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
height="26"
|
||||
width="26"
|
||||
version="1.1"
|
||||
id="svg2"
|
||||
inkscape:version="0.92.1 r"
|
||||
sodipodi:docname="measurement.svg">
|
||||
<metadata
|
||||
id="metadata50">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1146"
|
||||
inkscape:window-height="964"
|
||||
id="namedview48"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="18.568355"
|
||||
inkscape:cy="20.983557"
|
||||
inkscape:window-x="768"
|
||||
inkscape:window-y="96"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg2"
|
||||
inkscape:snap-to-guides="false"
|
||||
inkscape:snap-grids="true"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:measure-start="5,19"
|
||||
inkscape:measure-end="14,12">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid3006"
|
||||
empspacing="5"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs4" />
|
||||
<path
|
||||
style="fill:#666666;fill-rule:evenodd"
|
||||
d="m 2,10 v 9 l 2,2 H 5 V 10 H 4"
|
||||
id="path9597"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path9599"
|
||||
d="m 15,10 v 9 l -2,2 H 12 V 10 h 1"
|
||||
style="fill:#666666;fill-rule:evenodd" />
|
||||
<path
|
||||
style="fill:#666666;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 8,9 H 5 V 3 l 3,4 z"
|
||||
id="path9621"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path9623"
|
||||
d="m 9,9 h 3 V 3 L 9,7 Z"
|
||||
style="fill:#666666;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
style="opacity:1;fill:#d1d1d1;fill-opacity:1;stroke:none;stroke-width:1"
|
||||
d="M 1.4999999,8.5 H 26 v 5 H 1.4999999 Z"
|
||||
id="rect9595"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#333333;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 21.5,10 v 3"
|
||||
id="path9601"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path9603"
|
||||
d="m 18.5,11 v 2"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#333333;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path9605"
|
||||
d="m 15.5,10 v 3"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#333333;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#333333;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 12.5,11 v 2"
|
||||
id="path9607"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path9609"
|
||||
d="m 9.5,10 v 3"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#333333;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#333333;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 6.5,11 v 2"
|
||||
id="path9611"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#333333;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 3.5,10 v 3"
|
||||
id="path9613"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#333333;stroke-width:1"
|
||||
d="M 26,13.5 H 1.7613635 c -0.1447954,0 -0.2613636,-0.1115 -0.2613636,-0.25 v -4.5 c 0,-0.1385 0.1165682,-0.25 0.2613636,-0.25 H 26"
|
||||
id="rect9617"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cssssc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#333333;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 24.5,11 v 2"
|
||||
id="path9625"
|
||||
inkscape:connector-curvature="0" />
|
||||
</svg>
|
After Width: | Height: | Size: 5.1 KiB |
|
@ -184,6 +184,8 @@ set( COMMON_PAGE_LAYOUT_SRCS
|
|||
)
|
||||
|
||||
set( COMMON_PREVIEW_ITEMS_SRCS
|
||||
preview_items/preview_utils.cpp
|
||||
preview_items/ruler_item.cpp
|
||||
preview_items/simple_overlay_item.cpp
|
||||
preview_items/selection_area.cpp
|
||||
)
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <preview_items/preview_utils.h>
|
||||
|
||||
#include <gal/graphics_abstraction_layer.h>
|
||||
|
||||
#include <base_units.h>
|
||||
|
||||
using namespace KIGFX;
|
||||
|
||||
|
||||
COLOR4D KIGFX::PREVIEW::PreviewOverlayDefaultColor()
|
||||
{
|
||||
return COLOR4D( 1.0, 1.0, 1.0, 1.0 );
|
||||
}
|
||||
|
||||
|
||||
double KIGFX::PREVIEW::PreviewOverlayFillAlpha()
|
||||
{
|
||||
return 0.2;
|
||||
}
|
||||
|
||||
|
||||
double KIGFX::PREVIEW::PreviewOverlayDeemphAlpha( bool aDeemph )
|
||||
{
|
||||
return aDeemph ? 0.5 : 1.0;
|
||||
}
|
||||
|
||||
|
||||
COLOR4D KIGFX::PREVIEW::PreviewOverlaySpecialAngleColor()
|
||||
{
|
||||
return COLOR4D( 0.5, 1.0, 0.5, 1.0 );
|
||||
}
|
||||
|
||||
|
||||
static wxString getDimensionUnit( EDA_UNITS_T aUnits )
|
||||
{
|
||||
switch( aUnits )
|
||||
{
|
||||
case INCHES:
|
||||
return _( "\"" );
|
||||
|
||||
case MILLIMETRES:
|
||||
return _( "mm" );
|
||||
|
||||
case DEGREES:
|
||||
return _( "°" );
|
||||
|
||||
case UNSCALED_UNITS:
|
||||
break;
|
||||
// no default: handle all cases
|
||||
}
|
||||
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
|
||||
static wxString formatPreviewDimension( double aVal, EDA_UNITS_T aUnits )
|
||||
{
|
||||
int precision = 4;
|
||||
|
||||
// show a sane precision for the preview, which doesn't need to
|
||||
// be accurate down to the nanometre
|
||||
switch( aUnits )
|
||||
{
|
||||
case MILLIMETRES:
|
||||
precision = 2; // 10um
|
||||
break;
|
||||
case INCHES:
|
||||
precision = 4; // 1mil
|
||||
break;
|
||||
case DEGREES:
|
||||
precision = 1; // 0.1deg (limit of formats anyway)
|
||||
break;
|
||||
case UNSCALED_UNITS:
|
||||
break;
|
||||
}
|
||||
|
||||
const wxString fmtStr = wxString::Format( "%%.%df", precision );
|
||||
|
||||
wxString str = wxString::Format( fmtStr, To_User_Unit( aUnits, aVal ) );
|
||||
|
||||
const wxString symbol = getDimensionUnit( aUnits );
|
||||
|
||||
if( symbol.size() )
|
||||
str << " " << symbol;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
wxString KIGFX::PREVIEW::DimensionLabel( const wxString& prefix,
|
||||
double aVal, EDA_UNITS_T aUnits )
|
||||
{
|
||||
wxString str;
|
||||
|
||||
if( prefix.size() )
|
||||
str << prefix << ": ";
|
||||
|
||||
str << formatPreviewDimension( aVal, aUnits );
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
void KIGFX::PREVIEW::SetConstantGlyphHeight( KIGFX::GAL& aGal, double aHeight )
|
||||
{
|
||||
aHeight /= aGal.GetWorldScale();
|
||||
|
||||
auto glyphSize = aGal.GetGlyphSize();
|
||||
glyphSize = glyphSize * ( aHeight / glyphSize.y );
|
||||
aGal.SetGlyphSize( glyphSize );
|
||||
}
|
||||
|
||||
|
||||
void KIGFX::PREVIEW::DrawTextNextToCursor( KIGFX::GAL& aGal,
|
||||
const VECTOR2D& aCursorPos, const VECTOR2D& aTextQuadrant,
|
||||
const std::vector<wxString>& aStrings )
|
||||
{
|
||||
auto glyphSize = aGal.GetGlyphSize();
|
||||
|
||||
const auto lineSpace = glyphSize.y * 0.2;
|
||||
auto linePitch = glyphSize.y + lineSpace;
|
||||
|
||||
// radius string goes on the right of the cursor centre line
|
||||
// with a small horizontal offset (enough to keep clear of a
|
||||
// system cursor if present)
|
||||
auto textPos = aCursorPos;
|
||||
|
||||
// if the text goes above the cursor, shift it up
|
||||
if( aTextQuadrant.y > 0 )
|
||||
{
|
||||
textPos.y -= linePitch * ( aStrings.size() + 1 );
|
||||
}
|
||||
|
||||
if( aTextQuadrant.x < 0 )
|
||||
{
|
||||
aGal.SetHorizontalJustify( GR_TEXT_HJUSTIFY_LEFT );
|
||||
textPos.x += 15.0 / aGal.GetWorldScale();
|
||||
}
|
||||
else
|
||||
{
|
||||
aGal.SetHorizontalJustify( GR_TEXT_HJUSTIFY_RIGHT );
|
||||
textPos.x -= 15.0 / aGal.GetWorldScale();
|
||||
}
|
||||
|
||||
aGal.SetStrokeColor( PreviewOverlayDefaultColor().WithAlpha(
|
||||
PreviewOverlayDeemphAlpha( true ) ) );
|
||||
aGal.SetIsFill( false );
|
||||
|
||||
// write strings top-to-bottom
|
||||
for( const auto& str : aStrings )
|
||||
{
|
||||
textPos.y += linePitch;
|
||||
aGal.BitmapText( str, textPos, 0.0 );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <preview_items/ruler_item.h>
|
||||
|
||||
#include <preview_items/preview_utils.h>
|
||||
#include <gal/graphics_abstraction_layer.h>
|
||||
#include <layers_id_colors_and_visibility.h>
|
||||
#include <view/view.h>
|
||||
|
||||
#include <base_units.h>
|
||||
#include <common.h>
|
||||
|
||||
using namespace KIGFX::PREVIEW;
|
||||
|
||||
static const double maxTickDensity = 10.0; // min pixels between tick marks
|
||||
static const double midTickLengthFactor = 1.5;
|
||||
static const double majorTickLengthFactor = 2.5;
|
||||
|
||||
|
||||
static void drawCursorStrings( KIGFX::GAL& aGal, const VECTOR2D& aCursor,
|
||||
const VECTOR2D& aRulerVec )
|
||||
{
|
||||
// draw the cursor labels
|
||||
std::vector<wxString> cursorStrings;
|
||||
|
||||
cursorStrings.push_back( DimensionLabel( "r", aRulerVec.EuclideanNorm(), g_UserUnit ) );
|
||||
|
||||
double degs = RAD2DECIDEG( -aRulerVec.Angle() );
|
||||
cursorStrings.push_back( DimensionLabel( "θ", degs, DEGREES ) );
|
||||
|
||||
for( auto& str: cursorStrings )
|
||||
{
|
||||
// FIXME: remove spaces that choke OpenGL lp:1668455
|
||||
str.erase( std::remove( str.begin(), str.end(), ' ' ), str.end() );
|
||||
}
|
||||
|
||||
auto temp = aRulerVec;
|
||||
DrawTextNextToCursor( aGal, aCursor, -temp, cursorStrings );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Description of a "tick format" for a scale factor - how many ticks there are
|
||||
* between medium/major ticks and how each scale relates to the last one
|
||||
*/
|
||||
struct TICK_FORMAT
|
||||
{
|
||||
double divisionBase; ///> multiple from the last scale
|
||||
int majorStep; ///> ticks between major ticks
|
||||
int midStep; ///> ticks between medium ticks (0 if no medium ticks)
|
||||
};
|
||||
|
||||
|
||||
static TICK_FORMAT getTickFormatForScale( double aScale, double& aTickSpace )
|
||||
{
|
||||
// simple 1/2/5 scales per decade
|
||||
static std::vector<TICK_FORMAT> tickFormats =
|
||||
{
|
||||
{ 2, 10, 5 }, // |....:....|
|
||||
{ 2, 5, 0 }, // |....|
|
||||
{ 2.5, 2, 0 }, // |.|.|
|
||||
};
|
||||
|
||||
// could start at a set number of MM, but that's not available in common
|
||||
aTickSpace = 1;
|
||||
|
||||
// convert to a round (mod-10) number of mils
|
||||
if( g_UserUnit == INCHES )
|
||||
{
|
||||
aTickSpace *= 2.54;
|
||||
}
|
||||
|
||||
int tickFormat = 0;
|
||||
|
||||
while( true )
|
||||
{
|
||||
const auto pixelSpace = aTickSpace * aScale;
|
||||
|
||||
if( pixelSpace >= maxTickDensity )
|
||||
break;
|
||||
|
||||
tickFormat = ( tickFormat + 1 ) % tickFormats.size();
|
||||
aTickSpace *= tickFormats[tickFormat].divisionBase;
|
||||
}
|
||||
|
||||
return tickFormats[tickFormat];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Draw labelled ticks on a line. Ticks are spaced according to a
|
||||
* maximum density. Miror ticks are not labelled.
|
||||
*
|
||||
* @param aGal the GAL to draw on
|
||||
* @param aOrigin start of line to draw ticks on
|
||||
* @param aLine line vector
|
||||
* @param aMinorTickLen length of minor ticks in IU
|
||||
*/
|
||||
void drawTicksAlongLine( KIGFX::GAL& aGal, const VECTOR2D& aOrigin,
|
||||
const VECTOR2D& aLine, double aMinorTickLen )
|
||||
{
|
||||
VECTOR2D tickLine = aLine.Rotate( -M_PI_2 );
|
||||
|
||||
double tickSpace;
|
||||
TICK_FORMAT tickF = getTickFormatForScale( aGal.GetWorldScale(), tickSpace );
|
||||
|
||||
// number of ticks in whole ruler
|
||||
int numTicks = (int) std::ceil( aLine.EuclideanNorm() / tickSpace );
|
||||
|
||||
// work out which way up the tick labels go
|
||||
double labelAngle = -tickLine.Angle();
|
||||
|
||||
if( aLine.Angle() > 0 )
|
||||
{
|
||||
aGal.SetHorizontalJustify( GR_TEXT_HJUSTIFY_LEFT );
|
||||
}
|
||||
else
|
||||
{
|
||||
aGal.SetHorizontalJustify( GR_TEXT_HJUSTIFY_RIGHT );
|
||||
labelAngle += M_PI;
|
||||
}
|
||||
|
||||
// text and ticks are dimmed
|
||||
aGal.SetStrokeColor( PreviewOverlayDefaultColor().WithAlpha( PreviewOverlayDeemphAlpha( true ) ) );
|
||||
|
||||
const auto labelOffset = tickLine.Resize( aMinorTickLen * ( majorTickLengthFactor + 1 ) );
|
||||
|
||||
for( int i = 0; i < numTicks; ++i )
|
||||
{
|
||||
const auto tickPos = aOrigin + aLine.Resize( tickSpace * i );
|
||||
|
||||
double length = aMinorTickLen;
|
||||
bool drawLabel = false;
|
||||
|
||||
if( i % tickF.majorStep == 0)
|
||||
{
|
||||
drawLabel = true;
|
||||
length *= majorTickLengthFactor;
|
||||
}
|
||||
else if( tickF.midStep && i % tickF.midStep == 0 )
|
||||
{
|
||||
drawLabel = true;
|
||||
length *= midTickLengthFactor;
|
||||
}
|
||||
|
||||
aGal.DrawLine( tickPos, tickPos + tickLine.Resize( length ) );
|
||||
|
||||
if( drawLabel )
|
||||
{
|
||||
wxString label = DimensionLabel( "", tickSpace * i, g_UserUnit );
|
||||
|
||||
// FIXME: spaces choke OpenGL lp:1668455
|
||||
label.erase( std::remove( label.begin(), label.end(), ' ' ), label.end() );
|
||||
|
||||
aGal.BitmapText( label, tickPos + labelOffset, labelAngle );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Draw simple ticks on the back of a line such that the line is
|
||||
* divided into n parts.
|
||||
*
|
||||
* @param aGal the GAL to draw on
|
||||
* @param aOrigin start of line to draw ticks on
|
||||
* @param aLine line vector
|
||||
* @param aTickLen length of ticks in IU
|
||||
* @param aNumDivisions number of parts to divide the line into
|
||||
*/
|
||||
void drawBacksideTicks( KIGFX::GAL& aGal, const VECTOR2D& aOrigin,
|
||||
const VECTOR2D& aLine, double aTickLen, int aNumDivisions )
|
||||
{
|
||||
const double backTickSpace = aLine.EuclideanNorm() / aNumDivisions;
|
||||
const auto backTickVec = aLine.Rotate( M_PI_2 ).Resize( aTickLen );
|
||||
|
||||
for( int i = 0; i < aNumDivisions + 1; ++i )
|
||||
{
|
||||
const auto backTickPos = aOrigin + aLine.Resize( backTickSpace * i );
|
||||
aGal.DrawLine( backTickPos, backTickPos + backTickVec );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RULER_ITEM::RULER_ITEM():
|
||||
EDA_ITEM( NOT_USED ) // Never added to anything - just a preview
|
||||
{}
|
||||
|
||||
|
||||
const BOX2I RULER_ITEM::ViewBBox() const
|
||||
{
|
||||
BOX2I tmp;
|
||||
|
||||
tmp.SetOrigin( m_origin );
|
||||
tmp.SetEnd( m_end );
|
||||
tmp.Normalize();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
void RULER_ITEM::ViewGetLayers( int aLayers[], int& aCount ) const
|
||||
{
|
||||
aLayers[0] = ITEM_GAL_LAYER( GP_OVERLAY );
|
||||
aCount = 1;
|
||||
}
|
||||
|
||||
|
||||
void RULER_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
|
||||
{
|
||||
auto& gal = *aView->GetGAL();
|
||||
|
||||
gal.SetLineWidth( 1.0 );
|
||||
gal.SetIsStroke( true );
|
||||
gal.SetIsFill( false );
|
||||
gal.SetStrokeColor( PreviewOverlayDefaultColor() );
|
||||
|
||||
// draw the main line from the origin to cursor
|
||||
gal.DrawLine( m_origin, m_end );
|
||||
|
||||
VECTOR2D rulerVec( m_end - m_origin );
|
||||
|
||||
// constant text size on screen
|
||||
SetConstantGlyphHeight( gal, 12.0 );
|
||||
|
||||
drawCursorStrings( gal, m_end, rulerVec );
|
||||
|
||||
// tick label size
|
||||
SetConstantGlyphHeight( gal, 10.0 );
|
||||
|
||||
// basic tick size
|
||||
const double minorTickLen = 5.0 / gal.GetWorldScale();
|
||||
|
||||
drawTicksAlongLine( gal, m_origin, rulerVec, minorTickLen );
|
||||
|
||||
gal.SetStrokeColor( PreviewOverlayDefaultColor().WithAlpha( PreviewOverlayDeemphAlpha( true ) ) );
|
||||
drawBacksideTicks( gal, m_origin, rulerVec, minorTickLen * majorTickLengthFactor, 2 );
|
||||
|
||||
// draw the back of the origin "crosshair"
|
||||
gal.DrawLine( m_origin, m_origin + rulerVec.Resize( -minorTickLen * midTickLengthFactor ) );
|
||||
}
|
|
@ -283,6 +283,7 @@ EXTERN_BITMAP( load_module_board_xpm )
|
|||
EXTERN_BITMAP( load_module_lib_xpm )
|
||||
EXTERN_BITMAP( local_ratsnest_xpm )
|
||||
EXTERN_BITMAP( locked_xpm )
|
||||
EXTERN_BITMAP( measurement_xpm )
|
||||
EXTERN_BITMAP( mirepcb_xpm )
|
||||
EXTERN_BITMAP( mirror_h_xpm )
|
||||
EXTERN_BITMAP( mirror_v_xpm )
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017 Kicad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef PREVIEW_PREVIEW_UTILS__H_
|
||||
#define PREVIEW_PREVIEW_UTILS__H_
|
||||
|
||||
#include <common.h>
|
||||
#include <gal/color4d.h>
|
||||
#include <math/vector2d.h>
|
||||
|
||||
namespace KIGFX
|
||||
{
|
||||
class GAL;
|
||||
|
||||
namespace PREVIEW
|
||||
{
|
||||
|
||||
/**
|
||||
* The default fill/stroke color of preview overlay items
|
||||
*/
|
||||
COLOR4D PreviewOverlayDefaultColor();
|
||||
|
||||
/**
|
||||
* The default alpha of overlay fills
|
||||
*/
|
||||
double PreviewOverlayFillAlpha();
|
||||
|
||||
/**
|
||||
* Default alpha of "de-emphasised" features (like previously locked-in
|
||||
* lines
|
||||
*/
|
||||
double PreviewOverlayDeemphAlpha( bool aDeemph = true );
|
||||
|
||||
/**
|
||||
* The colour of "special" angle overlay features
|
||||
*/
|
||||
COLOR4D PreviewOverlaySpecialAngleColor();
|
||||
|
||||
/**
|
||||
* Get a formatted string showing a dimension to a sane precision
|
||||
* with an optional prefix and unit suffix.
|
||||
*/
|
||||
wxString DimensionLabel( const wxString& prefix, double aVal,
|
||||
EDA_UNITS_T aUnits );
|
||||
|
||||
/**
|
||||
* Set the GAL glyph height to a constant scaled value, so that it
|
||||
* always looks the same on screen
|
||||
*
|
||||
* @param aHeight the height of the glyph, in pixels
|
||||
*/
|
||||
void SetConstantGlyphHeight( KIGFX::GAL& aGal, double aHeight );
|
||||
|
||||
/**
|
||||
* Draw strings next to the cursor
|
||||
*
|
||||
* @param aGal the GAL to draw on
|
||||
* @param aCursorPos the position of the cursor to draw next to
|
||||
* @param aTextQuadrant a vector pointing to the quadrant to draw the
|
||||
* text in
|
||||
* @param aStrings list of strings to draw, top to bottom
|
||||
*/
|
||||
void DrawTextNextToCursor( KIGFX::GAL& aGal,
|
||||
const VECTOR2D& aCursorPos, const VECTOR2D& aTextQuadrant,
|
||||
const std::vector<wxString>& aStrings );
|
||||
|
||||
} // PREVIEW
|
||||
} // KIGFX
|
||||
|
||||
#endif // PREVIEW_PREVIEW_UTILS__H_
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017 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_RULER_ITEM_H
|
||||
#define PREVIEW_ITEMS_RULER_ITEM_H
|
||||
|
||||
#include <base_struct.h>
|
||||
|
||||
namespace KIGFX
|
||||
{
|
||||
class GAL;
|
||||
|
||||
namespace PREVIEW
|
||||
{
|
||||
|
||||
/**
|
||||
* Class RULER_ITEM
|
||||
*
|
||||
* A drawn ruler item for showing the distance between two points.
|
||||
*/
|
||||
class RULER_ITEM : public EDA_ITEM
|
||||
{
|
||||
public:
|
||||
|
||||
RULER_ITEM();
|
||||
|
||||
///> @copydoc EDA_ITEM::ViewBBox()
|
||||
const BOX2I ViewBBox() const override;
|
||||
|
||||
///> @copydoc EDA_ITEM::ViewGetLayers()
|
||||
void ViewGetLayers( int aLayers[], int& aCount ) const override;
|
||||
|
||||
///> @copydoc EDA_ITEM::ViewDraw();
|
||||
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 "RULER_ITEM"
|
||||
*/
|
||||
wxString GetClass() const override
|
||||
{
|
||||
return wxT( "RULER_ITEM" );
|
||||
}
|
||||
|
||||
///> Set the origin of the ruler (the fixed end)
|
||||
void SetOrigin( VECTOR2I aOrigin )
|
||||
{
|
||||
m_origin = aOrigin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current end of the rectangle (the end that moves
|
||||
* with the cursor.
|
||||
*/
|
||||
void SetEnd( VECTOR2I aEnd )
|
||||
{
|
||||
m_end = aEnd;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
VECTOR2I m_origin, m_end;
|
||||
};
|
||||
|
||||
} // PREVIEW
|
||||
} // KIGFX
|
||||
|
||||
#endif // PREVIEW_ITEMS_RULER_ITEM_H
|
|
@ -1525,6 +1525,11 @@ void PCB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent )
|
|||
Compile_Ratsnest( &dc, true );
|
||||
|
||||
break;
|
||||
|
||||
// collect GAL-only tools here
|
||||
case ID_PCB_MEASUREMENT_TOOL:
|
||||
SetToolID( id, wxCURSOR_DEFAULT, _( "Unsupported tool in this canvas" ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -962,6 +962,11 @@ void FOOTPRINT_EDIT_FRAME::OnVerticalToolbar( wxCommandEvent& aEvent )
|
|||
SetToolID( id, wxCURSOR_BULLSEYE, _( "Delete item" ) );
|
||||
break;
|
||||
|
||||
case ID_MODEDIT_MEASUREMENT_TOOL:
|
||||
DisplayError( this, wxT( "Unsupported tool in legacy canvas" ) );
|
||||
SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
|
||||
break;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( wxT( "Unknown command id." ) );
|
||||
SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
|
||||
|
|
|
@ -200,6 +200,11 @@ void FOOTPRINT_EDIT_FRAME::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
|
|||
|
||||
break;
|
||||
|
||||
case ID_MODEDIT_MEASUREMENT_TOOL:
|
||||
DisplayError( this, wxT( "Unsupported tool in legacy canvas" ) );
|
||||
SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
|
||||
break;
|
||||
|
||||
default:
|
||||
DisplayError( this, wxT( "FOOTPRINT_EDIT_FRAME::ProcessCommand error" ) );
|
||||
SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
|
||||
|
|
|
@ -116,7 +116,7 @@ BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME )
|
|||
// Vertical tool bar button click event handler.
|
||||
EVT_TOOL( ID_NO_TOOL_SELECTED, FOOTPRINT_EDIT_FRAME::OnVerticalToolbar )
|
||||
EVT_TOOL( ID_ZOOM_SELECTION, FOOTPRINT_EDIT_FRAME::OnVerticalToolbar )
|
||||
EVT_TOOL_RANGE( ID_MODEDIT_PAD_TOOL, ID_MODEDIT_PLACE_GRID_COORD,
|
||||
EVT_TOOL_RANGE( ID_MODEDIT_PAD_TOOL, ID_MODEDIT_MEASUREMENT_TOOL,
|
||||
FOOTPRINT_EDIT_FRAME::OnVerticalToolbar )
|
||||
|
||||
// Options Toolbar (ID_TB_OPTIONS_SHOW_PADS_SKETCH id is managed in PCB_BASE_FRAME)
|
||||
|
@ -195,7 +195,7 @@ BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME )
|
|||
EVT_UPDATE_UI( ID_NO_TOOL_SELECTED, FOOTPRINT_EDIT_FRAME::OnUpdateVerticalToolbar )
|
||||
EVT_UPDATE_UI( ID_ZOOM_SELECTION, FOOTPRINT_EDIT_FRAME::OnUpdateVerticalToolbar )
|
||||
|
||||
EVT_UPDATE_UI_RANGE( ID_MODEDIT_PAD_TOOL, ID_MODEDIT_PLACE_GRID_COORD,
|
||||
EVT_UPDATE_UI_RANGE( ID_MODEDIT_PAD_TOOL, ID_MODEDIT_MEASUREMENT_TOOL,
|
||||
FOOTPRINT_EDIT_FRAME::OnUpdateVerticalToolbar )
|
||||
|
||||
// Option toolbar:
|
||||
|
|
|
@ -439,6 +439,11 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
|
|||
m_canvas->DrawGridAxis( aDC, GR_COPY, GetBoard()->GetGridOrigin() );
|
||||
break;
|
||||
|
||||
case ID_PCB_MEASUREMENT_TOOL:
|
||||
DisplayError( this, wxT( "This tool is not available in the legacy canvas" ) );
|
||||
SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
|
||||
break;
|
||||
|
||||
default:
|
||||
DisplayError( this, wxT( "PCB_EDIT_FRAME::OnLeftClick() id error" ) );
|
||||
SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
|
||||
|
|
|
@ -259,7 +259,7 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME )
|
|||
// Vertical main toolbar:
|
||||
EVT_TOOL( ID_NO_TOOL_SELECTED, PCB_EDIT_FRAME::OnSelectTool )
|
||||
EVT_TOOL( ID_ZOOM_SELECTION, PCB_EDIT_FRAME::OnSelectTool )
|
||||
EVT_TOOL_RANGE( ID_PCB_HIGHLIGHT_BUTT, ID_PCB_PLACE_GRID_COORD_BUTT,
|
||||
EVT_TOOL_RANGE( ID_PCB_HIGHLIGHT_BUTT, ID_PCB_MEASUREMENT_TOOL,
|
||||
PCB_EDIT_FRAME::OnSelectTool )
|
||||
|
||||
EVT_TOOL_RANGE( ID_PCB_MUWAVE_START_CMD, ID_PCB_MUWAVE_END_CMD,
|
||||
|
@ -311,7 +311,7 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME )
|
|||
PCB_EDIT_FRAME::OnUpdateSelectTrackWidth )
|
||||
EVT_UPDATE_UI_RANGE( ID_POPUP_PCB_SELECT_VIASIZE1, ID_POPUP_PCB_SELECT_VIASIZE8,
|
||||
PCB_EDIT_FRAME::OnUpdateSelectViaSize )
|
||||
EVT_UPDATE_UI_RANGE( ID_PCB_HIGHLIGHT_BUTT, ID_PCB_PLACE_GRID_COORD_BUTT,
|
||||
EVT_UPDATE_UI_RANGE( ID_PCB_HIGHLIGHT_BUTT, ID_PCB_MEASUREMENT_TOOL,
|
||||
PCB_EDIT_FRAME::OnUpdateVerticalToolbar )
|
||||
EVT_UPDATE_UI_RANGE( ID_TB_OPTIONS_SHOW_ZONES, ID_TB_OPTIONS_SHOW_ZONES_OUTLINES_ONLY,
|
||||
PCB_EDIT_FRAME::OnUpdateZoneDisplayStyle )
|
||||
|
|
|
@ -40,6 +40,8 @@ enum pcbnew_ids
|
|||
ID_PCB_DELETE_ITEM_BUTT,
|
||||
ID_PCB_PLACE_OFFSET_COORD_BUTT,
|
||||
ID_PCB_PLACE_GRID_COORD_BUTT,
|
||||
ID_PCB_MEASUREMENT_TOOL,
|
||||
|
||||
ID_DIFF_PAIR_BUTT,
|
||||
ID_TUNE_SINGLE_TRACK_LEN_BUTT,
|
||||
ID_TUNE_DIFF_PAIR_LEN_BUTT,
|
||||
|
@ -343,6 +345,7 @@ enum pcbnew_ids
|
|||
ID_MODEDIT_ANCHOR_TOOL,
|
||||
ID_MODEDIT_DELETE_TOOL,
|
||||
ID_MODEDIT_PLACE_GRID_COORD,
|
||||
ID_MODEDIT_MEASUREMENT_TOOL,
|
||||
|
||||
// ID used in module editor:
|
||||
ID_POPUP_MODEDIT_GLOBAL_EDIT_EDGE,
|
||||
|
|
|
@ -196,6 +196,11 @@ void FOOTPRINT_EDIT_FRAME::ReCreateVToolbar()
|
|||
_( "Set the origin point for the grid" ),
|
||||
wxITEM_CHECK );
|
||||
|
||||
m_drawToolBar->AddTool( ID_MODEDIT_MEASUREMENT_TOOL, wxEmptyString,
|
||||
KiBitmap( measurement_xpm ),
|
||||
_( "Measure distance between two points" ),
|
||||
wxITEM_CHECK );
|
||||
|
||||
m_drawToolBar->Realize();
|
||||
}
|
||||
|
||||
|
|
|
@ -484,6 +484,11 @@ void PCB_EDIT_FRAME::ReCreateVToolbar()
|
|||
_( "Set the origin point for the grid" ),
|
||||
wxITEM_CHECK );
|
||||
|
||||
m_drawToolBar->AddTool( ID_PCB_MEASUREMENT_TOOL, wxEmptyString,
|
||||
KiBitmap( measurement_xpm ),
|
||||
_( "Measure distance between two points" ),
|
||||
wxITEM_CHECK );
|
||||
|
||||
m_drawToolBar->Realize();
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <class_draw_panel_gal.h>
|
||||
#include <module_editor_frame.h>
|
||||
#include <array_creator.h>
|
||||
#include <pcbnew_id.h>
|
||||
|
||||
#include <tool/tool_manager.h>
|
||||
#include <view/view_controls.h>
|
||||
|
@ -62,6 +63,8 @@ using namespace std::placeholders;
|
|||
|
||||
#include <tools/tool_event_utils.h>
|
||||
|
||||
#include <preview_items/ruler_item.h>
|
||||
|
||||
#include <board_commit.h>
|
||||
|
||||
// Edit tool actions
|
||||
|
@ -149,6 +152,11 @@ TOOL_ACTION PCB_ACTIONS::editModifiedSelection( "pcbnew.InteractiveEdit.Modified
|
|||
AS_GLOBAL, 0,
|
||||
"", "" );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::measureTool( "pcbnew.InteractiveEdit.measureTool",
|
||||
AS_GLOBAL, MD_CTRL + MD_SHIFT + 'M',
|
||||
_( "Measure tool" ), _( "Interactively measure distance between points" ),
|
||||
nullptr, AF_ACTIVATE );
|
||||
|
||||
|
||||
EDIT_TOOL::EDIT_TOOL() :
|
||||
PCB_TOOL( "pcbnew.InteractiveEdit" ), m_selectionTool( NULL ),
|
||||
|
@ -927,6 +935,95 @@ int EDIT_TOOL::ExchangeFootprints( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
int EDIT_TOOL::MeasureTool( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
auto& view = *getView();
|
||||
auto& controls = *getViewControls();
|
||||
|
||||
Activate();
|
||||
frame()->SetToolID( EditingModules() ? ID_MODEDIT_MEASUREMENT_TOOL
|
||||
: ID_PCB_MEASUREMENT_TOOL,
|
||||
wxCURSOR_PENCIL, _( "Measure distance between two points" ) );
|
||||
|
||||
KIGFX::PREVIEW::RULER_ITEM ruler;
|
||||
view.Add( &ruler );
|
||||
view.SetVisible( &ruler, false );
|
||||
|
||||
bool originSet = false;
|
||||
|
||||
controls.ShowCursor( true );
|
||||
controls.SetSnapping( true );
|
||||
|
||||
while( auto evt = Wait() )
|
||||
{
|
||||
const VECTOR2I cursorPos = controls.GetCursorPosition();
|
||||
|
||||
if( evt->IsCancel() || evt->IsActivate() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// click or drag starts
|
||||
else if( !originSet &&
|
||||
( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) )
|
||||
{
|
||||
if( !evt->IsDrag( BUT_LEFT ) )
|
||||
{
|
||||
ruler.SetOrigin( cursorPos );
|
||||
ruler.SetEnd( cursorPos );
|
||||
}
|
||||
|
||||
controls.CaptureCursor( true );
|
||||
controls.SetAutoPan( true );
|
||||
|
||||
originSet = true;
|
||||
}
|
||||
|
||||
else if( !originSet && evt->IsMotion() )
|
||||
{
|
||||
// make sure the origin is set before a drag starts
|
||||
// otherwise you can miss a step
|
||||
ruler.SetOrigin( cursorPos );
|
||||
ruler.SetEnd( cursorPos );
|
||||
}
|
||||
|
||||
// second click or mouse up after drag ends
|
||||
else if( originSet &&
|
||||
( evt->IsClick( BUT_LEFT ) || evt->IsMouseUp( BUT_LEFT ) ) )
|
||||
{
|
||||
originSet = false;
|
||||
|
||||
controls.SetAutoPan( false );
|
||||
controls.CaptureCursor( false );
|
||||
|
||||
view.SetVisible( &ruler, false );
|
||||
}
|
||||
|
||||
// move or drag when origin set updates rules
|
||||
else if( originSet &&
|
||||
( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
|
||||
{
|
||||
ruler.SetEnd( cursorPos );
|
||||
|
||||
view.SetVisible( &ruler, true );
|
||||
view.Update( &ruler, KIGFX::GEOMETRY );
|
||||
}
|
||||
|
||||
else if( evt->IsClick( BUT_RIGHT ) )
|
||||
{
|
||||
GetManager()->PassEvent();
|
||||
}
|
||||
}
|
||||
|
||||
view.SetVisible( &ruler, false );
|
||||
view.Remove( &ruler );
|
||||
|
||||
frame()->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void EDIT_TOOL::SetTransitions()
|
||||
{
|
||||
Go( &EDIT_TOOL::Main, PCB_ACTIONS::editActivate.MakeEvent() );
|
||||
|
@ -943,6 +1040,7 @@ void EDIT_TOOL::SetTransitions()
|
|||
Go( &EDIT_TOOL::Mirror, PCB_ACTIONS::mirror.MakeEvent() );
|
||||
Go( &EDIT_TOOL::editFootprintInFpEditor, PCB_ACTIONS::editFootprintInFpEditor.MakeEvent() );
|
||||
Go( &EDIT_TOOL::ExchangeFootprints, PCB_ACTIONS::exchangeFootprints.MakeEvent() );
|
||||
Go( &EDIT_TOOL::MeasureTool, PCB_ACTIONS::measureTool.MakeEvent() );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -124,6 +124,9 @@ public:
|
|||
*/
|
||||
int ExchangeFootprints( const TOOL_EVENT& aEvent );
|
||||
|
||||
///> Launches a tool to measure between points
|
||||
int MeasureTool( const TOOL_EVENT& aEvent );
|
||||
|
||||
///> Sets up handlers for various events.
|
||||
void SetTransitions() override;
|
||||
|
||||
|
|
|
@ -151,6 +151,10 @@ boost::optional<TOOL_EVENT> PCB_ACTIONS::TranslateLegacyId( int aId )
|
|||
case ID_PCB_PLACE_OFFSET_COORD_BUTT:
|
||||
return PCB_ACTIONS::drillOrigin.MakeEvent();
|
||||
|
||||
case ID_PCB_MEASUREMENT_TOOL:
|
||||
case ID_MODEDIT_MEASUREMENT_TOOL:
|
||||
return PCB_ACTIONS::measureTool.MakeEvent();
|
||||
|
||||
case ID_PCB_HIGHLIGHT_BUTT:
|
||||
return PCB_ACTIONS::highlightNetCursor.MakeEvent();
|
||||
|
||||
|
|
|
@ -324,6 +324,7 @@ public:
|
|||
static TOOL_ACTION zoomTool;
|
||||
static TOOL_ACTION pickerTool;
|
||||
static TOOL_ACTION resetCoords;
|
||||
static TOOL_ACTION measureTool;
|
||||
static TOOL_ACTION switchCursor;
|
||||
static TOOL_ACTION switchUnits;
|
||||
static TOOL_ACTION deleteItemCursor;
|
||||
|
|
Loading…
Reference in New Issue