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
|
load_module_lib
|
||||||
local_ratsnest
|
local_ratsnest
|
||||||
locked
|
locked
|
||||||
|
measurement
|
||||||
mirepcb
|
mirepcb
|
||||||
mirror_h
|
mirror_h
|
||||||
mirror_v
|
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
|
set( COMMON_PREVIEW_ITEMS_SRCS
|
||||||
|
preview_items/preview_utils.cpp
|
||||||
|
preview_items/ruler_item.cpp
|
||||||
preview_items/simple_overlay_item.cpp
|
preview_items/simple_overlay_item.cpp
|
||||||
preview_items/selection_area.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( load_module_lib_xpm )
|
||||||
EXTERN_BITMAP( local_ratsnest_xpm )
|
EXTERN_BITMAP( local_ratsnest_xpm )
|
||||||
EXTERN_BITMAP( locked_xpm )
|
EXTERN_BITMAP( locked_xpm )
|
||||||
|
EXTERN_BITMAP( measurement_xpm )
|
||||||
EXTERN_BITMAP( mirepcb_xpm )
|
EXTERN_BITMAP( mirepcb_xpm )
|
||||||
EXTERN_BITMAP( mirror_h_xpm )
|
EXTERN_BITMAP( mirror_h_xpm )
|
||||||
EXTERN_BITMAP( mirror_v_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 );
|
Compile_Ratsnest( &dc, true );
|
||||||
|
|
||||||
break;
|
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" ) );
|
SetToolID( id, wxCURSOR_BULLSEYE, _( "Delete item" ) );
|
||||||
break;
|
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:
|
default:
|
||||||
wxFAIL_MSG( wxT( "Unknown command id." ) );
|
wxFAIL_MSG( wxT( "Unknown command id." ) );
|
||||||
SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
|
SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
|
||||||
|
|
|
@ -200,6 +200,11 @@ void FOOTPRINT_EDIT_FRAME::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
|
||||||
|
|
||||||
break;
|
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:
|
default:
|
||||||
DisplayError( this, wxT( "FOOTPRINT_EDIT_FRAME::ProcessCommand error" ) );
|
DisplayError( this, wxT( "FOOTPRINT_EDIT_FRAME::ProcessCommand error" ) );
|
||||||
SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
|
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.
|
// Vertical tool bar button click event handler.
|
||||||
EVT_TOOL( ID_NO_TOOL_SELECTED, FOOTPRINT_EDIT_FRAME::OnVerticalToolbar )
|
EVT_TOOL( ID_NO_TOOL_SELECTED, FOOTPRINT_EDIT_FRAME::OnVerticalToolbar )
|
||||||
EVT_TOOL( ID_ZOOM_SELECTION, 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 )
|
FOOTPRINT_EDIT_FRAME::OnVerticalToolbar )
|
||||||
|
|
||||||
// Options Toolbar (ID_TB_OPTIONS_SHOW_PADS_SKETCH id is managed in PCB_BASE_FRAME)
|
// 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_NO_TOOL_SELECTED, FOOTPRINT_EDIT_FRAME::OnUpdateVerticalToolbar )
|
||||||
EVT_UPDATE_UI( ID_ZOOM_SELECTION, 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 )
|
FOOTPRINT_EDIT_FRAME::OnUpdateVerticalToolbar )
|
||||||
|
|
||||||
// Option toolbar:
|
// Option toolbar:
|
||||||
|
|
|
@ -439,6 +439,11 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
|
||||||
m_canvas->DrawGridAxis( aDC, GR_COPY, GetBoard()->GetGridOrigin() );
|
m_canvas->DrawGridAxis( aDC, GR_COPY, GetBoard()->GetGridOrigin() );
|
||||||
break;
|
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:
|
default:
|
||||||
DisplayError( this, wxT( "PCB_EDIT_FRAME::OnLeftClick() id error" ) );
|
DisplayError( this, wxT( "PCB_EDIT_FRAME::OnLeftClick() id error" ) );
|
||||||
SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
|
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:
|
// Vertical main toolbar:
|
||||||
EVT_TOOL( ID_NO_TOOL_SELECTED, PCB_EDIT_FRAME::OnSelectTool )
|
EVT_TOOL( ID_NO_TOOL_SELECTED, PCB_EDIT_FRAME::OnSelectTool )
|
||||||
EVT_TOOL( ID_ZOOM_SELECTION, 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 )
|
PCB_EDIT_FRAME::OnSelectTool )
|
||||||
|
|
||||||
EVT_TOOL_RANGE( ID_PCB_MUWAVE_START_CMD, ID_PCB_MUWAVE_END_CMD,
|
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 )
|
PCB_EDIT_FRAME::OnUpdateSelectTrackWidth )
|
||||||
EVT_UPDATE_UI_RANGE( ID_POPUP_PCB_SELECT_VIASIZE1, ID_POPUP_PCB_SELECT_VIASIZE8,
|
EVT_UPDATE_UI_RANGE( ID_POPUP_PCB_SELECT_VIASIZE1, ID_POPUP_PCB_SELECT_VIASIZE8,
|
||||||
PCB_EDIT_FRAME::OnUpdateSelectViaSize )
|
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 )
|
PCB_EDIT_FRAME::OnUpdateVerticalToolbar )
|
||||||
EVT_UPDATE_UI_RANGE( ID_TB_OPTIONS_SHOW_ZONES, ID_TB_OPTIONS_SHOW_ZONES_OUTLINES_ONLY,
|
EVT_UPDATE_UI_RANGE( ID_TB_OPTIONS_SHOW_ZONES, ID_TB_OPTIONS_SHOW_ZONES_OUTLINES_ONLY,
|
||||||
PCB_EDIT_FRAME::OnUpdateZoneDisplayStyle )
|
PCB_EDIT_FRAME::OnUpdateZoneDisplayStyle )
|
||||||
|
|
|
@ -40,6 +40,8 @@ enum pcbnew_ids
|
||||||
ID_PCB_DELETE_ITEM_BUTT,
|
ID_PCB_DELETE_ITEM_BUTT,
|
||||||
ID_PCB_PLACE_OFFSET_COORD_BUTT,
|
ID_PCB_PLACE_OFFSET_COORD_BUTT,
|
||||||
ID_PCB_PLACE_GRID_COORD_BUTT,
|
ID_PCB_PLACE_GRID_COORD_BUTT,
|
||||||
|
ID_PCB_MEASUREMENT_TOOL,
|
||||||
|
|
||||||
ID_DIFF_PAIR_BUTT,
|
ID_DIFF_PAIR_BUTT,
|
||||||
ID_TUNE_SINGLE_TRACK_LEN_BUTT,
|
ID_TUNE_SINGLE_TRACK_LEN_BUTT,
|
||||||
ID_TUNE_DIFF_PAIR_LEN_BUTT,
|
ID_TUNE_DIFF_PAIR_LEN_BUTT,
|
||||||
|
@ -343,6 +345,7 @@ enum pcbnew_ids
|
||||||
ID_MODEDIT_ANCHOR_TOOL,
|
ID_MODEDIT_ANCHOR_TOOL,
|
||||||
ID_MODEDIT_DELETE_TOOL,
|
ID_MODEDIT_DELETE_TOOL,
|
||||||
ID_MODEDIT_PLACE_GRID_COORD,
|
ID_MODEDIT_PLACE_GRID_COORD,
|
||||||
|
ID_MODEDIT_MEASUREMENT_TOOL,
|
||||||
|
|
||||||
// ID used in module editor:
|
// ID used in module editor:
|
||||||
ID_POPUP_MODEDIT_GLOBAL_EDIT_EDGE,
|
ID_POPUP_MODEDIT_GLOBAL_EDIT_EDGE,
|
||||||
|
|
|
@ -196,6 +196,11 @@ void FOOTPRINT_EDIT_FRAME::ReCreateVToolbar()
|
||||||
_( "Set the origin point for the grid" ),
|
_( "Set the origin point for the grid" ),
|
||||||
wxITEM_CHECK );
|
wxITEM_CHECK );
|
||||||
|
|
||||||
|
m_drawToolBar->AddTool( ID_MODEDIT_MEASUREMENT_TOOL, wxEmptyString,
|
||||||
|
KiBitmap( measurement_xpm ),
|
||||||
|
_( "Measure distance between two points" ),
|
||||||
|
wxITEM_CHECK );
|
||||||
|
|
||||||
m_drawToolBar->Realize();
|
m_drawToolBar->Realize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -484,6 +484,11 @@ void PCB_EDIT_FRAME::ReCreateVToolbar()
|
||||||
_( "Set the origin point for the grid" ),
|
_( "Set the origin point for the grid" ),
|
||||||
wxITEM_CHECK );
|
wxITEM_CHECK );
|
||||||
|
|
||||||
|
m_drawToolBar->AddTool( ID_PCB_MEASUREMENT_TOOL, wxEmptyString,
|
||||||
|
KiBitmap( measurement_xpm ),
|
||||||
|
_( "Measure distance between two points" ),
|
||||||
|
wxITEM_CHECK );
|
||||||
|
|
||||||
m_drawToolBar->Realize();
|
m_drawToolBar->Realize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include <class_draw_panel_gal.h>
|
#include <class_draw_panel_gal.h>
|
||||||
#include <module_editor_frame.h>
|
#include <module_editor_frame.h>
|
||||||
#include <array_creator.h>
|
#include <array_creator.h>
|
||||||
|
#include <pcbnew_id.h>
|
||||||
|
|
||||||
#include <tool/tool_manager.h>
|
#include <tool/tool_manager.h>
|
||||||
#include <view/view_controls.h>
|
#include <view/view_controls.h>
|
||||||
|
@ -62,6 +63,8 @@ using namespace std::placeholders;
|
||||||
|
|
||||||
#include <tools/tool_event_utils.h>
|
#include <tools/tool_event_utils.h>
|
||||||
|
|
||||||
|
#include <preview_items/ruler_item.h>
|
||||||
|
|
||||||
#include <board_commit.h>
|
#include <board_commit.h>
|
||||||
|
|
||||||
// Edit tool actions
|
// Edit tool actions
|
||||||
|
@ -149,6 +152,11 @@ TOOL_ACTION PCB_ACTIONS::editModifiedSelection( "pcbnew.InteractiveEdit.Modified
|
||||||
AS_GLOBAL, 0,
|
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() :
|
EDIT_TOOL::EDIT_TOOL() :
|
||||||
PCB_TOOL( "pcbnew.InteractiveEdit" ), m_selectionTool( NULL ),
|
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()
|
void EDIT_TOOL::SetTransitions()
|
||||||
{
|
{
|
||||||
Go( &EDIT_TOOL::Main, PCB_ACTIONS::editActivate.MakeEvent() );
|
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::Mirror, PCB_ACTIONS::mirror.MakeEvent() );
|
||||||
Go( &EDIT_TOOL::editFootprintInFpEditor, PCB_ACTIONS::editFootprintInFpEditor.MakeEvent() );
|
Go( &EDIT_TOOL::editFootprintInFpEditor, PCB_ACTIONS::editFootprintInFpEditor.MakeEvent() );
|
||||||
Go( &EDIT_TOOL::ExchangeFootprints, PCB_ACTIONS::exchangeFootprints.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 );
|
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.
|
///> Sets up handlers for various events.
|
||||||
void SetTransitions() override;
|
void SetTransitions() override;
|
||||||
|
|
||||||
|
|
|
@ -151,6 +151,10 @@ boost::optional<TOOL_EVENT> PCB_ACTIONS::TranslateLegacyId( int aId )
|
||||||
case ID_PCB_PLACE_OFFSET_COORD_BUTT:
|
case ID_PCB_PLACE_OFFSET_COORD_BUTT:
|
||||||
return PCB_ACTIONS::drillOrigin.MakeEvent();
|
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:
|
case ID_PCB_HIGHLIGHT_BUTT:
|
||||||
return PCB_ACTIONS::highlightNetCursor.MakeEvent();
|
return PCB_ACTIONS::highlightNetCursor.MakeEvent();
|
||||||
|
|
||||||
|
|
|
@ -324,6 +324,7 @@ public:
|
||||||
static TOOL_ACTION zoomTool;
|
static TOOL_ACTION zoomTool;
|
||||||
static TOOL_ACTION pickerTool;
|
static TOOL_ACTION pickerTool;
|
||||||
static TOOL_ACTION resetCoords;
|
static TOOL_ACTION resetCoords;
|
||||||
|
static TOOL_ACTION measureTool;
|
||||||
static TOOL_ACTION switchCursor;
|
static TOOL_ACTION switchCursor;
|
||||||
static TOOL_ACTION switchUnits;
|
static TOOL_ACTION switchUnits;
|
||||||
static TOOL_ACTION deleteItemCursor;
|
static TOOL_ACTION deleteItemCursor;
|
||||||
|
|
Loading…
Reference in New Issue