Make pad & via teardrops 1st-class citizens (props of the pad/via)

Change teardrop generation to rely more heavily on BOARD_CONNECTIVITY
for improved performance.

Add updating of teardrops on BOARD_COMMIT::Push().

Also converts m_CopperItemRTreeCache to std::shared_ptr.
We don't copy it around anyway, and having to create a new set
of std::unique_ptr's for each operation is likely to be more
expensive than std::shared_ptr's overhead.
This commit is contained in:
Jeff Young 2023-05-12 22:03:54 +01:00
parent 329025f8a7
commit 8b1fd62d35
83 changed files with 20386 additions and 10678 deletions

View File

@ -194,14 +194,31 @@ CHANGE_TYPE COMMIT::convert( UNDO_REDO aType ) const
return CHT_REMOVE;
default:
assert( false );
// Can't fall through if the assert fires, so quiet our warning
#ifdef NDEBUG
wxASSERT( false );
KI_FALLTHROUGH;
#endif
case UNDO_REDO::CHANGED:
return CHT_MODIFY;
}
}
UNDO_REDO COMMIT::convert( CHANGE_TYPE aType ) const
{
switch( aType )
{
case CHT_ADD:
return UNDO_REDO::NEWITEM;
case CHT_REMOVE:
return UNDO_REDO::DELETED;
default:
wxASSERT( false );
KI_FALLTHROUGH;
case CHT_MODIFY:
return UNDO_REDO::CHANGED;
}
}

View File

@ -2,7 +2,7 @@
# This program source code file is part of KiCad, a free EDA CAD application.
#
# Copyright (C) 2012 CERN.
# Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
# Copyright (C) 2019-2023 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
@ -31,6 +31,7 @@ allowed
allow_missing_courtyard
allow_soldermask_bridges
allow_soldermask_bridges_in_footprints
allow_two_segments
anchor
angle
arc
@ -46,6 +47,8 @@ attr
autoplace_cost90
autoplace_cost180
aux_axis_origin
best_length_ratio
best_width_ratio
bevelled
blind
blind_buried_vias_allowed
@ -69,6 +72,7 @@ connect_pads
copperpour
copper_finish
crossbar
curve_points
custom
outline
convexhull
@ -96,6 +100,7 @@ edge_connector
edge_plating
edge_width
effects
enabled
end
epsilon_r
exclude_from_pos_files
@ -112,6 +117,7 @@ fill_segments
filled_polygon
filled_areas_thickness
fillet
filter_ratio
font
format
footprint
@ -171,12 +177,15 @@ layers
leader
leader_length
left
legacy_teardrops
linear
line_spacing
links
locked
loss_tangent
max_error
max_length
max_width
material
members
micro
@ -223,6 +232,7 @@ pad_prop_castellated
pad_prop_testpoint
pad_prop_heatsink
padvia
prefer_zone_connections
private_layers
property
page
@ -281,6 +291,7 @@ target
title
title_block
teardrop
teardrops
tedit
text_frame
text_position_mode

View File

@ -171,7 +171,7 @@ void UNIT_BINDER::onUnitsChanged( wxCommandEvent& aEvent )
&& m_units != EDA_UNITS::DEGREES
&& m_units != EDA_UNITS::PERCENT )
{
int temp = (int) GetValue();
int temp = GetIntValue();
SetUnits( provider->GetUserUnits() );
m_iuScale = &provider->GetIuScale();

View File

@ -137,7 +137,7 @@ DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS_BASE::DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS_
fgSizer2->Add( 0, 0, 1, wxEXPAND, 5 );
m_selectedFilterOpt = new wxCheckBox( sbFilters->GetStaticBox(), wxID_ANY, _("Only include selected items"), wxDefaultPosition, wxDefaultSize, 0 );
m_selectedFilterOpt = new wxCheckBox( sbFilters->GetStaticBox(), wxID_ANY, _("Selected items only"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer2->Add( m_selectedFilterOpt, 0, wxRIGHT|wxLEFT, 5 );

View File

@ -1712,7 +1712,7 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Only include selected items</property>
<property name="label">Selected items only</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>

View File

@ -187,7 +187,7 @@ bool DIALOG_WIRE_BUS_PROPERTIES::TransferDataFromWindow()
{
if( !m_wireWidth.IsIndeterminate() )
{
int width = std::max( (long long int) 0, m_wireWidth.GetValue() );
int width = std::max( 0, m_wireWidth.GetIntValue() );
if( item->Type() == SCH_LINE_T )
static_cast<SCH_LINE*>( item )->SetLineWidth( width );

View File

@ -107,8 +107,8 @@ bool PANEL_EESCHEMA_EDITING_OPTIONS::TransferDataFromWindow()
cfg->m_Drawing.default_sheet_border_color = m_borderColorSwatch->GetSwatchColor();
cfg->m_Drawing.default_sheet_background_color = m_backgroundColorSwatch->GetSwatchColor();
cfg->m_Drawing.default_repeat_offset_x = schIUScale.IUToMils( (int) m_hPitch.GetValue() );
cfg->m_Drawing.default_repeat_offset_y = schIUScale.IUToMils( (int) m_vPitch.GetValue() );
cfg->m_Drawing.default_repeat_offset_x = schIUScale.IUToMils( m_hPitch.GetIntValue() );
cfg->m_Drawing.default_repeat_offset_y = schIUScale.IUToMils( m_vPitch.GetIntValue() );
cfg->m_Drawing.repeat_label_increment = m_spinLabelRepeatStep->GetValue();
cfg->m_Drawing.line_mode = m_choiceLineMode->GetSelection();

View File

@ -182,8 +182,10 @@ protected:
virtual EDA_ITEM* makeImage( EDA_ITEM* aItem ) const = 0;
CHANGE_TYPE convert( UNDO_REDO aType ) const;
UNDO_REDO convert( CHANGE_TYPE aType ) const;
std::set<EDA_ITEM*> m_changedItems;
protected:
std::set<EDA_ITEM*> m_changedItems;
std::vector<COMMIT_LINE> m_changes;
};

View File

@ -124,6 +124,8 @@ public:
*/
virtual long long int GetValue();
int GetIntValue() { return (int) GetValue(); }
/**
* Return the current value in Internal Units.
*

View File

@ -30,8 +30,6 @@ include_directories(
)
set( PCBNEW_DIALOGS
teardrop/dialog_teardrop_base.cpp
teardrop/dialog_teardrop.cpp
dialogs/dialog_filter_selection.cpp
dialogs/dialog_filter_selection_base.cpp
dialogs/dialog_board_setup.cpp
@ -88,6 +86,8 @@ set( PCBNEW_DIALOGS
dialogs/dialog_global_deletion_base.cpp
dialogs/dialog_global_edit_tracks_and_vias.cpp
dialogs/dialog_global_edit_tracks_and_vias_base.cpp
dialogs/dialog_global_edit_teardrops.cpp
dialogs/dialog_global_edit_teardrops_base.cpp
dialogs/dialog_global_edit_text_and_graphics.cpp
dialogs/dialog_global_edit_text_and_graphics_base.cpp
dialogs/dialog_global_fp_lib_table_config.cpp
@ -171,6 +171,8 @@ set( PCBNEW_DIALOGS
dialogs/panel_setup_layers_base.cpp
dialogs/panel_setup_rules.cpp
dialogs/panel_setup_rules_base.cpp
dialogs/panel_setup_teardrops.cpp
dialogs/panel_setup_teardrops_base.cpp
dialogs/panel_setup_text_and_graphics.cpp
dialogs/panel_setup_text_and_graphics_base.cpp
dialogs/panel_setup_tracks_and_vias.cpp
@ -354,6 +356,7 @@ set( PCBNEW_CLASS_SRCS
tools/zone_create_helper.cpp
tools/zone_filler_tool.cpp
teardrop/teardrop.cpp
teardrop/teardrop_parameters.cpp
teardrop/teardrop_utils.cpp
footprint_preview_panel.cpp

View File

@ -244,7 +244,8 @@ void BOARD::IncrementTimeStamp()
|| !m_IntersectsFCourtyardCache.empty()
|| !m_IntersectsBCourtyardCache.empty()
|| !m_LayerExpressionCache.empty()
|| !m_ZoneBBoxCache.empty() )
|| !m_ZoneBBoxCache.empty()
|| m_CopperItemRTreeCache )
{
std::unique_lock<std::mutex> cacheLock( m_CachesMutex );
@ -257,6 +258,8 @@ void BOARD::IncrementTimeStamp()
m_ZoneBBoxCache.clear();
m_CopperItemRTreeCache = nullptr;
// These are always regenerated before use, but still probably safer to clear them
// while we're here.
m_DRCMaxClearance = 0;
@ -265,12 +268,6 @@ void BOARD::IncrementTimeStamp()
m_DRCCopperZones.clear();
m_ZoneIsolatedIslandsMap.clear();
m_CopperZoneRTreeCache.clear();
m_CopperItemRTreeCache = std::make_unique<DRC_RTREE>();
}
else if( !m_CopperItemRTreeCache )
{
std::unique_lock<std::mutex> cacheLock( m_CachesMutex );
m_CopperItemRTreeCache = std::make_unique<DRC_RTREE>();
}
}

View File

@ -1156,6 +1156,9 @@ public:
*/
GroupLegalOpsField GroupLegalOps( const PCB_SELECTION& selection ) const;
bool LegacyTeardrops() const { return m_legacyTeardrops; }
void SetLegacyTeardrops( bool aFlag ) { m_legacyTeardrops = aFlag; }
// --------- Item order comparators ---------
struct cmp_items
@ -1177,7 +1180,7 @@ public:
std::unordered_map<PTR_PTR_LAYER_CACHE_KEY, bool> m_EnclosedByAreaCache;
std::unordered_map< wxString, LSET > m_LayerExpressionCache;
std::unordered_map<ZONE*, std::unique_ptr<DRC_RTREE>> m_CopperZoneRTreeCache;
std::unique_ptr<DRC_RTREE> m_CopperItemRTreeCache;
std::shared_ptr<DRC_RTREE> m_CopperItemRTreeCache;
mutable std::unordered_map<const ZONE*, BOX2I> m_ZoneBBoxCache;
// ------------ DRC caches -------------
@ -1249,6 +1252,12 @@ private:
*/
std::unique_ptr<BOARD_DESIGN_SETTINGS> m_designSettings;
/**
* Teardrops in 7.0 were applied as a post-processing step (rather than from pad and via
* properties). If this flag is set, then auto-teardrop-generation will be disabled.
*/
bool m_legacyTeardrops = false;
NETINFO_LIST m_NetInfo; // net info list (name, design constraints...
std::vector<BOARD_LISTENER*> m_listeners;

View File

@ -27,6 +27,7 @@
#include <board.h>
#include <footprint.h>
#include <pcb_group.h>
#include <pcb_track.h>
#include <tool/tool_manager.h>
#include <tools/pcb_selection_tool.h>
#include <tools/zone_filler_tool.h>
@ -35,6 +36,7 @@
#include <tools/pcb_tool_base.h>
#include <tools/pcb_actions.h>
#include <connectivity/connectivity_data.h>
#include <teardrop/teardrop.h>
#include <functional>
using namespace std::placeholders;
@ -82,8 +84,9 @@ COMMIT& BOARD_COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType, BASE_SCRE
aItem->ClearFlags( IS_MODIFIED_CHILD );
// If aItem belongs a footprint, the full footprint will be saved because undo/redo does
// not handle "sub items" modifications. This has implications for auto-zone-refill, so
// we need to store a bit more information.
// not handle "sub items" modifications. This has implications for some udpate mechanisms,
// such as auto-zone-refill and teardrop regeneration, so we need to store a bit more
// information.
if( aChangeType == CHT_MODIFY )
{
if( aItem->Type() == PCB_FOOTPRINT_T )
@ -93,9 +96,23 @@ COMMIT& BOARD_COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType, BASE_SCRE
{
child->SetFlags( IS_MODIFIED_CHILD );
} );
return COMMIT::Stage( aItem, aChangeType );
}
else if( aItem->GetParent() && aItem->GetParent()->Type() == PCB_FOOTPRINT_T )
{
FOOTPRINT* parentFootprint = static_cast<FOOTPRINT*>( aItem->GetParent() );
bool parentFootprintStaged = alg::contains( m_changedItems, parentFootprint );
if( !parentFootprintStaged )
{
parentFootprint->RunOnChildren(
[&]( BOARD_ITEM* child )
{
child->ClearFlags( IS_MODIFIED_CHILD );
} );
}
if( aItem->Type() == PCB_GROUP_T )
{
static_cast<PCB_GROUP*>( aItem )->RunOnChildren(
@ -109,7 +126,10 @@ COMMIT& BOARD_COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType, BASE_SCRE
aItem->SetFlags( IS_MODIFIED_CHILD );
}
aItem = aItem->GetParent();
if( !parentFootprintStaged )
return COMMIT::Stage( parentFootprint, aChangeType );
return *this;
}
else if( aItem->Type() == PCB_GROUP_T )
{
@ -120,6 +140,8 @@ COMMIT& BOARD_COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType, BASE_SCRE
{
COMMIT::Stage( child, aChangeType );
} );
return COMMIT::Stage( aItem, aChangeType );
}
}
@ -127,13 +149,15 @@ COMMIT& BOARD_COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType, BASE_SCRE
}
COMMIT& BOARD_COMMIT::Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType, BASE_SCREEN* aScreen )
COMMIT& BOARD_COMMIT::Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType,
BASE_SCREEN* aScreen )
{
return COMMIT::Stage( container, aChangeType, aScreen );
}
COMMIT& BOARD_COMMIT::Stage( const PICKED_ITEMS_LIST& aItems, UNDO_REDO aModFlag, BASE_SCREEN* aScreen )
COMMIT& BOARD_COMMIT::Stage( const PICKED_ITEMS_LIST& aItems, UNDO_REDO aModFlag,
BASE_SCREEN* aScreen )
{
return COMMIT::Stage( aItems, aModFlag, aScreen );
}
@ -201,18 +225,23 @@ void BOARD_COMMIT::dirtyIntersectingZones( BOARD_ITEM* item, int aChangeType )
void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
{
// Objects potentially interested in changes:
PICKED_ITEMS_LIST undoList;
KIGFX::VIEW* view = m_toolMgr->GetView();
BOARD* board = static_cast<BOARD*>( m_toolMgr->GetModel() );
PCB_BASE_FRAME* frame = dynamic_cast<PCB_BASE_FRAME*>( m_toolMgr->GetToolHolder() );
std::set<EDA_ITEM*> savedModules;
PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
// Notification info
PICKED_ITEMS_LIST undoList;
std::set<EDA_ITEM*> savedModules;
bool itemsDeselected = false;
bool solderMaskDirty = false;
bool autofillZones = false;
bool selectedModified = false;
// Dirty flags and lists
bool solderMaskDirty = false;
bool autofillZones = false;
std::vector<BOARD_ITEM*> staleTeardropPadsAndVias;
std::set<PCB_TRACK*> staleTeardropTracks;
if( Empty() )
return;
@ -279,10 +308,46 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
}
}
if( boardItem->Type() == PCB_VIA_T || boardItem->Type() == PCB_FOOTPRINT_T
|| boardItem->IsOnLayer( F_Mask ) || boardItem->IsOnLayer( B_Mask ) )
if( m_isBoardEditor )
{
solderMaskDirty = true;
if( boardItem->Type() == PCB_VIA_T || boardItem->Type() == PCB_FOOTPRINT_T
|| boardItem->IsOnLayer( F_Mask ) || boardItem->IsOnLayer( B_Mask ) )
{
solderMaskDirty = true;
}
if( !( aCommitFlags & SKIP_TEARDROPS ) )
{
if( boardItem->Type() == PCB_PAD_T || boardItem->Type() == PCB_VIA_T )
{
staleTeardropPadsAndVias.push_back( boardItem );
}
else if( boardItem->Type() == PCB_TRACE_T || boardItem->Type() == PCB_ARC_T )
{
PCB_TRACK* track = static_cast<PCB_TRACK*>( boardItem );
staleTeardropTracks.insert( track );
std::vector<PAD*> connectedPads;
std::vector<PCB_VIA*> connectedVias;
connectivity->GetConnectedPadsAndVias( track, &connectedPads, &connectedVias );
for( PAD* pad : connectedPads )
staleTeardropPadsAndVias.push_back( pad );
for( PCB_VIA* via : connectedVias )
staleTeardropPadsAndVias.push_back( via );
}
else if( boardItem->Type() == PCB_FOOTPRINT_T )
{
for( PAD* pad : static_cast<FOOTPRINT*>( boardItem )->Pads() )
{
if( pad->GetFlags() & IS_MODIFIED_CHILD )
staleTeardropPadsAndVias.push_back( pad );
}
}
}
}
if( boardItem->IsSelected() )
@ -362,6 +427,14 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
if( autofillZones )
dirtyIntersectingZones( boardItem, changeType );
boardItem->SetFlags( STRUCT_DELETED );
if( boardItem->Type() == PCB_FOOTPRINT_T )
{
for( PAD* pad : static_cast<FOOTPRINT*>( boardItem )->Pads() )
pad->SetFlags( STRUCT_DELETED );
}
switch( boardItem->Type() )
{
case PCB_TEXT_T:
@ -545,19 +618,21 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
frame->HideSolderMask();
}
// Log undo items for any connectivity changes
if( !staleTeardropPadsAndVias.empty() || !staleTeardropTracks.empty() )
{
TEARDROP_MANAGER teardropMgr( board, m_toolMgr );
teardropMgr.UpdateTeardrops( *this, &staleTeardropPadsAndVias, &staleTeardropTracks );
}
// Log undo items for any connectivity or teardrop changes
for( size_t i = num_changes; i < m_changes.size(); ++i )
{
COMMIT_LINE& ent = m_changes[i];
wxASSERT( ( ent.m_type & CHT_TYPE ) == CHT_MODIFY );
BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( ent.m_item );
BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( ent.m_item );
if( !( aCommitFlags & SKIP_UNDO ) )
{
ITEM_PICKER itemWrapper( nullptr, boardItem, UNDO_REDO::CHANGED );
wxASSERT( ent.m_copy );
ITEM_PICKER itemWrapper( nullptr, boardItem, convert( ent.m_type & CHT_TYPE ) );
itemWrapper.SetLink( ent.m_copy );
undoList.PushItem( itemWrapper );
}
@ -567,7 +642,14 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
}
if( view )
view->Update( boardItem );
{
if( ( ent.m_type & CHT_TYPE ) == CHT_ADD )
view->Add( boardItem );
else if( ( ent.m_type & CHT_TYPE ) == CHT_REMOVE )
view->Remove( boardItem );
else
view->Update( boardItem );
}
}
}

View File

@ -41,6 +41,7 @@ class TOOL_BASE;
#define SKIP_SET_DIRTY 0x0004
#define SKIP_CONNECTIVITY 0x0008
#define ZONE_FILL_OP 0x0010
#define SKIP_TEARDROPS 0x0020
class BOARD_COMMIT : public COMMIT
{

View File

@ -203,5 +203,89 @@ static struct BOARD_CONNECTED_ITEM_DESC
&BOARD_CONNECTED_ITEM::GetNetname ) )
.SetIsHiddenFromPropertiesManager()
.SetIsHiddenFromLibraryEditors();
auto supportsTeardrops =
[]( INSPECTABLE* aItem ) -> bool
{
if( BOARD_CONNECTED_ITEM* bci = dynamic_cast<BOARD_CONNECTED_ITEM*>( aItem ) )
{
if( bci->GetBoard()->LegacyTeardrops() )
return false;
return bci->Type() == PCB_PAD_T || bci->Type() == PCB_VIA_T;
}
return false;
};
auto supportsTeardropPreferZoneSetting =
[]( INSPECTABLE* aItem ) -> bool
{
if( BOARD_CONNECTED_ITEM* bci = dynamic_cast<BOARD_CONNECTED_ITEM*>( aItem ) )
{
if( bci->GetBoard()->LegacyTeardrops() )
return false;
return bci->Type() == PCB_PAD_T;
}
return false;
};
const wxString groupTeardrops = _HKI( "Teardrops" );
auto enableTeardrops = new PROPERTY<BOARD_CONNECTED_ITEM, bool>( _HKI( "Enable Teardrops" ),
&BOARD_CONNECTED_ITEM::SetTeardropsEnabled,
&BOARD_CONNECTED_ITEM::GetTeardropsEnabled );
enableTeardrops->SetAvailableFunc( supportsTeardrops );
propMgr.AddProperty( enableTeardrops, groupTeardrops );
auto bestLength = new PROPERTY<BOARD_CONNECTED_ITEM, double>( _HKI( "Best Length Ratio" ),
&BOARD_CONNECTED_ITEM::SetTeardropBestLengthRatio,
&BOARD_CONNECTED_ITEM::GetTeardropBestLengthRatio );
bestLength->SetAvailableFunc( supportsTeardrops );
propMgr.AddProperty( bestLength, groupTeardrops );
auto maxLength = new PROPERTY<BOARD_CONNECTED_ITEM, int>( _HKI( "Max Length" ),
&BOARD_CONNECTED_ITEM::SetTeardropMaxLength,
&BOARD_CONNECTED_ITEM::GetTeardropMaxLength, PROPERTY_DISPLAY::PT_SIZE );
maxLength->SetAvailableFunc( supportsTeardrops );
propMgr.AddProperty( maxLength, groupTeardrops );
auto bestWidth = new PROPERTY<BOARD_CONNECTED_ITEM, double>( _HKI( "Best Width Ratio" ),
&BOARD_CONNECTED_ITEM::SetTeardropBestWidthRatio,
&BOARD_CONNECTED_ITEM::GetTeardropBestWidthRatio );
bestWidth->SetAvailableFunc( supportsTeardrops );
propMgr.AddProperty( bestWidth, groupTeardrops );
auto maxWidth = new PROPERTY<BOARD_CONNECTED_ITEM, int>( _HKI( "Max Width" ),
&BOARD_CONNECTED_ITEM::SetTeardropMaxWidth,
&BOARD_CONNECTED_ITEM::GetTeardropMaxWidth, PROPERTY_DISPLAY::PT_SIZE );
maxWidth->SetAvailableFunc( supportsTeardrops );
propMgr.AddProperty( maxWidth, groupTeardrops );
auto curvePts = new PROPERTY<BOARD_CONNECTED_ITEM, int>( _HKI( "Curve Points" ),
&BOARD_CONNECTED_ITEM::SetTeardropCurvePts,
&BOARD_CONNECTED_ITEM::GetTeardropCurvePts );
curvePts->SetAvailableFunc( supportsTeardrops );
propMgr.AddProperty( curvePts, groupTeardrops );
auto preferZones = new PROPERTY<BOARD_CONNECTED_ITEM, bool>( _HKI( "Prefer zone connections" ),
&BOARD_CONNECTED_ITEM::SetTeardropPreferZoneConnections,
&BOARD_CONNECTED_ITEM::GetTeardropPreferZoneConnections );
preferZones->SetAvailableFunc( supportsTeardropPreferZoneSetting );
propMgr.AddProperty( preferZones, groupTeardrops );
auto twoTracks = new PROPERTY<BOARD_CONNECTED_ITEM, bool>( _HKI( "Allow teardrops to span two tracks" ),
&BOARD_CONNECTED_ITEM::SetTeardropAllowSpanTwoTracks,
&BOARD_CONNECTED_ITEM::GetTeardropAllowSpanTwoTracks );
twoTracks->SetAvailableFunc( supportsTeardrops );
propMgr.AddProperty( twoTracks, groupTeardrops );
auto maxTrackWidth = new PROPERTY<BOARD_CONNECTED_ITEM, double>( _HKI( "Max Width Ratio" ),
&BOARD_CONNECTED_ITEM::SetTeardropMaxTrackWidth,
&BOARD_CONNECTED_ITEM::GetTeardropMaxTrackWidth );
maxTrackWidth->SetAvailableFunc( supportsTeardrops );
propMgr.AddProperty( maxTrackWidth, groupTeardrops );
}
} _BOARD_CONNECTED_ITEM_DESC;

View File

@ -27,6 +27,7 @@
#define BOARD_CONNECTED_ITEM_H
#include <board_item.h>
#include <teardrop/teardrop_parameters.h>
class NETCLASS;
class NETINFO_ITEM;
@ -168,22 +169,50 @@ public:
*/
wxString GetNetClassName() const;
void SetLocalRatsnestVisible( bool aVisible )
{
m_localRatsnestVisible = aVisible;
}
void SetLocalRatsnestVisible( bool aVisible ) { m_localRatsnestVisible = aVisible; }
bool GetLocalRatsnestVisible() const { return m_localRatsnestVisible; }
bool GetLocalRatsnestVisible() const
{
return m_localRatsnestVisible;
}
TEARDROP_PARAMETERS& GetTeardropParams() { return m_teardropParams; }
const TEARDROP_PARAMETERS& GetTeardropParams() const { return m_teardropParams; }
void SetTeardropsEnabled( bool aEnable ) { m_teardropParams.m_Enabled = aEnable; }
bool GetTeardropsEnabled() const { return m_teardropParams.m_Enabled; }
void SetTeardropBestLengthRatio( double aRatio ) { m_teardropParams.m_BestLengthRatio = aRatio; }
double GetTeardropBestLengthRatio() const { return m_teardropParams.m_BestLengthRatio; }
void SetTeardropMaxLength( int aMaxLength ) { m_teardropParams.m_TdMaxLen = aMaxLength; }
int GetTeardropMaxLength() const { return m_teardropParams.m_TdMaxLen; }
void SetTeardropBestWidthRatio( double aRatio ) { m_teardropParams.m_BestWidthRatio = aRatio; }
double GetTeardropBestWidthRatio() const { return m_teardropParams.m_BestWidthRatio; }
void SetTeardropMaxWidth( int aMaxWidth ) { m_teardropParams.m_TdMaxWidth = aMaxWidth; }
int GetTeardropMaxWidth() const { return m_teardropParams.m_TdMaxWidth; }
void SetTeardropCurvePts( int aPointCount ) { m_teardropParams.m_CurveSegCount = aPointCount; }
int GetTeardropCurvePts() const { return m_teardropParams.m_CurveSegCount; }
void SetTeardropPreferZoneConnections( bool aPrefer ) { m_teardropParams.m_TdOnPadsInZones = !aPrefer; }
bool GetTeardropPreferZoneConnections() const { return !m_teardropParams.m_TdOnPadsInZones; }
void SetTeardropAllowSpanTwoTracks( bool aAllow ) { m_teardropParams.m_AllowUseTwoTracks = aAllow; }
bool GetTeardropAllowSpanTwoTracks() const { return m_teardropParams.m_AllowUseTwoTracks; }
void SetTeardropMaxTrackWidth( double aRatio ) { m_teardropParams.m_WidthtoSizeFilterRatio = aRatio; }
double GetTeardropMaxTrackWidth() const { return m_teardropParams.m_WidthtoSizeFilterRatio; }
protected:
/// Store all information about the net that item belongs to.
NETINFO_ITEM* m_netinfo;
/// Not all BOARD_CONNECTED_ITEMs support teardrops, but we want those that do to share a
/// single section in the property inspector.
TEARDROP_PARAMETERS m_teardropParams;
private:
bool m_localRatsnestVisible;
};
#endif // BOARD_CONNECTED_ITEM_H

View File

@ -471,9 +471,6 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
entry["td_onpadsmd"] = m_TeardropParamsList.m_TargetPadsWithNoHole;
entry["td_ontrackend"] = m_TeardropParamsList.m_TargetTrack2Track;
entry["td_onroundshapesonly"] = m_TeardropParamsList.m_UseRoundShapesOnly;
entry["td_allow_use_two_tracks"] = m_TeardropParamsList.m_AllowUseTwoTracks;
entry["td_curve_segcount"] = m_TeardropParamsList.m_CurveSegCount;
entry["td_on_pad_in_zone"] = m_TeardropParamsList.m_TdOnPadsInZones;
js.push_back( entry );
@ -501,14 +498,20 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
if( entry.contains( "td_onroundshapesonly" ) )
m_TeardropParamsList.m_UseRoundShapesOnly = entry["td_onroundshapesonly"].get<bool>();
if( entry.contains( "td_allow_use_two_tracks" ) )
m_TeardropParamsList.m_AllowUseTwoTracks = entry["td_allow_use_two_tracks"].get<bool>();
// Legacy settings
for( int ii = 0; ii < 3; ++ii )
{
TEARDROP_PARAMETERS* td_prm = m_TeardropParamsList.GetParameters( (TARGET_TD)ii );
if( entry.contains( "td_curve_segcount" ) )
m_TeardropParamsList.m_CurveSegCount = entry["td_curve_segcount"].get<int>();
if( entry.contains( "td_allow_use_two_tracks" ) )
td_prm->m_AllowUseTwoTracks = entry["td_allow_use_two_tracks"].get<bool>();
if( entry.contains( "td_on_pad_in_zone" ) )
m_TeardropParamsList.m_TdOnPadsInZones = entry["td_on_pad_in_zone"].get<bool>();
if( entry.contains( "td_curve_segcount" ) )
td_prm->m_CurveSegCount = entry["td_curve_segcount"].get<int>();
if( entry.contains( "td_on_pad_in_zone" ) )
td_prm->m_TdOnPadsInZones = entry["td_on_pad_in_zone"].get<bool>();
}
}
},
{} ) );
@ -526,11 +529,14 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
entry["td_target_name"] = GetTeardropTargetCanonicalName( (TARGET_TD)ii );
entry["td_maxlen"] = pcbIUScale.IUTomm( td_prm->m_TdMaxLen );
entry["td_maxheight"] = pcbIUScale.IUTomm( td_prm->m_TdMaxHeight );
entry["td_length_ratio"] = td_prm->m_LengthRatio;
entry["td_height_ratio"] = td_prm->m_HeightRatio;
entry["td_maxheight"] = pcbIUScale.IUTomm( td_prm->m_TdMaxWidth );
entry["td_length_ratio"] = td_prm->m_BestLengthRatio;
entry["td_height_ratio"] = td_prm->m_BestWidthRatio;
entry["td_curve_segcount"] = td_prm->m_CurveSegCount;
entry["td_width_to_size_filter_ratio"] = td_prm->m_WidthtoSizeFilterRatio;
entry["td_allow_use_two_tracks"] = td_prm->m_AllowUseTwoTracks;
entry["td_curve_segcount"] = td_prm->m_CurveSegCount;
entry["td_on_pad_in_zone"] = td_prm->m_TdOnPadsInZones;
js.push_back( entry );
}
@ -560,19 +566,28 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
td_prm->m_TdMaxLen = pcbIUScale.mmToIU( entry["td_maxlen"].get<double>() );
if( entry.contains( "td_maxheight" ) )
td_prm->m_TdMaxHeight = pcbIUScale.mmToIU( entry["td_maxheight"].get<double>() );
td_prm->m_TdMaxWidth = pcbIUScale.mmToIU( entry["td_maxheight"].get<double>() );
if( entry.contains( "td_length_ratio" ) )
td_prm->m_LengthRatio = entry["td_length_ratio"].get<double>();
td_prm->m_BestLengthRatio = entry["td_length_ratio"].get<double>();
if( entry.contains( "td_height_ratio" ) )
td_prm->m_HeightRatio = entry["td_height_ratio"].get<double>();
td_prm->m_BestWidthRatio = entry["td_height_ratio"].get<double>();
if( entry.contains( "td_curve_segcount" ) )
td_prm->m_CurveSegCount = entry["td_curve_segcount"].get<int>();
if( entry.contains( "td_width_to_size_filter_ratio" ) )
td_prm->m_WidthtoSizeFilterRatio = entry["td_width_to_size_filter_ratio"].get<double>();
if( entry.contains( "td_allow_use_two_tracks" ) )
td_prm->m_AllowUseTwoTracks = entry["td_allow_use_two_tracks"].get<bool>();
if( entry.contains( "td_curve_segcount" ) )
td_prm->m_CurveSegCount = entry["td_curve_segcount"].get<int>();
if( entry.contains( "td_on_pad_in_zone" ) )
td_prm->m_TdOnPadsInZones = entry["td_on_pad_in_zone"].get<bool>();
}
}
},

View File

@ -637,6 +637,28 @@ const
}
void CONNECTIVITY_DATA::GetConnectedPadsAndVias( const BOARD_CONNECTED_ITEM* aItem,
std::vector<PAD*>* pads,
std::vector<PCB_VIA*>* vias )
{
for( CN_ITEM* citem : m_connAlgo->ItemEntry( aItem ).GetItems() )
{
for( CN_ITEM* connected : citem->ConnectedItems() )
{
if( connected->Valid() )
{
BOARD_CONNECTED_ITEM* parent = connected->Parent();
if( parent->Type() == PCB_PAD_T )
pads->push_back( static_cast<PAD*>( parent ) );
else if( parent->Type() == PCB_VIA_T )
vias->push_back( static_cast<PCB_VIA*>( parent ) );
}
}
}
}
unsigned int CONNECTIVITY_DATA::GetNodeCount( int aNet ) const
{
int sum = 0;

View File

@ -51,6 +51,7 @@ class ZONE;
class RN_DATA;
class RN_NET;
class PCB_TRACK;
class PCB_VIA;
class PAD;
class FOOTPRINT;
class PROGRESS_REPORTER;
@ -193,6 +194,9 @@ public:
void GetConnectedPads( const BOARD_CONNECTED_ITEM* aItem, std::set<PAD*>* pads ) const;
void GetConnectedPadsAndVias( const BOARD_CONNECTED_ITEM* aItem, std::vector<PAD*>* pads,
std::vector<PCB_VIA*>* vias );
/**
* Function GetConnectedItemsAtAnchor()
* Returns a list of items connected to a source item aItem at position aAnchor

View File

@ -228,7 +228,7 @@ const std::vector<CN_ITEM*> CN_LIST::Add( ZONE* zone, PCB_LAYER_ID aLayer )
zitem->BuildRTree();
for( VECTOR2I pt : zone->GetFilledPolysList( aLayer )->COutline( j ).CPoints() )
for( const VECTOR2I& pt : zone->GetFilledPolysList( aLayer )->COutline( j ).CPoints() )
zitem->AddAnchor( pt );
rv.push_back( Add( zitem ) );

View File

@ -258,18 +258,22 @@ class CN_ZONE_LAYER : public CN_ITEM
public:
CN_ZONE_LAYER( ZONE* aParent, PCB_LAYER_ID aLayer, int aSubpolyIndex ) :
CN_ITEM( aParent, false ),
m_zone( aParent ),
m_subpolyIndex( aSubpolyIndex ),
m_layer( aLayer )
{
m_triangulatedPoly = aParent->GetFilledPolysList( aLayer );
m_fillPoly = aParent->GetFilledPolysList( aLayer );
SetLayers( aLayer );
}
void BuildRTree()
{
for( unsigned int ii = 0; ii < m_triangulatedPoly->TriangulatedPolyCount(); ++ii )
if( m_zone->IsTeardropArea() )
return;
for( unsigned int ii = 0; ii < m_fillPoly->TriangulatedPolyCount(); ++ii )
{
const auto* triangleSet = m_triangulatedPoly->TriangulatedPolygon( ii );
const auto* triangleSet = m_fillPoly->TriangulatedPolygon( ii );
if( triangleSet->GetSourceOutlineIndex() != m_subpolyIndex )
continue;
@ -291,6 +295,9 @@ public:
bool ContainsPoint( const VECTOR2I& p ) const
{
if( m_zone->IsTeardropArea() )
return m_fillPoly->Outline( m_subpolyIndex ).Collide( p ) ;
int min[2] = { p.x, p.y };
int max[2] = { p.x, p.y };
bool collision = false;
@ -319,11 +326,14 @@ public:
const SHAPE_LINE_CHAIN& GetOutline() const
{
return m_triangulatedPoly->Outline( m_subpolyIndex );
return m_fillPoly->Outline( m_subpolyIndex );
}
bool Collide( SHAPE* aRefShape ) const
{
if( m_zone->IsTeardropArea() )
return m_fillPoly->Collide( aRefShape );
BOX2I bbox = aRefShape->BBox();
int min[2] = { bbox.GetX(), bbox.GetY() };
int max[2] = { bbox.GetRight(), bbox.GetBottom() };
@ -349,9 +359,10 @@ public:
bool HasSingleConnection();
private:
ZONE* m_zone;
int m_subpolyIndex;
PCB_LAYER_ID m_layer;
std::shared_ptr<SHAPE_POLY_SET> m_triangulatedPoly;
std::shared_ptr<SHAPE_POLY_SET> m_fillPoly;
RTree<const SHAPE*, int, 2, double> m_rTree;
};

View File

@ -42,6 +42,7 @@
#include "dialog_board_setup.h"
#include "panel_setup_rules.h"
#include "panel_setup_teardrops.h"
std::mutex DIALOG_BOARD_SETUP::g_Mutex;
@ -64,6 +65,7 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame ) :
m_maskAndPagePage( 0 ),
m_constraintsPage( 0 ),
m_tracksAndViasPage( 0 ),
m_teardropsPage( 0 ),
m_netclassesPage( 0 ),
m_severitiesPage( 0 )
@ -149,6 +151,13 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame ) :
return new PANEL_SETUP_TRACKS_AND_VIAS( aParent, m_frame );
}, _( "Pre-defined Sizes" ) );
m_teardropsPage = m_treebook->GetPageCount();
m_treebook->AddLazySubPage(
[this]( wxWindow* aParent ) -> wxWindow*
{
return new PANEL_SETUP_TEARDROPS( aParent, m_frame );
}, _( "Teardrops" ) );
m_netclassesPage = m_treebook->GetPageCount();
m_treebook->AddLazySubPage(
[this]( wxWindow* aParent ) -> wxWindow*
@ -353,6 +362,12 @@ void DIALOG_BOARD_SETUP::onAuxiliaryAction( wxCommandEvent& aEvent )
m_tracksAndViasPage )->ImportSettingsFrom( otherBoard );
}
if( importDlg.m_TeardropsOpt->GetValue() )
{
RESOLVE_PAGE( PANEL_SETUP_TEARDROPS,
m_teardropsPage )->ImportSettingsFrom( otherBoard );
}
if( importDlg.m_MaskAndPasteOpt->GetValue() )
{
RESOLVE_PAGE( PANEL_SETUP_MASK_AND_PASTE,

View File

@ -67,6 +67,7 @@ private:
size_t m_maskAndPagePage;
size_t m_constraintsPage;
size_t m_tracksAndViasPage;
size_t m_teardropsPage;
size_t m_netclassesPage;
size_t m_severitiesPage;
};

View File

@ -479,8 +479,8 @@ bool DIALOG_COPPER_ZONE::TransferDataFromWindow()
}
m_settings.m_HatchOrientation = m_gridStyleRotation.GetAngleValue();
m_settings.m_HatchThickness = m_gridStyleThickness.GetValue();
m_settings.m_HatchGap = m_gridStyleGap.GetValue();
m_settings.m_HatchThickness = m_gridStyleThickness.GetIntValue();
m_settings.m_HatchGap = m_gridStyleGap.GetIntValue();
m_settings.m_HatchSmoothingLevel = m_spinCtrlSmoothLevel->GetValue();
m_settings.m_HatchSmoothingValue = m_spinCtrlSmoothValue->GetValue();
@ -514,7 +514,7 @@ bool DIALOG_COPPER_ZONE::AcceptOptions( bool aUseExportableSetupOnly )
if( m_settings.m_FillMode == ZONE_FILL_MODE::HATCH_PATTERN )
{
int minThickness = m_minWidth.GetValue();
int minThickness = m_minWidth.GetIntValue();
if( !m_gridStyleThickness.Validate( minThickness, INT_MAX ) )
return false;
@ -542,15 +542,17 @@ bool DIALOG_COPPER_ZONE::AcceptOptions( bool aUseExportableSetupOnly )
pcbIUScale.mmToIU( ZONE_BORDER_HATCH_MAXDIST_MM ) ) )
return false;
m_settings.m_BorderHatchPitch = m_outlineHatchPitch.GetValue();
m_settings.m_BorderHatchPitch = m_outlineHatchPitch.GetIntValue();
m_settings.m_ZoneClearance = m_clearance.GetValue();
m_settings.m_ZoneMinThickness = m_minWidth.GetValue();
m_settings.m_ZoneClearance = m_clearance.GetIntValue();
m_settings.m_ZoneMinThickness = m_minWidth.GetIntValue();
m_settings.SetCornerSmoothingType( m_cornerSmoothingChoice->GetSelection() );
m_settings.SetCornerRadius( m_settings.GetCornerSmoothingType() == ZONE_SETTINGS::SMOOTHING_NONE
? 0 : m_cornerRadius.GetValue() );
if( m_settings.GetCornerSmoothingType() == ZONE_SETTINGS::SMOOTHING_NONE )
m_settings.SetCornerRadius( 0 );
else
m_settings.SetCornerRadius( m_cornerRadius.GetIntValue() );
m_settings.m_ZonePriority = m_PriorityLevelCtrl->GetValue();

View File

@ -0,0 +1,569 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 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 <widgets/unit_binder.h>
#include <pcb_edit_frame.h>
#include <board.h>
#include <board_design_settings.h>
#include <pcb_track.h>
#include <pcb_group.h>
#include <footprint.h>
#include <teardrop/teardrop.h>
#include <zone_filler.h>
#include <connectivity/connectivity_data.h>
#include <pcb_layer_box_selector.h>
#include <tool/tool_manager.h>
#include <tools/global_edit_tool.h>
#include "dialog_global_edit_teardrops_base.h"
// Globals to remember control settings during a session
static bool g_vias = true;
static bool g_pthPads = true;
static bool g_smdPads = true;
static bool g_trackToTrack = false;
static bool g_filterByNetclass;
static wxString g_netclassFilter;
static bool g_filterByNet;
static wxString g_netFilter;
static bool g_filterByLayer;
static int g_layerFilter;
static bool g_filterRoundPads = false;
static bool g_filterSelected = false;
static int g_action = 1;
class DIALOG_GLOBAL_EDIT_TEARDROPS : public DIALOG_GLOBAL_EDIT_TEARDROPS_BASE
{
public:
DIALOG_GLOBAL_EDIT_TEARDROPS( PCB_EDIT_FRAME* aParent );
~DIALOG_GLOBAL_EDIT_TEARDROPS() override;
protected:
void onSpecifiedValuesUpdateUi( wxUpdateUIEvent& event ) override
{
event.Enable( m_specifiedValues->GetValue() );
}
void onCurvedEdgesUpdateUi( wxUpdateUIEvent& event ) override
{
event.Enable( m_specifiedValues->GetValue() && m_rbCurved->GetValue() );
}
void onFilterUpdateUi( wxUpdateUIEvent& event ) override
{
event.Enable( !m_trackToTrack->GetValue() );
}
// We can't use standard wxWidgets radio button processing for these because you must
// be able to turn them both off to set a "don't modify" state
void onStraightLines( wxMouseEvent& event ) override
{
if( !m_rbStraightLines->GetValue() )
{
m_rbStraightLines->SetValue( true );
m_rbCurved->SetValue( false );
}
else
{
m_rbStraightLines->SetValue( false );
}
}
void onCurvedLines( wxMouseEvent& event ) override
{
if( !m_rbCurved->GetValue() )
{
m_rbCurved->SetValue( true );
m_rbStraightLines->SetValue( false );
}
else
{
m_rbCurved->SetValue( false );
}
}
void onTrackToTrack( wxCommandEvent& event ) override
{
if( event.IsChecked() && m_specifiedValues->GetValue() )
{
m_specifiedValues->SetValue( false );
m_addTeardrops->SetValue( true );
}
}
void OnNetclassFilterSelect( wxCommandEvent& event ) override
{
m_netclassFilterOpt->SetValue( true );
}
void OnLayerFilterSelect( wxCommandEvent& event ) override
{
m_layerFilterOpt->SetValue( true );
}
void OnNetFilterSelect( wxCommandEvent& event )
{
m_netFilterOpt->SetValue( true );
}
void OnExistingFilterSelect( wxCommandEvent& event ) override
{
if( event.IsChecked() )
m_specifiedValues->SetLabel( _( "Update teardrops to specified values:" ) );
else
m_specifiedValues->SetLabel( _( "Add teardrops with specified values:" ) );
}
void setSpecifiedParams( TEARDROP_PARAMETERS* targetParams );
void visitItem( BOARD_COMMIT* aCommit, BOARD_CONNECTED_ITEM* aItem );
void processItem( BOARD_COMMIT* aCommit, BOARD_CONNECTED_ITEM* aItem );
bool TransferDataToWindow() override;
bool TransferDataFromWindow() override;
void onShowBoardSetup( wxHyperlinkEvent& event ) override
{
m_parent->ShowBoardSetupDialog( _( "Teardrops" ) );
}
void buildFilterLists();
private:
PCB_EDIT_FRAME* m_parent;
BOARD* m_brd;
PCB_SELECTION m_selection;
UNIT_BINDER m_teardropHDPercent;
UNIT_BINDER m_teardropLenPercent;
UNIT_BINDER m_teardropMaxLen;
UNIT_BINDER m_teardropHeightPercent;
UNIT_BINDER m_teardropMaxHeight;
UNIT_BINDER m_curvePoints;
};
DIALOG_GLOBAL_EDIT_TEARDROPS::DIALOG_GLOBAL_EDIT_TEARDROPS( PCB_EDIT_FRAME* aParent ) :
DIALOG_GLOBAL_EDIT_TEARDROPS_BASE( aParent ),
m_teardropHDPercent( aParent, m_stHDRatio, m_tcHDRatio, m_stHDRatioUnits ),
m_teardropLenPercent( aParent, m_stLenPercentLabel, m_tcLenPercent, m_stLenPercentUnits ),
m_teardropMaxLen( aParent, m_stMaxLen, m_tcTdMaxLen, m_stMaxLenUnits ),
m_teardropHeightPercent( aParent, m_stHeightPercentLabel, m_tcHeightPercent, m_stHeightPercentUnits ),
m_teardropMaxHeight( aParent, m_stMaxHeight, m_tcMaxHeight, m_stMaxHeightUnits ),
m_curvePoints( aParent, m_curvePointsLabel, m_curvePointsCtrl, nullptr )
{
m_parent = aParent;
m_brd = m_parent->GetBoard();
m_bitmapTeardrop->SetBitmap( KiBitmap( BITMAPS::teardrop_sizes ) );
m_teardropHDPercent.SetUnits( EDA_UNITS::PERCENT );
m_teardropLenPercent.SetUnits( EDA_UNITS::PERCENT );
m_teardropHeightPercent.SetUnits( EDA_UNITS::PERCENT );
m_curvePoints.SetUnits( EDA_UNITS::UNSCALED );
m_minTrackWidthHint->SetFont( KIUI::GetInfoFont( this ).Italic() );
buildFilterLists();
SetupStandardButtons();
m_netFilter->Connect( NET_SELECTED,
wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS::OnNetFilterSelect ),
nullptr, this );
finishDialogSettings();
}
DIALOG_GLOBAL_EDIT_TEARDROPS::~DIALOG_GLOBAL_EDIT_TEARDROPS()
{
g_vias = m_vias->GetValue();
g_pthPads = m_pthPads->GetValue();
g_smdPads = m_smdPads->GetValue();
g_trackToTrack = m_trackToTrack->GetValue();
g_filterByNetclass = m_netclassFilterOpt->GetValue();
g_netclassFilter = m_netclassFilter->GetStringSelection();
g_filterByNet = m_netFilterOpt->GetValue();
g_netFilter = m_netFilter->GetSelectedNetname();
g_filterByLayer = m_layerFilterOpt->GetValue();
g_layerFilter = m_layerFilter->GetLayerSelection();
g_filterRoundPads = m_roundPadsFilter->GetValue();
g_filterSelected = m_selectedItemsFilter->GetValue();
if( m_removeTeardrops->GetValue() )
g_action = 0;
else if( m_specifiedValues->GetValue() )
g_action = 2;
else
g_action = 1;
m_netFilter->Disconnect( NET_SELECTED,
wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS::OnNetFilterSelect ),
nullptr, this );
}
void DIALOG_GLOBAL_EDIT_TEARDROPS::buildFilterLists()
{
// Populate the net filter list with net names
m_netFilter->SetBoard( m_brd );
m_netFilter->SetNetInfo( &m_brd->GetNetInfo() );
if( !m_brd->GetHighLightNetCodes().empty() )
m_netFilter->SetSelectedNetcode( *m_brd->GetHighLightNetCodes().begin() );
// Populate the netclass filter list with netclass names
wxArrayString netclassNames;
std::shared_ptr<NET_SETTINGS>& settings = m_brd->GetDesignSettings().m_NetSettings;
netclassNames.push_back( settings->m_DefaultNetClass->GetName() );
for( const auto& [ name, netclass ] : settings->m_NetClasses )
netclassNames.push_back( name );
m_netclassFilter->Set( netclassNames );
m_netclassFilter->SetStringSelection( m_brd->GetDesignSettings().GetCurrentNetClassName() );
// Populate the layer filter list
m_layerFilter->SetBoardFrame( m_parent );
m_layerFilter->SetLayersHotkeys( false );
m_layerFilter->SetNotAllowedLayerSet( LSET::AllNonCuMask() );
m_layerFilter->Resync();
m_layerFilter->SetLayerSelection( m_parent->GetActiveLayer() );
}
bool DIALOG_GLOBAL_EDIT_TEARDROPS::TransferDataToWindow()
{
PCB_SELECTION_TOOL* selTool = m_parent->GetToolManager()->GetTool<PCB_SELECTION_TOOL>();
m_selection = selTool->GetSelection();
BOARD_CONNECTED_ITEM* item = dynamic_cast<BOARD_CONNECTED_ITEM*>( m_selection.Front() );
m_vias->SetValue( g_vias );
m_pthPads->SetValue( g_pthPads );
m_smdPads->SetValue( g_smdPads );
m_trackToTrack->SetValue( g_trackToTrack );
if( g_filterByNetclass && m_netclassFilter->SetStringSelection( g_netclassFilter ) )
m_netclassFilterOpt->SetValue( true );
else if( item )
m_netclassFilter->SetStringSelection( item->GetNet()->GetNetClass()->GetName() );
if( g_filterByNet && m_brd->FindNet( g_netFilter ) != nullptr )
{
m_netFilter->SetSelectedNet( g_netFilter );
m_netFilterOpt->SetValue( true );
}
else if( item )
{
m_netFilter->SetSelectedNetcode( item->GetNetCode() );
}
if( g_filterByLayer && m_layerFilter->SetLayerSelection( g_layerFilter ) != wxNOT_FOUND )
{
m_layerFilterOpt->SetValue( true );
}
else if( item )
{
if( item->Type() == PCB_ZONE_T ) // a zone can be on more than one layer
m_layerFilter->SetLayerSelection( static_cast<ZONE*>(item)->GetFirstLayer() );
else
m_layerFilter->SetLayerSelection( item->GetLayer() );
}
m_roundPadsFilter->SetValue( g_filterRoundPads );
m_selectedItemsFilter->SetValue( g_filterSelected );
if( g_action == 0 )
m_removeTeardrops->SetValue( true );
else if( g_action == 1 )
m_addTeardrops->SetValue( true );
else
m_specifiedValues->SetValue( true );
m_cbPreferZoneConnection->Set3StateValue( wxCHK_UNDETERMINED );
m_cbTeardropsUseNextTrack->Set3StateValue( wxCHK_UNDETERMINED );
m_teardropHDPercent.SetValue( INDETERMINATE_ACTION );
m_teardropLenPercent.SetValue( INDETERMINATE_ACTION );
m_teardropMaxLen.SetValue( INDETERMINATE_ACTION );
m_teardropHeightPercent.SetValue( INDETERMINATE_ACTION );
m_teardropMaxHeight.SetValue( INDETERMINATE_ACTION );
m_curvePoints.SetValue( INDETERMINATE_ACTION );
return true;
}
void DIALOG_GLOBAL_EDIT_TEARDROPS::setSpecifiedParams( TEARDROP_PARAMETERS* targetParams )
{
if( m_cbPreferZoneConnection->Get3StateValue() != wxCHK_UNDETERMINED )
targetParams->m_TdOnPadsInZones = !m_cbPreferZoneConnection->GetValue();
if( m_cbTeardropsUseNextTrack->Get3StateValue() != wxCHK_UNDETERMINED )
targetParams->m_AllowUseTwoTracks = m_cbTeardropsUseNextTrack->GetValue();
if( !m_teardropHDPercent.IsIndeterminate() )
targetParams->m_WidthtoSizeFilterRatio = m_teardropHDPercent.GetDoubleValue() / 100.0;
if( !m_teardropLenPercent.IsIndeterminate() )
targetParams->m_BestLengthRatio = m_teardropLenPercent.GetDoubleValue() / 100.0;
if( !m_teardropMaxLen.IsIndeterminate() )
targetParams->m_TdMaxLen = m_teardropMaxLen.GetIntValue();
if( !m_teardropHeightPercent.IsIndeterminate() )
targetParams->m_BestWidthRatio = m_teardropHeightPercent.GetDoubleValue() / 100.0;
if( !m_teardropMaxHeight.IsIndeterminate() )
targetParams->m_TdMaxWidth = m_teardropMaxHeight.GetIntValue();
if( m_rbStraightLines->GetValue() )
{
targetParams->m_CurveSegCount = 0;
}
else if( m_rbCurved->GetValue() )
{
if( !m_curvePoints.IsIndeterminate() )
targetParams->m_CurveSegCount = m_curvePoints.GetIntValue();
else if( targetParams->m_CurveSegCount == 0 )
targetParams->m_CurveSegCount = 5;
}
}
void DIALOG_GLOBAL_EDIT_TEARDROPS::processItem( BOARD_COMMIT* aCommit, BOARD_CONNECTED_ITEM* aItem )
{
BOARD_DESIGN_SETTINGS& brdSettings = m_brd->GetDesignSettings();
TEARDROP_PARAMETERS* targetParams = nullptr;
if( aItem->Type() == PCB_PAD_T )
targetParams = &static_cast<PAD*>( aItem )->GetTeardropParams();
else if( aItem->Type() == PCB_VIA_T )
targetParams = &static_cast<PCB_VIA*>( aItem )->GetTeardropParams();
else
return;
aCommit->Stage( aItem, CHT_MODIFY );
if( m_removeTeardrops->GetValue() )
{
targetParams->m_Enabled = false;
}
else if( m_addTeardrops->GetValue() )
{
if( TEARDROP_MANAGER::IsRound( aItem ) )
*targetParams = *brdSettings.GetTeadropParamsList()->GetParameters( TARGET_ROUND );
else
*targetParams = *brdSettings.GetTeadropParamsList()->GetParameters( TARGET_RECT );
targetParams->m_Enabled = true;
}
else if( m_specifiedValues->GetValue() )
{
setSpecifiedParams( targetParams );
if( !m_existingFilter->GetValue() )
targetParams->m_Enabled = true;
}
}
void DIALOG_GLOBAL_EDIT_TEARDROPS::visitItem( BOARD_COMMIT* aCommit, BOARD_CONNECTED_ITEM* aItem )
{
if( m_selectedItemsFilter->GetValue() )
{
if( !aItem->IsSelected() )
{
PCB_GROUP* group = aItem->GetParentGroup();
while( group && !group->IsSelected() )
group = group->GetParentGroup();
if( !group )
return;
}
}
if( m_netFilterOpt->GetValue() && m_netFilter->GetSelectedNetcode() >= 0 )
{
if( aItem->GetNetCode() != m_netFilter->GetSelectedNetcode() )
return;
}
if( m_netclassFilterOpt->GetValue() && !m_netclassFilter->GetStringSelection().IsEmpty() )
{
if( aItem->GetEffectiveNetClass()->GetName() != m_netclassFilter->GetStringSelection() )
return;
}
if( m_layerFilterOpt->GetValue() && m_layerFilter->GetLayerSelection() != UNDEFINED_LAYER )
{
if( aItem->GetLayer() != m_layerFilter->GetLayerSelection() )
return;
}
if( m_roundPadsFilter->GetValue() )
{
if( !TEARDROP_MANAGER::IsRound( aItem ) )
return;
}
if( m_existingFilter->GetValue() )
{
if( aItem->Type() == PCB_PAD_T )
{
if( !static_cast<PAD*>( aItem )->GetTeardropParams().m_Enabled )
return;
}
else if( aItem->Type() == PCB_VIA_T )
{
if( !static_cast<PCB_VIA*>( aItem )->GetTeardropParams().m_Enabled )
return;
}
}
processItem( aCommit, aItem );
}
bool DIALOG_GLOBAL_EDIT_TEARDROPS::TransferDataFromWindow()
{
m_brd->SetLegacyTeardrops( false );
BOARD_COMMIT commit( m_parent );
wxBusyCursor dummy;
if( m_vias->GetValue() )
{
for( PCB_TRACK* track : m_brd->Tracks() )
{
if ( track->Type() == PCB_VIA_T )
visitItem( &commit, track );
}
}
for( FOOTPRINT* footprint : m_brd->Footprints() )
{
for( PAD* pad : footprint->Pads() )
{
if( m_pthPads->GetValue() && pad->GetAttribute() == PAD_ATTRIB::PTH )
{
visitItem( &commit, pad );
}
else if( m_smdPads->GetValue() && ( pad->GetAttribute() == PAD_ATTRIB::SMD
|| pad->GetAttribute() == PAD_ATTRIB::CONN ) )
{
visitItem( &commit, pad );
}
}
}
if( m_trackToTrack->GetValue() )
{
TEARDROP_PARAMETERS_LIST* paramsList = m_brd->GetDesignSettings().GetTeadropParamsList();
TEARDROP_PARAMETERS* targetParams = paramsList->GetParameters( TARGET_TRACK );
TEARDROP_MANAGER teardropManager( m_brd, m_parent->GetToolManager() );
teardropManager.DeleteTrackToTrackTeardrops( commit );
if( m_removeTeardrops->GetValue() )
{
targetParams->m_Enabled = false; // JEY TODO: how does this get undone/redone?
}
else if( m_addTeardrops->GetValue() )
{
targetParams->m_Enabled = true; // JEY TODO: how does this get undone/redone?
teardropManager.AddTeardropsOnTracks( commit, nullptr, true );
}
}
// If there are no filters then a force-full-update is equivalent, and will be faster.
if( !m_netFilterOpt->GetValue()
&& !m_netclassFilterOpt->GetValue()
&& !m_layerFilterOpt->GetValue()
&& !m_roundPadsFilter->GetValue()
&& !m_existingFilter->GetValue()
&& !m_selectedItemsFilter->GetValue() )
{
commit.Push( _( "Edit Teardrops" ), SKIP_TEARDROPS );
TEARDROP_MANAGER teardropMgr( m_brd, m_parent->GetToolManager() );
teardropMgr.UpdateTeardrops( commit, nullptr, nullptr, true /* forceFullUpdate */ );
commit.Push( _( "Edit Teardrops" ), SKIP_TEARDROPS | APPEND_UNDO );
}
else
{
commit.Push( _( "Edit Teardrops" ) );
}
// Showing the unfilled, fully cross-hatched teardrops seems to be working fairly well, and
// accurate fills can then be manually generated by doing a zone fill.
//
// But here's the old code which allowed for either "draft" fills or an automatic full zone
// fill in case we decide the current situation isn't good enough:
#if 0
if( aFillAfter )
{
ZONE_FILLER filler( m_board, aCommit );
if( m_reporter )
filler.SetProgressReporter( m_reporter );
filler.Fill( m_board->Zones() );
if( aCommit )
aCommit->Push( _( "Edit Teardrops" ), APPEND_UNDO );
}
else
{
// Fill raw teardrop shapes. This is a rough calculation, just to show a filled
// shape on screen without the (potentially large) performance hit of a zone refill
int epsilon = pcbIUScale.mmToIU( 0.001 );
int allowed_error = pcbIUScale.mmToIU( 0.005 );
for( ZONE* zone: m_createdTdList )
{
int half_min_width = zone->GetMinThickness() / 2;
int numSegs = GetArcToSegmentCount( half_min_width, allowed_error, FULL_CIRCLE );
SHAPE_POLY_SET filledPolys = *zone->Outline();
filledPolys.Deflate( half_min_width - epsilon, numSegs );
// Re-inflate after pruning of areas that don't meet minimum-width criteria
if( half_min_width - epsilon > epsilon )
filledPolys.Inflate( half_min_width - epsilon, numSegs );
zone->SetFilledPolysList( zone->GetFirstLayer(), filledPolys );
}
}
#endif
return true;
}
int GLOBAL_EDIT_TOOL::EditTeardrops( const TOOL_EVENT& aEvent )
{
PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>();
DIALOG_GLOBAL_EDIT_TEARDROPS dlg( editFrame );
dlg.ShowQuasiModal(); // QuasiModal required for NET_SELECTOR
return 0;
}

View File

@ -0,0 +1,411 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "pcb_layer_box_selector.h"
#include "dialog_global_edit_teardrops_base.h"
///////////////////////////////////////////////////////////////////////////
DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::DIALOG_GLOBAL_EDIT_TEARDROPS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
wxBoxSizer* bMainSizer;
bMainSizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizerTop;
bSizerTop = new wxBoxSizer( wxHORIZONTAL );
wxStaticBoxSizer* sbScope;
sbScope = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Scope") ), wxVERTICAL );
m_pthPads = new wxCheckBox( sbScope->GetStaticBox(), wxID_ANY, _("PTH pads"), wxDefaultPosition, wxDefaultSize, 0 );
m_pthPads->SetValue(true);
sbScope->Add( m_pthPads, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_smdPads = new wxCheckBox( sbScope->GetStaticBox(), wxID_ANY, _("SMD pads"), wxDefaultPosition, wxDefaultSize, 0 );
m_smdPads->SetValue(true);
sbScope->Add( m_smdPads, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_vias = new wxCheckBox( sbScope->GetStaticBox(), wxID_ANY, _("Vias"), wxDefaultPosition, wxDefaultSize, 0 );
m_vias->SetValue(true);
sbScope->Add( m_vias, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_trackToTrack = new wxCheckBox( sbScope->GetStaticBox(), wxID_ANY, _("Track to track"), wxDefaultPosition, wxDefaultSize, 0 );
sbScope->Add( m_trackToTrack, 0, wxALL, 5 );
bSizerTop->Add( sbScope, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 10 );
wxStaticBoxSizer* sbFilters;
sbFilters = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Filter Items") ), wxVERTICAL );
wxFlexGridSizer* fgSizer3;
fgSizer3 = new wxFlexGridSizer( 0, 2, 4, 0 );
fgSizer3->AddGrowableCol( 1 );
fgSizer3->AddGrowableRow( 0 );
fgSizer3->AddGrowableRow( 1 );
fgSizer3->AddGrowableRow( 2 );
fgSizer3->AddGrowableRow( 3 );
fgSizer3->SetFlexibleDirection( wxBOTH );
fgSizer3->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_netFilterOpt = new wxCheckBox( sbFilters->GetStaticBox(), wxID_ANY, _("Filter items by net:"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer3->Add( m_netFilterOpt, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_netFilter = new NET_SELECTOR( sbFilters->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer3->Add( m_netFilter, 1, wxEXPAND|wxRIGHT, 5 );
m_netclassFilterOpt = new wxCheckBox( sbFilters->GetStaticBox(), wxID_ANY, _("Filter items by net class:"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer3->Add( m_netclassFilterOpt, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
wxArrayString m_netclassFilterChoices;
m_netclassFilter = new wxChoice( sbFilters->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_netclassFilterChoices, 0 );
m_netclassFilter->SetSelection( 0 );
fgSizer3->Add( m_netclassFilter, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxRIGHT, 5 );
fgSizer3->Add( 0, 0, 1, wxEXPAND|wxTOP|wxBOTTOM, 3 );
fgSizer3->Add( 0, 0, 1, wxEXPAND|wxTOP|wxBOTTOM, 3 );
m_layerFilterOpt = new wxCheckBox( sbFilters->GetStaticBox(), wxID_ANY, _("Filter items by layer:"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer3->Add( m_layerFilterOpt, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_layerFilter = new PCB_LAYER_BOX_SELECTOR( sbFilters->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
fgSizer3->Add( m_layerFilter, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
fgSizer3->Add( 0, 5, 1, wxEXPAND, 5 );
fgSizer3->Add( 0, 0, 1, wxEXPAND, 5 );
sbFilters->Add( fgSizer3, 1, wxEXPAND, 5 );
sbFilters->Add( 0, 5, 0, 0, 5 );
m_roundPadsFilter = new wxCheckBox( sbFilters->GetStaticBox(), wxID_ANY, _("Round pads only"), wxDefaultPosition, wxDefaultSize, 0 );
sbFilters->Add( m_roundPadsFilter, 0, wxRIGHT|wxLEFT, 5 );
m_existingFilter = new wxCheckBox( sbFilters->GetStaticBox(), wxID_ANY, _("Existing teardrops only"), wxDefaultPosition, wxDefaultSize, 0 );
sbFilters->Add( m_existingFilter, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_selectedItemsFilter = new wxCheckBox( sbFilters->GetStaticBox(), wxID_ANY, _("Selected items only"), wxDefaultPosition, wxDefaultSize, 0 );
sbFilters->Add( m_selectedItemsFilter, 0, wxALL, 5 );
bSizerTop->Add( sbFilters, 2, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 10 );
bMainSizer->Add( bSizerTop, 0, wxEXPAND, 5 );
wxStaticBoxSizer* sbAction;
sbAction = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Action") ), wxVERTICAL );
m_removeTeardrops = new wxRadioButton( sbAction->GetStaticBox(), ID_SPECIFIED_NET_TO_NETCLASS_VALUES, _("Remove teardrops"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
sbAction->Add( m_removeTeardrops, 0, wxBOTTOM|wxRIGHT, 15 );
wxBoxSizer* bSizer12;
bSizer12 = new wxBoxSizer( wxHORIZONTAL );
m_addTeardrops = new wxRadioButton( sbAction->GetStaticBox(), ID_SPECIFIED_NET_TO_NETCLASS_VALUES, _("Add teardrops with default values for shape"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer12->Add( m_addTeardrops, 1, wxALIGN_CENTER_VERTICAL, 5 );
m_boardSetupLink = new wxHyperlinkCtrl( sbAction->GetStaticBox(), wxID_ANY, _("Edit default values in Board Setup"), wxT("#teardrops"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE );
bSizer12->Add( m_boardSetupLink, 1, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 10 );
sbAction->Add( bSizer12, 0, wxEXPAND|wxBOTTOM, 15 );
m_specifiedValues = new wxRadioButton( sbAction->GetStaticBox(), ID_SPECIFIED_NET_TO_SPECIFIED_VALUES, _("Add teardrops with specified values:"), wxDefaultPosition, wxDefaultSize, 0 );
sbAction->Add( m_specifiedValues, 0, wxEXPAND, 5 );
wxBoxSizer* bSizerSpecifiedValues;
bSizerSpecifiedValues = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizerCols11;
bSizerCols11 = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bSizerLeftCol11;
bSizerLeftCol11 = new wxBoxSizer( wxVERTICAL );
m_cbPreferZoneConnection = new wxCheckBox( sbAction->GetStaticBox(), wxID_ANY, _("Prefer zone connection"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER );
bSizerLeftCol11->Add( m_cbPreferZoneConnection, 0, wxBOTTOM|wxRIGHT, 5 );
m_cbTeardropsUseNextTrack = new wxCheckBox( sbAction->GetStaticBox(), wxID_ANY, _("Allow teardrops to span 2 track segments"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER );
m_cbTeardropsUseNextTrack->SetToolTip( _("Allows a teardrop to spread over 2 tracks if the first track segment is too short") );
bSizerLeftCol11->Add( m_cbTeardropsUseNextTrack, 0, wxBOTTOM|wxRIGHT, 5 );
bSizerCols11->Add( bSizerLeftCol11, 1, wxEXPAND|wxTOP, 3 );
bSizerCols11->Add( 25, 0, 0, wxEXPAND, 5 );
wxBoxSizer* bSizerRightCol11;
bSizerRightCol11 = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizer39;
bSizer39 = new wxBoxSizer( wxHORIZONTAL );
m_stHDRatio = new wxStaticText( sbAction->GetStaticBox(), wxID_ANY, _("Maximum track width:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHDRatio->Wrap( -1 );
m_stHDRatio->SetToolTip( _("Max pad/via size to track width ratio to create a teardrop.\n100 always creates a teardrop.") );
bSizer39->Add( m_stHDRatio, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_tcHDRatio = new wxTextCtrl( sbAction->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 );
m_tcHDRatio->SetToolTip( _("Tracks which are similar in size to the pad or via do not need teardrops.") );
bSizer39->Add( m_tcHDRatio, 0, wxRIGHT|wxLEFT, 5 );
m_stHDRatioUnits = new wxStaticText( sbAction->GetStaticBox(), wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHDRatioUnits->Wrap( -1 );
bSizer39->Add( m_stHDRatioUnits, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 );
bSizerRightCol11->Add( bSizer39, 0, wxEXPAND, 3 );
m_minTrackWidthHint = new wxStaticText( sbAction->GetStaticBox(), wxID_ANY, _("(as a percentage of pad/via size)"), wxDefaultPosition, wxDefaultSize, 0 );
m_minTrackWidthHint->Wrap( -1 );
bSizerRightCol11->Add( m_minTrackWidthHint, 0, wxTOP|wxBOTTOM|wxLEFT, 2 );
bSizerCols11->Add( bSizerRightCol11, 1, wxEXPAND|wxLEFT, 10 );
bSizerSpecifiedValues->Add( bSizerCols11, 0, wxEXPAND|wxTOP, 3 );
bSizerSpecifiedValues->Add( 0, 5, 0, wxEXPAND, 5 );
wxBoxSizer* bSizerShapeColumns;
bSizerShapeColumns = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bSizerLeftCol;
bSizerLeftCol = new wxBoxSizer( wxVERTICAL );
m_bitmapTeardrop = new wxStaticBitmap( sbAction->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
bSizerLeftCol->Add( m_bitmapTeardrop, 1, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT, 5 );
wxBoxSizer* bSizer41;
bSizer41 = new wxBoxSizer( wxHORIZONTAL );
m_staticText15 = new wxStaticText( sbAction->GetStaticBox(), wxID_ANY, _("Edges:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText15->Wrap( -1 );
bSizer41->Add( m_staticText15, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5 );
m_rbStraightLines = new wxRadioButton( sbAction->GetStaticBox(), wxID_ANY, _("Straight lines"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
bSizer41->Add( m_rbStraightLines, 1, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5 );
m_rbCurved = new wxRadioButton( sbAction->GetStaticBox(), wxID_ANY, _("Curved"), wxDefaultPosition, wxDefaultSize, wxRB_SINGLE );
bSizer41->Add( m_rbCurved, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5 );
bSizerLeftCol->Add( bSizer41, 0, wxEXPAND|wxBOTTOM, 5 );
bSizerShapeColumns->Add( bSizerLeftCol, 1, wxEXPAND|wxRIGHT, 10 );
bSizerShapeColumns->Add( 25, 0, 0, wxEXPAND, 5 );
wxFlexGridSizer* fgSizerRightCol;
fgSizerRightCol = new wxFlexGridSizer( 0, 3, 2, 0 );
fgSizerRightCol->AddGrowableCol( 1 );
fgSizerRightCol->SetFlexibleDirection( wxBOTH );
fgSizerRightCol->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_stLenPercentLabel = new wxStaticText( sbAction->GetStaticBox(), wxID_ANY, _("Best length:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stLenPercentLabel->Wrap( -1 );
fgSizerRightCol->Add( m_stLenPercentLabel, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_tcLenPercent = new wxTextCtrl( sbAction->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerRightCol->Add( m_tcLenPercent, 0, wxEXPAND|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
m_stLenPercentUnits = new wxStaticText( sbAction->GetStaticBox(), wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stLenPercentUnits->Wrap( -1 );
fgSizerRightCol->Add( m_stLenPercentUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_stMaxLen = new wxStaticText( sbAction->GetStaticBox(), wxID_ANY, _("Max length:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxLen->Wrap( -1 );
fgSizerRightCol->Add( m_stMaxLen, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_tcTdMaxLen = new wxTextCtrl( sbAction->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerRightCol->Add( m_tcTdMaxLen, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_stMaxLenUnits = new wxStaticText( sbAction->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxLenUnits->Wrap( -1 );
fgSizerRightCol->Add( m_stMaxLenUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
fgSizerRightCol->Add( 0, 5, 1, wxEXPAND, 5 );
fgSizerRightCol->Add( 0, 0, 1, wxEXPAND, 5 );
fgSizerRightCol->Add( 0, 0, 1, wxEXPAND, 5 );
m_stHeightPercentLabel = new wxStaticText( sbAction->GetStaticBox(), wxID_ANY, _("Best height:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHeightPercentLabel->Wrap( -1 );
fgSizerRightCol->Add( m_stHeightPercentLabel, 0, wxALIGN_CENTER_VERTICAL, 10 );
m_tcHeightPercent = new wxTextCtrl( sbAction->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerRightCol->Add( m_tcHeightPercent, 0, wxEXPAND|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
m_stHeightPercentUnits = new wxStaticText( sbAction->GetStaticBox(), wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHeightPercentUnits->Wrap( -1 );
fgSizerRightCol->Add( m_stHeightPercentUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_stMaxHeight = new wxStaticText( sbAction->GetStaticBox(), wxID_ANY, _("Max height:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxHeight->Wrap( -1 );
fgSizerRightCol->Add( m_stMaxHeight, 0, wxALIGN_CENTER_VERTICAL, 10 );
m_tcMaxHeight = new wxTextCtrl( sbAction->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerRightCol->Add( m_tcMaxHeight, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_stMaxHeightUnits = new wxStaticText( sbAction->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxHeightUnits->Wrap( -1 );
fgSizerRightCol->Add( m_stMaxHeightUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
fgSizerRightCol->Add( 0, 0, 1, wxEXPAND, 5 );
fgSizerRightCol->Add( 0, 0, 1, wxEXPAND, 5 );
fgSizerRightCol->Add( 0, 5, 1, wxEXPAND, 5 );
m_curvePointsLabel = new wxStaticText( sbAction->GetStaticBox(), wxID_ANY, _("Curve points:"), wxDefaultPosition, wxDefaultSize, 0 );
m_curvePointsLabel->Wrap( -1 );
fgSizerRightCol->Add( m_curvePointsLabel, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 5 );
m_curvePointsCtrl = new wxTextCtrl( sbAction->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 );
fgSizerRightCol->Add( m_curvePointsCtrl, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
bSizerShapeColumns->Add( fgSizerRightCol, 1, wxEXPAND|wxTOP|wxLEFT, 10 );
bSizerSpecifiedValues->Add( bSizerShapeColumns, 1, wxEXPAND|wxBOTTOM, 3 );
sbAction->Add( bSizerSpecifiedValues, 0, wxEXPAND|wxLEFT, 25 );
bMainSizer->Add( sbAction, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 10 );
m_sdbSizer = new wxStdDialogButtonSizer();
m_sdbSizerOK = new wxButton( this, wxID_OK );
m_sdbSizer->AddButton( m_sdbSizerOK );
m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
m_sdbSizer->AddButton( m_sdbSizerCancel );
m_sdbSizer->Realize();
bMainSizer->Add( m_sdbSizer, 0, wxEXPAND|wxALL, 5 );
this->SetSizer( bMainSizer );
this->Layout();
bMainSizer->Fit( this );
// Connect Events
m_trackToTrack->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onTrackToTrack ), NULL, this );
m_netFilterOpt->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onFilterUpdateUi ), NULL, this );
m_netFilter->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onFilterUpdateUi ), NULL, this );
m_netclassFilterOpt->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onFilterUpdateUi ), NULL, this );
m_netclassFilter->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::OnNetclassFilterSelect ), NULL, this );
m_netclassFilter->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onFilterUpdateUi ), NULL, this );
m_layerFilterOpt->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onFilterUpdateUi ), NULL, this );
m_layerFilter->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::OnLayerFilterSelect ), NULL, this );
m_layerFilter->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onFilterUpdateUi ), NULL, this );
m_roundPadsFilter->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onFilterUpdateUi ), NULL, this );
m_existingFilter->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::OnExistingFilterSelect ), NULL, this );
m_existingFilter->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onFilterUpdateUi ), NULL, this );
m_selectedItemsFilter->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onFilterUpdateUi ), NULL, this );
m_boardSetupLink->Connect( wxEVT_COMMAND_HYPERLINK, wxHyperlinkEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onShowBoardSetup ), NULL, this );
m_cbPreferZoneConnection->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_cbTeardropsUseNextTrack->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_stHDRatio->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_tcHDRatio->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_stHDRatioUnits->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_minTrackWidthHint->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_bitmapTeardrop->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_staticText15->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_rbStraightLines->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onStraightLines ), NULL, this );
m_rbStraightLines->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_rbCurved->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onCurvedLines ), NULL, this );
m_rbCurved->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_stLenPercentLabel->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_tcLenPercent->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_stLenPercentUnits->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_stMaxLen->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_tcTdMaxLen->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_stMaxLenUnits->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_stHeightPercentLabel->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_tcHeightPercent->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_stHeightPercentUnits->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_stMaxHeight->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_tcMaxHeight->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_stMaxHeightUnits->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_curvePointsLabel->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onCurvedEdgesUpdateUi ), NULL, this );
m_curvePointsCtrl->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onCurvedEdgesUpdateUi ), NULL, this );
}
DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::~DIALOG_GLOBAL_EDIT_TEARDROPS_BASE()
{
// Disconnect Events
m_trackToTrack->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onTrackToTrack ), NULL, this );
m_netFilterOpt->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onFilterUpdateUi ), NULL, this );
m_netFilter->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onFilterUpdateUi ), NULL, this );
m_netclassFilterOpt->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onFilterUpdateUi ), NULL, this );
m_netclassFilter->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::OnNetclassFilterSelect ), NULL, this );
m_netclassFilter->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onFilterUpdateUi ), NULL, this );
m_layerFilterOpt->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onFilterUpdateUi ), NULL, this );
m_layerFilter->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::OnLayerFilterSelect ), NULL, this );
m_layerFilter->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onFilterUpdateUi ), NULL, this );
m_roundPadsFilter->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onFilterUpdateUi ), NULL, this );
m_existingFilter->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::OnExistingFilterSelect ), NULL, this );
m_existingFilter->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onFilterUpdateUi ), NULL, this );
m_selectedItemsFilter->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onFilterUpdateUi ), NULL, this );
m_boardSetupLink->Disconnect( wxEVT_COMMAND_HYPERLINK, wxHyperlinkEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onShowBoardSetup ), NULL, this );
m_cbPreferZoneConnection->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_cbTeardropsUseNextTrack->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_stHDRatio->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_tcHDRatio->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_stHDRatioUnits->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_minTrackWidthHint->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_bitmapTeardrop->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_staticText15->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_rbStraightLines->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onStraightLines ), NULL, this );
m_rbStraightLines->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_rbCurved->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onCurvedLines ), NULL, this );
m_rbCurved->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_stLenPercentLabel->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_tcLenPercent->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_stLenPercentUnits->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_stMaxLen->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_tcTdMaxLen->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_stMaxLenUnits->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_stHeightPercentLabel->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_tcHeightPercent->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_stHeightPercentUnits->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_stMaxHeight->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_tcMaxHeight->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_stMaxHeightUnits->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onSpecifiedValuesUpdateUi ), NULL, this );
m_curvePointsLabel->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onCurvedEdgesUpdateUi ), NULL, this );
m_curvePointsCtrl->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_GLOBAL_EDIT_TEARDROPS_BASE::onCurvedEdgesUpdateUi ), NULL, this );
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,116 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
class PCB_LAYER_BOX_SELECTOR;
#include "dialog_shim.h"
#include <wx/string.h>
#include <wx/checkbox.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/sizer.h>
#include <wx/statbox.h>
#include <widgets/net_selector.h>
#include <wx/choice.h>
#include <wx/bmpcbox.h>
#include <wx/radiobut.h>
#include <wx/hyperlink.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/statbmp.h>
#include <wx/button.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
#define ID_SPECIFIED_NET_TO_NETCLASS_VALUES 1000
#define ID_SPECIFIED_NET_TO_SPECIFIED_VALUES 1001
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_GLOBAL_EDIT_TEARDROPS_BASE
///////////////////////////////////////////////////////////////////////////////
class DIALOG_GLOBAL_EDIT_TEARDROPS_BASE : public DIALOG_SHIM
{
private:
protected:
wxCheckBox* m_pthPads;
wxCheckBox* m_smdPads;
wxCheckBox* m_vias;
wxCheckBox* m_trackToTrack;
wxCheckBox* m_netFilterOpt;
NET_SELECTOR* m_netFilter;
wxCheckBox* m_netclassFilterOpt;
wxChoice* m_netclassFilter;
wxCheckBox* m_layerFilterOpt;
PCB_LAYER_BOX_SELECTOR* m_layerFilter;
wxCheckBox* m_roundPadsFilter;
wxCheckBox* m_existingFilter;
wxCheckBox* m_selectedItemsFilter;
wxRadioButton* m_removeTeardrops;
wxRadioButton* m_addTeardrops;
wxHyperlinkCtrl* m_boardSetupLink;
wxRadioButton* m_specifiedValues;
wxCheckBox* m_cbPreferZoneConnection;
wxCheckBox* m_cbTeardropsUseNextTrack;
wxStaticText* m_stHDRatio;
wxTextCtrl* m_tcHDRatio;
wxStaticText* m_stHDRatioUnits;
wxStaticText* m_minTrackWidthHint;
wxStaticBitmap* m_bitmapTeardrop;
wxStaticText* m_staticText15;
wxRadioButton* m_rbStraightLines;
wxRadioButton* m_rbCurved;
wxStaticText* m_stLenPercentLabel;
wxTextCtrl* m_tcLenPercent;
wxStaticText* m_stLenPercentUnits;
wxStaticText* m_stMaxLen;
wxTextCtrl* m_tcTdMaxLen;
wxStaticText* m_stMaxLenUnits;
wxStaticText* m_stHeightPercentLabel;
wxTextCtrl* m_tcHeightPercent;
wxStaticText* m_stHeightPercentUnits;
wxStaticText* m_stMaxHeight;
wxTextCtrl* m_tcMaxHeight;
wxStaticText* m_stMaxHeightUnits;
wxStaticText* m_curvePointsLabel;
wxTextCtrl* m_curvePointsCtrl;
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;
wxButton* m_sdbSizerCancel;
// Virtual event handlers, override them in your derived class
virtual void onTrackToTrack( wxCommandEvent& event ) { event.Skip(); }
virtual void onFilterUpdateUi( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void OnNetclassFilterSelect( wxCommandEvent& event ) { event.Skip(); }
virtual void OnLayerFilterSelect( wxCommandEvent& event ) { event.Skip(); }
virtual void OnExistingFilterSelect( wxCommandEvent& event ) { event.Skip(); }
virtual void onShowBoardSetup( wxHyperlinkEvent& event ) { event.Skip(); }
virtual void onSpecifiedValuesUpdateUi( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void onStraightLines( wxMouseEvent& event ) { event.Skip(); }
virtual void onCurvedLines( wxMouseEvent& event ) { event.Skip(); }
virtual void onCurvedEdgesUpdateUi( wxUpdateUIEvent& event ) { event.Skip(); }
public:
DIALOG_GLOBAL_EDIT_TEARDROPS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Set Teardrops"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_GLOBAL_EDIT_TEARDROPS_BASE();
};

View File

@ -88,7 +88,7 @@ DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS_BASE::DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS_
m_footprintFilter = new wxTextCtrl( sbFilters->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer2->Add( m_footprintFilter, 0, wxBOTTOM|wxEXPAND|wxLEFT, 5 );
m_selectedItemsFilter = new wxCheckBox( sbFilters->GetStaticBox(), wxID_ANY, _("Only include selected items"), wxDefaultPosition, wxDefaultSize, 0 );
m_selectedItemsFilter = new wxCheckBox( sbFilters->GetStaticBox(), wxID_ANY, _("Selected items only"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer2->Add( m_selectedItemsFilter, 0, wxALL, 5 );

View File

@ -1077,7 +1077,7 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Only include selected items</property>
<property name="label">Selected items only</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>

View File

@ -180,9 +180,9 @@ DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::~DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS()
g_filterByLayer = m_layerFilterOpt->GetValue();
g_layerFilter = m_layerFilter->GetLayerSelection();
g_filterByTrackWidth = m_filterByTrackWidth->GetValue();
g_trackWidthFilter = m_trackWidthFilter.GetValue();
g_trackWidthFilter = m_trackWidthFilter.GetIntValue();
g_filterByViaSize = m_filterByViaSize->GetValue();
g_viaSizeFilter = m_viaSizeFilter.GetValue();
g_viaSizeFilter = m_viaSizeFilter.GetIntValue();
g_filterSelected = m_selectedItemsFilter->GetValue();
m_netFilter->Disconnect( NET_SELECTED,

View File

@ -118,7 +118,7 @@ DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE::DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS_BASE
sbFilters->Add( 0, 5, 0, 0, 5 );
m_selectedItemsFilter = new wxCheckBox( sbFilters->GetStaticBox(), wxID_ANY, _("Only include selected items"), wxDefaultPosition, wxDefaultSize, 0 );
m_selectedItemsFilter = new wxCheckBox( sbFilters->GetStaticBox(), wxID_ANY, _("Selected items only"), wxDefaultPosition, wxDefaultSize, 0 );
sbFilters->Add( m_selectedItemsFilter, 0, wxALL, 5 );

View File

@ -1112,7 +1112,7 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Only include selected items</property>
<property name="label">Selected items only</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>

View File

@ -66,6 +66,9 @@ DIALOG_IMPORT_SETTINGS_BASE::DIALOG_IMPORT_SETTINGS_BASE( wxWindow* parent, wxWi
m_TracksAndViasOpt = new wxCheckBox( this, wxID_ANY, _("Predefined track && via dimensions"), wxDefaultPosition, wxDefaultSize, 0 );
bLeftCol->Add( m_TracksAndViasOpt, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_TeardropsOpt = new wxCheckBox( this, wxID_ANY, _("Teardrop defaults"), wxDefaultPosition, wxDefaultSize, 0 );
bLeftCol->Add( m_TeardropsOpt, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_NetclassesOpt = new wxCheckBox( this, wxID_ANY, _("Net classes"), wxDefaultPosition, wxDefaultSize, 0 );
bLeftCol->Add( m_NetclassesOpt, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );

View File

@ -739,6 +739,70 @@
<event name="OnCheckBox">OnCheckboxClicked</event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Teardrop defaults</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_TeardropsOpt</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">public</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>

View File

@ -61,6 +61,7 @@ class DIALOG_IMPORT_SETTINGS_BASE : public DIALOG_SHIM
wxCheckBox* m_FormattingOpt;
wxCheckBox* m_ConstraintsOpt;
wxCheckBox* m_TracksAndViasOpt;
wxCheckBox* m_TeardropsOpt;
wxCheckBox* m_NetclassesOpt;
wxCheckBox* m_SeveritiesOpt;

View File

@ -201,7 +201,7 @@ bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataFromWindow()
// Transfer data out of the GUI.
STROKE_PARAMS stroke = m_shape->GetStroke();
stroke.SetWidth( m_thickness.GetValue() );
stroke.SetWidth( m_thickness.GetIntValue() );
m_shape->SetStroke( stroke );
m_shape->SetFilled( m_filledCtrl->GetValue() );
@ -210,26 +210,26 @@ bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataFromWindow()
{
case SHAPE_T::SEGMENT:
case SHAPE_T::RECT:
m_shape->SetStart( VECTOR2I( m_startX.GetValue(), m_startY.GetValue() ) );
m_shape->SetEnd( VECTOR2I( m_endX.GetValue(), m_endY.GetValue() ) );
m_shape->SetStart( VECTOR2I( m_startX.GetIntValue(), m_startY.GetIntValue() ) );
m_shape->SetEnd( VECTOR2I( m_endX.GetIntValue(), m_endY.GetIntValue() ) );
break;
case SHAPE_T::BEZIER:
m_shape->SetStart( VECTOR2I( m_startX.GetValue(), m_startY.GetValue() ) );
m_shape->SetEnd( VECTOR2I( m_endX.GetValue(), m_endY.GetValue() ) );
m_shape->SetBezierC1( VECTOR2I( m_ctrl1X.GetValue(), m_ctrl1Y.GetValue()));
m_shape->SetBezierC2( VECTOR2I( m_ctrl2X.GetValue(), m_ctrl2Y.GetValue()));
m_shape->SetStart( VECTOR2I( m_startX.GetIntValue(), m_startY.GetIntValue() ) );
m_shape->SetEnd( VECTOR2I( m_endX.GetIntValue(), m_endY.GetIntValue() ) );
m_shape->SetBezierC1( VECTOR2I( m_ctrl1X.GetIntValue(), m_ctrl1Y.GetIntValue()));
m_shape->SetBezierC2( VECTOR2I( m_ctrl2X.GetIntValue(), m_ctrl2Y.GetIntValue()));
break;
case SHAPE_T::ARC:
m_shape->SetCenter( VECTOR2I( m_endX.GetValue(), m_endY.GetValue() ) );
m_shape->SetStart( VECTOR2I( m_startX.GetValue(), m_startY.GetValue() ) );
m_shape->SetCenter( VECTOR2I( m_endX.GetIntValue(), m_endY.GetIntValue() ) );
m_shape->SetStart( VECTOR2I( m_startX.GetIntValue(), m_startY.GetIntValue() ) );
m_shape->SetArcAngleAndEnd( m_radius.GetAngleValue() );
break;
case SHAPE_T::CIRCLE:
m_shape->SetStart( VECTOR2I( m_startX.GetValue(), m_startY.GetValue() ) );
m_shape->SetEnd( m_shape->GetStart() + VECTOR2I( m_radius.GetValue(), 0 ) );
m_shape->SetStart( VECTOR2I( m_startX.GetIntValue(), m_startY.GetIntValue() ) );
m_shape->SetEnd( m_shape->GetStart() + VECTOR2I( m_radius.GetIntValue(), 0 ) );
break;
case SHAPE_T::POLY:
@ -333,7 +333,7 @@ bool DIALOG_PAD_PRIMITIVE_POLY_PROPS::TransferDataFromWindow()
m_shape->SetPolyPoints( m_currPoints );
STROKE_PARAMS stroke = m_shape->GetStroke();
stroke.SetWidth( m_thickness.GetValue() );
stroke.SetWidth( m_thickness.GetIntValue() );
m_shape->SetStroke( stroke );
m_shape->SetFilled( m_filledCtrl->GetValue() );
@ -496,7 +496,7 @@ void DIALOG_PAD_PRIMITIVE_POLY_PROPS::onPaintPolyPanel( wxPaintEvent& event )
// The draw origin is the center of the window.
// Therefore the window size is twice the minsize just calculated
minsize *= 2;
minsize += m_thickness.GetValue();
minsize += m_thickness.GetIntValue();
// Give a margin
double scale = std::min( double( dc_size.x ) / minsize, double( dc_size.y ) / minsize ) * 0.9;

View File

@ -139,7 +139,9 @@ DIALOG_PAD_PROPERTIES::DIALOG_PAD_PROPERTIES( PCB_BASE_FRAME* aParent, PAD* aPad
m_thermalGap( aParent, m_thermalGapLabel, m_thermalGapCtrl, m_thermalGapUnits ),
m_spokeWidth( aParent, m_spokeWidthLabel, m_spokeWidthCtrl, m_spokeWidthUnits ),
m_spokeAngle( aParent, m_spokeAngleLabel, m_spokeAngleCtrl, m_spokeAngleUnits ),
m_pad_orientation( aParent, m_PadOrientText, m_cb_padrotation, m_orientationUnits )
m_pad_orientation( aParent, m_PadOrientText, m_cb_padrotation, m_orientationUnits ),
m_teardropMaxLenSetting( aParent, m_stMaxLen, m_tcTdMaxLen, m_stMaxLenUnits ),
m_teardropMaxHeightSetting( aParent, m_stTdMaxSize, m_tcMaxHeight, m_stMaxHeightUnits )
{
SetName( PAD_PROPERTIES_DLG_NAME );
m_isFpEditor = dynamic_cast<FOOTPRINT_EDIT_FRAME*>( aParent ) != nullptr;
@ -160,6 +162,7 @@ DIALOG_PAD_PROPERTIES::DIALOG_PAD_PROPERTIES( PCB_BASE_FRAME* aParent, PAD* aPad
m_FlippedWarningIcon->SetBitmap( KiBitmap( BITMAPS::dialog_warning ) );
m_nonCopperWarningIcon->SetBitmap( KiBitmap( BITMAPS::dialog_warning ) );
m_legacyTeardropsIcon->SetBitmap( KiBitmap( BITMAPS::dialog_warning ) );
m_masterPad = m_parent->GetDesignSettings().m_Pad_Master.get();
m_previewPad = new PAD( (FOOTPRINT*) nullptr );
@ -169,6 +172,7 @@ DIALOG_PAD_PROPERTIES::DIALOG_PAD_PROPERTIES( PCB_BASE_FRAME* aParent, PAD* aPad
SetTitle( _( "Pad Properties" ) );
*m_previewPad = *aPad;
m_previewPad->GetTeardropParams() = aPad->GetTeardropParams();
m_previewPad->ClearFlags( SELECTED|BRIGHTENED );
}
else
@ -176,6 +180,7 @@ DIALOG_PAD_PROPERTIES::DIALOG_PAD_PROPERTIES( PCB_BASE_FRAME* aParent, PAD* aPad
SetTitle( _( "Default Pad Properties for Add Pad Tool" ) );
*m_previewPad = *m_masterPad;
m_previewPad->GetTeardropParams() = m_masterPad->GetTeardropParams();
}
if( m_isFpEditor )
@ -211,11 +216,13 @@ DIALOG_PAD_PROPERTIES::DIALOG_PAD_PROPERTIES( PCB_BASE_FRAME* aParent, PAD* aPad
m_copperLayersLabel->SetFont( infoFont );
m_techLayersLabel->SetFont( infoFont );
m_parentInfo->SetFont( infoFont );
m_teardropShapeLabel->SetFont( infoFont );
infoFont.SetStyle( wxFONTSTYLE_ITALIC );
m_nonCopperNote->SetFont( infoFont );
m_staticTextInfoPaste->SetFont( infoFont );
m_staticTextPrimitiveListWarning->SetFont( infoFont );
m_minTrackWidthHint->SetFont( infoFont );
updateHoleControls();
updatePadSizeControls();
@ -560,6 +567,26 @@ void DIALOG_PAD_PROPERTIES::initValues()
m_pasteMarginRatio.ChangeDoubleValue( m_previewPad->GetLocalSolderPasteMarginRatio() * 100.0 );
m_pad_orientation.ChangeAngleValue( m_previewPad->GetOrientation() );
m_cbTeardrops->SetValue( m_previewPad->GetTeardropParams().m_Enabled );
m_cbTeardropsUseNextTrack->SetValue( m_previewPad->GetTeardropParams().m_AllowUseTwoTracks );
m_cbPreferZoneConnection->SetValue( !m_previewPad->GetTeardropParams().m_TdOnPadsInZones );
m_teardropMaxLenSetting.SetValue( m_previewPad->GetTeardropParams().m_TdMaxLen );
m_teardropMaxHeightSetting.SetValue( m_previewPad->GetTeardropParams().m_TdMaxWidth );
m_spTeardropLenPercent->SetValue( m_previewPad->GetTeardropParams().m_BestLengthRatio *100 );
m_spTeardropSizePercent->SetValue( m_previewPad->GetTeardropParams().m_BestWidthRatio *100 );
m_spTeardropHDPercent->SetValue( m_previewPad->GetTeardropParams().m_WidthtoSizeFilterRatio*100 );
if( m_previewPad->GetTeardropParams().IsCurved() )
{
m_rbCurved->SetValue( true );
m_curvePointsCtrl->SetValue( m_previewPad->GetTeardropParams().m_CurveSegCount );
}
else
{
m_rbStraightLines->SetValue( true );
m_curvePointsCtrl->SetValue( 5 );
}
switch( m_previewPad->GetZoneConnection() )
{
default:
@ -598,14 +625,14 @@ void DIALOG_PAD_PROPERTIES::initValues()
break;
}
m_cbTopLeft->SetValue( ( m_previewPad->GetChamferPositions() & RECT_CHAMFER_TOP_LEFT) );
m_cbTopLeft1->SetValue( ( m_previewPad->GetChamferPositions() & RECT_CHAMFER_TOP_LEFT) );
m_cbTopRight->SetValue( ( m_previewPad->GetChamferPositions() & RECT_CHAMFER_TOP_RIGHT) );
m_cbTopRight1->SetValue( ( m_previewPad->GetChamferPositions() & RECT_CHAMFER_TOP_RIGHT) );
m_cbBottomLeft->SetValue( ( m_previewPad->GetChamferPositions() & RECT_CHAMFER_BOTTOM_LEFT) );
m_cbBottomLeft1->SetValue( ( m_previewPad->GetChamferPositions() & RECT_CHAMFER_BOTTOM_LEFT) );
m_cbBottomRight->SetValue( ( m_previewPad->GetChamferPositions() & RECT_CHAMFER_BOTTOM_RIGHT) );
m_cbBottomRight1->SetValue( ( m_previewPad->GetChamferPositions() & RECT_CHAMFER_BOTTOM_RIGHT) );
m_cbTopLeft->SetValue( m_previewPad->GetChamferPositions() & RECT_CHAMFER_TOP_LEFT );
m_cbTopLeft1->SetValue( m_previewPad->GetChamferPositions() & RECT_CHAMFER_TOP_LEFT );
m_cbTopRight->SetValue( m_previewPad->GetChamferPositions() & RECT_CHAMFER_TOP_RIGHT );
m_cbTopRight1->SetValue( m_previewPad->GetChamferPositions() & RECT_CHAMFER_TOP_RIGHT );
m_cbBottomLeft->SetValue( m_previewPad->GetChamferPositions() & RECT_CHAMFER_BOTTOM_LEFT );
m_cbBottomLeft1->SetValue( m_previewPad->GetChamferPositions() & RECT_CHAMFER_BOTTOM_LEFT );
m_cbBottomRight->SetValue( m_previewPad->GetChamferPositions() & RECT_CHAMFER_BOTTOM_RIGHT );
m_cbBottomRight1->SetValue( m_previewPad->GetChamferPositions() & RECT_CHAMFER_BOTTOM_RIGHT );
updateRoundRectCornerValues();
@ -665,14 +692,16 @@ void DIALOG_PAD_PROPERTIES::initValues()
displayPrimitivesList();
}
// A small helper function, to display coordinates:
static wxString formatCoord( EDA_UNITS aUnits, VECTOR2I aCoord )
static wxString formatCoord( EDA_UNITS aUnits, const VECTOR2I& aCoord )
{
return wxString::Format( wxT( "(X:%s Y:%s)" ),
EDA_UNIT_UTILS::UI::MessageTextFromValue( pcbIUScale, aUnits, aCoord.x ),
EDA_UNIT_UTILS::UI::MessageTextFromValue( pcbIUScale, aUnits, aCoord.y ) );
}
void DIALOG_PAD_PROPERTIES::displayPrimitivesList()
{
m_listCtrlPrimitives->ClearAll();
@ -1096,6 +1125,20 @@ void DIALOG_PAD_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& event )
m_stackupImagesBook->ChangeSelection( 3 );
break;
}
m_legacyTeardropsWarning->Show( m_board->LegacyTeardrops() );
}
void DIALOG_PAD_PROPERTIES::onTeardropsUpdateUi( wxUpdateUIEvent& event )
{
event.Enable( !m_board->LegacyTeardrops() );
}
void DIALOG_PAD_PROPERTIES::onTeardropCurvePointsUpdateUi( wxUpdateUIEvent& event )
{
event.Enable( !m_board->LegacyTeardrops() && m_rbCurved->GetValue() );
}
@ -1624,6 +1667,8 @@ bool DIALOG_PAD_PROPERTIES::TransferDataFromWindow()
m_currentPad->SetChamferPositions( m_masterPad->GetChamferPositions() );
m_currentPad->SetZoneConnection( m_masterPad->GetZoneConnection() );
m_currentPad->GetTeardropParams() = m_masterPad->GetTeardropParams();
// rounded rect pads with radius ratio = 0 are in fact rect pads.
// So set the right shape (and perhaps issues with a radius = 0)
if( m_currentPad->GetShape() == PAD_SHAPE::ROUNDRECT &&
@ -1681,22 +1726,36 @@ PAD_PROP DIALOG_PAD_PROPERTIES::getSelectedProperty()
void DIALOG_PAD_PROPERTIES::updateHoleControls()
{
m_holeXLabel->SetLabel( ( m_holeShapeCtrl->GetSelection() == CHOICE_SHAPE_CIRCLE )
? _( "Diameter:" )
: _( "Hole size X:" ) );
m_holeY.Show( m_holeShapeCtrl->GetSelection() != CHOICE_SHAPE_CIRCLE
&& m_holeShapeCtrl->GetSelection() != CHOICE_SHAPE_CUSTOM_CIRC_ANCHOR );
if( m_holeShapeCtrl->GetSelection() == CHOICE_SHAPE_CIRCLE )
{
m_holeXLabel->SetLabel( _( "Diameter:" ) );
m_holeY.Show( false );
}
else
{
m_holeXLabel->SetLabel( _( "Hole size X:" ) );
m_holeY.Show( true );
}
m_holeXLabel->GetParent()->Layout();
}
void DIALOG_PAD_PROPERTIES::updatePadSizeControls()
{
m_sizeXLabel->SetLabel( ( m_PadShapeSelector->GetSelection() == CHOICE_SHAPE_CIRCLE
|| m_PadShapeSelector->GetSelection() == CHOICE_SHAPE_CUSTOM_CIRC_ANCHOR )
? _( "Diameter:" )
: _( "Pad size X:" ) );
m_sizeY.Show( m_PadShapeSelector->GetSelection() != CHOICE_SHAPE_CIRCLE
&& m_PadShapeSelector->GetSelection() != CHOICE_SHAPE_CUSTOM_CIRC_ANCHOR );
if( m_PadShapeSelector->GetSelection() == CHOICE_SHAPE_CIRCLE
|| m_PadShapeSelector->GetSelection() == CHOICE_SHAPE_CUSTOM_CIRC_ANCHOR )
{
m_sizeXLabel->SetLabel( _( "Diameter:" ) );
m_sizeY.Show( false );
m_bitmapTeardrop->SetBitmap( KiBitmap( BITMAPS::teardrop_sizes ) );
}
else
{
m_sizeXLabel->SetLabel( _( "Pad size X:" ) );
m_sizeY.Show( true );
m_bitmapTeardrop->SetBitmap( KiBitmap( BITMAPS::teardrop_rect_sizes ) );
}
m_sizeXLabel->GetParent()->Layout();
}
@ -1726,14 +1785,29 @@ bool DIALOG_PAD_PROPERTIES::transferDataToPad( PAD* aPad )
if( aPad->GetShape() == PAD_SHAPE::CUSTOM )
aPad->ReplacePrimitives( m_primitives );
aPad->GetTeardropParams().m_Enabled = m_cbTeardrops->GetValue();
aPad->GetTeardropParams().m_AllowUseTwoTracks = m_cbTeardropsUseNextTrack->GetValue();
aPad->GetTeardropParams().m_TdOnPadsInZones = !m_cbPreferZoneConnection->GetValue();
aPad->GetTeardropParams().m_TdMaxLen = m_teardropMaxLenSetting.GetIntValue();
aPad->GetTeardropParams().m_TdMaxWidth = m_teardropMaxHeightSetting.GetIntValue();
aPad->GetTeardropParams().m_BestLengthRatio = m_spTeardropLenPercent->GetValue() / 100;
aPad->GetTeardropParams().m_BestWidthRatio = m_spTeardropSizePercent->GetValue() / 100;
if( m_rbStraightLines->GetValue() )
aPad->GetTeardropParams().m_CurveSegCount = 0;
else
aPad->GetTeardropParams().m_CurveSegCount = m_curvePointsCtrl->GetValue();
aPad->GetTeardropParams().m_WidthtoSizeFilterRatio = m_spTeardropHDPercent->GetValue() / 100;
// Read pad clearances values:
aPad->SetLocalClearance( m_clearance.GetValue() );
aPad->SetLocalSolderMaskMargin( m_maskMargin.GetValue() );
aPad->SetLocalSolderPasteMargin( m_pasteMargin.GetValue() );
aPad->SetLocalClearance( m_clearance.GetIntValue() );
aPad->SetLocalSolderMaskMargin( m_maskMargin.GetIntValue() );
aPad->SetLocalSolderPasteMargin( m_pasteMargin.GetIntValue() );
aPad->SetLocalSolderPasteMarginRatio( m_pasteMarginRatio.GetDoubleValue() / 100.0 );
aPad->SetThermalSpokeWidth( m_spokeWidth.GetValue() );
aPad->SetThermalSpokeWidth( m_spokeWidth.GetIntValue() );
aPad->SetThermalSpokeAngle( m_spokeAngle.GetAngleValue() );
aPad->SetThermalGap( m_thermalGap.GetValue() );
aPad->SetThermalGap( m_thermalGap.GetIntValue() );
// And rotation
aPad->SetOrientation( m_pad_orientation.GetAngleValue() );
@ -1747,23 +1821,23 @@ bool DIALOG_PAD_PROPERTIES::transferDataToPad( PAD* aPad )
case 3: aPad->SetZoneConnection( ZONE_CONNECTION::NONE ); break;
}
aPad->SetPosition( VECTOR2I( m_posX.GetValue(), m_posY.GetValue() ) );
aPad->SetPosition( VECTOR2I( m_posX.GetIntValue(), m_posY.GetIntValue() ) );
if( m_holeShapeCtrl->GetSelection() == CHOICE_SHAPE_CIRCLE )
{
aPad->SetDrillShape( PAD_DRILL_SHAPE_CIRCLE );
aPad->SetDrillSize( VECTOR2I( m_holeX.GetValue(), m_holeX.GetValue() ) );
aPad->SetDrillSize( VECTOR2I( m_holeX.GetIntValue(), m_holeX.GetIntValue() ) );
}
else
{
aPad->SetDrillShape( PAD_DRILL_SHAPE_OBLONG );
aPad->SetDrillSize( VECTOR2I( m_holeX.GetValue(), m_holeY.GetValue() ) );
aPad->SetDrillSize( VECTOR2I( m_holeX.GetIntValue(), m_holeY.GetIntValue() ) );
}
if( aPad->GetShape() == PAD_SHAPE::CIRCLE )
aPad->SetSize( VECTOR2I( m_sizeX.GetValue(), m_sizeX.GetValue() ) );
aPad->SetSize( VECTOR2I( m_sizeX.GetIntValue(), m_sizeX.GetIntValue() ) );
else
aPad->SetSize( VECTOR2I( m_sizeX.GetValue(), m_sizeY.GetValue() ) );
aPad->SetSize( VECTOR2I( m_sizeX.GetIntValue(), m_sizeY.GetIntValue() ) );
// For a trapezoid, test delta value (be sure delta is not too large for pad size)
// remember DeltaSize.x is the Y size variation
@ -1774,9 +1848,9 @@ bool DIALOG_PAD_PROPERTIES::transferDataToPad( PAD* aPad )
{
// For a trapezoid, only one of delta.x or delta.y is not 0, depending on axis.
if( m_trapAxisCtrl->GetSelection() == 0 )
delta.x = m_trapDelta.GetValue();
delta.x = m_trapDelta.GetIntValue();
else
delta.y = m_trapDelta.GetValue();
delta.y = m_trapDelta.GetIntValue();
if( delta.x < 0 && delta.x < -aPad->GetSize().y )
{
@ -1806,13 +1880,13 @@ bool DIALOG_PAD_PROPERTIES::transferDataToPad( PAD* aPad )
aPad->SetDelta( delta );
if( m_offsetShapeOpt->GetValue() )
aPad->SetOffset( VECTOR2I( m_offsetX.GetValue(), m_offsetY.GetValue() ) );
aPad->SetOffset( VECTOR2I( m_offsetX.GetIntValue(), m_offsetY.GetIntValue() ) );
else
aPad->SetOffset( VECTOR2I() );
// Read pad length die
if( m_padToDieOpt->GetValue() )
aPad->SetPadToDieLength( m_padToDie.GetValue() );
aPad->SetPadToDieLength( m_padToDie.GetIntValue() );
else
aPad->SetPadToDieLength( 0 );
@ -1858,7 +1932,7 @@ bool DIALOG_PAD_PROPERTIES::transferDataToPad( PAD* aPad )
// diameter is acceptable, and is used in Gerber files as flashed area
// reference
if( aPad->GetAnchorPadShape() == PAD_SHAPE::CIRCLE )
aPad->SetSize( VECTOR2I( m_sizeX.GetValue(), m_sizeX.GetValue() ) );
aPad->SetSize( VECTOR2I( m_sizeX.GetIntValue(), m_sizeX.GetIntValue() ) );
}
// Define the way the clearance area is defined in zones. Since all non-custom pad

View File

@ -78,6 +78,8 @@ private:
void OnResize( wxSizeEvent& event );
void OnCancel( wxCommandEvent& event ) override;
void OnUpdateUI( wxUpdateUIEvent& event ) override;
void onTeardropsUpdateUi( wxUpdateUIEvent& event ) override;
void onTeardropCurvePointsUpdateUi( wxUpdateUIEvent& event ) override;
void OnUpdateUINonCopperWarning( wxUpdateUIEvent& event ) override;
@ -172,6 +174,8 @@ private:
UNIT_BINDER m_spokeWidth;
UNIT_BINDER m_spokeAngle;
UNIT_BINDER m_pad_orientation;
UNIT_BINDER m_teardropMaxLenSetting;
UNIT_BINDER m_teardropMaxHeightSetting;
};

View File

@ -569,6 +569,321 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind
m_panelGeneral->Layout();
bGeneralSizer->Fit( m_panelGeneral );
m_notebook->AddPage( m_panelGeneral, _("General"), true );
m_connectionsPanel = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizerPanelConnections;
bSizerPanelConnections = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizerConnectionsMargins;
bSizerConnectionsMargins = new wxBoxSizer( wxVERTICAL );
wxStaticBoxSizer* bSizerTeardrops;
bSizerTeardrops = new wxStaticBoxSizer( new wxStaticBox( m_connectionsPanel, wxID_ANY, _("Teardrops") ), wxVERTICAL );
m_legacyTeardropsWarning = new wxBoxSizer( wxHORIZONTAL );
m_legacyTeardropsIcon = new wxStaticBitmap( bSizerTeardrops->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
m_legacyTeardropsWarning->Add( m_legacyTeardropsIcon, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
wxBoxSizer* bSizer42;
bSizer42 = new wxBoxSizer( wxVERTICAL );
m_staticText85 = new wxStaticText( bSizerTeardrops->GetStaticBox(), wxID_ANY, _("Board contains legacy teardrops. "), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText85->Wrap( -1 );
bSizer42->Add( m_staticText85, 0, wxRIGHT|wxLEFT, 5 );
m_staticText851 = new wxStaticText( bSizerTeardrops->GetStaticBox(), wxID_ANY, _("Use Edit > Edit Teardrops to apply automatic teardrops."), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText851->Wrap( -1 );
bSizer42->Add( m_staticText851, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_legacyTeardropsWarning->Add( bSizer42, 1, wxALIGN_CENTER_VERTICAL, 5 );
bSizerTeardrops->Add( m_legacyTeardropsWarning, 0, wxEXPAND|wxBOTTOM, 5 );
wxBoxSizer* bSizerCols11;
bSizerCols11 = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bSizerLeftCol11;
bSizerLeftCol11 = new wxBoxSizer( wxVERTICAL );
m_cbTeardrops = new wxCheckBox( bSizerTeardrops->GetStaticBox(), wxID_ANY, _("Add teardrops on pad's track connections"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerLeftCol11->Add( m_cbTeardrops, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_cbPreferZoneConnection = new wxCheckBox( bSizerTeardrops->GetStaticBox(), wxID_ANY, _("Prefer zone connection"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbPreferZoneConnection->SetValue(true);
bSizerLeftCol11->Add( m_cbPreferZoneConnection, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_cbTeardropsUseNextTrack = new wxCheckBox( bSizerTeardrops->GetStaticBox(), wxID_ANY, _("Allow teardrops to span 2 track segments"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbTeardropsUseNextTrack->SetValue(true);
m_cbTeardropsUseNextTrack->SetToolTip( _("Allows a teardrop to spread over 2 tracks if the first track segment is too short") );
bSizerLeftCol11->Add( m_cbTeardropsUseNextTrack, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
bSizerCols11->Add( bSizerLeftCol11, 1, wxEXPAND|wxTOP, 3 );
bSizerCols11->Add( 15, 0, 0, wxEXPAND, 5 );
wxBoxSizer* bSizerRightCol11;
bSizerRightCol11 = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizer39;
bSizer39 = new wxBoxSizer( wxHORIZONTAL );
m_stHDRatio = new wxStaticText( bSizerTeardrops->GetStaticBox(), wxID_ANY, _("Maximum track width:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHDRatio->Wrap( -1 );
m_stHDRatio->SetToolTip( _("Max pad/via size to track width ratio to create a teardrop.\n100 always creates a teardrop.") );
bSizer39->Add( m_stHDRatio, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_spTeardropHDPercent = new wxSpinCtrlDouble( bSizerTeardrops->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 100, 90, 10 );
m_spTeardropHDPercent->SetDigits( 0 );
m_spTeardropHDPercent->SetToolTip( _("Tracks which are similar in size to the pad do not need teardrops.") );
bSizer39->Add( m_spTeardropHDPercent, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
m_minTrackWidthUnits = new wxStaticText( bSizerTeardrops->GetStaticBox(), wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_minTrackWidthUnits->Wrap( -1 );
bSizer39->Add( m_minTrackWidthUnits, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 );
bSizerRightCol11->Add( bSizer39, 0, wxEXPAND, 3 );
m_minTrackWidthHint = new wxStaticText( bSizerTeardrops->GetStaticBox(), wxID_ANY, _("(as a percentage of pad size)"), wxDefaultPosition, wxDefaultSize, 0 );
m_minTrackWidthHint->Wrap( -1 );
bSizerRightCol11->Add( m_minTrackWidthHint, 0, wxTOP|wxBOTTOM, 3 );
bSizerCols11->Add( bSizerRightCol11, 1, wxEXPAND|wxLEFT, 10 );
bSizerTeardrops->Add( bSizerCols11, 0, wxEXPAND, 5 );
bSizerTeardrops->Add( 0, 5, 0, wxEXPAND, 5 );
m_teardropShapeLabel = new wxStaticText( bSizerTeardrops->GetStaticBox(), wxID_ANY, _("Teardrop Shape"), wxDefaultPosition, wxDefaultSize, 0 );
m_teardropShapeLabel->Wrap( -1 );
bSizerTeardrops->Add( m_teardropShapeLabel, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_staticline51 = new wxStaticLine( bSizerTeardrops->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bSizerTeardrops->Add( m_staticline51, 0, wxEXPAND, 5 );
wxBoxSizer* bSizerShapeColumns;
bSizerShapeColumns = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bSizerLeftCol;
bSizerLeftCol = new wxBoxSizer( wxVERTICAL );
m_bitmapTeardrop = new wxStaticBitmap( bSizerTeardrops->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
bSizerLeftCol->Add( m_bitmapTeardrop, 1, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT, 5 );
wxBoxSizer* bSizer41;
bSizer41 = new wxBoxSizer( wxHORIZONTAL );
m_edgesLabel = new wxStaticText( bSizerTeardrops->GetStaticBox(), wxID_ANY, _("Edges:"), wxDefaultPosition, wxDefaultSize, 0 );
m_edgesLabel->Wrap( -1 );
bSizer41->Add( m_edgesLabel, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_rbStraightLines = new wxRadioButton( bSizerTeardrops->GetStaticBox(), wxID_ANY, _("Straight lines"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
bSizer41->Add( m_rbStraightLines, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_rbCurved = new wxRadioButton( bSizerTeardrops->GetStaticBox(), wxID_ANY, _("Curved"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer41->Add( m_rbCurved, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
bSizerLeftCol->Add( bSizer41, 0, wxEXPAND, 5 );
bSizerShapeColumns->Add( bSizerLeftCol, 1, wxEXPAND|wxRIGHT, 10 );
bSizerShapeColumns->Add( 10, 0, 0, wxEXPAND, 5 );
wxFlexGridSizer* fgSizerRightCol;
fgSizerRightCol = new wxFlexGridSizer( 0, 3, 2, 0 );
fgSizerRightCol->AddGrowableCol( 1 );
fgSizerRightCol->SetFlexibleDirection( wxBOTH );
fgSizerRightCol->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_stHsetting = new wxStaticText( bSizerTeardrops->GetStaticBox(), wxID_ANY, _("Best length:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHsetting->Wrap( -1 );
fgSizerRightCol->Add( m_stHsetting, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_spTeardropLenPercent = new wxSpinCtrlDouble( bSizerTeardrops->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 20, 100, 40.000000, 10 );
m_spTeardropLenPercent->SetDigits( 0 );
fgSizerRightCol->Add( m_spTeardropLenPercent, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_stTeardropLenUnits = new wxStaticText( bSizerTeardrops->GetStaticBox(), wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stTeardropLenUnits->Wrap( -1 );
fgSizerRightCol->Add( m_stTeardropLenUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_stMaxLen = new wxStaticText( bSizerTeardrops->GetStaticBox(), wxID_ANY, _("Max length:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxLen->Wrap( -1 );
fgSizerRightCol->Add( m_stMaxLen, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_tcTdMaxLen = new wxTextCtrl( bSizerTeardrops->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerRightCol->Add( m_tcTdMaxLen, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_stMaxLenUnits = new wxStaticText( bSizerTeardrops->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxLenUnits->Wrap( -1 );
fgSizerRightCol->Add( m_stMaxLenUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
fgSizerRightCol->Add( 0, 5, 1, wxEXPAND, 5 );
fgSizerRightCol->Add( 0, 0, 1, wxEXPAND, 5 );
fgSizerRightCol->Add( 0, 0, 1, wxEXPAND, 5 );
m_stVsetting = new wxStaticText( bSizerTeardrops->GetStaticBox(), wxID_ANY, _("Best height:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stVsetting->Wrap( -1 );
fgSizerRightCol->Add( m_stVsetting, 0, wxALIGN_CENTER_VERTICAL, 10 );
m_spTeardropSizePercent = new wxSpinCtrlDouble( bSizerTeardrops->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 60, 100, 100.000000, 10 );
m_spTeardropSizePercent->SetDigits( 0 );
fgSizerRightCol->Add( m_spTeardropSizePercent, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_stLenPercent = new wxStaticText( bSizerTeardrops->GetStaticBox(), wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stLenPercent->Wrap( -1 );
fgSizerRightCol->Add( m_stLenPercent, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_stTdMaxSize = new wxStaticText( bSizerTeardrops->GetStaticBox(), wxID_ANY, _("Max height:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stTdMaxSize->Wrap( -1 );
fgSizerRightCol->Add( m_stTdMaxSize, 0, wxALIGN_CENTER_VERTICAL, 10 );
m_tcMaxHeight = new wxTextCtrl( bSizerTeardrops->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerRightCol->Add( m_tcMaxHeight, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_stMaxHeightUnits = new wxStaticText( bSizerTeardrops->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxHeightUnits->Wrap( -1 );
fgSizerRightCol->Add( m_stMaxHeightUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
fgSizerRightCol->Add( 0, 0, 1, wxEXPAND, 5 );
fgSizerRightCol->Add( 0, 0, 1, wxEXPAND, 5 );
fgSizerRightCol->Add( 0, 5, 1, wxEXPAND, 5 );
m_curvePointsLabel = new wxStaticText( bSizerTeardrops->GetStaticBox(), wxID_ANY, _("Curve points:"), wxDefaultPosition, wxDefaultSize, 0 );
m_curvePointsLabel->Wrap( -1 );
fgSizerRightCol->Add( m_curvePointsLabel, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 5 );
m_curvePointsCtrl = new wxSpinCtrl( bSizerTeardrops->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 3, 10, 5 );
fgSizerRightCol->Add( m_curvePointsCtrl, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
bSizerShapeColumns->Add( fgSizerRightCol, 1, wxEXPAND|wxTOP|wxLEFT, 10 );
bSizerTeardrops->Add( bSizerShapeColumns, 1, wxEXPAND|wxBOTTOM, 5 );
bSizerConnectionsMargins->Add( bSizerTeardrops, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
wxBoxSizer* bSizerConnectionsLower;
bSizerConnectionsLower = new wxBoxSizer( wxHORIZONTAL );
m_sbSizerZonesSettings = new wxStaticBoxSizer( new wxStaticBox( m_connectionsPanel, wxID_ANY, _("Connection to Copper Zones") ), wxVERTICAL );
wxFlexGridSizer* fgSizerCopperZonesOpts;
fgSizerCopperZonesOpts = new wxFlexGridSizer( 0, 2, 5, 0 );
fgSizerCopperZonesOpts->AddGrowableCol( 1 );
fgSizerCopperZonesOpts->SetFlexibleDirection( wxBOTH );
fgSizerCopperZonesOpts->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_padConnectionLabel = new wxStaticText( m_sbSizerZonesSettings->GetStaticBox(), wxID_ANY, _("Pad connection:"), wxDefaultPosition, wxDefaultSize, 0 );
m_padConnectionLabel->Wrap( -1 );
fgSizerCopperZonesOpts->Add( m_padConnectionLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
wxString m_ZoneConnectionChoiceChoices[] = { _("From parent footprint"), _("Solid"), _("Thermal relief"), _("None") };
int m_ZoneConnectionChoiceNChoices = sizeof( m_ZoneConnectionChoiceChoices ) / sizeof( wxString );
m_ZoneConnectionChoice = new wxChoice( m_sbSizerZonesSettings->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_ZoneConnectionChoiceNChoices, m_ZoneConnectionChoiceChoices, 0 );
m_ZoneConnectionChoice->SetSelection( 0 );
fgSizerCopperZonesOpts->Add( m_ZoneConnectionChoice, 1, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_zoneKnockoutLabel = new wxStaticText( m_sbSizerZonesSettings->GetStaticBox(), wxID_ANY, _("Zone knockout:"), wxDefaultPosition, wxDefaultSize, 0 );
m_zoneKnockoutLabel->Wrap( -1 );
fgSizerCopperZonesOpts->Add( m_zoneKnockoutLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
wxString m_ZoneCustomPadShapeChoices[] = { _("Pad shape"), _("Pad convex hull") };
int m_ZoneCustomPadShapeNChoices = sizeof( m_ZoneCustomPadShapeChoices ) / sizeof( wxString );
m_ZoneCustomPadShape = new wxChoice( m_sbSizerZonesSettings->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_ZoneCustomPadShapeNChoices, m_ZoneCustomPadShapeChoices, 0 );
m_ZoneCustomPadShape->SetSelection( 0 );
fgSizerCopperZonesOpts->Add( m_ZoneCustomPadShape, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxLEFT, 5 );
m_sbSizerZonesSettings->Add( fgSizerCopperZonesOpts, 0, 0, 5 );
bSizerConnectionsLower->Add( m_sbSizerZonesSettings, 1, wxALL|wxEXPAND, 5 );
wxStaticBoxSizer* sbSizerThermalReliefs;
sbSizerThermalReliefs = new wxStaticBoxSizer( new wxStaticBox( m_connectionsPanel, wxID_ANY, _("Thermal Relief Overrides") ), wxVERTICAL );
wxFlexGridSizer* fgSizerThermalReliefs;
fgSizerThermalReliefs = new wxFlexGridSizer( 0, 3, 3, 0 );
fgSizerThermalReliefs->AddGrowableCol( 1 );
fgSizerThermalReliefs->SetFlexibleDirection( wxBOTH );
fgSizerThermalReliefs->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_thermalGapLabel = new wxStaticText( sbSizerThermalReliefs->GetStaticBox(), wxID_ANY, _("Relief gap:"), wxDefaultPosition, wxDefaultSize, 0 );
m_thermalGapLabel->Wrap( -1 );
fgSizerThermalReliefs->Add( m_thermalGapLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_thermalGapCtrl = new wxTextCtrl( sbSizerThermalReliefs->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerThermalReliefs->Add( m_thermalGapCtrl, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxEXPAND, 5 );
m_thermalGapUnits = new wxStaticText( sbSizerThermalReliefs->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_thermalGapUnits->Wrap( -1 );
fgSizerThermalReliefs->Add( m_thermalGapUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
m_spokeWidthLabel = new wxStaticText( sbSizerThermalReliefs->GetStaticBox(), wxID_ANY, _("Spoke width:"), wxDefaultPosition, wxDefaultSize, 0 );
m_spokeWidthLabel->Wrap( -1 );
fgSizerThermalReliefs->Add( m_spokeWidthLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_spokeWidthCtrl = new wxTextCtrl( sbSizerThermalReliefs->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerThermalReliefs->Add( m_spokeWidthCtrl, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_spokeWidthUnits = new wxStaticText( sbSizerThermalReliefs->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_spokeWidthUnits->Wrap( -1 );
fgSizerThermalReliefs->Add( m_spokeWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
m_spokeAngleLabel = new wxStaticText( sbSizerThermalReliefs->GetStaticBox(), wxID_ANY, _("Spoke angle:"), wxDefaultPosition, wxDefaultSize, 0 );
m_spokeAngleLabel->Wrap( -1 );
fgSizerThermalReliefs->Add( m_spokeAngleLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
m_spokeAngleCtrl = new wxTextCtrl( sbSizerThermalReliefs->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerThermalReliefs->Add( m_spokeAngleCtrl, 0, wxEXPAND|wxLEFT, 5 );
m_spokeAngleUnits = new wxStaticText( sbSizerThermalReliefs->GetStaticBox(), wxID_ANY, _("deg"), wxDefaultPosition, wxDefaultSize, 0 );
m_spokeAngleUnits->Wrap( -1 );
fgSizerThermalReliefs->Add( m_spokeAngleUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
sbSizerThermalReliefs->Add( fgSizerThermalReliefs, 1, wxEXPAND, 5 );
bSizerConnectionsLower->Add( sbSizerThermalReliefs, 1, wxEXPAND|wxALL, 5 );
bSizerConnectionsMargins->Add( bSizerConnectionsLower, 0, wxEXPAND|wxTOP, 10 );
bSizerPanelConnections->Add( bSizerConnectionsMargins, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_connectionsPanel->SetSizer( bSizerPanelConnections );
m_connectionsPanel->Layout();
bSizerPanelConnections->Fit( m_connectionsPanel );
m_notebook->AddPage( m_connectionsPanel, _("Connections"), false );
m_localSettingsPanel = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizerPanelClearance;
bSizerPanelClearance = new wxBoxSizer( wxVERTICAL );
@ -698,94 +1013,6 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind
bSizerClearance->Add( sbClearancesSizer, 0, wxALL|wxEXPAND, 5 );
wxBoxSizer* bSizerLower;
bSizerLower = new wxBoxSizer( wxHORIZONTAL );
m_sbSizerZonesSettings = new wxStaticBoxSizer( new wxStaticBox( m_localSettingsPanel, wxID_ANY, _("Connection to Copper Zones") ), wxVERTICAL );
wxFlexGridSizer* fgSizerCopperZonesOpts;
fgSizerCopperZonesOpts = new wxFlexGridSizer( 0, 2, 0, 0 );
fgSizerCopperZonesOpts->AddGrowableCol( 1 );
fgSizerCopperZonesOpts->SetFlexibleDirection( wxBOTH );
fgSizerCopperZonesOpts->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticText40 = new wxStaticText( m_sbSizerZonesSettings->GetStaticBox(), wxID_ANY, _("Pad connection:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText40->Wrap( -1 );
fgSizerCopperZonesOpts->Add( m_staticText40, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
wxString m_ZoneConnectionChoiceChoices[] = { _("From parent footprint"), _("Solid"), _("Thermal relief"), _("None") };
int m_ZoneConnectionChoiceNChoices = sizeof( m_ZoneConnectionChoiceChoices ) / sizeof( wxString );
m_ZoneConnectionChoice = new wxChoice( m_sbSizerZonesSettings->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_ZoneConnectionChoiceNChoices, m_ZoneConnectionChoiceChoices, 0 );
m_ZoneConnectionChoice->SetSelection( 0 );
fgSizerCopperZonesOpts->Add( m_ZoneConnectionChoice, 1, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
m_staticTextcps = new wxStaticText( m_sbSizerZonesSettings->GetStaticBox(), wxID_ANY, _("Zone knockout:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextcps->Wrap( -1 );
fgSizerCopperZonesOpts->Add( m_staticTextcps, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
wxString m_ZoneCustomPadShapeChoices[] = { _("Pad shape"), _("Pad convex hull") };
int m_ZoneCustomPadShapeNChoices = sizeof( m_ZoneCustomPadShapeChoices ) / sizeof( wxString );
m_ZoneCustomPadShape = new wxChoice( m_sbSizerZonesSettings->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_ZoneCustomPadShapeNChoices, m_ZoneCustomPadShapeChoices, 0 );
m_ZoneCustomPadShape->SetSelection( 0 );
fgSizerCopperZonesOpts->Add( m_ZoneCustomPadShape, 1, wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_sbSizerZonesSettings->Add( fgSizerCopperZonesOpts, 0, 0, 5 );
bSizerLower->Add( m_sbSizerZonesSettings, 1, wxALL|wxEXPAND, 5 );
wxStaticBoxSizer* sbSizerThermalReliefs;
sbSizerThermalReliefs = new wxStaticBoxSizer( new wxStaticBox( m_localSettingsPanel, wxID_ANY, _("Thermal Relief Overrides") ), wxVERTICAL );
wxFlexGridSizer* fgSizerThermalReliefs;
fgSizerThermalReliefs = new wxFlexGridSizer( 0, 3, 0, 0 );
fgSizerThermalReliefs->AddGrowableCol( 1 );
fgSizerThermalReliefs->SetFlexibleDirection( wxBOTH );
fgSizerThermalReliefs->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_thermalGapLabel = new wxStaticText( sbSizerThermalReliefs->GetStaticBox(), wxID_ANY, _("Relief gap:"), wxDefaultPosition, wxDefaultSize, 0 );
m_thermalGapLabel->Wrap( -1 );
fgSizerThermalReliefs->Add( m_thermalGapLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_thermalGapCtrl = new wxTextCtrl( sbSizerThermalReliefs->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerThermalReliefs->Add( m_thermalGapCtrl, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxEXPAND, 5 );
m_thermalGapUnits = new wxStaticText( sbSizerThermalReliefs->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_thermalGapUnits->Wrap( -1 );
fgSizerThermalReliefs->Add( m_thermalGapUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
m_spokeWidthLabel = new wxStaticText( sbSizerThermalReliefs->GetStaticBox(), wxID_ANY, _("Spoke width:"), wxDefaultPosition, wxDefaultSize, 0 );
m_spokeWidthLabel->Wrap( -1 );
fgSizerThermalReliefs->Add( m_spokeWidthLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP, 5 );
m_spokeWidthCtrl = new wxTextCtrl( sbSizerThermalReliefs->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerThermalReliefs->Add( m_spokeWidthCtrl, 0, wxEXPAND|wxLEFT|wxTOP|wxALIGN_CENTER_VERTICAL, 5 );
m_spokeWidthUnits = new wxStaticText( sbSizerThermalReliefs->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_spokeWidthUnits->Wrap( -1 );
fgSizerThermalReliefs->Add( m_spokeWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
m_spokeAngleLabel = new wxStaticText( sbSizerThermalReliefs->GetStaticBox(), wxID_ANY, _("Spoke angle:"), wxDefaultPosition, wxDefaultSize, 0 );
m_spokeAngleLabel->Wrap( -1 );
fgSizerThermalReliefs->Add( m_spokeAngleLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
m_spokeAngleCtrl = new wxTextCtrl( sbSizerThermalReliefs->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerThermalReliefs->Add( m_spokeAngleCtrl, 0, wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 5 );
m_spokeAngleUnits = new wxStaticText( sbSizerThermalReliefs->GetStaticBox(), wxID_ANY, _("deg"), wxDefaultPosition, wxDefaultSize, 0 );
m_spokeAngleUnits->Wrap( -1 );
fgSizerThermalReliefs->Add( m_spokeAngleUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
sbSizerThermalReliefs->Add( fgSizerThermalReliefs, 1, wxEXPAND, 5 );
bSizerLower->Add( sbSizerThermalReliefs, 1, wxEXPAND|wxALL, 5 );
bSizerClearance->Add( bSizerLower, 1, wxEXPAND, 5 );
bSizerPanelClearance->Add( bSizerClearance, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
@ -793,7 +1020,7 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind
m_localSettingsPanel->SetSizer( bSizerPanelClearance );
m_localSettingsPanel->Layout();
bSizerPanelClearance->Fit( m_localSettingsPanel );
m_notebook->AddPage( m_localSettingsPanel, _("Clearance Overrides and Settings"), false );
m_notebook->AddPage( m_localSettingsPanel, _("Clearance Overrides"), false );
m_panelCustomShapePrimitives = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
m_bSizerPanelPrimitives = new wxBoxSizer( wxVERTICAL );
@ -1054,6 +1281,32 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind
m_layerUserDwgs->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
m_layerECO1->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
m_layerECO2->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
m_cbTeardrops->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_cbPreferZoneConnection->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_cbTeardropsUseNextTrack->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stHDRatio->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_spTeardropHDPercent->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_minTrackWidthUnits->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_minTrackWidthHint->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_teardropShapeLabel->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_bitmapTeardrop->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_edgesLabel->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_rbStraightLines->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_rbCurved->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stHsetting->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_spTeardropLenPercent->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stTeardropLenUnits->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stMaxLen->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_tcTdMaxLen->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stMaxLenUnits->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stVsetting->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_spTeardropSizePercent->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stLenPercent->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stTdMaxSize->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_tcMaxHeight->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stMaxHeightUnits->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_curvePointsLabel->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropCurvePointsUpdateUi ), NULL, this );
m_curvePointsCtrl->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropCurvePointsUpdateUi ), NULL, this );
m_clearanceCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
m_nonCopperWarningBook->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnUpdateUINonCopperWarning ), NULL, this );
m_listCtrlPrimitives->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( DIALOG_PAD_PROPERTIES_BASE::onPrimitiveDClick ), NULL, this );
@ -1114,6 +1367,32 @@ DIALOG_PAD_PROPERTIES_BASE::~DIALOG_PAD_PROPERTIES_BASE()
m_layerUserDwgs->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
m_layerECO1->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
m_layerECO2->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayers ), NULL, this );
m_cbTeardrops->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_cbPreferZoneConnection->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_cbTeardropsUseNextTrack->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stHDRatio->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_spTeardropHDPercent->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_minTrackWidthUnits->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_minTrackWidthHint->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_teardropShapeLabel->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_bitmapTeardrop->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_edgesLabel->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_rbStraightLines->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_rbCurved->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stHsetting->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_spTeardropLenPercent->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stTeardropLenUnits->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stMaxLen->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_tcTdMaxLen->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stMaxLenUnits->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stVsetting->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_spTeardropSizePercent->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stLenPercent->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stTdMaxSize->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_tcMaxHeight->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stMaxHeightUnits->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_curvePointsLabel->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropCurvePointsUpdateUi ), NULL, this );
m_curvePointsCtrl->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::onTeardropCurvePointsUpdateUi ), NULL, this );
m_clearanceCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this );
m_nonCopperWarningBook->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnUpdateUINonCopperWarning ), NULL, this );
m_listCtrlPrimitives->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( DIALOG_PAD_PROPERTIES_BASE::onPrimitiveDClick ), NULL, this );

File diff suppressed because it is too large Load Diff

View File

@ -35,6 +35,8 @@ class wxListView;
#include <wx/icon.h>
#include <wx/statbmp.h>
#include <wx/statbox.h>
#include <wx/spinctrl.h>
#include <wx/radiobut.h>
#include <wx/listctrl.h>
#include <wx/button.h>
#include <wx/notebook.h>
@ -167,6 +169,52 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM
wxCheckBox* m_layerECO2;
wxStaticText* m_staticTextFabProperty;
wxChoice* m_choiceFabProperty;
wxPanel* m_connectionsPanel;
wxBoxSizer* m_legacyTeardropsWarning;
wxStaticBitmap* m_legacyTeardropsIcon;
wxStaticText* m_staticText85;
wxStaticText* m_staticText851;
wxCheckBox* m_cbTeardrops;
wxCheckBox* m_cbPreferZoneConnection;
wxCheckBox* m_cbTeardropsUseNextTrack;
wxStaticText* m_stHDRatio;
wxSpinCtrlDouble* m_spTeardropHDPercent;
wxStaticText* m_minTrackWidthUnits;
wxStaticText* m_minTrackWidthHint;
wxStaticText* m_teardropShapeLabel;
wxStaticLine* m_staticline51;
wxStaticBitmap* m_bitmapTeardrop;
wxStaticText* m_edgesLabel;
wxRadioButton* m_rbStraightLines;
wxRadioButton* m_rbCurved;
wxStaticText* m_stHsetting;
wxSpinCtrlDouble* m_spTeardropLenPercent;
wxStaticText* m_stTeardropLenUnits;
wxStaticText* m_stMaxLen;
wxTextCtrl* m_tcTdMaxLen;
wxStaticText* m_stMaxLenUnits;
wxStaticText* m_stVsetting;
wxSpinCtrlDouble* m_spTeardropSizePercent;
wxStaticText* m_stLenPercent;
wxStaticText* m_stTdMaxSize;
wxTextCtrl* m_tcMaxHeight;
wxStaticText* m_stMaxHeightUnits;
wxStaticText* m_curvePointsLabel;
wxSpinCtrl* m_curvePointsCtrl;
wxStaticBoxSizer* m_sbSizerZonesSettings;
wxStaticText* m_padConnectionLabel;
wxChoice* m_ZoneConnectionChoice;
wxStaticText* m_zoneKnockoutLabel;
wxChoice* m_ZoneCustomPadShape;
wxStaticText* m_thermalGapLabel;
wxTextCtrl* m_thermalGapCtrl;
wxStaticText* m_thermalGapUnits;
wxStaticText* m_spokeWidthLabel;
wxTextCtrl* m_spokeWidthCtrl;
wxStaticText* m_spokeWidthUnits;
wxStaticText* m_spokeAngleLabel;
wxTextCtrl* m_spokeAngleCtrl;
wxStaticText* m_spokeAngleUnits;
wxPanel* m_localSettingsPanel;
wxStaticText* m_staticTextInfoPosValue;
wxStaticText* m_staticTextInfoNegVal;
@ -187,20 +235,6 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM
wxStaticText* m_staticTextInfoPaste;
wxStaticBitmap* m_nonCopperWarningIcon;
wxStaticText* m_nonCopperWarningText;
wxStaticBoxSizer* m_sbSizerZonesSettings;
wxStaticText* m_staticText40;
wxChoice* m_ZoneConnectionChoice;
wxStaticText* m_staticTextcps;
wxChoice* m_ZoneCustomPadShape;
wxStaticText* m_thermalGapLabel;
wxTextCtrl* m_thermalGapCtrl;
wxStaticText* m_thermalGapUnits;
wxStaticText* m_spokeWidthLabel;
wxTextCtrl* m_spokeWidthCtrl;
wxStaticText* m_spokeWidthUnits;
wxStaticText* m_spokeAngleLabel;
wxTextCtrl* m_spokeAngleCtrl;
wxStaticText* m_spokeAngleUnits;
wxPanel* m_panelCustomShapePrimitives;
wxBoxSizer* m_bSizerPanelPrimitives;
wxStaticText* m_staticTextPrimitivesList;
@ -249,6 +283,8 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM
virtual void OnOffsetCheckbox( wxCommandEvent& event ) { event.Skip(); }
virtual void OnPadToDieCheckbox( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSetCopperLayers( wxCommandEvent& event ) { event.Skip(); }
virtual void onTeardropsUpdateUi( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void onTeardropCurvePointsUpdateUi( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void OnUpdateUINonCopperWarning( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void onPrimitiveDClick( wxMouseEvent& event ) { event.Skip(); }
virtual void OnPrimitiveSelection( wxListEvent& event ) { event.Skip(); }

View File

@ -239,7 +239,7 @@ bool DIALOG_RULE_AREA_PROPERTIES::TransferDataFromWindow()
pcbIUScale.mmToIU( ZONE_BORDER_HATCH_MAXDIST_MM ) ) )
return false;
m_zonesettings.m_BorderHatchPitch = m_outlineHatchPitch.GetValue();
m_zonesettings.m_BorderHatchPitch = m_outlineHatchPitch.GetIntValue();
m_zonesettings.m_Locked = m_cbLocked->GetValue();
m_zonesettings.m_ZonePriority = 0; // for a keepout, this param is not used.

View File

@ -41,20 +41,26 @@
DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParent,
const PCB_SELECTION& aItems,
COMMIT& aCommit ) :
BOARD_COMMIT& aCommit ) :
DIALOG_TRACK_VIA_PROPERTIES_BASE( aParent ),
m_frame( aParent ),
m_items( aItems ),
m_commit( aCommit ),
m_trackStartX( aParent, m_TrackStartXLabel, m_TrackStartXCtrl, m_TrackStartXUnit ),
m_trackStartX( aParent, m_TrackStartXLabel, m_TrackStartXCtrl, nullptr ),
m_trackStartY( aParent, m_TrackStartYLabel, m_TrackStartYCtrl, m_TrackStartYUnit ),
m_trackEndX( aParent, m_TrackEndXLabel, m_TrackEndXCtrl, m_TrackEndXUnit ),
m_trackEndX( aParent, m_TrackEndXLabel, m_TrackEndXCtrl, nullptr ),
m_trackEndY( aParent, m_TrackEndYLabel, m_TrackEndYCtrl, m_TrackEndYUnit ),
m_trackWidth( aParent, m_TrackWidthLabel, m_TrackWidthCtrl, m_TrackWidthUnit ),
m_viaX( aParent, m_ViaXLabel, m_ViaXCtrl, m_ViaXUnit ),
m_viaX( aParent, m_ViaXLabel, m_ViaXCtrl, nullptr ),
m_viaY( aParent, m_ViaYLabel, m_ViaYCtrl, m_ViaYUnit ),
m_viaDiameter( aParent, m_ViaDiameterLabel, m_ViaDiameterCtrl, m_ViaDiameterUnit ),
m_viaDrill( aParent, m_ViaDrillLabel, m_ViaDrillCtrl, m_ViaDrillUnit ),
m_teardropHDPercent( aParent, m_stHDRatio, m_tcHDRatio, m_stHDRatioUnits ),
m_teardropLenPercent( aParent, m_stLenPercentLabel, m_tcLenPercent, m_stLenPercentUnits ),
m_teardropMaxLen( aParent, m_stMaxLen, m_tcTdMaxLen, m_stMaxLenUnits ),
m_teardropHeightPercent( aParent, m_stHeightPercentLabel, m_tcHeightPercent, m_stHeightPercentUnits ),
m_teardropMaxHeight( aParent, m_stMaxHeight, m_tcMaxHeight, m_stMaxHeightUnits ),
m_curvePoints( aParent, m_curvePointsLabel, m_curvePointsCtrl, nullptr ),
m_tracks( false ),
m_vias( false )
{
@ -62,6 +68,18 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParen
wxASSERT( !m_items.Empty() );
m_legacyTeardropsIcon->SetBitmap( KiBitmap( BITMAPS::dialog_warning ) );
m_legacyTeardropsWarning->Show( m_frame->GetBoard()->LegacyTeardrops() );
m_bitmapTeardrop->SetBitmap( KiBitmap( BITMAPS::teardrop_sizes ) );
m_teardropHDPercent.SetUnits( EDA_UNITS::PERCENT );
m_teardropLenPercent.SetUnits( EDA_UNITS::PERCENT );
m_teardropHeightPercent.SetUnits( EDA_UNITS::PERCENT );
m_curvePoints.SetUnits( EDA_UNITS::UNSCALED );
m_minTrackWidthHint->SetFont( KIUI::GetInfoFont( this ).Italic() );
// Configure display origin transforms
m_trackStartX.SetCoordType( ORIGIN_TRANSFORMS::ABS_X_COORD );
m_trackStartY.SetCoordType( ORIGIN_TRANSFORMS::ABS_Y_COORD );
@ -160,9 +178,7 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParen
m_trackWidth.SetValue( INDETERMINATE_STATE );
if( track_selection_layer != t->GetLayer() )
{
track_selection_layer = UNDEFINED_LAYER;
}
}
if( t->IsLocked() )
@ -175,7 +191,7 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParen
case PCB_VIA_T:
{
const PCB_VIA* v = static_cast<const PCB_VIA*>( item );
PCB_VIA* v = static_cast<PCB_VIA*>( item );
if( !m_vias ) // first via in the list
{
@ -189,6 +205,15 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParen
m_annularRingsCtrl->SetSelection( getAnnularRingSelection( v ) );
selection_first_layer = v->TopLayer();
selection_last_layer = v->BottomLayer();
m_cbTeardrops->SetValue( v->GetTeardropParams().m_Enabled );
m_cbTeardropsUseNextTrack->SetValue( v->GetTeardropParams().m_AllowUseTwoTracks );
m_teardropMaxLen.SetValue( v->GetTeardropParams().m_TdMaxLen );
m_teardropMaxHeight.SetValue( v->GetTeardropParams().m_TdMaxWidth );
m_teardropLenPercent.SetDoubleValue( v->GetTeardropParams().m_BestLengthRatio*100.0 );
m_teardropHeightPercent.SetDoubleValue( v->GetTeardropParams().m_BestWidthRatio*100.0 );
m_teardropHDPercent.SetDoubleValue( v->GetTeardropParams().m_WidthtoSizeFilterRatio*100.0 );
m_curvePoints.SetValue( v->GetTeardropParams().m_CurveSegCount );
}
else // check if values are the same for every selected via
{
@ -211,14 +236,10 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParen
m_viaNotFree->Set3StateValue( wxCHK_UNDETERMINED );
if( selection_first_layer != v->TopLayer() )
{
selection_first_layer = UNDEFINED_LAYER;
}
if( selection_last_layer != v->BottomLayer() )
{
selection_last_layer = UNDEFINED_LAYER;
}
if( m_annularRingsCtrl->GetSelection() != getAnnularRingSelection( v ) )
{
@ -227,6 +248,30 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParen
m_annularRingsCtrl->SetSelection( 3 );
}
if( m_cbTeardrops->GetValue() != v->GetTeardropParams().m_Enabled )
m_cbTeardrops->Set3StateValue( wxCHK_UNDETERMINED );
if( m_cbTeardropsUseNextTrack->GetValue() != v->GetTeardropParams().m_AllowUseTwoTracks )
m_cbTeardropsUseNextTrack->Set3StateValue( wxCHK_UNDETERMINED );
if( m_teardropMaxLen.GetValue() != v->GetTeardropParams().m_TdMaxLen )
m_teardropMaxLen.SetValue( INDETERMINATE_STATE );
if( m_teardropMaxHeight.GetValue() != v->GetTeardropParams().m_TdMaxWidth )
m_teardropMaxHeight.SetValue( INDETERMINATE_STATE );
if( m_teardropLenPercent.GetDoubleValue() != v->GetTeardropParams().m_BestLengthRatio *100.0 )
m_teardropLenPercent.SetValue( INDETERMINATE_STATE );
if( m_teardropHeightPercent.GetDoubleValue() != v->GetTeardropParams().m_BestWidthRatio *100.0 )
m_teardropHeightPercent.SetValue( INDETERMINATE_STATE );
if( m_teardropHDPercent.GetDoubleValue() != v->GetTeardropParams().m_WidthtoSizeFilterRatio*100.0 )
m_teardropHDPercent.SetValue( INDETERMINATE_STATE );
if( m_curvePoints.GetValue() != v->GetTeardropParams().m_CurveSegCount )
m_curvePoints.SetValue( INDETERMINATE_STATE );
}
if( v->IsLocked() )
@ -341,6 +386,23 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParen
m_annularRingsLabel->Show( getLayerDepth() > 1 );
m_annularRingsCtrl->Show( getLayerDepth() > 1 );
if( m_curvePoints.IsIndeterminate() )
{
m_rbStraightLines->SetValue( false );
m_rbCurved->SetValue( false );
}
else if( m_curvePoints.GetValue() == 0 )
{
m_rbStraightLines->SetValue( true );
m_rbCurved->SetValue( false );
m_curvePoints.SetValue( wxEmptyString );
}
else
{
m_rbStraightLines->SetValue( false );
m_rbCurved->SetValue( true );
}
}
else
{
@ -492,7 +554,9 @@ bool DIALOG_TRACK_VIA_PROPERTIES::TransferDataFromWindow()
{
if( !m_viaDiameter.Validate( GEOMETRY_MIN_SIZE, INT_MAX )
|| !m_viaDrill.Validate( GEOMETRY_MIN_SIZE, INT_MAX ) )
{
return false;
}
if( m_ViaDiameterCtrl->IsEnabled() && !m_viaDiameter.IsIndeterminate()
&& m_ViaDrillCtrl->IsEnabled() && !m_viaDrill.IsIndeterminate()
@ -539,16 +603,16 @@ bool DIALOG_TRACK_VIA_PROPERTIES::TransferDataFromWindow()
PCB_TRACK* t = static_cast<PCB_TRACK*>( item );
if( !m_trackStartX.IsIndeterminate() )
t->SetStart( VECTOR2I( m_trackStartX.GetValue(), t->GetStart().y ) );
t->SetStart( VECTOR2I( m_trackStartX.GetIntValue(), t->GetStart().y ) );
if( !m_trackStartY.IsIndeterminate() )
t->SetStart( VECTOR2I( t->GetStart().x, m_trackStartY.GetValue() ) );
t->SetStart( VECTOR2I( t->GetStart().x, m_trackStartY.GetIntValue() ) );
if( !m_trackEndX.IsIndeterminate() )
t->SetEnd( VECTOR2I( m_trackEndX.GetValue(), t->GetEnd().y ) );
t->SetEnd( VECTOR2I( m_trackEndX.GetIntValue(), t->GetEnd().y ) );
if( !m_trackEndY.IsIndeterminate() )
t->SetEnd( VECTOR2I( t->GetEnd().x, m_trackEndY.GetValue() ) );
t->SetEnd( VECTOR2I( t->GetEnd().x, m_trackEndY.GetIntValue() ) );
if( m_trackNetclass->IsChecked() )
{
@ -561,7 +625,7 @@ bool DIALOG_TRACK_VIA_PROPERTIES::TransferDataFromWindow()
}
else if( !m_trackWidth.IsIndeterminate() )
{
t->SetWidth( m_trackWidth.GetValue() );
t->SetWidth( m_trackWidth.GetIntValue() );
}
int layer = m_TrackLayerCtrl->GetLayerSelection();
@ -581,10 +645,10 @@ bool DIALOG_TRACK_VIA_PROPERTIES::TransferDataFromWindow()
PCB_VIA* v = static_cast<PCB_VIA*>( item );
if( !m_viaX.IsIndeterminate() )
v->SetPosition( VECTOR2I( m_viaX.GetValue(), v->GetPosition().y ) );
v->SetPosition( VECTOR2I( m_viaX.GetIntValue(), v->GetPosition().y ) );
if( !m_viaY.IsIndeterminate() )
v->SetPosition( VECTOR2I( v->GetPosition().x, m_viaY.GetValue() ) );
v->SetPosition( VECTOR2I( v->GetPosition().x, m_viaY.GetIntValue() ) );
if( m_viaNotFree->Get3StateValue() != wxCHK_UNDETERMINED )
v->SetIsFree( !m_viaNotFree->GetValue() );
@ -658,10 +722,48 @@ bool DIALOG_TRACK_VIA_PROPERTIES::TransferDataFromWindow()
else
{
if( !m_viaDiameter.IsIndeterminate() )
v->SetWidth( m_viaDiameter.GetValue() );
v->SetWidth( m_viaDiameter.GetIntValue() );
if( !m_viaDrill.IsIndeterminate() )
v->SetDrill( m_viaDrill.GetValue() );
v->SetDrill( m_viaDrill.GetIntValue() );
}
TEARDROP_PARAMETERS* targetParams = &v->GetTeardropParams();
if( m_cbTeardrops->Get3StateValue() != wxCHK_UNDETERMINED )
targetParams->m_Enabled = m_cbTeardrops->GetValue();
if( m_cbTeardropsUseNextTrack->Get3StateValue() != wxCHK_UNDETERMINED )
targetParams->m_AllowUseTwoTracks = m_cbTeardropsUseNextTrack->GetValue();
if( !m_teardropMaxLen.IsIndeterminate() )
targetParams->m_TdMaxLen = m_teardropMaxLen.GetIntValue();
if( !m_teardropMaxHeight.IsIndeterminate() )
targetParams->m_TdMaxWidth = m_teardropMaxHeight.GetIntValue();
if( !m_teardropLenPercent.IsIndeterminate() )
targetParams->m_BestLengthRatio = m_teardropLenPercent.GetDoubleValue() / 100.0;
if( !m_teardropHeightPercent.IsIndeterminate() )
targetParams->m_BestWidthRatio = m_teardropHeightPercent.GetDoubleValue() / 100.0;
if( !m_teardropHDPercent.IsIndeterminate() )
targetParams->m_WidthtoSizeFilterRatio = m_teardropHDPercent.GetDoubleValue() / 100.0;
if( m_curvePoints.GetValue() != v->GetTeardropParams().m_CurveSegCount )
m_curvePoints.SetValue( INDETERMINATE_STATE );
if( m_rbStraightLines->GetValue() )
{
targetParams->m_CurveSegCount = 0;
}
else if( m_rbCurved->GetValue() )
{
if( !m_curvePoints.IsIndeterminate() && m_curvePoints.GetValue() > 0 )
targetParams->m_CurveSegCount = m_curvePoints.GetIntValue();
else if( targetParams->m_CurveSegCount == 0 )
targetParams->m_CurveSegCount = 5;
}
if( changeLock )
@ -852,3 +954,15 @@ void DIALOG_TRACK_VIA_PROPERTIES::onViaEdit( wxCommandEvent& aEvent )
m_annularRingsCtrl->Show( getLayerDepth() > 1 );
}
}
void DIALOG_TRACK_VIA_PROPERTIES::onTeardropsUpdateUi( wxUpdateUIEvent& event )
{
event.Enable( !m_frame->GetBoard()->LegacyTeardrops() );
}
void DIALOG_TRACK_VIA_PROPERTIES::onCurvedEdgesUpdateUi( wxUpdateUIEvent& event )
{
event.Enable( !m_frame->GetBoard()->LegacyTeardrops() && m_rbCurved->GetValue() );
}

View File

@ -28,7 +28,7 @@
#include <layer_ids.h>
class PCB_SELECTION;
class COMMIT;
class BOARD_COMMIT;
class PCB_BASE_FRAME;
class PAD;
@ -36,7 +36,7 @@ class DIALOG_TRACK_VIA_PROPERTIES : public DIALOG_TRACK_VIA_PROPERTIES_BASE
{
public:
DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParent, const PCB_SELECTION& aItems,
COMMIT& aCommit );
BOARD_COMMIT& aCommit );
~DIALOG_TRACK_VIA_PROPERTIES();
@ -53,6 +53,8 @@ private:
void onViaEdit( wxCommandEvent& aEvent ) override;
void onUnitsChanged( wxCommandEvent& aEvent );
void onTeardropsUpdateUi( wxUpdateUIEvent& event ) override;
void onCurvedEdgesUpdateUi( wxUpdateUIEvent& event ) override;
bool confirmPadChange( const std::vector<PAD*>& connectedPads );
@ -61,7 +63,7 @@ private:
private:
PCB_BASE_FRAME* m_frame;
const PCB_SELECTION& m_items; // List of items to be modified.
COMMIT& m_commit; // An undo record to add any changes to.
BOARD_COMMIT& m_commit; // An undo record to add any changes to.
UNIT_BINDER m_trackStartX, m_trackStartY;
UNIT_BINDER m_trackEndX, m_trackEndY;
@ -70,6 +72,13 @@ private:
UNIT_BINDER m_viaX, m_viaY;
UNIT_BINDER m_viaDiameter, m_viaDrill;
UNIT_BINDER m_teardropHDPercent;
UNIT_BINDER m_teardropLenPercent;
UNIT_BINDER m_teardropMaxLen;
UNIT_BINDER m_teardropHeightPercent;
UNIT_BINDER m_teardropMaxHeight;
UNIT_BINDER m_curvePoints;
bool m_tracks; // True if dialog displays any track properties.
bool m_vias; // True if dialog displays any via properties.
};

View File

@ -22,235 +22,270 @@ DIALOG_TRACK_VIA_PROPERTIES_BASE::DIALOG_TRACK_VIA_PROPERTIES_BASE( wxWindow* pa
wxBoxSizer* bSizerNetWidgets;
bSizerNetWidgets = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bNetWidgetsLeftCol;
bNetWidgetsLeftCol = new wxBoxSizer( wxHORIZONTAL );
m_netSelectorLabel = new wxStaticText( m_sbCommonSizer->GetStaticBox(), wxID_ANY, _("Net:"), wxDefaultPosition, wxDefaultSize, 0 );
m_netSelectorLabel->Wrap( -1 );
bSizerNetWidgets->Add( m_netSelectorLabel, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
bNetWidgetsLeftCol->Add( m_netSelectorLabel, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 );
m_netSelector = new NET_SELECTOR( m_sbCommonSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
bSizerNetWidgets->Add( m_netSelector, 1, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
bNetWidgetsLeftCol->Add( m_netSelector, 1, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
bSizerNetWidgets->Add( 20, 0, 0, wxEXPAND, 5 );
bSizerNetWidgets->Add( bNetWidgetsLeftCol, 1, wxRIGHT|wxALIGN_CENTER_VERTICAL, 10 );
wxBoxSizer* bNetWidgetsRightCol;
bNetWidgetsRightCol = new wxBoxSizer( wxHORIZONTAL );
m_viaNotFree = new wxCheckBox( m_sbCommonSizer->GetStaticBox(), wxID_ANY, _("Automatically update via nets"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE );
m_viaNotFree->SetToolTip( _("Automatically change the net of this via when the pads or zones it touches are changed") );
bSizerNetWidgets->Add( m_viaNotFree, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
bNetWidgetsRightCol->Add( m_viaNotFree, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 10 );
m_sbCommonSizer->Add( bSizerNetWidgets, 5, wxEXPAND|wxRIGHT, 10 );
bSizerNetWidgets->Add( bNetWidgetsRightCol, 1, wxLEFT|wxALIGN_CENTER_VERTICAL, 10 );
m_sbCommonSizer->Add( bSizerNetWidgets, 5, wxEXPAND, 10 );
m_staticline1 = new wxStaticLine( m_sbCommonSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
m_sbCommonSizer->Add( m_staticline1, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
m_sbCommonSizer->Add( m_staticline1, 0, wxEXPAND|wxBOTTOM, 10 );
m_lockedCbox = new wxCheckBox( m_sbCommonSizer->GetStaticBox(), wxID_ANY, _("Locked"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE );
m_sbCommonSizer->Add( m_lockedCbox, 0, wxALL, 5 );
m_sbCommonSizer->Add( m_lockedCbox, 0, wxBOTTOM, 2 );
m_MainSizer->Add( m_sbCommonSizer, 0, wxEXPAND|wxALL, 10 );
m_sbTrackSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Tracks") ), wxHORIZONTAL );
wxFlexGridSizer* fgTrackLeftGridSizer;
fgTrackLeftGridSizer = new wxFlexGridSizer( 7, 3, 3, 5 );
fgTrackLeftGridSizer->AddGrowableCol( 1 );
fgTrackLeftGridSizer->SetFlexibleDirection( wxBOTH );
fgTrackLeftGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
wxBoxSizer* bSizerTracksLeftCol;
bSizerTracksLeftCol = new wxBoxSizer( wxVERTICAL );
m_TrackStartXLabel = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Start point X:"), wxDefaultPosition, wxDefaultSize, 0 );
wxFlexGridSizer* fgTrackEnds;
fgTrackEnds = new wxFlexGridSizer( 7, 5, 3, 2 );
fgTrackEnds->AddGrowableCol( 1 );
fgTrackEnds->AddGrowableCol( 3 );
fgTrackEnds->SetFlexibleDirection( wxBOTH );
fgTrackEnds->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_TrackStartXLabel = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Start X:"), wxDefaultPosition, wxDefaultSize, 0 );
m_TrackStartXLabel->Wrap( -1 );
fgTrackLeftGridSizer->Add( m_TrackStartXLabel, 0, wxALIGN_CENTER_VERTICAL, 3 );
fgTrackEnds->Add( m_TrackStartXLabel, 0, wxALIGN_CENTER_VERTICAL, 3 );
m_TrackStartXCtrl = new wxTextCtrl( m_sbTrackSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgTrackLeftGridSizer->Add( m_TrackStartXCtrl, 0, wxEXPAND, 3 );
fgTrackEnds->Add( m_TrackStartXCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 3 );
m_TrackStartXUnit = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
m_TrackStartXUnit->Wrap( -1 );
fgTrackLeftGridSizer->Add( m_TrackStartXUnit, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3 );
m_TrackStartYLabel = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Start point Y:"), wxDefaultPosition, wxDefaultSize, 0 );
m_TrackStartYLabel = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Y:"), wxDefaultPosition, wxDefaultSize, 0 );
m_TrackStartYLabel->Wrap( -1 );
fgTrackLeftGridSizer->Add( m_TrackStartYLabel, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 );
fgTrackEnds->Add( m_TrackStartYLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 8 );
m_TrackStartYCtrl = new wxTextCtrl( m_sbTrackSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgTrackLeftGridSizer->Add( m_TrackStartYCtrl, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND, 5 );
fgTrackEnds->Add( m_TrackStartYCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 3 );
m_TrackStartYUnit = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
m_TrackStartYUnit = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_TrackStartYUnit->Wrap( -1 );
fgTrackLeftGridSizer->Add( m_TrackStartYUnit, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 );
fgTrackEnds->Add( m_TrackStartYUnit, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_TrackEndXLabel = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("End point X:"), wxDefaultPosition, wxDefaultSize, 0 );
m_TrackEndXLabel = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("End X:"), wxDefaultPosition, wxDefaultSize, 0 );
m_TrackEndXLabel->Wrap( -1 );
fgTrackLeftGridSizer->Add( m_TrackEndXLabel, 0, wxALIGN_CENTER_VERTICAL, 5 );
fgTrackEnds->Add( m_TrackEndXLabel, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_TrackEndXCtrl = new wxTextCtrl( m_sbTrackSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgTrackLeftGridSizer->Add( m_TrackEndXCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
fgTrackEnds->Add( m_TrackEndXCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 3 );
m_TrackEndXUnit = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
m_TrackEndXUnit->Wrap( -1 );
fgTrackLeftGridSizer->Add( m_TrackEndXUnit, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_TrackEndYLabel = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("End point Y:"), wxDefaultPosition, wxDefaultSize, 0 );
m_TrackEndYLabel = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Y:"), wxDefaultPosition, wxDefaultSize, 0 );
m_TrackEndYLabel->Wrap( -1 );
fgTrackLeftGridSizer->Add( m_TrackEndYLabel, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 8 );
fgTrackEnds->Add( m_TrackEndYLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 8 );
m_TrackEndYCtrl = new wxTextCtrl( m_sbTrackSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgTrackLeftGridSizer->Add( m_TrackEndYCtrl, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND, 8 );
fgTrackEnds->Add( m_TrackEndYCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 3 );
m_TrackEndYUnit = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
m_TrackEndYUnit = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_TrackEndYUnit->Wrap( -1 );
fgTrackLeftGridSizer->Add( m_TrackEndYUnit, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 8 );
fgTrackEnds->Add( m_TrackEndYUnit, 0, wxALIGN_CENTER_VERTICAL, 8 );
m_DesignRuleWidths = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Pre-defined widths:"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerTracksLeftCol->Add( fgTrackEnds, 0, wxEXPAND|wxBOTTOM, 8 );
wxFlexGridSizer* fgTrackSizes;
fgTrackSizes = new wxFlexGridSizer( 7, 3, 3, 3 );
fgTrackSizes->AddGrowableCol( 1 );
fgTrackSizes->SetFlexibleDirection( wxBOTH );
fgTrackSizes->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_DesignRuleWidths = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Pre-defined sizes:"), wxDefaultPosition, wxDefaultSize, 0 );
m_DesignRuleWidths->Wrap( -1 );
fgTrackLeftGridSizer->Add( m_DesignRuleWidths, 0, wxALIGN_CENTER_VERTICAL|wxTOP, 5 );
fgTrackSizes->Add( m_DesignRuleWidths, 0, wxALIGN_CENTER_VERTICAL|wxTOP, 5 );
wxArrayString m_DesignRuleWidthsCtrlChoices;
m_DesignRuleWidthsCtrl = new wxChoice( m_sbTrackSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_DesignRuleWidthsCtrlChoices, 0 );
m_DesignRuleWidthsCtrl->SetSelection( 0 );
fgTrackLeftGridSizer->Add( m_DesignRuleWidthsCtrl, 0, wxEXPAND|wxTOP|wxALIGN_CENTER_VERTICAL, 5 );
fgTrackSizes->Add( m_DesignRuleWidthsCtrl, 0, wxEXPAND|wxTOP|wxALIGN_CENTER_VERTICAL, 5 );
m_DesignRuleWidthsUnits = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
m_DesignRuleWidthsUnits = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_DesignRuleWidthsUnits->Wrap( -1 );
fgTrackLeftGridSizer->Add( m_DesignRuleWidthsUnits, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT, 5 );
fgTrackSizes->Add( m_DesignRuleWidthsUnits, 0, wxALIGN_CENTER_VERTICAL|wxTOP, 5 );
m_TrackWidthLabel = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Track width:"), wxDefaultPosition, wxDefaultSize, 0 );
m_TrackWidthLabel->Wrap( -1 );
fgTrackLeftGridSizer->Add( m_TrackWidthLabel, 0, wxALIGN_CENTER_VERTICAL, 5 );
fgTrackSizes->Add( m_TrackWidthLabel, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_TrackWidthCtrl = new wxTextCtrl( m_sbTrackSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgTrackLeftGridSizer->Add( m_TrackWidthCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
fgTrackSizes->Add( m_TrackWidthCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_TrackWidthUnit = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
m_TrackWidthUnit = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_TrackWidthUnit->Wrap( -1 );
fgTrackLeftGridSizer->Add( m_TrackWidthUnit, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT, 5 );
fgTrackSizes->Add( m_TrackWidthUnit, 0, wxALIGN_CENTER_VERTICAL|wxTOP, 5 );
fgTrackLeftGridSizer->Add( 0, 0, 1, wxEXPAND, 5 );
fgTrackSizes->Add( 0, 0, 1, wxEXPAND, 5 );
m_trackNetclass = new wxCheckBox( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Use net class widths"), wxDefaultPosition, wxDefaultSize, 0 );
fgTrackLeftGridSizer->Add( m_trackNetclass, 0, wxTOP|wxBOTTOM, 5 );
fgTrackSizes->Add( m_trackNetclass, 0, wxBOTTOM, 3 );
fgTrackLeftGridSizer->Add( 0, 0, 1, wxEXPAND, 5 );
fgTrackSizes->Add( 0, 0, 1, wxEXPAND, 5 );
m_sbTrackSizer->Add( fgTrackLeftGridSizer, 5, wxEXPAND|wxRIGHT|wxLEFT, 5 );
bSizerTracksLeftCol->Add( fgTrackSizes, 1, wxEXPAND, 5 );
m_sbTrackSizer->Add( bSizerTracksLeftCol, 1, wxEXPAND, 5 );
m_sbTrackSizer->Add( 0, 0, 0, wxEXPAND|wxRIGHT|wxLEFT, 15 );
wxFlexGridSizer* fgTrackRightSizer;
fgTrackRightSizer = new wxFlexGridSizer( 1, 3, 3, 5 );
fgTrackRightSizer->AddGrowableCol( 1 );
fgTrackRightSizer->AddGrowableCol( 2 );
fgTrackRightSizer->SetFlexibleDirection( wxBOTH );
fgTrackRightSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_TrackLayerLabel = new wxStaticText( m_sbTrackSizer->GetStaticBox(), wxID_ANY, _("Layer:"), wxDefaultPosition, wxDefaultSize, 0 );
m_TrackLayerLabel->Wrap( -1 );
fgTrackRightSizer->Add( m_TrackLayerLabel, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 25 );
fgTrackRightSizer->Add( m_TrackLayerLabel, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
fgTrackRightSizer->Add( 25, 0, 0, wxEXPAND, 5 );
m_TrackLayerCtrl = new PCB_LAYER_BOX_SELECTOR( m_sbTrackSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
fgTrackRightSizer->Add( m_TrackLayerCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_sbTrackSizer->Add( fgTrackRightSizer, 4, wxEXPAND|wxRIGHT, 10 );
m_sbTrackSizer->Add( fgTrackRightSizer, 1, wxEXPAND|wxRIGHT, 3 );
m_MainSizer->Add( m_sbTrackSizer, 0, wxEXPAND|wxRIGHT|wxLEFT, 10 );
m_sbViaSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Vias") ), wxHORIZONTAL );
m_sbViaSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Vias") ), wxVERTICAL );
wxFlexGridSizer* viaLeftColumn;
viaLeftColumn = new wxFlexGridSizer( 6, 3, 4, 5 );
viaLeftColumn->AddGrowableCol( 1 );
viaLeftColumn->SetFlexibleDirection( wxBOTH );
viaLeftColumn->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
wxBoxSizer* bSizerViaCols;
bSizerViaCols = new wxBoxSizer( wxHORIZONTAL );
m_ViaXLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Position X:"), wxDefaultPosition, wxDefaultSize, 0 );
wxBoxSizer* bSizerViasLeftCol;
bSizerViasLeftCol = new wxBoxSizer( wxVERTICAL );
wxFlexGridSizer* fgViaPos;
fgViaPos = new wxFlexGridSizer( 6, 5, 4, 2 );
fgViaPos->AddGrowableCol( 1 );
fgViaPos->AddGrowableCol( 3 );
fgViaPos->SetFlexibleDirection( wxBOTH );
fgViaPos->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_ViaXLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Pos X:"), wxDefaultPosition, wxDefaultSize, 0 );
m_ViaXLabel->Wrap( -1 );
viaLeftColumn->Add( m_ViaXLabel, 0, wxALIGN_CENTER_VERTICAL, 3 );
fgViaPos->Add( m_ViaXLabel, 0, wxALIGN_CENTER_VERTICAL, 3 );
m_ViaXCtrl = new wxTextCtrl( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
viaLeftColumn->Add( m_ViaXCtrl, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 3 );
fgViaPos->Add( m_ViaXCtrl, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 3 );
m_ViaXUnit = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
m_ViaXUnit->Wrap( -1 );
viaLeftColumn->Add( m_ViaXUnit, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3 );
m_ViaYLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Position Y:"), wxDefaultPosition, wxDefaultSize, 0 );
m_ViaYLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Y:"), wxDefaultPosition, wxDefaultSize, 0 );
m_ViaYLabel->Wrap( -1 );
viaLeftColumn->Add( m_ViaYLabel, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 );
fgViaPos->Add( m_ViaYLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 8 );
m_ViaYCtrl = new wxTextCtrl( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
viaLeftColumn->Add( m_ViaYCtrl, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND, 5 );
fgViaPos->Add( m_ViaYCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 3 );
m_ViaYUnit = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
m_ViaYUnit = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_ViaYUnit->Wrap( -1 );
viaLeftColumn->Add( m_ViaYUnit, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 );
fgViaPos->Add( m_ViaYUnit, 0, wxALIGN_CENTER_VERTICAL, 5 );
bSizerViasLeftCol->Add( fgViaPos, 0, wxEXPAND|wxBOTTOM, 8 );
wxFlexGridSizer* fgViaSizes;
fgViaSizes = new wxFlexGridSizer( 6, 3, 3, 3 );
fgViaSizes->AddGrowableCol( 1 );
fgViaSizes->SetFlexibleDirection( wxBOTH );
fgViaSizes->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_DesignRuleVias = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Pre-defined sizes:"), wxDefaultPosition, wxDefaultSize, 0 );
m_DesignRuleVias->Wrap( -1 );
viaLeftColumn->Add( m_DesignRuleVias, 0, wxALIGN_CENTER_VERTICAL|wxTOP, 5 );
fgViaSizes->Add( m_DesignRuleVias, 0, wxALIGN_CENTER_VERTICAL|wxTOP, 5 );
wxArrayString m_DesignRuleViasCtrlChoices;
m_DesignRuleViasCtrl = new wxChoice( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_DesignRuleViasCtrlChoices, 0 );
m_DesignRuleViasCtrl->SetSelection( 0 );
viaLeftColumn->Add( m_DesignRuleViasCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP, 5 );
fgViaSizes->Add( m_DesignRuleViasCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP, 5 );
m_DesignRuleViasUnit = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
m_DesignRuleViasUnit = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_DesignRuleViasUnit->Wrap( -1 );
viaLeftColumn->Add( m_DesignRuleViasUnit, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxTOP, 5 );
fgViaSizes->Add( m_DesignRuleViasUnit, 0, wxALIGN_CENTER_VERTICAL|wxTOP, 5 );
m_ViaDiameterLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Via diameter:"), wxDefaultPosition, wxDefaultSize, 0 );
m_ViaDiameterLabel->Wrap( -1 );
viaLeftColumn->Add( m_ViaDiameterLabel, 0, wxALIGN_CENTER_VERTICAL, 5 );
fgViaSizes->Add( m_ViaDiameterLabel, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_ViaDiameterCtrl = new wxTextCtrl( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
viaLeftColumn->Add( m_ViaDiameterCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
fgViaSizes->Add( m_ViaDiameterCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_ViaDiameterUnit = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
m_ViaDiameterUnit = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_ViaDiameterUnit->Wrap( -1 );
viaLeftColumn->Add( m_ViaDiameterUnit, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
fgViaSizes->Add( m_ViaDiameterUnit, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_ViaDrillLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Via hole:"), wxDefaultPosition, wxDefaultSize, 0 );
m_ViaDrillLabel->Wrap( -1 );
viaLeftColumn->Add( m_ViaDrillLabel, 0, wxALIGN_CENTER_VERTICAL, 5 );
fgViaSizes->Add( m_ViaDrillLabel, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_ViaDrillCtrl = new wxTextCtrl( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
viaLeftColumn->Add( m_ViaDrillCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
fgViaSizes->Add( m_ViaDrillCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_ViaDrillUnit = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Unit"), wxDefaultPosition, wxDefaultSize, 0 );
m_ViaDrillUnit = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_ViaDrillUnit->Wrap( -1 );
viaLeftColumn->Add( m_ViaDrillUnit, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
fgViaSizes->Add( m_ViaDrillUnit, 0, wxALIGN_CENTER_VERTICAL, 5 );
viaLeftColumn->Add( 0, 0, 1, wxEXPAND, 5 );
fgViaSizes->Add( 0, 0, 1, wxEXPAND, 5 );
m_viaNetclass = new wxCheckBox( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Use net class sizes"), wxDefaultPosition, wxDefaultSize, 0 );
viaLeftColumn->Add( m_viaNetclass, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 5 );
fgViaSizes->Add( m_viaNetclass, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 3 );
viaLeftColumn->Add( 0, 0, 1, wxEXPAND, 5 );
fgViaSizes->Add( 0, 0, 1, wxEXPAND, 5 );
m_sbViaSizer->Add( viaLeftColumn, 5, wxEXPAND|wxRIGHT|wxLEFT, 5 );
bSizerViasLeftCol->Add( fgViaSizes, 1, wxEXPAND, 5 );
m_sbViaSizer->Add( 0, 0, 0, wxEXPAND|wxRIGHT|wxLEFT, 15 );
bSizerViaCols->Add( bSizerViasLeftCol, 1, wxEXPAND, 5 );
bSizerViaCols->Add( 0, 0, 0, wxEXPAND|wxRIGHT|wxLEFT, 15 );
wxBoxSizer* viaRightColumn;
viaRightColumn = new wxBoxSizer( wxVERTICAL );
wxFlexGridSizer* fgSizer4;
fgSizer4 = new wxFlexGridSizer( 0, 2, 5, 0 );
fgSizer4 = new wxFlexGridSizer( 0, 2, 0, 5 );
fgSizer4->AddGrowableCol( 1 );
fgSizer4->SetFlexibleDirection( wxBOTH );
fgSizer4->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_ViaTypeLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Via type:"), wxDefaultPosition, wxDefaultSize, 0 );
m_ViaTypeLabel->Wrap( -1 );
fgSizer4->Add( m_ViaTypeLabel, 0, wxALIGN_CENTER_VERTICAL, 5 );
fgSizer4->Add( m_ViaTypeLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
wxString m_ViaTypeChoiceChoices[] = { _("Through"), _("Micro"), _("Blind/buried") };
int m_ViaTypeChoiceNChoices = sizeof( m_ViaTypeChoiceChoices ) / sizeof( wxString );
@ -260,35 +295,256 @@ DIALOG_TRACK_VIA_PROPERTIES_BASE::DIALOG_TRACK_VIA_PROPERTIES_BASE( wxWindow* pa
fgSizer4->Add( m_ViaTypeChoice, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
fgSizer4->Add( 0, 3, 1, wxEXPAND, 5 );
fgSizer4->Add( 0, 0, 1, wxEXPAND, 5 );
m_ViaStartLayerLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Start layer:"), wxDefaultPosition, wxDefaultSize, 0 );
m_ViaStartLayerLabel->Wrap( -1 );
fgSizer4->Add( m_ViaStartLayerLabel, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 );
fgSizer4->Add( m_ViaStartLayerLabel, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_ViaStartLayer = new PCB_LAYER_BOX_SELECTOR( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
fgSizer4->Add( m_ViaStartLayer, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_ViaEndLayerLabel1 = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("End layer:"), wxDefaultPosition, wxDefaultSize, 0 );
m_ViaEndLayerLabel1->Wrap( -1 );
fgSizer4->Add( m_ViaEndLayerLabel1, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 );
fgSizer4->Add( m_ViaEndLayerLabel1, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_ViaEndLayer = new PCB_LAYER_BOX_SELECTOR( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
fgSizer4->Add( m_ViaEndLayer, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
viaRightColumn->Add( fgSizer4, 0, wxBOTTOM|wxEXPAND|wxRIGHT, 5 );
fgSizer4->Add( 0, 15, 1, wxEXPAND, 5 );
fgSizer4->Add( 0, 0, 1, wxEXPAND, 5 );
m_annularRingsLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Annular rings:"), wxDefaultPosition, wxDefaultSize, 0 );
m_annularRingsLabel->Wrap( -1 );
viaRightColumn->Add( m_annularRingsLabel, 0, wxTOP, 10 );
fgSizer4->Add( m_annularRingsLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
wxString m_annularRingsCtrlChoices[] = { _("All copper layers"), _("Start, end, and connected layers"), _("Connected layers only") };
int m_annularRingsCtrlNChoices = sizeof( m_annularRingsCtrlChoices ) / sizeof( wxString );
m_annularRingsCtrl = new wxChoice( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_annularRingsCtrlNChoices, m_annularRingsCtrlChoices, 0 );
m_annularRingsCtrl->SetSelection( 0 );
viaRightColumn->Add( m_annularRingsCtrl, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 5 );
fgSizer4->Add( m_annularRingsCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_sbViaSizer->Add( viaRightColumn, 4, wxEXPAND|wxRIGHT, 5 );
viaRightColumn->Add( fgSizer4, 0, wxEXPAND|wxBOTTOM|wxRIGHT, 3 );
bSizerViaCols->Add( viaRightColumn, 1, wxEXPAND, 5 );
m_sbViaSizer->Add( bSizerViaCols, 0, wxEXPAND, 5 );
m_staticline2 = new wxStaticLine( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
m_sbViaSizer->Add( m_staticline2, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
m_legacyTeardropsWarning = new wxBoxSizer( wxHORIZONTAL );
m_legacyTeardropsIcon = new wxStaticBitmap( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
m_legacyTeardropsWarning->Add( m_legacyTeardropsIcon, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
wxBoxSizer* bSizer42;
bSizer42 = new wxBoxSizer( wxVERTICAL );
m_staticText85 = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Board contains legacy teardrops. "), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText85->Wrap( -1 );
bSizer42->Add( m_staticText85, 0, wxRIGHT|wxLEFT, 5 );
m_staticText851 = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Use Edit > Edit Teardrops to apply automatic teardrops."), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText851->Wrap( -1 );
bSizer42->Add( m_staticText851, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_legacyTeardropsWarning->Add( bSizer42, 1, wxALIGN_CENTER_VERTICAL, 5 );
m_sbViaSizer->Add( m_legacyTeardropsWarning, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
wxBoxSizer* bSizerTeardrops;
bSizerTeardrops = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizerCols11;
bSizerCols11 = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bSizerLeftCol11;
bSizerLeftCol11 = new wxBoxSizer( wxVERTICAL );
m_cbTeardrops = new wxCheckBox( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Add teardrops on via's track connections"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE );
bSizerLeftCol11->Add( m_cbTeardrops, 0, wxBOTTOM|wxRIGHT, 5 );
m_cbTeardropsUseNextTrack = new wxCheckBox( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Allow teardrops to span 2 track segments"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE );
m_cbTeardropsUseNextTrack->SetToolTip( _("Allows a teardrop to spread over 2 tracks if the first track segment is too short") );
bSizerLeftCol11->Add( m_cbTeardropsUseNextTrack, 0, wxBOTTOM|wxRIGHT, 5 );
bSizerCols11->Add( bSizerLeftCol11, 1, wxEXPAND|wxTOP, 3 );
bSizerCols11->Add( 20, 0, 0, wxEXPAND, 5 );
wxBoxSizer* bSizerRightCol11;
bSizerRightCol11 = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizer39;
bSizer39 = new wxBoxSizer( wxHORIZONTAL );
m_stHDRatio = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Maximum track width:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHDRatio->Wrap( -1 );
m_stHDRatio->SetToolTip( _("Max pad/via size to track width ratio to create a teardrop.\n100 always creates a teardrop.") );
bSizer39->Add( m_stHDRatio, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_tcHDRatio = new wxTextCtrl( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 );
m_tcHDRatio->SetToolTip( _("Tracks which are similar in size to the via do not need teardrops.") );
bSizer39->Add( m_tcHDRatio, 0, wxRIGHT|wxLEFT, 5 );
m_stHDRatioUnits = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHDRatioUnits->Wrap( -1 );
bSizer39->Add( m_stHDRatioUnits, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 );
bSizerRightCol11->Add( bSizer39, 0, wxEXPAND, 3 );
wxBoxSizer* bSizer17;
bSizer17 = new wxBoxSizer( wxVERTICAL );
m_minTrackWidthHint = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("(as a percentage of pad/via/track size)"), wxDefaultPosition, wxDefaultSize, 0 );
m_minTrackWidthHint->Wrap( -1 );
bSizer17->Add( m_minTrackWidthHint, 0, wxEXPAND|wxTOP|wxBOTTOM, 2 );
bSizerRightCol11->Add( bSizer17, 0, wxEXPAND|wxLEFT, 5 );
bSizerCols11->Add( bSizerRightCol11, 1, wxEXPAND|wxLEFT, 10 );
bSizerTeardrops->Add( bSizerCols11, 0, wxEXPAND|wxTOP, 3 );
bSizerTeardrops->Add( 0, 5, 0, wxEXPAND, 5 );
wxBoxSizer* bSizerShapeColumns;
bSizerShapeColumns = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bSizerLeftCol;
bSizerLeftCol = new wxBoxSizer( wxVERTICAL );
m_bitmapTeardrop = new wxStaticBitmap( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
bSizerLeftCol->Add( m_bitmapTeardrop, 1, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT, 5 );
wxBoxSizer* bSizer41;
bSizer41 = new wxBoxSizer( wxHORIZONTAL );
m_staticText15 = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Edges:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText15->Wrap( -1 );
bSizer41->Add( m_staticText15, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5 );
m_rbStraightLines = new wxRadioButton( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Straight lines"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
bSizer41->Add( m_rbStraightLines, 1, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5 );
m_rbCurved = new wxRadioButton( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Curved"), wxDefaultPosition, wxDefaultSize, wxRB_SINGLE );
bSizer41->Add( m_rbCurved, 1, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5 );
bSizerLeftCol->Add( bSizer41, 0, wxEXPAND|wxBOTTOM, 4 );
bSizerShapeColumns->Add( bSizerLeftCol, 1, wxEXPAND|wxRIGHT, 10 );
bSizerShapeColumns->Add( 20, 0, 0, wxEXPAND, 5 );
wxFlexGridSizer* fgSizerRightCol;
fgSizerRightCol = new wxFlexGridSizer( 0, 3, 2, 5 );
fgSizerRightCol->AddGrowableCol( 1 );
fgSizerRightCol->SetFlexibleDirection( wxBOTH );
fgSizerRightCol->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_stLenPercentLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Best length:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stLenPercentLabel->Wrap( -1 );
fgSizerRightCol->Add( m_stLenPercentLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_tcLenPercent = new wxTextCtrl( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerRightCol->Add( m_tcLenPercent, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
m_stLenPercentUnits = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stLenPercentUnits->Wrap( -1 );
fgSizerRightCol->Add( m_stLenPercentUnits, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_stMaxLen = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Max length:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxLen->Wrap( -1 );
fgSizerRightCol->Add( m_stMaxLen, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_tcTdMaxLen = new wxTextCtrl( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerRightCol->Add( m_tcTdMaxLen, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
m_stMaxLenUnits = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxLenUnits->Wrap( -1 );
fgSizerRightCol->Add( m_stMaxLenUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3 );
fgSizerRightCol->Add( 0, 3, 1, wxEXPAND, 5 );
fgSizerRightCol->Add( 0, 0, 1, wxEXPAND, 5 );
fgSizerRightCol->Add( 0, 0, 1, wxEXPAND, 5 );
m_stHeightPercentLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Best height:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHeightPercentLabel->Wrap( -1 );
fgSizerRightCol->Add( m_stHeightPercentLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_tcHeightPercent = new wxTextCtrl( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerRightCol->Add( m_tcHeightPercent, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
m_stHeightPercentUnits = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHeightPercentUnits->Wrap( -1 );
fgSizerRightCol->Add( m_stHeightPercentUnits, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_stMaxHeight = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Max height:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxHeight->Wrap( -1 );
fgSizerRightCol->Add( m_stMaxHeight, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_tcMaxHeight = new wxTextCtrl( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerRightCol->Add( m_tcMaxHeight, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
m_stMaxHeightUnits = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxHeightUnits->Wrap( -1 );
fgSizerRightCol->Add( m_stMaxHeightUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3 );
fgSizerRightCol->Add( 0, 0, 1, wxEXPAND, 5 );
fgSizerRightCol->Add( 0, 0, 1, wxEXPAND, 5 );
fgSizerRightCol->Add( 0, 3, 1, wxEXPAND, 5 );
m_curvePointsLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Curve points:"), wxDefaultPosition, wxDefaultSize, 0 );
m_curvePointsLabel->Wrap( -1 );
fgSizerRightCol->Add( m_curvePointsLabel, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 3 );
m_curvePointsCtrl = new wxTextCtrl( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 );
fgSizerRightCol->Add( m_curvePointsCtrl, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 3 );
bSizerShapeColumns->Add( fgSizerRightCol, 1, wxEXPAND|wxTOP|wxLEFT, 5 );
bSizerTeardrops->Add( bSizerShapeColumns, 1, wxEXPAND|wxBOTTOM, 3 );
m_sbViaSizer->Add( bSizerTeardrops, 1, wxEXPAND, 5 );
m_MainSizer->Add( m_sbViaSizer, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 10 );
@ -321,6 +577,32 @@ DIALOG_TRACK_VIA_PROPERTIES_BASE::DIALOG_TRACK_VIA_PROPERTIES_BASE( wxWindow* pa
m_ViaTypeChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onViaEdit ), NULL, this );
m_ViaStartLayer->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onViaEdit ), NULL, this );
m_ViaEndLayer->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onViaEdit ), NULL, this );
m_cbTeardrops->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_cbTeardropsUseNextTrack->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stHDRatio->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_tcHDRatio->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stHDRatioUnits->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_minTrackWidthHint->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_bitmapTeardrop->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_staticText15->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_rbStraightLines->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onStraightLines ), NULL, this );
m_rbStraightLines->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_rbCurved->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onCurvedLines ), NULL, this );
m_rbCurved->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stLenPercentLabel->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_tcLenPercent->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stLenPercentUnits->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stMaxLen->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_tcTdMaxLen->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stMaxLenUnits->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stHeightPercentLabel->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_tcHeightPercent->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stHeightPercentUnits->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stMaxHeight->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_tcMaxHeight->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stMaxHeightUnits->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_curvePointsLabel->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onCurvedEdgesUpdateUi ), NULL, this );
m_curvePointsCtrl->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onCurvedEdgesUpdateUi ), NULL, this );
}
DIALOG_TRACK_VIA_PROPERTIES_BASE::~DIALOG_TRACK_VIA_PROPERTIES_BASE()
@ -337,5 +619,31 @@ DIALOG_TRACK_VIA_PROPERTIES_BASE::~DIALOG_TRACK_VIA_PROPERTIES_BASE()
m_ViaTypeChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onViaEdit ), NULL, this );
m_ViaStartLayer->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onViaEdit ), NULL, this );
m_ViaEndLayer->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onViaEdit ), NULL, this );
m_cbTeardrops->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_cbTeardropsUseNextTrack->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stHDRatio->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_tcHDRatio->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stHDRatioUnits->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_minTrackWidthHint->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_bitmapTeardrop->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_staticText15->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_rbStraightLines->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onStraightLines ), NULL, this );
m_rbStraightLines->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_rbCurved->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onCurvedLines ), NULL, this );
m_rbCurved->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stLenPercentLabel->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_tcLenPercent->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stLenPercentUnits->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stMaxLen->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_tcTdMaxLen->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stMaxLenUnits->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stHeightPercentLabel->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_tcHeightPercent->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stHeightPercentUnits->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stMaxHeight->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_tcMaxHeight->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stMaxHeightUnits->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_curvePointsLabel->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onCurvedEdgesUpdateUi ), NULL, this );
m_curvePointsCtrl->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onCurvedEdgesUpdateUi ), NULL, this );
}

File diff suppressed because it is too large Load Diff

View File

@ -20,13 +20,18 @@ class PCB_LAYER_BOX_SELECTOR;
#include <wx/colour.h>
#include <wx/settings.h>
#include <widgets/net_selector.h>
#include <wx/checkbox.h>
#include <wx/sizer.h>
#include <wx/checkbox.h>
#include <wx/statline.h>
#include <wx/statbox.h>
#include <wx/textctrl.h>
#include <wx/choice.h>
#include <wx/bmpcbox.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/statbmp.h>
#include <wx/radiobut.h>
#include <wx/button.h>
#include <wx/dialog.h>
@ -51,13 +56,11 @@ class DIALOG_TRACK_VIA_PROPERTIES_BASE : public DIALOG_SHIM
wxStaticBoxSizer* m_sbTrackSizer;
wxStaticText* m_TrackStartXLabel;
wxTextCtrl* m_TrackStartXCtrl;
wxStaticText* m_TrackStartXUnit;
wxStaticText* m_TrackStartYLabel;
wxTextCtrl* m_TrackStartYCtrl;
wxStaticText* m_TrackStartYUnit;
wxStaticText* m_TrackEndXLabel;
wxTextCtrl* m_TrackEndXCtrl;
wxStaticText* m_TrackEndXUnit;
wxStaticText* m_TrackEndYLabel;
wxTextCtrl* m_TrackEndYCtrl;
wxStaticText* m_TrackEndYUnit;
@ -73,7 +76,6 @@ class DIALOG_TRACK_VIA_PROPERTIES_BASE : public DIALOG_SHIM
wxStaticBoxSizer* m_sbViaSizer;
wxStaticText* m_ViaXLabel;
wxTextCtrl* m_ViaXCtrl;
wxStaticText* m_ViaXUnit;
wxStaticText* m_ViaYLabel;
wxTextCtrl* m_ViaYCtrl;
wxStaticText* m_ViaYUnit;
@ -95,6 +97,35 @@ class DIALOG_TRACK_VIA_PROPERTIES_BASE : public DIALOG_SHIM
PCB_LAYER_BOX_SELECTOR* m_ViaEndLayer;
wxStaticText* m_annularRingsLabel;
wxChoice* m_annularRingsCtrl;
wxStaticLine* m_staticline2;
wxBoxSizer* m_legacyTeardropsWarning;
wxStaticBitmap* m_legacyTeardropsIcon;
wxStaticText* m_staticText85;
wxStaticText* m_staticText851;
wxCheckBox* m_cbTeardrops;
wxCheckBox* m_cbTeardropsUseNextTrack;
wxStaticText* m_stHDRatio;
wxTextCtrl* m_tcHDRatio;
wxStaticText* m_stHDRatioUnits;
wxStaticText* m_minTrackWidthHint;
wxStaticBitmap* m_bitmapTeardrop;
wxStaticText* m_staticText15;
wxRadioButton* m_rbStraightLines;
wxRadioButton* m_rbCurved;
wxStaticText* m_stLenPercentLabel;
wxTextCtrl* m_tcLenPercent;
wxStaticText* m_stLenPercentUnits;
wxStaticText* m_stMaxLen;
wxTextCtrl* m_tcTdMaxLen;
wxStaticText* m_stMaxLenUnits;
wxStaticText* m_stHeightPercentLabel;
wxTextCtrl* m_tcHeightPercent;
wxStaticText* m_stHeightPercentUnits;
wxStaticText* m_stMaxHeight;
wxTextCtrl* m_tcMaxHeight;
wxStaticText* m_stMaxHeightUnits;
wxStaticText* m_curvePointsLabel;
wxTextCtrl* m_curvePointsCtrl;
wxStdDialogButtonSizer* m_StdButtons;
wxButton* m_StdButtonsOK;
wxButton* m_StdButtonsCancel;
@ -107,6 +138,10 @@ class DIALOG_TRACK_VIA_PROPERTIES_BASE : public DIALOG_SHIM
virtual void onViaSelect( wxCommandEvent& event ) { event.Skip(); }
virtual void onViaEdit( wxCommandEvent& event ) { event.Skip(); }
virtual void onViaNetclassCheck( wxCommandEvent& event ) { event.Skip(); }
virtual void onTeardropsUpdateUi( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void onStraightLines( wxMouseEvent& event ) { event.Skip(); }
virtual void onCurvedLines( wxMouseEvent& event ) { event.Skip(); }
virtual void onCurvedEdgesUpdateUi( wxUpdateUIEvent& event ) { event.Skip(); }
public:

View File

@ -62,9 +62,9 @@ bool DIALOG_TRACK_VIA_SIZE::TransferDataFromWindow()
}
// Store dialog values to the router settings
m_settings.SetCustomTrackWidth( m_trackWidth.GetValue() );
m_settings.SetCustomViaSize( m_viaDiameter.GetValue() );
m_settings.SetCustomViaDrill( m_viaDrill.GetValue() );
m_settings.SetCustomTrackWidth( m_trackWidth.GetIntValue() );
m_settings.SetCustomViaSize( m_viaDiameter.GetIntValue() );
m_settings.SetCustomViaDrill( m_viaDrill.GetIntValue() );
return true;
}

View File

@ -53,6 +53,20 @@ PANEL_SETUP_CONSTRAINTS::PANEL_SETUP_CONSTRAINTS( wxWindow* aParentWindow, PCB_E
m_Frame = aFrame;
m_BrdSettings = &m_Frame->GetBoard()->GetDesignSettings();
m_filletBitmap->SetBitmap( KiBitmap( BITMAPS::zone_fillet ) );
m_spokeBitmap->SetBitmap( KiBitmap( BITMAPS::thermal_spokes ) );
m_bitmapClearance->SetBitmap( KiBitmap( BITMAPS::ps_diff_pair_gap ) );
m_bitmapMinTrackWidth->SetBitmap( KiBitmap( BITMAPS::width_track ) );
m_bitmapMinConn->SetBitmap( KiBitmap( BITMAPS::width_conn ) );
m_bitmapMinViaAnnulus->SetBitmap( KiBitmap( BITMAPS::via_annulus ) );
m_bitmapMinViaDiameter->SetBitmap( KiBitmap( BITMAPS::via_diameter ) );
m_bitmapMinViaDrill->SetBitmap( KiBitmap( BITMAPS::via_hole_diameter ) );
m_bitmapMinuViaDiameter->SetBitmap( KiBitmap( BITMAPS::via_diameter ) );
m_bitmapMinuViaDrill->SetBitmap( KiBitmap( BITMAPS::via_hole_diameter ) );
m_bitmapHoleClearance->SetBitmap( KiBitmap( BITMAPS::hole_to_copper_clearance ) );
m_bitmapMinHoleClearance->SetBitmap( KiBitmap( BITMAPS::hole_to_hole_clearance ) );
m_bitmapEdgeClearance->SetBitmap( KiBitmap( BITMAPS::edge_to_copper_clearance ) );
m_stCircleToPolyWarning->SetFont( KIUI::GetInfoFont( this ) );
wxSize ctrlSize = m_minResolvedSpokeCountCtrl->GetSize();
@ -158,36 +172,6 @@ bool PANEL_SETUP_CONSTRAINTS::TransferDataFromWindow()
}
bool PANEL_SETUP_CONSTRAINTS::Show( bool aShow )
{
bool retVal = wxPanel::Show( aShow );
if( aShow )
{
// These *should* work in the constructor, and indeed they do if this panel is the
// first displayed. However, on OSX 3.0.5 (at least), if another panel is displayed
// first then the icons will be blank unless they're set here.
m_filletBitmap->SetBitmap( KiBitmap( BITMAPS::zone_fillet ) );
m_spokeBitmap->SetBitmap( KiBitmap( BITMAPS::thermal_spokes ) );
m_bitmapClearance->SetBitmap( KiBitmap( BITMAPS::ps_diff_pair_gap ) );
m_bitmapMinTrackWidth->SetBitmap( KiBitmap( BITMAPS::width_track ) );
m_bitmapMinConn->SetBitmap( KiBitmap( BITMAPS::width_conn ) );
m_bitmapMinViaAnnulus->SetBitmap( KiBitmap( BITMAPS::via_annulus ) );
m_bitmapMinViaDiameter->SetBitmap( KiBitmap( BITMAPS::via_diameter ) );
m_bitmapMinViaDrill->SetBitmap( KiBitmap( BITMAPS::via_hole_diameter ) );
m_bitmapMinuViaDiameter->SetBitmap( KiBitmap( BITMAPS::via_diameter ) );
m_bitmapMinuViaDrill->SetBitmap( KiBitmap( BITMAPS::via_hole_diameter ) );
m_bitmapHoleClearance->SetBitmap( KiBitmap( BITMAPS::hole_to_copper_clearance ) );
m_bitmapMinHoleClearance->SetBitmap( KiBitmap( BITMAPS::hole_to_hole_clearance ) );
m_bitmapEdgeClearance->SetBitmap( KiBitmap( BITMAPS::edge_to_copper_clearance ) );
Layout();
}
return retVal;
}
void PANEL_SETUP_CONSTRAINTS::ImportSettingsFrom( BOARD* aBoard )
{
BOARD_DESIGN_SETTINGS* savedSettings = m_BrdSettings;

View File

@ -44,7 +44,6 @@ public:
void ImportSettingsFrom( BOARD* aBoard );
private:
bool Show( bool aShow ) override;
bool TransferDataToWindow() override;
bool TransferDataFromWindow() override;

View File

@ -26,8 +26,6 @@
#include <board.h>
#include <board_design_settings.h>
#include <panel_setup_formatting.h>
#include <widgets/paged_dialog.h>
#include <wx/treebook.h>
PANEL_SETUP_FORMATTING::PANEL_SETUP_FORMATTING( wxWindow* aParentWindow, PCB_EDIT_FRAME* aFrame ) :

View File

@ -0,0 +1,164 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 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 <pcb_edit_frame.h>
#include <pcb_painter.h>
#include <board.h>
#include <board_design_settings.h>
#include "panel_setup_teardrops.h"
PANEL_SETUP_TEARDROPS::PANEL_SETUP_TEARDROPS( wxWindow* aParentWindow, PCB_EDIT_FRAME* aFrame ) :
PANEL_SETUP_TEARDROPS_BASE( aParentWindow ),
m_BrdSettings( &aFrame->GetBoard()->GetDesignSettings() ),
m_teardropMaxLenRound( aFrame, m_stMaxLen, m_tcTdMaxLen, m_stMaxLenUnits ),
m_teardropMaxHeightRound( aFrame, m_stTdMaxSize, m_tcMaxHeight, m_stMaxHeightUnits ),
m_teardropMaxLenRect( aFrame, m_stMaxLen1, m_tcTdMaxLen1, m_stMaxLenUnits1 ),
m_teardropMaxHeightRect( aFrame, m_stTdMaxSize1, m_tcMaxHeight1, m_stMaxHeightUnits1 ),
m_teardropMaxLenTrack( aFrame, m_stMaxLen2, m_tcTdMaxLen2, m_stMaxLenUnits2 ),
m_teardropMaxHeightTrack( aFrame, m_stTdMaxSize2, m_tcMaxHeight2, m_stMaxHeightUnits2 )
{
m_bitmapTeardrop->SetBitmap( KiBitmap( BITMAPS::teardrop_sizes ) );
m_bitmapTeardrop1->SetBitmap( KiBitmap( BITMAPS::teardrop_rect_sizes ) );
m_bitmapTeardrop2->SetBitmap( KiBitmap( BITMAPS::teardrop_track_sizes ) );
wxFont infoFont = KIUI::GetInfoFont( this ).Italic();
m_minTrackWidthHint->SetFont( infoFont );
m_minTrackWidthHint1->SetFont( infoFont );
m_minTrackWidthHint2->SetFont( infoFont );
}
bool PANEL_SETUP_TEARDROPS::TransferDataToWindow()
{
TEARDROP_PARAMETERS_LIST* prmsList = m_BrdSettings->GetTeadropParamsList();
TEARDROP_PARAMETERS* prms = prmsList->GetParameters( TARGET_ROUND );
m_teardropMaxLenRound.SetValue( prms->m_TdMaxLen );
m_teardropMaxHeightRound.SetValue( prms->m_TdMaxWidth );
m_spTeardropLenPercent->SetValue( prms->m_BestLengthRatio *100.0 );
m_spTeardropSizePercent->SetValue( prms->m_BestWidthRatio *100.0 );
m_spTeardropHDPercent->SetValue( prms->m_WidthtoSizeFilterRatio*100.0 );
m_cbPreferZoneConnection->SetValue( !prms->m_TdOnPadsInZones );
m_cbTeardropsUseNextTrack->SetValue( prms->m_AllowUseTwoTracks );
if( prms->IsCurved() )
{
m_rbCurved->SetValue( true );
m_curvePointsCtrl->SetValue( prms->m_CurveSegCount );
}
else
{
m_rbStraightLines->SetValue( true );
m_curvePointsCtrl->SetValue( 5 );
}
prms = prmsList->GetParameters( TARGET_RECT );
m_teardropMaxLenRect.SetValue( prms->m_TdMaxLen );
m_teardropMaxHeightRect.SetValue( prms->m_TdMaxWidth );
m_spTeardropLenPercent1->SetValue( prms->m_BestLengthRatio *100.0 );
m_spTeardropSizePercent1->SetValue( prms->m_BestWidthRatio *100.0 );
m_spTeardropHDPercent1->SetValue( prms->m_WidthtoSizeFilterRatio*100.0 );
m_cbPreferZoneConnection1->SetValue( !prms->m_TdOnPadsInZones );
m_cbTeardropsUseNextTrack1->SetValue( prms->m_AllowUseTwoTracks );
if( prms->IsCurved() )
{
m_rbCurved1->SetValue( true );
m_curvePointsCtrl1->SetValue( prms->m_CurveSegCount );
}
else
{
m_rbStraightLines1->SetValue( true );
m_curvePointsCtrl1->SetValue( 5 );
}
prms = prmsList->GetParameters( TARGET_TRACK );
m_teardropMaxLenTrack.SetValue( prms->m_TdMaxLen );
m_teardropMaxHeightTrack.SetValue( prms->m_TdMaxWidth );
m_spTeardropLenPercent2->SetValue( prms->m_BestLengthRatio *100.0 );
m_spTeardropSizePercent2->SetValue( prms->m_BestWidthRatio *100.0 );
m_spTeardropHDPercent2->SetValue( prms->m_WidthtoSizeFilterRatio*100.0 );
m_cbTeardropsUseNextTrack2->SetValue( prms->m_AllowUseTwoTracks );
if( prms->IsCurved() )
{
m_rbCurved2->SetValue( true );
m_curvePointsCtrl2->SetValue( prms->m_CurveSegCount );
}
else
{
m_rbStraightLines2->SetValue( true );
m_curvePointsCtrl2->SetValue( 5 );
}
return true;
}
bool PANEL_SETUP_TEARDROPS::TransferDataFromWindow()
{
TEARDROP_PARAMETERS_LIST* prmsList = m_BrdSettings->GetTeadropParamsList();
TEARDROP_PARAMETERS* prms = prmsList->GetParameters( TARGET_ROUND );
prms->m_BestLengthRatio = m_spTeardropLenPercent->GetValue() / 100.0;
prms->m_BestWidthRatio = m_spTeardropSizePercent->GetValue() / 100.0;
prms->m_TdMaxLen = m_teardropMaxLenRound.GetIntValue();
prms->m_TdMaxWidth = m_teardropMaxHeightRound.GetIntValue();
prms->m_CurveSegCount = m_rbStraightLines->GetValue() ? 0 : m_curvePointsCtrl->GetValue();
prms->m_WidthtoSizeFilterRatio = m_spTeardropHDPercent->GetValue() / 100.0;
prms->m_TdOnPadsInZones = !m_cbPreferZoneConnection->GetValue();
prms->m_AllowUseTwoTracks = m_cbTeardropsUseNextTrack->GetValue();
prms = prmsList->GetParameters( TARGET_RECT );
prms->m_BestLengthRatio = m_spTeardropLenPercent1->GetValue() / 100.0;
prms->m_BestWidthRatio = m_spTeardropSizePercent1->GetValue() / 100.0;
prms->m_TdMaxLen = m_teardropMaxLenRect.GetIntValue();
prms->m_TdMaxWidth = m_teardropMaxHeightRect.GetIntValue();
prms->m_CurveSegCount = m_rbStraightLines1->GetValue() ? 0 : m_curvePointsCtrl1->GetValue();
prms->m_WidthtoSizeFilterRatio = m_spTeardropHDPercent1->GetValue() / 100.0;
prms->m_TdOnPadsInZones = !m_cbPreferZoneConnection1->GetValue();
prms->m_AllowUseTwoTracks = m_cbTeardropsUseNextTrack1->GetValue();
prms = prmsList->GetParameters( TARGET_TRACK );
prms->m_BestLengthRatio = m_spTeardropLenPercent2->GetValue() / 100.0;
prms->m_BestWidthRatio = m_spTeardropSizePercent2->GetValue() / 100.0;
prms->m_TdMaxLen = m_teardropMaxLenTrack.GetIntValue();
prms->m_TdMaxWidth = m_teardropMaxHeightTrack.GetIntValue();
prms->m_CurveSegCount = m_rbStraightLines2->GetValue() ? 0 : m_curvePointsCtrl2->GetValue();
prms->m_WidthtoSizeFilterRatio = m_spTeardropHDPercent2->GetValue() / 100.0;
prms->m_AllowUseTwoTracks = m_cbTeardropsUseNextTrack2->GetValue();
return true;
}
void PANEL_SETUP_TEARDROPS::ImportSettingsFrom( BOARD* aBoard )
{
BOARD_DESIGN_SETTINGS* savedSettings = m_BrdSettings;
m_BrdSettings = &aBoard->GetDesignSettings();
TransferDataToWindow();
m_BrdSettings = savedSettings;
}

View File

@ -0,0 +1,53 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef PANEL_SETUP_TEARDROPS_H
#define PANEL_SETUP_TEARDROPS_H
#include <widgets/unit_binder.h>
#include <panel_setup_teardrops_base.h>
class PCB_EDIT_FRAME;
class BOARD;
class PAGED_DIALOG;
class PANEL_SETUP_TEARDROPS : public PANEL_SETUP_TEARDROPS_BASE
{
public:
PANEL_SETUP_TEARDROPS( wxWindow* aParentWindow, PCB_EDIT_FRAME* aFrame );
bool TransferDataToWindow() override;
bool TransferDataFromWindow() override;
void ImportSettingsFrom( BOARD* aBoard );
private:
BOARD_DESIGN_SETTINGS* m_BrdSettings;
UNIT_BINDER m_teardropMaxLenRound;
UNIT_BINDER m_teardropMaxHeightRound;
UNIT_BINDER m_teardropMaxLenRect;
UNIT_BINDER m_teardropMaxHeightRect;
UNIT_BINDER m_teardropMaxLenTrack;
UNIT_BINDER m_teardropMaxHeightTrack;
};
#endif //PANEL_SETUP_TEARDROPS_H

View File

@ -0,0 +1,423 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "panel_setup_teardrops_base.h"
///////////////////////////////////////////////////////////////////////////
PANEL_SETUP_TEARDROPS_BASE::PANEL_SETUP_TEARDROPS_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name )
{
wxBoxSizer* mainSizer;
mainSizer = new wxBoxSizer( wxVERTICAL );
m_gridSizer = new wxBoxSizer( wxVERTICAL );
m_roundShapesLabel = new wxStaticText( this, wxID_ANY, _("Default properties for round shapes:"), wxDefaultPosition, wxDefaultSize, 0 );
m_roundShapesLabel->Wrap( -1 );
m_gridSizer->Add( m_roundShapesLabel, 0, wxTOP|wxRIGHT|wxLEFT, 8 );
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
m_gridSizer->Add( m_staticline1, 0, wxEXPAND|wxBOTTOM, 10 );
wxBoxSizer* bSizerShapeColumns;
bSizerShapeColumns = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bSizerLeftCol;
bSizerLeftCol = new wxBoxSizer( wxVERTICAL );
m_bitmapTeardrop = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
bSizerLeftCol->Add( m_bitmapTeardrop, 1, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT, 5 );
wxBoxSizer* bSizer41;
bSizer41 = new wxBoxSizer( wxHORIZONTAL );
m_edgesLabel = new wxStaticText( this, wxID_ANY, _("Edges:"), wxDefaultPosition, wxDefaultSize, 0 );
m_edgesLabel->Wrap( -1 );
bSizer41->Add( m_edgesLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_rbStraightLines = new wxRadioButton( this, wxID_ANY, _("Straight lines"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
bSizer41->Add( m_rbStraightLines, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_rbCurved = new wxRadioButton( this, wxID_ANY, _("Curved"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer41->Add( m_rbCurved, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
bSizerLeftCol->Add( bSizer41, 0, wxEXPAND|wxBOTTOM, 4 );
bSizerShapeColumns->Add( bSizerLeftCol, 0, wxEXPAND|wxRIGHT, 10 );
bSizerShapeColumns->Add( 10, 0, 0, wxEXPAND, 5 );
wxGridBagSizer* gbSizer;
gbSizer = new wxGridBagSizer( 2, 5 );
gbSizer->SetFlexibleDirection( wxBOTH );
gbSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
gbSizer->SetEmptyCellSize( wxSize( 10,9 ) );
m_stHsetting = new wxStaticText( this, wxID_ANY, _("Best length:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHsetting->Wrap( -1 );
gbSizer->Add( m_stHsetting, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_spTeardropLenPercent = new wxSpinCtrlDouble( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 20, 100, 40.000000, 10 );
m_spTeardropLenPercent->SetDigits( 0 );
gbSizer->Add( m_spTeardropLenPercent, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_stTeardropLenUnits = new wxStaticText( this, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stTeardropLenUnits->Wrap( -1 );
gbSizer->Add( m_stTeardropLenUnits, wxGBPosition( 0, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_stMaxLen = new wxStaticText( this, wxID_ANY, _("Max length:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxLen->Wrap( -1 );
gbSizer->Add( m_stMaxLen, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_tcTdMaxLen = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
gbSizer->Add( m_tcTdMaxLen, wxGBPosition( 1, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_stMaxLenUnits = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxLenUnits->Wrap( -1 );
gbSizer->Add( m_stMaxLenUnits, wxGBPosition( 1, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_stVsetting = new wxStaticText( this, wxID_ANY, _("Best height:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stVsetting->Wrap( -1 );
gbSizer->Add( m_stVsetting, wxGBPosition( 3, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_spTeardropSizePercent = new wxSpinCtrlDouble( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 60, 100, 100.000000, 10 );
m_spTeardropSizePercent->SetDigits( 0 );
gbSizer->Add( m_spTeardropSizePercent, wxGBPosition( 3, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_stLenPercent = new wxStaticText( this, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stLenPercent->Wrap( -1 );
gbSizer->Add( m_stLenPercent, wxGBPosition( 3, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_stTdMaxSize = new wxStaticText( this, wxID_ANY, _("Max height:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stTdMaxSize->Wrap( -1 );
gbSizer->Add( m_stTdMaxSize, wxGBPosition( 4, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_tcMaxHeight = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
gbSizer->Add( m_tcMaxHeight, wxGBPosition( 4, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_stMaxHeightUnits = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxHeightUnits->Wrap( -1 );
gbSizer->Add( m_stMaxHeightUnits, wxGBPosition( 4, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_curvePointsLabel = new wxStaticText( this, wxID_ANY, _("Curve points:"), wxDefaultPosition, wxDefaultSize, 0 );
m_curvePointsLabel->Wrap( -1 );
gbSizer->Add( m_curvePointsLabel, wxGBPosition( 6, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_curvePointsCtrl = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 3, 10, 5 );
gbSizer->Add( m_curvePointsCtrl, wxGBPosition( 6, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_cbPreferZoneConnection = new wxCheckBox( this, wxID_ANY, _("Prefer zone connection"), wxDefaultPosition, wxDefaultSize, 0 );
gbSizer->Add( m_cbPreferZoneConnection, wxGBPosition( 3, 3 ), wxGBSpan( 1, 3 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 60 );
m_stHDRatio = new wxStaticText( this, wxID_ANY, _("Maximum track width:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHDRatio->Wrap( -1 );
m_stHDRatio->SetToolTip( _("Max pad/via size to track width ratio to create a teardrop.\n100 always creates a teardrop.") );
gbSizer->Add( m_stHDRatio, wxGBPosition( 0, 3 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 60 );
m_spTeardropHDPercent = new wxSpinCtrlDouble( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 100, 90, 10 );
m_spTeardropHDPercent->SetDigits( 0 );
m_spTeardropHDPercent->SetToolTip( _("Tracks which are similar in size to the pad or via do not need teardrops.") );
gbSizer->Add( m_spTeardropHDPercent, wxGBPosition( 0, 4 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_minTrackWidthUnits = new wxStaticText( this, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_minTrackWidthUnits->Wrap( -1 );
gbSizer->Add( m_minTrackWidthUnits, wxGBPosition( 0, 5 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_minTrackWidthHint = new wxStaticText( this, wxID_ANY, _("(as a percentage of pad/via size)"), wxDefaultPosition, wxDefaultSize, 0 );
m_minTrackWidthHint->Wrap( -1 );
gbSizer->Add( m_minTrackWidthHint, wxGBPosition( 1, 3 ), wxGBSpan( 1, 3 ), wxLEFT, 65 );
m_cbTeardropsUseNextTrack = new wxCheckBox( this, wxID_ANY, _("Allow teardrop to span two track segments"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbTeardropsUseNextTrack->SetValue(true);
gbSizer->Add( m_cbTeardropsUseNextTrack, wxGBPosition( 6, 2 ), wxGBSpan( 1, 5 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
bSizerShapeColumns->Add( gbSizer, 0, wxEXPAND|wxLEFT, 20 );
m_gridSizer->Add( bSizerShapeColumns, 1, wxEXPAND, 5 );
m_gridSizer->Add( 0, 25, 0, wxEXPAND, 5 );
m_rectShapesLabel = new wxStaticText( this, wxID_ANY, _("Default properties for rectangular shapes:"), wxDefaultPosition, wxDefaultSize, 0 );
m_rectShapesLabel->Wrap( -1 );
m_gridSizer->Add( m_rectShapesLabel, 0, wxTOP|wxRIGHT|wxLEFT, 8 );
m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
m_gridSizer->Add( m_staticline2, 0, wxEXPAND|wxBOTTOM, 10 );
wxBoxSizer* bSizerShapeColumns1;
bSizerShapeColumns1 = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bSizerLeftCol1;
bSizerLeftCol1 = new wxBoxSizer( wxVERTICAL );
m_bitmapTeardrop1 = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
bSizerLeftCol1->Add( m_bitmapTeardrop1, 1, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT, 5 );
wxBoxSizer* bSizer411;
bSizer411 = new wxBoxSizer( wxHORIZONTAL );
m_edgesLabel1 = new wxStaticText( this, wxID_ANY, _("Edges:"), wxDefaultPosition, wxDefaultSize, 0 );
m_edgesLabel1->Wrap( -1 );
bSizer411->Add( m_edgesLabel1, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_rbStraightLines1 = new wxRadioButton( this, wxID_ANY, _("Straight lines"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
bSizer411->Add( m_rbStraightLines1, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_rbCurved1 = new wxRadioButton( this, wxID_ANY, _("Curved"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer411->Add( m_rbCurved1, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
bSizerLeftCol1->Add( bSizer411, 0, wxEXPAND|wxBOTTOM, 4 );
bSizerShapeColumns1->Add( bSizerLeftCol1, 0, wxEXPAND|wxRIGHT, 10 );
bSizerShapeColumns1->Add( 10, 0, 0, wxEXPAND, 5 );
wxGridBagSizer* gbSizer1;
gbSizer1 = new wxGridBagSizer( 2, 5 );
gbSizer1->SetFlexibleDirection( wxBOTH );
gbSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
gbSizer1->SetEmptyCellSize( wxSize( 10,9 ) );
m_stHsetting1 = new wxStaticText( this, wxID_ANY, _("Best length:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHsetting1->Wrap( -1 );
gbSizer1->Add( m_stHsetting1, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_spTeardropLenPercent1 = new wxSpinCtrlDouble( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 20, 100, 40.000000, 10 );
m_spTeardropLenPercent1->SetDigits( 0 );
gbSizer1->Add( m_spTeardropLenPercent1, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_stTeardropLenUnits1 = new wxStaticText( this, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stTeardropLenUnits1->Wrap( -1 );
gbSizer1->Add( m_stTeardropLenUnits1, wxGBPosition( 0, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_stMaxLen1 = new wxStaticText( this, wxID_ANY, _("Max length:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxLen1->Wrap( -1 );
gbSizer1->Add( m_stMaxLen1, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_tcTdMaxLen1 = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
gbSizer1->Add( m_tcTdMaxLen1, wxGBPosition( 1, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_stMaxLenUnits1 = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxLenUnits1->Wrap( -1 );
gbSizer1->Add( m_stMaxLenUnits1, wxGBPosition( 1, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_stVsetting1 = new wxStaticText( this, wxID_ANY, _("Best height:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stVsetting1->Wrap( -1 );
gbSizer1->Add( m_stVsetting1, wxGBPosition( 3, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_spTeardropSizePercent1 = new wxSpinCtrlDouble( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 60, 100, 100.000000, 10 );
m_spTeardropSizePercent1->SetDigits( 0 );
gbSizer1->Add( m_spTeardropSizePercent1, wxGBPosition( 3, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_stLenPercent1 = new wxStaticText( this, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stLenPercent1->Wrap( -1 );
gbSizer1->Add( m_stLenPercent1, wxGBPosition( 3, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_stTdMaxSize1 = new wxStaticText( this, wxID_ANY, _("Max height:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stTdMaxSize1->Wrap( -1 );
gbSizer1->Add( m_stTdMaxSize1, wxGBPosition( 4, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_tcMaxHeight1 = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
gbSizer1->Add( m_tcMaxHeight1, wxGBPosition( 4, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_stMaxHeightUnits1 = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxHeightUnits1->Wrap( -1 );
gbSizer1->Add( m_stMaxHeightUnits1, wxGBPosition( 4, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_curvePointsLabel1 = new wxStaticText( this, wxID_ANY, _("Curve points:"), wxDefaultPosition, wxDefaultSize, 0 );
m_curvePointsLabel1->Wrap( -1 );
gbSizer1->Add( m_curvePointsLabel1, wxGBPosition( 6, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_curvePointsCtrl1 = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 3, 10, 5 );
gbSizer1->Add( m_curvePointsCtrl1, wxGBPosition( 6, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_cbPreferZoneConnection1 = new wxCheckBox( this, wxID_ANY, _("Prefer zone connection"), wxDefaultPosition, wxDefaultSize, 0 );
gbSizer1->Add( m_cbPreferZoneConnection1, wxGBPosition( 3, 3 ), wxGBSpan( 1, 3 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 60 );
m_stHDRatio1 = new wxStaticText( this, wxID_ANY, _("Maximum track width:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHDRatio1->Wrap( -1 );
m_stHDRatio1->SetToolTip( _("Max pad/via size to track width ratio to create a teardrop.\n100 always creates a teardrop.") );
gbSizer1->Add( m_stHDRatio1, wxGBPosition( 0, 3 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 60 );
m_spTeardropHDPercent1 = new wxSpinCtrlDouble( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 100, 90, 10 );
m_spTeardropHDPercent1->SetDigits( 0 );
m_spTeardropHDPercent1->SetToolTip( _("Tracks which are similar in size to the pad do not need teardrops.") );
gbSizer1->Add( m_spTeardropHDPercent1, wxGBPosition( 0, 4 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_minTrackWidthUnits1 = new wxStaticText( this, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_minTrackWidthUnits1->Wrap( -1 );
gbSizer1->Add( m_minTrackWidthUnits1, wxGBPosition( 0, 5 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_minTrackWidthHint1 = new wxStaticText( this, wxID_ANY, _("(as a percentage of pad size)"), wxDefaultPosition, wxDefaultSize, 0 );
m_minTrackWidthHint1->Wrap( -1 );
gbSizer1->Add( m_minTrackWidthHint1, wxGBPosition( 1, 3 ), wxGBSpan( 1, 3 ), wxLEFT, 65 );
m_cbTeardropsUseNextTrack1 = new wxCheckBox( this, wxID_ANY, _("Allow teardrop to span two track segments"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbTeardropsUseNextTrack1->SetValue(true);
gbSizer1->Add( m_cbTeardropsUseNextTrack1, wxGBPosition( 6, 2 ), wxGBSpan( 1, 5 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
bSizerShapeColumns1->Add( gbSizer1, 0, wxEXPAND|wxLEFT, 20 );
m_gridSizer->Add( bSizerShapeColumns1, 1, wxEXPAND, 5 );
m_gridSizer->Add( 0, 25, 0, wxEXPAND, 5 );
m_tracksLabel = new wxStaticText( this, wxID_ANY, _("Properties for track-to-track teardrops:"), wxDefaultPosition, wxDefaultSize, 0 );
m_tracksLabel->Wrap( -1 );
m_gridSizer->Add( m_tracksLabel, 0, wxTOP|wxRIGHT|wxLEFT, 8 );
m_staticline3 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
m_gridSizer->Add( m_staticline3, 0, wxEXPAND|wxBOTTOM, 10 );
wxBoxSizer* bSizerShapeColumns2;
bSizerShapeColumns2 = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bSizerLeftCol2;
bSizerLeftCol2 = new wxBoxSizer( wxVERTICAL );
m_bitmapTeardrop2 = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
bSizerLeftCol2->Add( m_bitmapTeardrop2, 1, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT, 5 );
wxBoxSizer* bSizer412;
bSizer412 = new wxBoxSizer( wxHORIZONTAL );
m_edgesLabel2 = new wxStaticText( this, wxID_ANY, _("Edges:"), wxDefaultPosition, wxDefaultSize, 0 );
m_edgesLabel2->Wrap( -1 );
bSizer412->Add( m_edgesLabel2, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_rbStraightLines2 = new wxRadioButton( this, wxID_ANY, _("Straight lines"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
bSizer412->Add( m_rbStraightLines2, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_rbCurved2 = new wxRadioButton( this, wxID_ANY, _("Curved"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer412->Add( m_rbCurved2, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
bSizerLeftCol2->Add( bSizer412, 0, wxEXPAND|wxBOTTOM, 4 );
bSizerShapeColumns2->Add( bSizerLeftCol2, 0, wxEXPAND|wxRIGHT, 10 );
bSizerShapeColumns2->Add( 10, 0, 0, wxEXPAND, 5 );
wxGridBagSizer* gbSizer2;
gbSizer2 = new wxGridBagSizer( 2, 5 );
gbSizer2->SetFlexibleDirection( wxBOTH );
gbSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
gbSizer2->SetEmptyCellSize( wxSize( 10,9 ) );
m_stHsetting2 = new wxStaticText( this, wxID_ANY, _("Best length:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHsetting2->Wrap( -1 );
gbSizer2->Add( m_stHsetting2, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_spTeardropLenPercent2 = new wxSpinCtrlDouble( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 20, 100, 40.000000, 10 );
m_spTeardropLenPercent2->SetDigits( 0 );
gbSizer2->Add( m_spTeardropLenPercent2, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_stTeardropLenUnits2 = new wxStaticText( this, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stTeardropLenUnits2->Wrap( -1 );
gbSizer2->Add( m_stTeardropLenUnits2, wxGBPosition( 0, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_stMaxLen2 = new wxStaticText( this, wxID_ANY, _("Max length:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxLen2->Wrap( -1 );
gbSizer2->Add( m_stMaxLen2, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_tcTdMaxLen2 = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
gbSizer2->Add( m_tcTdMaxLen2, wxGBPosition( 1, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_stMaxLenUnits2 = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxLenUnits2->Wrap( -1 );
gbSizer2->Add( m_stMaxLenUnits2, wxGBPosition( 1, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_stVsetting2 = new wxStaticText( this, wxID_ANY, _("Best height:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stVsetting2->Wrap( -1 );
gbSizer2->Add( m_stVsetting2, wxGBPosition( 3, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_spTeardropSizePercent2 = new wxSpinCtrlDouble( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 60, 100, 100.000000, 10 );
m_spTeardropSizePercent2->SetDigits( 0 );
gbSizer2->Add( m_spTeardropSizePercent2, wxGBPosition( 3, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_stLenPercent2 = new wxStaticText( this, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stLenPercent2->Wrap( -1 );
gbSizer2->Add( m_stLenPercent2, wxGBPosition( 3, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_stTdMaxSize2 = new wxStaticText( this, wxID_ANY, _("Max height:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stTdMaxSize2->Wrap( -1 );
gbSizer2->Add( m_stTdMaxSize2, wxGBPosition( 4, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_tcMaxHeight2 = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
gbSizer2->Add( m_tcMaxHeight2, wxGBPosition( 4, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_stMaxHeightUnits2 = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxHeightUnits2->Wrap( -1 );
gbSizer2->Add( m_stMaxHeightUnits2, wxGBPosition( 4, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_curvePointsLabel2 = new wxStaticText( this, wxID_ANY, _("Curve points:"), wxDefaultPosition, wxDefaultSize, 0 );
m_curvePointsLabel2->Wrap( -1 );
gbSizer2->Add( m_curvePointsLabel2, wxGBPosition( 6, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_curvePointsCtrl2 = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 3, 10, 5 );
gbSizer2->Add( m_curvePointsCtrl2, wxGBPosition( 6, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_stHDRatio2 = new wxStaticText( this, wxID_ANY, _("Maximum track width"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHDRatio2->Wrap( -1 );
m_stHDRatio2->SetToolTip( _("Max pad/via size to track width ratio to create a teardrop.\n100 always creates a teardrop.") );
gbSizer2->Add( m_stHDRatio2, wxGBPosition( 0, 3 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 60 );
m_spTeardropHDPercent2 = new wxSpinCtrlDouble( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 100, 90, 10 );
m_spTeardropHDPercent2->SetDigits( 0 );
m_spTeardropHDPercent2->SetToolTip( _("Tracks which are similar in size do not need teardrops.") );
gbSizer2->Add( m_spTeardropHDPercent2, wxGBPosition( 0, 4 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_minTrackWidthUnits2 = new wxStaticText( this, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_minTrackWidthUnits2->Wrap( -1 );
gbSizer2->Add( m_minTrackWidthUnits2, wxGBPosition( 0, 5 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
m_minTrackWidthHint2 = new wxStaticText( this, wxID_ANY, _("(as a percentage of larger track width)"), wxDefaultPosition, wxDefaultSize, 0 );
m_minTrackWidthHint2->Wrap( -1 );
gbSizer2->Add( m_minTrackWidthHint2, wxGBPosition( 1, 3 ), wxGBSpan( 1, 3 ), wxLEFT, 65 );
m_cbTeardropsUseNextTrack2 = new wxCheckBox( this, wxID_ANY, _("Allow teardrop to span two track segments"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbTeardropsUseNextTrack2->SetValue(true);
gbSizer2->Add( m_cbTeardropsUseNextTrack2, wxGBPosition( 6, 2 ), wxGBSpan( 1, 5 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
bSizerShapeColumns2->Add( gbSizer2, 0, wxEXPAND|wxLEFT, 20 );
m_gridSizer->Add( bSizerShapeColumns2, 1, wxEXPAND, 5 );
mainSizer->Add( m_gridSizer, 0, wxLEFT, 5 );
this->SetSizer( mainSizer );
this->Layout();
mainSizer->Fit( this );
}
PANEL_SETUP_TEARDROPS_BASE::~PANEL_SETUP_TEARDROPS_BASE()
{
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,128 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
#include <wx/string.h>
#include <wx/stattext.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/statline.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/statbmp.h>
#include <wx/radiobut.h>
#include <wx/sizer.h>
#include <wx/spinctrl.h>
#include <wx/textctrl.h>
#include <wx/checkbox.h>
#include <wx/gbsizer.h>
#include <wx/panel.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class PANEL_SETUP_TEARDROPS_BASE
///////////////////////////////////////////////////////////////////////////////
class PANEL_SETUP_TEARDROPS_BASE : public wxPanel
{
private:
protected:
wxBoxSizer* m_gridSizer;
wxStaticText* m_roundShapesLabel;
wxStaticLine* m_staticline1;
wxStaticBitmap* m_bitmapTeardrop;
wxStaticText* m_edgesLabel;
wxRadioButton* m_rbStraightLines;
wxRadioButton* m_rbCurved;
wxStaticText* m_stHsetting;
wxSpinCtrlDouble* m_spTeardropLenPercent;
wxStaticText* m_stTeardropLenUnits;
wxStaticText* m_stMaxLen;
wxTextCtrl* m_tcTdMaxLen;
wxStaticText* m_stMaxLenUnits;
wxStaticText* m_stVsetting;
wxSpinCtrlDouble* m_spTeardropSizePercent;
wxStaticText* m_stLenPercent;
wxStaticText* m_stTdMaxSize;
wxTextCtrl* m_tcMaxHeight;
wxStaticText* m_stMaxHeightUnits;
wxStaticText* m_curvePointsLabel;
wxSpinCtrl* m_curvePointsCtrl;
wxCheckBox* m_cbPreferZoneConnection;
wxStaticText* m_stHDRatio;
wxSpinCtrlDouble* m_spTeardropHDPercent;
wxStaticText* m_minTrackWidthUnits;
wxStaticText* m_minTrackWidthHint;
wxCheckBox* m_cbTeardropsUseNextTrack;
wxStaticText* m_rectShapesLabel;
wxStaticLine* m_staticline2;
wxStaticBitmap* m_bitmapTeardrop1;
wxStaticText* m_edgesLabel1;
wxRadioButton* m_rbStraightLines1;
wxRadioButton* m_rbCurved1;
wxStaticText* m_stHsetting1;
wxSpinCtrlDouble* m_spTeardropLenPercent1;
wxStaticText* m_stTeardropLenUnits1;
wxStaticText* m_stMaxLen1;
wxTextCtrl* m_tcTdMaxLen1;
wxStaticText* m_stMaxLenUnits1;
wxStaticText* m_stVsetting1;
wxSpinCtrlDouble* m_spTeardropSizePercent1;
wxStaticText* m_stLenPercent1;
wxStaticText* m_stTdMaxSize1;
wxTextCtrl* m_tcMaxHeight1;
wxStaticText* m_stMaxHeightUnits1;
wxStaticText* m_curvePointsLabel1;
wxSpinCtrl* m_curvePointsCtrl1;
wxCheckBox* m_cbPreferZoneConnection1;
wxStaticText* m_stHDRatio1;
wxSpinCtrlDouble* m_spTeardropHDPercent1;
wxStaticText* m_minTrackWidthUnits1;
wxStaticText* m_minTrackWidthHint1;
wxCheckBox* m_cbTeardropsUseNextTrack1;
wxStaticText* m_tracksLabel;
wxStaticLine* m_staticline3;
wxStaticBitmap* m_bitmapTeardrop2;
wxStaticText* m_edgesLabel2;
wxRadioButton* m_rbStraightLines2;
wxRadioButton* m_rbCurved2;
wxStaticText* m_stHsetting2;
wxSpinCtrlDouble* m_spTeardropLenPercent2;
wxStaticText* m_stTeardropLenUnits2;
wxStaticText* m_stMaxLen2;
wxTextCtrl* m_tcTdMaxLen2;
wxStaticText* m_stMaxLenUnits2;
wxStaticText* m_stVsetting2;
wxSpinCtrlDouble* m_spTeardropSizePercent2;
wxStaticText* m_stLenPercent2;
wxStaticText* m_stTdMaxSize2;
wxTextCtrl* m_tcMaxHeight2;
wxStaticText* m_stMaxHeightUnits2;
wxStaticText* m_curvePointsLabel2;
wxSpinCtrl* m_curvePointsCtrl2;
wxStaticText* m_stHDRatio2;
wxSpinCtrlDouble* m_spTeardropHDPercent2;
wxStaticText* m_minTrackWidthUnits2;
wxStaticText* m_minTrackWidthHint2;
wxCheckBox* m_cbTeardropsUseNextTrack2;
public:
PANEL_SETUP_TEARDROPS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
~PANEL_SETUP_TEARDROPS_BASE();
};

View File

@ -142,7 +142,15 @@ bool DRC_CACHE_GENERATOR::Run()
};
forEachGeometryItem( itemTypes, LSET::AllCuMask(), countItems );
forEachGeometryItem( itemTypes, LSET::AllCuMask(), addToCopperTree );
{
std::unique_lock<std::mutex> cacheLock( m_board->m_CachesMutex );
if( !m_board->m_CopperItemRTreeCache )
m_board->m_CopperItemRTreeCache = std::make_shared<DRC_RTREE>();
forEachGeometryItem( itemTypes, LSET::AllCuMask(), addToCopperTree );
}
if( !reportPhase( _( "Tessellating copper zones..." ) ) )
return false; // DRC cancelled
@ -205,7 +213,7 @@ bool DRC_CACHE_GENERATOR::Run()
for( ZONE* zone : m_board->Zones() )
{
if( !zone->GetIsRuleArea() )
if( !zone->GetIsRuleArea() && !zone->IsTeardropArea() )
{
for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
m_board->m_ZoneIsolatedIslandsMap[ zone ][ layer ] = ISOLATED_ISLANDS();

View File

@ -207,6 +207,7 @@ void PCB_EDIT_FRAME::doReCreateMenuBar()
editMenu->AppendSeparator();
editMenu->Add( PCB_ACTIONS::editTracksAndVias );
editMenu->Add( PCB_ACTIONS::editTextAndGraphics );
editMenu->Add( PCB_ACTIONS::editTeardrops );
editMenu->Add( PCB_ACTIONS::changeFootprints );
editMenu->Add( PCB_ACTIONS::swapLayers );
@ -413,11 +414,6 @@ void PCB_EDIT_FRAME::doReCreateMenuBar()
toolsMenu->Add( ACTIONS::showFootprintEditor );
toolsMenu->Add( PCB_ACTIONS::updateFootprints );
// Add/remove teardrops menuitems:
toolsMenu->AppendSeparator();
toolsMenu->Add( _( "Add Teardrops..." ), "", ID_RUN_TEARDROP_TOOL, BITMAPS::via );
toolsMenu->Add( _( "Remove Teardrops" ), "", ID_REMOVE_TEARDROP_TOOL, BITMAPS::via );
toolsMenu->AppendSeparator();
toolsMenu->Add( PCB_ACTIONS::cleanupTracksAndVias );
toolsMenu->Add( PCB_ACTIONS::removeUnusedPads );

View File

@ -1811,12 +1811,15 @@ static struct PAD_DESC
&PAD::SetSizeY, &PAD::GetSizeY,
PROPERTY_DISPLAY::PT_SIZE ), groupPad );
auto roundRadiusRatio = new PROPERTY<PAD, double>( _HKI( "Round Radius Ratio" ),
auto roundRadiusRatio = new PROPERTY<PAD, double>( _HKI( "Corner Radius Ratio" ),
&PAD::SetRoundRectRadiusRatio, &PAD::GetRoundRectRadiusRatio );
roundRadiusRatio->SetAvailableFunc(
[=]( INSPECTABLE* aItem ) -> bool
{
return aItem->Get( shape ) == static_cast<int>( PAD_SHAPE::ROUNDRECT );
if( PAD* pad = dynamic_cast<PAD*>( aItem ) )
return pad->GetShape() == PAD_SHAPE::ROUNDRECT;
return false;
} );
propMgr.AddProperty( roundRadiusRatio, groupPad );

View File

@ -779,13 +779,6 @@ private:
mutable std::shared_ptr<SHAPE_POLY_SET> m_effectivePolygon;
mutable int m_effectiveBoundingRadius;
/*
* How to build the custom shape in zone, to create the clearance area:
* CUST_PAD_SHAPE_IN_ZONE_OUTLINE = use pad shape
* CUST_PAD_SHAPE_IN_ZONE_CONVEXHULL = use the convex hull of the pad shape
*/
CUST_PAD_SHAPE_IN_ZONE m_customShapeClearanceArea;
int m_subRatsnest; // Variable used to handle subnet (block) number in
// ratsnest computations
@ -849,11 +842,18 @@ private:
double m_localSolderPasteMarginRatio; // Local solder mask margin ratio of pad size
// The final margin is the sum of these 2 values
ZONE_CONNECTION m_zoneConnection; // No connection, thermal relief, etc.
int m_thermalSpokeWidth; // Thermal spoke width.
EDA_ANGLE m_thermalSpokeAngle; // Rotation of the spokes. 45° will produce an X,
/*
* How to build the custom shape in zone, to create the clearance area:
* CUST_PAD_SHAPE_IN_ZONE_OUTLINE = use pad shape
* CUST_PAD_SHAPE_IN_ZONE_CONVEXHULL = use the convex hull of the pad shape
*/
CUST_PAD_SHAPE_IN_ZONE m_customShapeClearanceArea;
ZONE_CONNECTION m_zoneConnection; // No connection, thermal relief, etc.
int m_thermalSpokeWidth; // Thermal spoke width.
EDA_ANGLE m_thermalSpokeAngle; // Rotation of the spokes. 45° will produce an X,
// while 90° will produce a +.
int m_thermalGap;
int m_thermalGap;
std::mutex m_zoneLayerOverridesMutex;
std::array<ZONE_LAYER_OVERRIDE, MAX_CU_LAYERS> m_zoneLayerOverrides;

View File

@ -146,9 +146,6 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME )
EVT_MENU( ID_GEN_EXPORT_FILE_STEP, PCB_EDIT_FRAME::OnExportSTEP )
EVT_MENU( ID_GEN_EXPORT_FILE_HYPERLYNX, PCB_EDIT_FRAME::OnExportHyperlynx )
EVT_MENU( ID_RUN_TEARDROP_TOOL, PCB_EDIT_FRAME::OnRunTeardropTool )
EVT_MENU( ID_REMOVE_TEARDROP_TOOL, PCB_EDIT_FRAME::OnRemoveTeardropTool )
EVT_MENU( ID_MENU_EXPORT_FOOTPRINTS_TO_LIBRARY, PCB_EDIT_FRAME::Process_Special_Functions )
EVT_MENU( ID_MENU_EXPORT_FOOTPRINTS_TO_NEW_LIBRARY, PCB_EDIT_FRAME::Process_Special_Functions )

View File

@ -116,10 +116,6 @@ enum pcbnew_ids
ID_ADD_FOOTPRINT_TO_BOARD,
ID_LOAD_FOOTPRINT_FROM_BOARD,
ID_RUN_TEARDROP_TOOL,
ID_REMOVE_TEARDROP_TOOL,
ID_PCB_UNUSED1,
ID_PCBNEW_END_LIST
};

View File

@ -380,6 +380,69 @@ std::pair<wxString, wxString> PCB_PARSER::parseProperty()
}
void PCB_PARSER::parseTEARDROP_PARAMETERS( TEARDROP_PARAMETERS* tdParams )
{
tdParams->m_Enabled = false;
tdParams->m_AllowUseTwoTracks = false;
tdParams->m_TdOnPadsInZones = true;
for( T token = NextTok(); token != T_RIGHT; token = NextTok() )
{
if( token == T_LEFT )
token = NextTok();
switch( token )
{
case T_enabled:
tdParams->m_Enabled = true;
break;
case T_allow_two_segments:
tdParams->m_AllowUseTwoTracks = true;
break;
case T_prefer_zone_connections:
tdParams->m_TdOnPadsInZones = false;
break;
case T_best_length_ratio:
tdParams->m_BestLengthRatio = parseDouble( "teardrop best length ratio" );
NeedRIGHT();
break;
case T_max_length:
tdParams->m_TdMaxLen = parseBoardUnits( "teardrop max length" );
NeedRIGHT();
break;
case T_best_width_ratio:
tdParams->m_BestWidthRatio = parseDouble( "teardrop best width ratio" );
NeedRIGHT();
break;
case T_max_width:
tdParams->m_TdMaxWidth = parseBoardUnits( "teardrop max width" );
NeedRIGHT();
break;
case T_curve_points:
tdParams->m_CurveSegCount = parseInt( "teardrop curve points count" );
NeedRIGHT();
break;
case T_filter_ratio:
tdParams->m_WidthtoSizeFilterRatio = parseDouble( "teardrop filter ratio" );
NeedRIGHT();
break;
default:
Expecting( "enabled, allow_two_segments, prefer_zone_connections, best_length_ratio, "
"max_length, best_width_ratio, max_width, curve_points or filter_ratio" );
}
}
}
void PCB_PARSER::parseEDA_TEXT( EDA_TEXT* aText )
{
wxCHECK_RET( CurTok() == T_effects,
@ -1124,7 +1187,12 @@ void PCB_PARSER::parseGeneralSection()
NeedRIGHT();
break;
default: // Skip everything but the board thickness.
case T_legacy_teardrops:
m_board->SetLegacyTeardrops( true );
NeedRIGHT();
break;
default: // Skip everything else.
while( ( token = NextTok() ) != T_RIGHT )
{
if( !IsSymbol( token ) && token != T_NUMBER )
@ -4276,6 +4344,10 @@ PAD* PCB_PARSER::parsePAD( FOOTPRINT* aParent )
NeedRIGHT();
break;
case T_teardrops:
parseTEARDROP_PARAMETERS( &pad->GetTeardropParams() );
break;
case T_zone_connect:
pad->SetZoneConnection( (ZONE_CONNECTION) parseInt( "zone connection value" ) );
NeedRIGHT();
@ -4499,7 +4571,8 @@ PAD* PCB_PARSER::parsePAD( FOOTPRINT* aParent )
Expecting( "at, locked, drill, layers, net, die_length, roundrect_rratio, "
"solder_mask_margin, solder_paste_margin, solder_paste_margin_ratio, "
"clearance, tstamp, primitives, remove_unused_layers, keep_end_layers, "
"pinfunction, pintype, zone_connect, thermal_width, or thermal_gap" );
"pinfunction, pintype, zone_connect, thermal_width, thermal_gap or "
"teardrops" );
}
}
@ -4916,6 +4989,10 @@ PCB_VIA* PCB_PARSER::parsePCB_VIA()
}
break;
case T_teardrops:
parseTEARDROP_PARAMETERS( &via->GetTeardropParams() );
break;
case T_tstamp:
NextTok();
const_cast<KIID&>( via->m_Uuid ) = CurStrToKIID();
@ -4940,7 +5017,8 @@ PCB_VIA* PCB_PARSER::parsePCB_VIA()
break;
default:
Expecting( "blind, micro, at, size, drill, layers, net, free, tstamp, or status" );
Expecting( "blind, micro, at, size, drill, layers, net, free, tstamp, status or "
"teardrops" );
}
}
@ -5478,14 +5556,6 @@ ZONE* PCB_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent )
case T_name:
NextTok();
zone->SetZoneName( FromUTF8() );
// TODO: remove this hack in next future, now keywords are added for teadrop attribute
// If a zone name starts by "$teardrop_", set its teardrop property flag
if( zone->GetZoneName().StartsWith( "$teardrop_p" ) )
zone->SetTeardropAreaType( TEARDROP_TYPE::TD_VIAPAD );
else if( zone->GetZoneName().StartsWith( "$teardrop_t" ) )
zone->SetTeardropAreaType( TEARDROP_TYPE::TD_TRACKEND );
NeedRIGHT();
break;
@ -5498,37 +5568,30 @@ ZONE* PCB_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent )
switch( token )
{
case T_teardrop:
token = NextTok();
// Expected teardrop data (type padvia) or (type track_end)
if( token == T_LEFT )
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
token = NextTok();
if( token == T_LEFT )
token = NextTok();
if( token == T_type )
switch( token )
{
case T_type:
token = NextTok();
if( token == T_padvia )
{
zone->SetTeardropAreaType( TEARDROP_TYPE::TD_VIAPAD );
NeedRIGHT();
}
else if( token == T_track_end )
{
zone->SetTeardropAreaType( TEARDROP_TYPE::TD_TRACKEND );
NeedRIGHT();
}
else
Expecting( "padvia or track_end" );
NeedRIGHT();
}
else
break;
default:
Expecting( "type" );
}
}
else
Expecting( "(" );
break;
@ -5598,6 +5661,9 @@ ZONE* PCB_PARSER::parseZONE( BOARD_ITEM_CONTAINER* aParent )
}
}
if( zone->IsTeardropArea() && m_requiredVersion < 20230517 )
m_board->SetLegacyTeardrops( true );
// Clear flags used in zone edition:
zone->SetNeedRefill( false );

View File

@ -63,6 +63,7 @@ class FP_3DMODEL;
class SHAPE_LINE_CHAIN;
struct LAYER;
class PROGRESS_REPORTER;
class TEARDROP_PARAMETERS;
/**
@ -174,6 +175,8 @@ private:
void parseNETINFO_ITEM();
void parseNETCLASS();
void parseTEARDROP_PARAMETERS( TEARDROP_PARAMETERS* tdParams );
PCB_SHAPE* parsePCB_SHAPE( BOARD_ITEM* aParent );
PCB_TEXT* parsePCB_TEXT( BOARD_ITEM* aParent );
PCB_BITMAP* parsePCB_BITMAP( BOARD_ITEM* aParent );

View File

@ -581,9 +581,13 @@ void PCB_PLUGIN::formatGeneral( const BOARD* aBoard, int aNestLevel ) const
m_out->Print( 0, "\n" );
m_out->Print( aNestLevel, "(general\n" );
m_out->Print( aNestLevel+1, "(thickness %s)\n",
formatInternalUnits( dsnSettings.GetBoardThickness() ).c_str() );
if( aBoard->LegacyTeardrops() )
m_out->Print( aNestLevel+1, "(legacy_teardrops)\n" );
m_out->Print( aNestLevel, ")\n\n" );
aBoard->GetPageSettings().Format( m_out, aNestLevel, m_ctl );
@ -709,6 +713,40 @@ void PCB_PLUGIN::formatHeader( const BOARD* aBoard, int aNestLevel ) const
}
bool isDefaultTeardropParameters( const TEARDROP_PARAMETERS& tdParams )
{
static const TEARDROP_PARAMETERS defaults;
return tdParams.m_Enabled == defaults.m_Enabled
&& tdParams.m_BestLengthRatio == defaults.m_BestLengthRatio
&& tdParams.m_TdMaxLen == defaults.m_TdMaxLen
&& tdParams.m_BestWidthRatio == defaults.m_BestWidthRatio
&& tdParams.m_TdMaxWidth == defaults.m_TdMaxWidth
&& tdParams.m_CurveSegCount == defaults.m_CurveSegCount
&& tdParams.m_WidthtoSizeFilterRatio == defaults.m_WidthtoSizeFilterRatio
&& tdParams.m_AllowUseTwoTracks == defaults.m_AllowUseTwoTracks
&& tdParams.m_TdOnPadsInZones == defaults.m_TdOnPadsInZones;
}
void PCB_PLUGIN::formatTeardropParameters( const TEARDROP_PARAMETERS& tdParams,
int aNestLevel ) const
{
m_out->Print( aNestLevel, "(teardrops%s%s%s (best_length_ratio %s) (max_length %s) "
"(best_width_ratio %s) (max_width %s) (curve_points %d) "
"(filter_ratio %s))\n",
tdParams.m_Enabled ? " enabled" : "",
tdParams.m_AllowUseTwoTracks ? " allow_two_segments" : "",
tdParams.m_TdOnPadsInZones ? " prefer_zone_connections" : "",
FormatDouble2Str( tdParams.m_BestLengthRatio ).c_str(),
formatInternalUnits( tdParams.m_TdMaxLen ).c_str(),
FormatDouble2Str( tdParams.m_BestWidthRatio ).c_str(),
formatInternalUnits( tdParams.m_TdMaxWidth ).c_str(),
tdParams.m_CurveSegCount,
FormatDouble2Str( tdParams.m_WidthtoSizeFilterRatio ).c_str() );
}
void PCB_PLUGIN::format( const BOARD* aBoard, int aNestLevel ) const
{
std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_footprints( aBoard->Footprints().begin(),
@ -1690,10 +1728,16 @@ void PCB_PLUGIN::format( const PAD* aPad, int aNestLevel ) const
m_out->Print( 0, ")" );
}
m_out->Print( 0, "\n");
m_out->Print( 0, "\n" );
m_out->Print( aNestLevel+1, ")" ); // end of (basic_shapes
}
if( !isDefaultTeardropParameters( aPad->GetTeardropParams() ) )
{
m_out->Print( 0, "\n" );
formatTeardropParameters( aPad->GetTeardropParams(), aNestLevel+1 );
}
m_out->Print( 0, " (tstamp %s)", TO_UTF8( aPad->m_Uuid.AsString() ) );
m_out->Print( 0, ")\n" );
@ -1925,6 +1969,12 @@ void PCB_PLUGIN::format( const PCB_TRACK* aTrack, int aNestLevel ) const
m_out->Print( 0, ")" );
}
if( !isDefaultTeardropParameters( via->GetTeardropParams() ) )
{
m_out->Print( 0, "\n" );
formatTeardropParameters( via->GetTeardropParams(), aNestLevel+1 );
}
}
else if( aTrack->Type() == PCB_ARC_T )
{

View File

@ -50,6 +50,7 @@ class PCB_TEXT;
class PCB_TEXTBOX;
class EDA_TEXT;
class SHAPE_LINE_CHAIN;
class TEARDROP_PARAMETERS;
class PCB_PLUGIN; // forward decl
/// Current s-expression file format version. 2 was the last legacy format version.
@ -128,7 +129,8 @@ class PCB_PLUGIN; // forward decl
//#define SEXPR_BOARD_FILE_VERSION 20220818 // First-class storage for net-ties
//#define SEXPR_BOARD_FILE_VERSION 20220914 // Number boxes for custom-shape pads
//#define SEXPR_BOARD_FILE_VERSION 20221018 // Via & pad zone-layer-connections
#define SEXPR_BOARD_FILE_VERSION 20230410 // DNP attribute propagated from schematic to attr
//#define SEXPR_BOARD_FILE_VERSION 20230410 // DNP attribute propagated from schematic to attr
#define SEXPR_BOARD_FILE_VERSION 20230517 // Teardrop parameters for pads and vias
#define BOARD_FILE_HOST_VERSION 20200825 ///< Earlier files than this include the host tag
#define LEGACY_ARC_FORMATTING 20210925 ///< These were the last to use old arc formatting
@ -371,6 +373,8 @@ protected:
/// writes everything that comes before the board_items, like settings and layers etc
void formatHeader( const BOARD* aBoard, int aNestLevel = 0 ) const;
void formatTeardropParameters( const TEARDROP_PARAMETERS& tdParams, int aNestLevel = 0 ) const;
private:
void format( const BOARD* aBoard, int aNestLevel = 0 ) const;

View File

@ -1181,9 +1181,6 @@ bool PNS_KICAD_IFACE_BASE::syncZone( PNS::NODE* aWorld, ZONE* aZone, SHAPE_POLY_
{
SHAPE_POLY_SET* poly;
if( !aZone->GetIsRuleArea() && aZone->GetZoneName().IsEmpty() )
return false;
// TODO handle aZone->GetDoNotAllowVias()
// TODO handle rules which disallow tracks & vias
if( !aZone->GetIsRuleArea() || !aZone->GetDoNotAllowTracks() )
@ -1562,7 +1559,7 @@ void PNS_KICAD_IFACE_BASE::SyncWorld( PNS::NODE *aWorld )
void PNS_KICAD_IFACE::EraseView()
{
for( auto item : m_hiddenItems )
for( BOARD_ITEM* item : m_hiddenItems )
m_view->SetVisible( item, true );
m_hiddenItems.clear();
@ -1696,6 +1693,17 @@ void PNS_KICAD_IFACE::HideItem( PNS::ITEM* aItem )
m_view->SetVisible( parent, false );
m_view->Update( parent, KIGFX::APPEARANCE );
for( ZONE* td : m_board->Zones() )
{
if( td->IsTeardropArea()
&& td->GetBoundingBox().Intersects( aItem->Parent()->GetBoundingBox() )
&& td->Outline()->Collide( aItem->Shape() ) )
{
m_view->SetVisible( td, false );
m_view->Update( td, KIGFX::APPEARANCE );
}
}
}
}
@ -1875,10 +1883,10 @@ void PNS_KICAD_IFACE::Commit()
EraseView();
for( const std::pair<const PAD*, OFFSET>& fpOffset : m_fpOffsets )
for( const auto& [ pad, fpOffset ] : m_fpOffsets )
{
VECTOR2I offset = fpOffset.second.p_new - fpOffset.second.p_old;
FOOTPRINT* footprint = fpOffset.first->GetParent();
VECTOR2I offset = fpOffset.p_new - fpOffset.p_old;
FOOTPRINT* footprint = pad->GetParent();
VECTOR2I p_orig = footprint->GetPosition();
VECTOR2I p_new = p_orig + offset;

View File

@ -1,260 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2021 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2021-2022 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 <board_design_settings.h>
#include <board_commit.h>
#include <bitmaps.h>
#include <tool/tool_manager.h>
#include <tool/actions.h>
#include "teardrop.h"
#include "dialog_teardrop_base.h"
#include <widgets/unit_binder.h>
#include <widgets/wx_progress_reporters.h>
// Curved shapes options. The actual value is the ORed of options
#define CURVED_OPTION_NONE 0 /* No curved teardrop shape */
#define CURVED_OPTION_ROUND 1 /* Curved teardrop shape for vias and round pad shapes */
#define CURVED_OPTION_RECT 2 /* Curved teardrop shape for rect pad shapes */
#define CURVED_OPTION_TRACK 4 /* Curved teardrop shape for track to track shapes */
bool g_rawTeardrops = false;
class TEARDROP_DIALOG: public TEARDROP_DIALOG_BASE
{
public:
TEARDROP_DIALOG( PCB_EDIT_FRAME* aParent ):
TEARDROP_DIALOG_BASE( aParent ),
m_brdSettings( nullptr ),
m_frame( aParent ),
m_teardropMaxLenSettingRound( aParent,m_stMaxLenRound, m_tcTdMaxLenRound, m_stMaxLenRoundUnits ),
m_teardropMaxHeightSettingRound( aParent, m_stTdMaxSizeRound, m_tcMaxHeightRound, m_stMaxHeightRoundUnits ),
m_teardropMaxLenSettingRect( aParent,m_stMaxLenRect, m_tcTdMaxLenRect, m_stMaxLenRectUnits ),
m_teardropMaxHeightSettingRect( aParent, m_stTdMaxSizeRect, m_tcMaxHeightRect, m_stMaxHeightRectUnits ),
m_teardropMaxLenSettingTrack( aParent,m_stMaxLenTrack, m_tcTdMaxLenTrack, m_stMaxLenTrackUnits ),
m_teardropMaxHeightSettingTrack( aParent, m_stTdMaxSizeTrack, m_tcMaxHeightTrack, m_stMaxHeightTrackUnits )
{
// Setup actual bitmaps that cannot be set inside wxFormBuilder:
m_bitmapTdCircularInfo->SetBitmap( KiBitmap( BITMAPS::teardrop_sizes ) );
m_bitmapTdRectangularInfo->SetBitmap( KiBitmap( BITMAPS::teardrop_rect_sizes ) );
m_bitmapTdTrackInfo->SetBitmap( KiBitmap( BITMAPS::teardrop_track_sizes ) );
m_rawTeardropsHint->SetFont( KIUI::GetInfoFont( this ) );
m_brdSettings = &m_frame->GetBoard()->GetBoard()->GetDesignSettings();
TEARDROP_PARAMETERS_LIST* prmsList = m_brdSettings->GetTeadropParamsList();
m_cbPadVia->SetValue( prmsList->m_TargetViasPads );
m_cbSmdSimilarPads->SetValue( prmsList->m_TargetPadsWithNoHole );
m_cbRoundShapesOnly->SetValue( prmsList->m_UseRoundShapesOnly );
m_cbTrack2Track->SetValue( prmsList->m_TargetTrack2Track );
m_cbPadsInZones->SetValue( prmsList->m_TdOnPadsInZones );
m_cbOptUseNextTrack->SetValue( prmsList->m_AllowUseTwoTracks );
m_spPointCount->SetValue( prmsList->m_CurveSegCount );
TEARDROP_PARAMETERS* prms = prmsList->GetParameters( TARGET_ROUND );
m_teardropMaxLenSettingRound.SetValue( prms->m_TdMaxLen );
m_teardropMaxHeightSettingRound.SetValue( prms->m_TdMaxHeight );
m_spTeardropLenPercentRound->SetValue( prms->m_LengthRatio*100 );
m_spTeardropSizePercentRound->SetValue( prms->m_HeightRatio*100 );
m_rbShapeRound->SetSelection( prms->IsCurved() );
m_spTeardropHDPercentRound->SetValue( prms->m_WidthtoSizeFilterRatio*100 );
prms = prmsList->GetParameters( TARGET_RECT );
m_teardropMaxLenSettingRect.SetValue( prms->m_TdMaxLen );
m_teardropMaxHeightSettingRect.SetValue( prms->m_TdMaxHeight );
m_spTeardropLenPercentRect->SetValue( prms->m_LengthRatio*100 );
m_spTeardropSizePercentRect->SetValue( prms->m_HeightRatio*100 );
m_rbShapeRect->SetSelection( prms->IsCurved() );
m_spTeardropHDPercentRect->SetValue( prms->m_WidthtoSizeFilterRatio*100 );
prms = prmsList->GetParameters( TARGET_TRACK );
m_teardropMaxLenSettingTrack.SetValue(prms->m_TdMaxLen );
m_teardropMaxHeightSettingTrack.SetValue( prms->m_TdMaxHeight );
m_spTeardropLenPercentTrack->SetValue( prms->m_LengthRatio*100 );
m_spTeardropSizePercentTrack->SetValue( prms->m_HeightRatio*100 );
m_rbShapeTrack->SetSelection( prms->IsCurved() );
m_spTeardropHDPercentTrack->SetValue( prms->m_WidthtoSizeFilterRatio*100 );
m_generateRawTeardrops->SetValue( g_rawTeardrops );
// recalculate sizers, now the bitmap is initialized
finishDialogSettings();
}
~TEARDROP_DIALOG()
{
g_rawTeardrops = m_generateRawTeardrops->GetValue();
TransferToParamList();
}
/**
* Copy the settings from dialog to the current board settings
*/
void TransferToParamList()
{
int shape_seg_count = GetCurvePointCount();
TEARDROP_PARAMETERS_LIST* prmsList = m_brdSettings->GetTeadropParamsList();
prmsList->m_TargetViasPads = m_cbPadVia->GetValue();
prmsList->m_TargetPadsWithNoHole = m_cbSmdSimilarPads->GetValue();
prmsList->m_UseRoundShapesOnly = m_cbRoundShapesOnly->GetValue();
prmsList->m_TargetTrack2Track = m_cbTrack2Track->GetValue();
prmsList->m_TdOnPadsInZones = m_cbPadsInZones->GetValue();
prmsList->m_AllowUseTwoTracks = m_cbOptUseNextTrack->GetValue();
prmsList->m_CurveSegCount = m_spPointCount->GetValue();
TEARDROP_PARAMETERS* prms = prmsList->GetParameters( TARGET_ROUND );
prms->m_LengthRatio = GetTeardropLenPercentRound();
prms->m_HeightRatio = GetTeardropSizePercentRound();
prms->m_TdMaxLen = m_teardropMaxLenSettingRound.GetValue();
prms->m_TdMaxHeight = m_teardropMaxHeightSettingRound.GetValue();
prms->m_CurveSegCount = (CurvedShapeOption() & CURVED_OPTION_ROUND) ? shape_seg_count : 0;
prms->m_WidthtoSizeFilterRatio = m_spTeardropHDPercentRound->GetValue() / 100.0;
prms = prmsList->GetParameters( TARGET_RECT );
prms->m_LengthRatio = GetTeardropLenPercentRect();
prms->m_HeightRatio = GetTeardropSizePercentRect();
prms->m_TdMaxLen = m_teardropMaxLenSettingRect.GetValue();
prms->m_TdMaxHeight = m_teardropMaxHeightSettingRect.GetValue();
prms->m_CurveSegCount = (CurvedShapeOption() & CURVED_OPTION_RECT) ? shape_seg_count : 0;
prms->m_WidthtoSizeFilterRatio = m_spTeardropHDPercentRect->GetValue() / 100.0;
prms = prmsList->GetParameters( TARGET_TRACK );
prms->m_LengthRatio = GetTeardropLenPercentTrack();
prms->m_HeightRatio = GetTeardropSizePercentTrack();
prms->m_TdMaxLen = m_teardropMaxLenSettingTrack.GetValue();
prms->m_TdMaxHeight = m_teardropMaxHeightSettingTrack.GetValue();
prms->m_CurveSegCount = (CurvedShapeOption() & CURVED_OPTION_TRACK) ? shape_seg_count : 0;
prms->m_WidthtoSizeFilterRatio = m_spTeardropHDPercentTrack->GetValue() / 100.0;
}
int CurvedShapeOption()
{
int opt = 0;
if( m_rbShapeRound->GetSelection() )
opt |= CURVED_OPTION_ROUND;
if( m_rbShapeRect->GetSelection() )
opt |= CURVED_OPTION_RECT;
if( m_rbShapeTrack->GetSelection() )
opt |= CURVED_OPTION_TRACK;
return opt;
}
// Options for curved shapes
int GetCurvePointCount() { return m_spPointCount->GetValue(); }
// Getters for size parameters
double GetTeardropLenPercentRound() { return m_spTeardropLenPercentRound->GetValue()/100.0; }
double GetTeardropSizePercentRound() { return m_spTeardropSizePercentRound->GetValue()/100.0; }
int GetTeardropMaxLenRound() { return m_teardropMaxLenSettingRound.GetValue(); }
int GetTeardropMaxHeightRound() { return m_teardropMaxHeightSettingRound.GetValue(); }
double GetTeardropLenPercentRect() { return m_spTeardropLenPercentRect->GetValue()/100.0; }
double GetTeardropSizePercentRect() { return m_spTeardropSizePercentRect->GetValue()/100.0; }
int GetTeardropMaxLenRect() { return m_teardropMaxLenSettingRect.GetValue(); }
int GetTeardropMaxHeightRect() { return m_teardropMaxHeightSettingRect.GetValue(); }
double GetTeardropLenPercentTrack() { return m_spTeardropLenPercentTrack->GetValue()/100.0; }
double GetTeardropSizePercentTrack() { return m_spTeardropSizePercentTrack->GetValue()/100.0; }
int GetTeardropMaxLenTrack() { return m_teardropMaxLenSettingTrack.GetValue(); }
int GetTeardropMaxHeightTrack() { return m_teardropMaxHeightSettingTrack.GetValue(); }
// Optins to filter pads
bool TeardropOnPadVia() { return m_cbPadVia->GetValue(); }
bool IncludeNotPTH() { return m_cbSmdSimilarPads->GetValue(); }
bool RoundShapesOnly() { return m_cbRoundShapesOnly->GetValue(); }
bool CanUseTwoTracks() { return m_cbOptUseNextTrack->GetValue(); }
bool TeardropOnTracks() { return m_cbTrack2Track->GetValue(); }
bool GenerateRawTeardrops() { return m_generateRawTeardrops->GetValue(); }
private:
BOARD_DESIGN_SETTINGS* m_brdSettings;
PCB_EDIT_FRAME* m_frame;
UNIT_BINDER m_teardropMaxLenSettingRound;
UNIT_BINDER m_teardropMaxHeightSettingRound;
UNIT_BINDER m_teardropMaxLenSettingRect;
UNIT_BINDER m_teardropMaxHeightSettingRect;
UNIT_BINDER m_teardropMaxLenSettingTrack;
UNIT_BINDER m_teardropMaxHeightSettingTrack;
};
void PCB_EDIT_FRAME::OnRunTeardropTool( wxCommandEvent& event )
{
TEARDROP_DIALOG dlg( this );
if( dlg.ShowModal() != wxID_OK )
return;
wxBusyCursor dummy;
std::unique_ptr<WX_PROGRESS_REPORTER> reporter;
reporter = std::make_unique<WX_PROGRESS_REPORTER>( this, _( "Filling Zones" ), 4 );
BOARD_COMMIT committer( this );
dlg.TransferToParamList();
TEARDROP_MANAGER trdm( GetBoard(), this, reporter.get() );
int added_count = trdm.SetTeardrops( &committer, dlg.CanUseTwoTracks(),
!dlg.GenerateRawTeardrops() );
GetToolManager()->PostEvent( EVENTS::ConnectivityChangedEvent );
m_infoBar->RemoveAllButtons();
m_infoBar->AddCloseButton();
m_infoBar->ShowMessageFor( wxString::Format( _( "%d teardrops created" ), added_count ),
1000, wxICON_EXCLAMATION );
}
void PCB_EDIT_FRAME::OnRemoveTeardropTool( wxCommandEvent& event )
{
BOARD_COMMIT committer( this );
TEARDROP_MANAGER trdm( GetBoard(), this );
int count = trdm.RemoveTeardrops( &committer, true );
GetCanvas()->RedrawRatsnest();
GetCanvas()->Refresh();
GetToolManager()->PostEvent( EVENTS::SelectedItemsModified );
m_infoBar->RemoveAllButtons();
m_infoBar->AddCloseButton();
m_infoBar->ShowMessageFor( wxString::Format( _( "%d teardrops removed." ), count ),
1000, wxICON_EXCLAMATION );
}

View File

@ -1,450 +0,0 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-282-g1fa54006)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "dialog_teardrop_base.h"
///////////////////////////////////////////////////////////////////////////
TEARDROP_DIALOG_BASE::TEARDROP_DIALOG_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
wxBoxSizer* bSizerMain;
bSizerMain = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizerUpper;
bSizerUpper = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizerTop;
bSizerTop = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizeScopeSize;
bSizeScopeSize = new wxBoxSizer( wxVERTICAL );
wxFlexGridSizer* fgSizerBitmaps;
fgSizerBitmaps = new wxFlexGridSizer( 0, 4, 5, 0 );
fgSizerBitmaps->AddGrowableCol( 2 );
fgSizerBitmaps->SetFlexibleDirection( wxBOTH );
fgSizerBitmaps->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticTextRndS = new wxStaticText( this, wxID_ANY, _("Round shapes:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextRndS->Wrap( -1 );
fgSizerBitmaps->Add( m_staticTextRndS, 0, wxTOP|wxBOTTOM, 12 );
m_bitmapTdCircularInfo = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerBitmaps->Add( m_bitmapTdCircularInfo, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
wxFlexGridSizer* fgSizerParmRound;
fgSizerParmRound = new wxFlexGridSizer( 0, 6, 5, 0 );
fgSizerParmRound->AddGrowableCol( 1 );
fgSizerParmRound->AddGrowableCol( 4 );
fgSizerParmRound->SetFlexibleDirection( wxBOTH );
fgSizerParmRound->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_stHsettingRound = new wxStaticText( this, wxID_ANY, _("Best length:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHsettingRound->Wrap( -1 );
fgSizerParmRound->Add( m_stHsettingRound, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_spTeardropLenPercentRound = new wxSpinCtrlDouble( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 20, 100, 40.000000, 10 );
m_spTeardropLenPercentRound->SetDigits( 0 );
fgSizerParmRound->Add( m_spTeardropLenPercentRound, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_stTeardropLenUnits = new wxStaticText( this, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stTeardropLenUnits->Wrap( -1 );
fgSizerParmRound->Add( m_stTeardropLenUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_stVsettingRound = new wxStaticText( this, wxID_ANY, _("Best height:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stVsettingRound->Wrap( -1 );
fgSizerParmRound->Add( m_stVsettingRound, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 10 );
m_spTeardropSizePercentRound = new wxSpinCtrlDouble( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 60, 100, 100.000000, 10 );
m_spTeardropSizePercentRound->SetDigits( 0 );
fgSizerParmRound->Add( m_spTeardropSizePercentRound, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_stLenPercentRound = new wxStaticText( this, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stLenPercentRound->Wrap( -1 );
fgSizerParmRound->Add( m_stLenPercentRound, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_stMaxLenRound = new wxStaticText( this, wxID_ANY, _("Max length:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxLenRound->Wrap( -1 );
fgSizerParmRound->Add( m_stMaxLenRound, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_tcTdMaxLenRound = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerParmRound->Add( m_tcTdMaxLenRound, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_stMaxLenRoundUnits = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxLenRoundUnits->Wrap( -1 );
fgSizerParmRound->Add( m_stMaxLenRoundUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_stTdMaxSizeRound = new wxStaticText( this, wxID_ANY, _("Max height:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stTdMaxSizeRound->Wrap( -1 );
fgSizerParmRound->Add( m_stTdMaxSizeRound, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 10 );
m_tcMaxHeightRound = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerParmRound->Add( m_tcMaxHeightRound, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_stMaxHeightRoundUnits = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxHeightRoundUnits->Wrap( -1 );
fgSizerParmRound->Add( m_stMaxHeightRoundUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
fgSizerParmRound->Add( 0, 0, 1, wxEXPAND, 5 );
fgSizerParmRound->Add( 0, 0, 1, wxEXPAND, 5 );
fgSizerParmRound->Add( 0, 0, 1, wxEXPAND, 5 );
m_stHDRatioRound = new wxStaticText( this, wxID_ANY, _("Max height:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHDRatioRound->Wrap( -1 );
m_stHDRatioRound->SetToolTip( _("Max pad/via size to track width ratio to create a teardrop.\n100 always creates a teardrop.") );
fgSizerParmRound->Add( m_stHDRatioRound, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 10 );
m_spTeardropHDPercentRound = new wxSpinCtrlDouble( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 100, 90, 10 );
m_spTeardropHDPercentRound->SetDigits( 0 );
fgSizerParmRound->Add( m_spTeardropHDPercentRound, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
m_stHDPercentRound = new wxStaticText( this, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHDPercentRound->Wrap( -1 );
fgSizerParmRound->Add( m_stHDPercentRound, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
fgSizerBitmaps->Add( fgSizerParmRound, 1, wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 10 );
wxString m_rbShapeRoundChoices[] = { _("Straight lines"), _("Curved") };
int m_rbShapeRoundNChoices = sizeof( m_rbShapeRoundChoices ) / sizeof( wxString );
m_rbShapeRound = new wxRadioBox( this, wxID_ANY, _("Style"), wxDefaultPosition, wxDefaultSize, m_rbShapeRoundNChoices, m_rbShapeRoundChoices, 1, wxRA_SPECIFY_COLS );
m_rbShapeRound->SetSelection( 0 );
fgSizerBitmaps->Add( m_rbShapeRound, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxEXPAND, 10 );
m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
fgSizerBitmaps->Add( m_staticline2, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
m_staticline3 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
fgSizerBitmaps->Add( m_staticline3, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
m_staticline4 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
fgSizerBitmaps->Add( m_staticline4, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
m_staticline5 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
fgSizerBitmaps->Add( m_staticline5, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
m_staticTextRectS = new wxStaticText( this, wxID_ANY, _("Rect shapes:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextRectS->Wrap( -1 );
fgSizerBitmaps->Add( m_staticTextRectS, 0, wxTOP|wxBOTTOM, 12 );
m_bitmapTdRectangularInfo = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerBitmaps->Add( m_bitmapTdRectangularInfo, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
wxFlexGridSizer* fgSizerParmRect;
fgSizerParmRect = new wxFlexGridSizer( 0, 6, 5, 0 );
fgSizerParmRect->AddGrowableCol( 1 );
fgSizerParmRect->AddGrowableCol( 4 );
fgSizerParmRect->SetFlexibleDirection( wxBOTH );
fgSizerParmRect->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_stHsettingRect = new wxStaticText( this, wxID_ANY, _("Best length:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHsettingRect->Wrap( -1 );
fgSizerParmRect->Add( m_stHsettingRect, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_spTeardropLenPercentRect = new wxSpinCtrlDouble( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 20, 100, 50.000000, 10 );
m_spTeardropLenPercentRect->SetDigits( 0 );
fgSizerParmRect->Add( m_spTeardropLenPercentRect, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_stHDPercentRect = new wxStaticText( this, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHDPercentRect->Wrap( -1 );
fgSizerParmRect->Add( m_stHDPercentRect, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_stVsettingRect = new wxStaticText( this, wxID_ANY, _("Best height:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stVsettingRect->Wrap( -1 );
fgSizerParmRect->Add( m_stVsettingRect, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 10 );
m_spTeardropSizePercentRect = new wxSpinCtrlDouble( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 60, 100, 100.000000, 10 );
m_spTeardropSizePercentRect->SetDigits( 0 );
fgSizerParmRect->Add( m_spTeardropSizePercentRect, 0, wxEXPAND|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
m_stLenPercentRect = new wxStaticText( this, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stLenPercentRect->Wrap( -1 );
fgSizerParmRect->Add( m_stLenPercentRect, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_stMaxLenRect = new wxStaticText( this, wxID_ANY, _("Max length:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxLenRect->Wrap( -1 );
fgSizerParmRect->Add( m_stMaxLenRect, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_tcTdMaxLenRect = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerParmRect->Add( m_tcTdMaxLenRect, 0, wxEXPAND|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
m_stMaxLenRectUnits = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxLenRectUnits->Wrap( -1 );
fgSizerParmRect->Add( m_stMaxLenRectUnits, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 );
m_stTdMaxSizeRect = new wxStaticText( this, wxID_ANY, _("Max height:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stTdMaxSizeRect->Wrap( -1 );
fgSizerParmRect->Add( m_stTdMaxSizeRect, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 10 );
m_tcMaxHeightRect = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerParmRect->Add( m_tcMaxHeightRect, 0, wxEXPAND|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
m_stMaxHeightRectUnits = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxHeightRectUnits->Wrap( -1 );
fgSizerParmRect->Add( m_stMaxHeightRectUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
fgSizerParmRect->Add( 0, 0, 1, wxEXPAND, 5 );
fgSizerParmRect->Add( 0, 0, 1, wxEXPAND, 5 );
fgSizerParmRect->Add( 0, 0, 1, wxEXPAND, 5 );
m_stHDRatioRect = new wxStaticText( this, wxID_ANY, _("Max height:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHDRatioRect->Wrap( -1 );
m_stHDRatioRect->SetToolTip( _("Max pad/via size to track width ratio to create a teardrop.\n100 always creates a teardrop.") );
fgSizerParmRect->Add( m_stHDRatioRect, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 10 );
m_spTeardropHDPercentRect = new wxSpinCtrlDouble( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 100, 90, 10 );
m_spTeardropHDPercentRect->SetDigits( 0 );
fgSizerParmRect->Add( m_spTeardropHDPercentRect, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxRIGHT|wxLEFT, 5 );
m_stTeardropHUnits = new wxStaticText( this, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stTeardropHUnits->Wrap( -1 );
fgSizerParmRect->Add( m_stTeardropHUnits, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 );
fgSizerBitmaps->Add( fgSizerParmRect, 1, wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 10 );
wxString m_rbShapeRectChoices[] = { _("Straight lines"), _("Curved") };
int m_rbShapeRectNChoices = sizeof( m_rbShapeRectChoices ) / sizeof( wxString );
m_rbShapeRect = new wxRadioBox( this, wxID_ANY, _("Style"), wxDefaultPosition, wxDefaultSize, m_rbShapeRectNChoices, m_rbShapeRectChoices, 1, wxRA_SPECIFY_COLS );
m_rbShapeRect->SetSelection( 0 );
fgSizerBitmaps->Add( m_rbShapeRect, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxLEFT, 10 );
m_staticline6 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
fgSizerBitmaps->Add( m_staticline6, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
m_staticline7 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
fgSizerBitmaps->Add( m_staticline7, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_staticline8 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
fgSizerBitmaps->Add( m_staticline8, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_staticline9 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
fgSizerBitmaps->Add( m_staticline9, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_staticTextTrck = new wxStaticText( this, wxID_ANY, _("Tracks:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextTrck->Wrap( -1 );
fgSizerBitmaps->Add( m_staticTextTrck, 0, wxTOP|wxBOTTOM, 12 );
m_bitmapTdTrackInfo = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerBitmaps->Add( m_bitmapTdTrackInfo, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
wxFlexGridSizer* fgSizerParmTrack;
fgSizerParmTrack = new wxFlexGridSizer( 0, 6, 5, 0 );
fgSizerParmTrack->AddGrowableCol( 1 );
fgSizerParmTrack->AddGrowableCol( 4 );
fgSizerParmTrack->SetFlexibleDirection( wxBOTH );
fgSizerParmTrack->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_stHsettingtrack = new wxStaticText( this, wxID_ANY, _("Best length:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHsettingtrack->Wrap( -1 );
fgSizerParmTrack->Add( m_stHsettingtrack, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_spTeardropLenPercentTrack = new wxSpinCtrlDouble( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 20, 100, 100.000000, 10 );
m_spTeardropLenPercentTrack->SetDigits( 0 );
fgSizerParmTrack->Add( m_spTeardropLenPercentTrack, 0, wxEXPAND|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
m_stTeardropLenTrackUnits = new wxStaticText( this, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stTeardropLenTrackUnits->Wrap( -1 );
fgSizerParmTrack->Add( m_stTeardropLenTrackUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_stVsettingtrack = new wxStaticText( this, wxID_ANY, _("Best height:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stVsettingtrack->Wrap( -1 );
fgSizerParmTrack->Add( m_stVsettingtrack, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 10 );
m_spTeardropSizePercentTrack = new wxSpinCtrlDouble( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 60, 100, 100.000000, 10 );
m_spTeardropSizePercentTrack->SetDigits( 0 );
fgSizerParmTrack->Add( m_spTeardropSizePercentTrack, 0, wxEXPAND|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
m_stLenPercentTrack = new wxStaticText( this, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stLenPercentTrack->Wrap( -1 );
fgSizerParmTrack->Add( m_stLenPercentTrack, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_stMaxLenTrack = new wxStaticText( this, wxID_ANY, _("Max length:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxLenTrack->Wrap( -1 );
fgSizerParmTrack->Add( m_stMaxLenTrack, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_tcTdMaxLenTrack = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerParmTrack->Add( m_tcTdMaxLenTrack, 0, wxEXPAND|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
m_stMaxLenTrackUnits = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxLenTrackUnits->Wrap( -1 );
fgSizerParmTrack->Add( m_stMaxLenTrackUnits, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 );
m_stTdMaxSizeTrack = new wxStaticText( this, wxID_ANY, _("Max height:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stTdMaxSizeTrack->Wrap( -1 );
fgSizerParmTrack->Add( m_stTdMaxSizeTrack, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 10 );
m_tcMaxHeightTrack = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerParmTrack->Add( m_tcMaxHeightTrack, 0, wxEXPAND|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
m_stMaxHeightTrackUnits = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
m_stMaxHeightTrackUnits->Wrap( -1 );
fgSizerParmTrack->Add( m_stMaxHeightTrackUnits, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
fgSizerParmTrack->Add( 0, 0, 1, wxEXPAND, 5 );
fgSizerParmTrack->Add( 0, 0, 1, wxEXPAND, 5 );
fgSizerParmTrack->Add( 0, 0, 1, wxEXPAND, 5 );
m_stHDRatioTrack = new wxStaticText( this, wxID_ANY, _("Max height:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHDRatioTrack->Wrap( -1 );
m_stHDRatioTrack->SetToolTip( _("Max pad/via size to track width ratio to create a teardrop.\n100 always creates a teardrop.") );
fgSizerParmTrack->Add( m_stHDRatioTrack, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 10 );
m_spTeardropHDPercentTrack = new wxSpinCtrlDouble( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 100, 90, 10 );
m_spTeardropHDPercentTrack->SetDigits( 0 );
fgSizerParmTrack->Add( m_spTeardropHDPercentTrack, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_stHDPercentTrack = new wxStaticText( this, wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
m_stHDPercentTrack->Wrap( -1 );
fgSizerParmTrack->Add( m_stHDPercentTrack, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
fgSizerBitmaps->Add( fgSizerParmTrack, 1, wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 10 );
wxString m_rbShapeTrackChoices[] = { _("Straight lines"), _("Curved") };
int m_rbShapeTrackNChoices = sizeof( m_rbShapeTrackChoices ) / sizeof( wxString );
m_rbShapeTrack = new wxRadioBox( this, wxID_ANY, _("Style"), wxDefaultPosition, wxDefaultSize, m_rbShapeTrackNChoices, m_rbShapeTrackChoices, 1, wxRA_SPECIFY_COLS );
m_rbShapeTrack->SetSelection( 0 );
fgSizerBitmaps->Add( m_rbShapeTrack, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxLEFT, 10 );
bSizeScopeSize->Add( fgSizerBitmaps, 1, wxEXPAND|wxRIGHT|wxLEFT, 10 );
bSizerTop->Add( bSizeScopeSize, 0, wxEXPAND, 5 );
bSizerUpper->Add( bSizerTop, 0, wxEXPAND, 5 );
wxBoxSizer* bSizerShape;
bSizerShape = new wxBoxSizer( wxHORIZONTAL );
wxStaticBoxSizer* sbSizerScope;
sbSizerScope = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Scope") ), wxVERTICAL );
m_cbPadVia = new wxCheckBox( sbSizerScope->GetStaticBox(), wxID_ANY, _("Vias and PTH pads"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbPadVia->SetValue(true);
m_cbPadVia->SetToolTip( _("Add teardrops to vias and pads with holes") );
sbSizerScope->Add( m_cbPadVia, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_cbRoundShapesOnly = new wxCheckBox( sbSizerScope->GetStaticBox(), wxID_ANY, _("Round pads only"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbRoundShapesOnly->SetToolTip( _("Add teardrops to round shapes only ") );
sbSizerScope->Add( m_cbRoundShapesOnly, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_cbSmdSimilarPads = new wxCheckBox( sbSizerScope->GetStaticBox(), wxID_ANY, _("SMD pads"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbSmdSimilarPads->SetValue(true);
m_cbSmdSimilarPads->SetToolTip( _("Add teardrops to not driiled pads, like SMD") );
sbSizerScope->Add( m_cbSmdSimilarPads, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_cbTrack2Track = new wxCheckBox( sbSizerScope->GetStaticBox(), wxID_ANY, _("Track to track"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbTrack2Track->SetValue(true);
m_cbTrack2Track->SetToolTip( _("Add teardrops to two connected tracks of different widths") );
sbSizerScope->Add( m_cbTrack2Track, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
bSizerShape->Add( sbSizerScope, 0, wxEXPAND|wxTOP, 5 );
wxStaticBoxSizer* sbSizerOptions;
sbSizerOptions = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Options") ), wxVERTICAL );
m_cbOptUseNextTrack = new wxCheckBox( sbSizerOptions->GetStaticBox(), wxID_ANY, _("Allow teardrops to span two track segments"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbOptUseNextTrack->SetValue(true);
m_cbOptUseNextTrack->SetToolTip( _("Allows a teardrop to spread over 2 tracks if the first track segment is too short") );
sbSizerOptions->Add( m_cbOptUseNextTrack, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_cbPadsInZones = new wxCheckBox( sbSizerOptions->GetStaticBox(), wxID_ANY, _("Place teardrops on pads in zones"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbPadsInZones->SetToolTip( _("Pads inside a copper zone outline of same net have no teardrop.\nCheck this option to allow teardrop for these pads.") );
sbSizerOptions->Add( m_cbPadsInZones, 0, wxALL, 5 );
sbSizerOptions->Add( 30, 0, 0, 0, 5 );
wxBoxSizer* bSizer6;
bSizer6 = new wxBoxSizer( wxHORIZONTAL );
m_stPointCount = new wxStaticText( sbSizerOptions->GetStaticBox(), wxID_ANY, _("Curve points:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stPointCount->Wrap( -1 );
m_stPointCount->SetToolTip( _("Number of segments to build a teardrop with curved shape") );
bSizer6->Add( m_stPointCount, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
m_spPointCount = new wxSpinCtrl( sbSizerOptions->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 3, 10, 5 );
bSizer6->Add( m_spPointCount, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
sbSizerOptions->Add( bSizer6, 1, wxEXPAND|wxTOP|wxBOTTOM, 5 );
m_generateRawTeardrops = new wxCheckBox( sbSizerOptions->GetStaticBox(), wxID_ANY, _("Generate raw teardrops"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizerOptions->Add( m_generateRawTeardrops, 0, wxRIGHT|wxLEFT, 5 );
sbSizerOptions->Add( 0, 2, 0, 0, 5 );
m_rawTeardropsHint = new wxStaticText( sbSizerOptions->GetStaticBox(), wxID_ANY, _("(Shapes will be adjusted for clearances on next zone fill.)"), wxDefaultPosition, wxDefaultSize, 0 );
m_rawTeardropsHint->Wrap( -1 );
m_rawTeardropsHint->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
sbSizerOptions->Add( m_rawTeardropsHint, 0, wxLEFT, 27 );
sbSizerOptions->Add( 0, 2, 0, 0, 5 );
bSizerShape->Add( sbSizerOptions, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
bSizerUpper->Add( bSizerShape, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
bSizerMain->Add( bSizerUpper, 1, wxEXPAND, 5 );
m_sdbSizer = new wxStdDialogButtonSizer();
m_sdbSizerOK = new wxButton( this, wxID_OK );
m_sdbSizer->AddButton( m_sdbSizerOK );
m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
m_sdbSizer->AddButton( m_sdbSizerCancel );
m_sdbSizer->Realize();
bSizerMain->Add( m_sdbSizer, 0, wxALIGN_RIGHT|wxALL, 5 );
this->SetSizer( bSizerMain );
this->Layout();
bSizerMain->Fit( this );
this->Centre( wxBOTH );
}
TEARDROP_DIALOG_BASE::~TEARDROP_DIALOG_BASE()
{
}

File diff suppressed because it is too large Load Diff

View File

@ -1,128 +0,0 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-282-g1fa54006)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
#include "dialog_shim.h"
#include <wx/string.h>
#include <wx/stattext.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/statbmp.h>
#include <wx/spinctrl.h>
#include <wx/textctrl.h>
#include <wx/sizer.h>
#include <wx/radiobox.h>
#include <wx/statline.h>
#include <wx/checkbox.h>
#include <wx/statbox.h>
#include <wx/button.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class TEARDROP_DIALOG_BASE
///////////////////////////////////////////////////////////////////////////////
class TEARDROP_DIALOG_BASE : public DIALOG_SHIM
{
private:
protected:
wxStaticText* m_staticTextRndS;
wxStaticBitmap* m_bitmapTdCircularInfo;
wxStaticText* m_stHsettingRound;
wxSpinCtrlDouble* m_spTeardropLenPercentRound;
wxStaticText* m_stTeardropLenUnits;
wxStaticText* m_stVsettingRound;
wxSpinCtrlDouble* m_spTeardropSizePercentRound;
wxStaticText* m_stLenPercentRound;
wxStaticText* m_stMaxLenRound;
wxTextCtrl* m_tcTdMaxLenRound;
wxStaticText* m_stMaxLenRoundUnits;
wxStaticText* m_stTdMaxSizeRound;
wxTextCtrl* m_tcMaxHeightRound;
wxStaticText* m_stMaxHeightRoundUnits;
wxStaticText* m_stHDRatioRound;
wxSpinCtrlDouble* m_spTeardropHDPercentRound;
wxStaticText* m_stHDPercentRound;
wxRadioBox* m_rbShapeRound;
wxStaticLine* m_staticline2;
wxStaticLine* m_staticline3;
wxStaticLine* m_staticline4;
wxStaticLine* m_staticline5;
wxStaticText* m_staticTextRectS;
wxStaticBitmap* m_bitmapTdRectangularInfo;
wxStaticText* m_stHsettingRect;
wxSpinCtrlDouble* m_spTeardropLenPercentRect;
wxStaticText* m_stHDPercentRect;
wxStaticText* m_stVsettingRect;
wxSpinCtrlDouble* m_spTeardropSizePercentRect;
wxStaticText* m_stLenPercentRect;
wxStaticText* m_stMaxLenRect;
wxTextCtrl* m_tcTdMaxLenRect;
wxStaticText* m_stMaxLenRectUnits;
wxStaticText* m_stTdMaxSizeRect;
wxTextCtrl* m_tcMaxHeightRect;
wxStaticText* m_stMaxHeightRectUnits;
wxStaticText* m_stHDRatioRect;
wxSpinCtrlDouble* m_spTeardropHDPercentRect;
wxStaticText* m_stTeardropHUnits;
wxRadioBox* m_rbShapeRect;
wxStaticLine* m_staticline6;
wxStaticLine* m_staticline7;
wxStaticLine* m_staticline8;
wxStaticLine* m_staticline9;
wxStaticText* m_staticTextTrck;
wxStaticBitmap* m_bitmapTdTrackInfo;
wxStaticText* m_stHsettingtrack;
wxSpinCtrlDouble* m_spTeardropLenPercentTrack;
wxStaticText* m_stTeardropLenTrackUnits;
wxStaticText* m_stVsettingtrack;
wxSpinCtrlDouble* m_spTeardropSizePercentTrack;
wxStaticText* m_stLenPercentTrack;
wxStaticText* m_stMaxLenTrack;
wxTextCtrl* m_tcTdMaxLenTrack;
wxStaticText* m_stMaxLenTrackUnits;
wxStaticText* m_stTdMaxSizeTrack;
wxTextCtrl* m_tcMaxHeightTrack;
wxStaticText* m_stMaxHeightTrackUnits;
wxStaticText* m_stHDRatioTrack;
wxSpinCtrlDouble* m_spTeardropHDPercentTrack;
wxStaticText* m_stHDPercentTrack;
wxRadioBox* m_rbShapeTrack;
wxCheckBox* m_cbPadVia;
wxCheckBox* m_cbRoundShapesOnly;
wxCheckBox* m_cbSmdSimilarPads;
wxCheckBox* m_cbTrack2Track;
wxCheckBox* m_cbOptUseNextTrack;
wxCheckBox* m_cbPadsInZones;
wxStaticText* m_stPointCount;
wxSpinCtrl* m_spPointCount;
wxCheckBox* m_generateRawTeardrops;
wxStaticText* m_rawTeardropsHint;
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;
wxButton* m_sdbSizerCancel;
public:
TEARDROP_DIALOG_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Add Teardrops"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~TEARDROP_DIALOG_BASE();
};

View File

@ -31,28 +31,26 @@
#include <zone_filler.h>
#include <board_commit.h>
#include "teardrop.h"
#include <geometry/convex_hull.h>
#include <connectivity/connectivity_data.h>
#include <teardrop/teardrop.h>
#include <drc/drc_rtree.h>
#include <geometry/shape_line_chain.h>
#include <geometry/rtree.h>
#include <convert_basic_shapes_to_polygon.h>
#include <bezier_curves.h>
#include <progress_reporter.h>
#include <wx/log.h>
// The first priority level of a teardrop area (arbitrary value)
#define MAGIC_TEARDROP_ZONE_ID 30000
TEARDROP_MANAGER::TEARDROP_MANAGER( BOARD* aBoard, PCB_EDIT_FRAME* aFrame, PROGRESS_REPORTER* aReporter )
TEARDROP_MANAGER::TEARDROP_MANAGER( BOARD* aBoard, TOOL_MANAGER* aToolManager ) :
m_board( aBoard ),
m_toolManager( aToolManager )
{
m_frame = aFrame;
m_reporter = aReporter;
m_board = aBoard;
m_prmsList = m_board->GetDesignSettings().GetTeadropParamsList();
m_tolerance = 0;
m_toolManager = m_frame->GetToolManager();
}
@ -69,24 +67,30 @@ ZONE* TEARDROP_MANAGER::createTeardrop( TEARDROP_VARIANT aTeardropVariant,
s_default_settings.ExportSetting( *teardrop, false );
// Add zone properties (priority will be fixed later)
teardrop->SetTeardropAreaType( aTeardropVariant == TD_TYPE_PADVIA ?
TEARDROP_TYPE::TD_VIAPAD :
TEARDROP_TYPE::TD_TRACKEND );
teardrop->SetTeardropAreaType( aTeardropVariant == TD_TYPE_PADVIA ? TEARDROP_TYPE::TD_VIAPAD
: TEARDROP_TYPE::TD_TRACKEND );
teardrop->SetLayer( aTrack->GetLayer() );
teardrop->SetNetCode( aTrack->GetNetCode() );
teardrop->SetLocalClearance( 0 );
teardrop->SetMinThickness( pcbIUScale.mmToIU( 0.0254 ) ); // The minimum zone thickness
teardrop->SetPadConnection( ZONE_CONNECTION::FULL );
teardrop->SetIsFilled( false );
teardrop->SetZoneName( aTeardropVariant == TD_TYPE_PADVIA ?
MAGIC_TEARDROP_PADVIA_NAME :
MAGIC_TEARDROP_TRACK_NAME );
teardrop->SetZoneName( aTeardropVariant == TD_TYPE_PADVIA ? MAGIC_TEARDROP_PADVIA_NAME
: MAGIC_TEARDROP_TRACK_NAME );
teardrop->SetIslandRemovalMode( ISLAND_REMOVAL_MODE::NEVER );
teardrop->SetBorderDisplayStyle( ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_FULL,
pcbIUScale.mmToIU( 0.1 ), true );
SHAPE_POLY_SET* outline = teardrop->Outline();
outline->NewOutline();
for( VECTOR2I pt: aPoints )
outline->Append(pt.x, pt.y);
for( const VECTOR2I& pt: aPoints )
outline->Append( pt.x, pt.y );
// Until we know better (ie: pay for a potentially very expensive zone refill), the teardrop
// fill is the same as its outline.
teardrop->SetFilledPolysList( aTrack->GetLayer(), *teardrop->Outline() );
teardrop->SetIsFilled( true );
// Used in priority calculations:
teardrop->CalculateFilledArea();
@ -95,163 +99,175 @@ ZONE* TEARDROP_MANAGER::createTeardrop( TEARDROP_VARIANT aTeardropVariant,
}
int TEARDROP_MANAGER::SetTeardrops( BOARD_COMMIT* aCommitter, bool aFollowTracks, bool aFillAfter )
void TEARDROP_MANAGER::UpdateTeardrops( BOARD_COMMIT& aCommit,
const std::vector<BOARD_ITEM*>* dirtyPadsAndVias,
const std::set<PCB_TRACK*>* dirtyTracks,
bool aForceFullUpdate )
{
if( m_board->LegacyTeardrops() )
return;
// Init parameters:
m_tolerance = pcbIUScale.mmToIU( 0.01 );
int count = 0; // Number of created teardrop
buildTrackCaches();
std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_board->GetConnectivity();
// Old teardrops must be removed, to ensure a clean teardrop rebuild
int removed_cnt = RemoveTeardrops( aCommitter, false );
std::vector<ZONE*> stale_teardrops;
// get vias, PAD_ATTRIB_PTH and others if aIncludeNotDrilled == true
// (custom pads are not collected)
std::vector< VIAPAD > viapad_list;
if( m_prmsList->m_TargetViasPads )
collectVias( viapad_list );
collectPadsCandidate( viapad_list, m_prmsList->m_TargetViasPads,
m_prmsList->m_UseRoundShapesOnly, m_prmsList->m_TargetPadsWithNoHole );
TRACK_BUFFER trackLookupList;
if( aFollowTracks )
for( ZONE* zone : m_board->Zones() )
{
// Build the track list (only straight lines)
for( PCB_TRACK* track: m_board->Tracks() )
if( zone->IsTeardropArea() )
{
if( track->Type() == PCB_TRACE_T || track->Type() == PCB_ARC_T)
bool stale = aForceFullUpdate;
if( !stale )
{
int netcode = track->GetNetCode();
int layer = track->GetLayer();
trackLookupList.AddTrack( track, layer, netcode );
std::vector<PAD*> connectedPads;
std::vector<PCB_VIA*> connectedVias;
connectivity->GetConnectedPadsAndVias( zone, &connectedPads, &connectedVias );
for( PAD* pad : connectedPads )
stale = stale || alg::contains( *dirtyPadsAndVias, pad );
for( PCB_VIA* via : connectedVias )
stale = stale || alg::contains( *dirtyPadsAndVias, via );
}
if( stale )
stale_teardrops.push_back( zone );
}
}
std::vector< ZONE*> teardrops;
collectTeardrops( teardrops );
for( ZONE* td : stale_teardrops )
{
m_board->Remove( td, REMOVE_MODE::BULK );
aCommit.Removed( td );
}
for( PCB_TRACK* track : m_board->Tracks() )
{
if( ! (track->Type() == PCB_TRACE_T || track->Type() == PCB_ARC_T ) )
if( ! ( track->Type() == PCB_TRACE_T || track->Type() == PCB_ARC_T ) )
continue;
// Search for a padvia connected to track, with one end inside and one end outside
// if both track ends are inside or outside, one cannot build a teadrop
for( VIAPAD& viapad: viapad_list )
std::vector<PAD*> connectedPads;
std::vector<PCB_VIA*> connectedVias;
connectivity->GetConnectedPadsAndVias( track, &connectedPads, &connectedVias );
bool forceUpdate = aForceFullUpdate || alg::contains( *dirtyTracks, track );
for( PAD* pad : connectedPads )
{
// Pad and track must be on the same layer
if( !viapad.IsOnLayer( track->GetLayer() ) )
if( !forceUpdate && !alg::contains( *dirtyPadsAndVias, pad ) )
continue;
bool start_in_pad = viapad.m_Parent->HitTest( track->GetStart() );
bool end_in_pad = viapad.m_Parent->HitTest( track->GetEnd() );
if( end_in_pad == start_in_pad )
// the track is inside or outside the via pad. Cannot create a teardrop
if( pad->GetShape() == PAD_SHAPE::CUSTOM )
// A teardrop shape cannot be built
continue;
// A pointer to one of available m_Parameters items
TEARDROP_PARAMETERS* currParams;
TEARDROP_PARAMETERS& tdParams = pad->GetTeardropParams();
int annularWidth = std::min( pad->GetSize().x, pad->GetSize().y );
if( viapad.m_IsRound )
currParams = m_prmsList->GetParameters( TARGET_ROUND );
else
currParams = m_prmsList->GetParameters( TARGET_RECT );
if( !tdParams.m_Enabled )
continue;
// Ensure a teardrop shape can be built:
// The track width must be < teardrop height
if( track->GetWidth() >= currParams->m_TdMaxHeight
|| track->GetWidth() >= viapad.m_Width * currParams->m_HeightRatio )
// Ensure a teardrop shape can be built: track width must be < teardrop width and
// filter width
if( track->GetWidth() >= tdParams.m_TdMaxWidth
|| track->GetWidth() >= annularWidth * tdParams.m_BestWidthRatio
|| track->GetWidth() >= annularWidth * tdParams.m_WidthtoSizeFilterRatio )
{
continue;
}
// Ensure also it is not filtered by a too high track->GetWidth()/viapad.m_Width ratio
if( track->GetWidth() >= viapad.m_Width * currParams->m_WidthtoSizeFilterRatio )
if( pad->HitTest( track->GetStart() ) && pad->HitTest( track->GetEnd() ) )
// The track is entirely inside the pad; cannot create a teardrop
continue;
// Skip case where pad/via and the track is within a copper zone with the same net
// (and the pad can be connected by the zone thermal relief )
if( !m_prmsList->m_TdOnPadsInZones && isViaAndTrackInSameZone( viapad, track ) )
// Skip case where pad and the track are within a copper zone with the same net
// (and the pad can be connected to the zone)
if( !tdParams.m_TdOnPadsInZones && areItemsInSameZone( pad, track ) )
continue;
std::vector<VECTOR2I> points;
bool success = computeTeardropPolygonPoints( currParams, points, track, viapad,
aFollowTracks, trackLookupList );
if( success )
if( computeTeardropPolygon( tdParams, points, track, pad, pad->GetPosition() ) )
{
ZONE* new_teardrop = createTeardrop( TD_TYPE_PADVIA, points, track );
m_board->Add( new_teardrop, ADD_MODE::BULK_INSERT );
m_createdTdList.push_back( new_teardrop );
if( aCommitter )
aCommitter->Added( new_teardrop );
aCommit.Added( new_teardrop );
}
}
count += 1;
for( PCB_VIA* via : connectedVias )
{
if( !forceUpdate && !alg::contains( *dirtyPadsAndVias, via ) )
continue;
TEARDROP_PARAMETERS tdParams = via->GetTeardropParams();
int annularWidth = via->GetWidth();
if( !tdParams.m_Enabled )
continue;
// Ensure a teardrop shape can be built: track width must be < teardrop width and
// filter width
if( track->GetWidth() >= tdParams.m_TdMaxWidth
|| track->GetWidth() >= annularWidth * tdParams.m_BestWidthRatio
|| track->GetWidth() >= annularWidth * tdParams.m_WidthtoSizeFilterRatio )
{
continue;
}
if( via->HitTest( track->GetStart() ) && via->HitTest( track->GetEnd() ) )
// The track is entirely inside the via; cannot create a teardrop
continue;
std::vector<VECTOR2I> points;
if( computeTeardropPolygon( tdParams, points, track, via, via->GetPosition() ) )
{
ZONE* new_teardrop = createTeardrop( TD_TYPE_PADVIA, points, track );
m_board->Add( new_teardrop, ADD_MODE::BULK_INSERT );
m_createdTdList.push_back( new_teardrop );
aCommit.Added( new_teardrop );
}
}
}
int track2trackCount = 0;
if( m_prmsList->m_TargetTrack2Track )
track2trackCount = addTeardropsOnTracks( aCommitter );
if( ( aForceFullUpdate || !dirtyTracks->empty() )
&& m_prmsList->GetParameters( TARGET_TRACK )->m_Enabled )
{
AddTeardropsOnTracks( aCommit, dirtyTracks, aForceFullUpdate );
}
// Now set priority of teardrops now all teardrops are added
setTeardropPriorities();
}
if( count || removed_cnt || track2trackCount )
void TEARDROP_MANAGER::DeleteTrackToTrackTeardrops( BOARD_COMMIT& aCommit )
{
std::vector<ZONE*> stale_teardrops;
for( ZONE* zone : m_board->Zones() )
{
// Note:
// Refill zones can be made only with clean data, especially connectivity data,
// therefore only after changes are pushed to avoid crashes in some cases
//
// Fill raw teardrop shapes, even if aFillAfter is true: it ensure teardrops
// will be filled even when undoing refilling zones.
// This is a rough calculation, just to show a filled
// shape on screen without the (potentially large) performance hit of a zone refill
int epsilon = pcbIUScale.mmToIU( 0.001 );
int allowed_error = pcbIUScale.mmToIU( 0.005 );
for( ZONE* zone: m_createdTdList )
{
int half_min_width = zone->GetMinThickness() / 2;
int numSegs = GetArcToSegmentCount( half_min_width, allowed_error, FULL_CIRCLE );
SHAPE_POLY_SET filledPolys = *zone->Outline();
filledPolys.Deflate( half_min_width - epsilon, numSegs );
// Re-inflate after pruning of areas that don't meet minimum-width criteria
if( half_min_width - epsilon > epsilon )
filledPolys.Inflate( half_min_width - epsilon, numSegs );
zone->SetFilledPolysList( zone->GetFirstLayer(), filledPolys );
}
if( aCommitter )
aCommitter->Push( _( "Add teardrops" ) );
if( aFillAfter )
{
ZONE_FILLER filler( m_board, aCommitter );
if( m_reporter )
filler.SetProgressReporter( m_reporter );
filler.Fill( m_board->Zones() );
if( aCommitter )
aCommitter->Push( _( "Add teardrops and refill zones" ) );
}
if( zone->IsTeardropArea() && zone->GetTeardropAreaType() == TEARDROP_TYPE::TD_TRACKEND )
stale_teardrops.push_back( zone );
}
return count + track2trackCount;
for( ZONE* td : stale_teardrops )
{
m_board->Remove( td, REMOVE_MODE::BULK );
aCommit.Removed( td );
}
}
@ -295,32 +311,15 @@ void TEARDROP_MANAGER::setTeardropPriorities()
}
int TEARDROP_MANAGER::addTeardropsOnTracks( BOARD_COMMIT* aCommitter )
void TEARDROP_MANAGER::AddTeardropsOnTracks( BOARD_COMMIT& aCommit,
const std::set<PCB_TRACK*>* aTracks,
bool aForceFullUpdate )
{
TRACK_BUFFER trackLookupList;
int count = 0;
// Build the track list (only straight lines)
for( PCB_TRACK* track: m_board->Tracks() )
{
if( track->Type() == PCB_TRACE_T || track->Type() == PCB_ARC_T )
{
int netcode = track->GetNetCode();
int layer = track->GetLayer();
trackLookupList.AddTrack( track, layer, netcode );
}
}
// get vias and pads (custom pads are not collected). We do not create a track to track
// teardrop inside a pad or via area
std::vector< VIAPAD > viapad_list;
collectVias( viapad_list );
collectPadsCandidate( viapad_list, true, true, true );
TEARDROP_PARAMETERS* currParams = m_prmsList->GetParameters( TARGET_TRACK );
std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_board->GetConnectivity();
TEARDROP_PARAMETERS params = *m_prmsList->GetParameters( TARGET_TRACK );
// Explore groups (a group is a set of tracks on the same layer and the same net):
for( auto& grp : trackLookupList.GetBuffer() )
for( auto& grp : m_trackLookupList.GetBuffer() )
{
int layer, netcode;
TRACK_BUFFER::GetNetcodeAndLayerFromIndex( grp.first, &layer, &netcode );
@ -348,15 +347,14 @@ int TEARDROP_MANAGER::addTeardropsOnTracks( BOARD_COMMIT* aCommitter )
for( unsigned ii = 0; ii < sublist->size()-1; ii++ )
{
PCB_TRACK* track = (*sublist)[ii];
int track_len = track->GetLength();
int track_len = (int) track->GetLength();
bool track_needs_update = aForceFullUpdate || alg::contains( *aTracks, track );
min_width = track->GetWidth();
// to avoid creating a teardrop between 2 tracks having similar widths
// give a threshold
const double th = currParams->m_WidthtoSizeFilterRatio > 0.1 ?
1.0 / currParams->m_WidthtoSizeFilterRatio
: 10.0;
min_width = min_width * th;
// to avoid creating a teardrop between 2 tracks having similar widths give a threshold
params.m_WidthtoSizeFilterRatio = std::max( params.m_WidthtoSizeFilterRatio, 0.1 );
const double th = 1.0 / params.m_WidthtoSizeFilterRatio;
min_width = KiROUND( min_width * th );
for( unsigned jj = ii+1; jj < sublist->size(); jj++ )
{
@ -375,82 +373,56 @@ int TEARDROP_MANAGER::addTeardropsOnTracks( BOARD_COMMIT* aCommitter )
EDA_ITEM_FLAGS match_points; // to return the end point EDA_ITEM_FLAGS:
// 0, STARTPOINT, ENDPOINT
VECTOR2I roundshape_pos = candidate->GetStart();
ENDPOINT_T endPointCandidate = ENDPOINT_START;
match_points = track->IsPointOnEnds( roundshape_pos, m_tolerance );
VECTOR2I pos = candidate->GetStart();
match_points = track->IsPointOnEnds( pos, m_tolerance );
if( !match_points )
{
roundshape_pos = candidate->GetEnd();
match_points = track->IsPointOnEnds( roundshape_pos, m_tolerance );
endPointCandidate = ENDPOINT_END;
pos = candidate->GetEnd();
match_points = track->IsPointOnEnds( pos, m_tolerance );
}
// Ensure a pad or via is not on test_pos point before creating a teardrop
// at this location
for( VIAPAD& viapad : viapad_list )
if( !match_points )
continue;
if( !track_needs_update && alg::contains( *aTracks, candidate ) )
continue;
// Pads/vias have priority for teardrops; ensure there isn't one at our position
bool existingPadOrVia = false;
std::vector<PAD*> connectedPads;
std::vector<PCB_VIA*> connectedVias;
connectivity->GetConnectedPadsAndVias( track, &connectedPads, &connectedVias );
for( PAD* pad : connectedPads )
{
if( viapad.IsOnLayer( track->GetLayer() )
&& viapad.m_Parent->HitTest( roundshape_pos, 0 ) )
{
match_points = 0;
break;
}
if( pad->HitTest( pos ) )
existingPadOrVia = true;
}
if( match_points )
for( PCB_VIA* via : connectedVias )
{
VIAPAD viatrack( candidate, endPointCandidate );
std::vector<VECTOR2I> points;
bool success = computeTeardropPolygonPoints( currParams,
points, track, viatrack,
false, trackLookupList );
if( via->HitTest( pos ) )
existingPadOrVia = true;
}
if( success )
{
ZONE* new_teardrop = createTeardrop( TD_TYPE_TRACKEND, points, track );
m_board->Add( new_teardrop, ADD_MODE::BULK_INSERT );
m_createdTdList.push_back( new_teardrop );
if( existingPadOrVia )
continue;
if( aCommitter )
aCommitter->Added( new_teardrop );
std::vector<VECTOR2I> points;
count += 1;
}
if( computeTeardropPolygon( params, points, track, candidate, pos ) )
{
ZONE* new_teardrop = createTeardrop( TD_TYPE_TRACKEND, points, track );
m_board->Add( new_teardrop, ADD_MODE::BULK_INSERT );
m_createdTdList.push_back( new_teardrop );
aCommit.Added( new_teardrop );
}
}
}
}
return count;
}
int TEARDROP_MANAGER::RemoveTeardrops( BOARD_COMMIT* aCommitter, bool aCommitAfterRemove )
{
int count = 0;
std::vector< ZONE*> teardrops;
collectTeardrops( teardrops );
for( ZONE* teardrop : teardrops )
{
m_board->Remove( teardrop, REMOVE_MODE::BULK );
if( aCommitter )
aCommitter->Removed( teardrop );
count += 1;
}
if( count )
{
if( aCommitter && aCommitAfterRemove )
aCommitter->Push( _( "Remove teardrops" ), SKIP_CONNECTIVITY );
m_board->BuildConnectivity();
}
return count;
}

View File

@ -25,41 +25,57 @@
#ifndef TEARDROP_H
#define TEARDROP_H
#include <pcb_edit_frame.h>
#include <tool/tool_manager.h>
#include <board.h>
#include <footprint.h>
#include <pad.h>
#include <pcb_track.h>
#include <zone.h>
#include <drc/drc_rtree.h>
#include "teardrop_parameters.h"
#define MAGIC_TEARDROP_PADVIA_NAME "$teardrop_padvia$"
#define MAGIC_TEARDROP_TRACK_NAME "$teardrop_track$"
class TRACK_BUFFER;
class PROGRESS_REPORTER;
/**
* Stores info of a pad, via or track end to build a teardrop
*/
struct VIAPAD
// A class to store tracks grouped by layer and netcode
class TRACK_BUFFER
{
VIAPAD( PCB_VIA* aVia );
VIAPAD( PAD* aPad );
VIAPAD( PCB_TRACK* aTrack, ENDPOINT_T aEndPoint );
public:
TRACK_BUFFER() {}
bool IsOnLayer( PCB_LAYER_ID aLayer ) const
/**
* Add a track in buffer, in space grouping tracks having the same netcode and the same layer
*/
void AddTrack( PCB_TRACK* aTrack, int aLayer, int aNetcode );
/**
* @return the buffer that stores tracks having the same layer and the same netcode
*/
std::vector<PCB_TRACK*>* GetTrackList( int aLayer, int aNetcode ) const
{
return m_Parent->IsOnLayer( aLayer );
return m_map_tracks.at( idxFromLayNet( aLayer, aNetcode ) );
}
VECTOR2I m_Pos;
int m_Width; // The diameter of a round shape, or the min size for others
int m_Drill;
int m_NetCode;
bool m_IsRound; // true for round shapes, false for any other shape
bool m_IsPad; // true for pads, false for vias and tracks
BOARD_CONNECTED_ITEM* m_Parent;
/**
* @return a reference to the internal buffer
*/
const std::map< int, std::vector<PCB_TRACK*>* >& GetBuffer() const { return m_map_tracks; }
static void GetNetcodeAndLayerFromIndex( int aIdx, int* aLayer, int* aNetcode )
{
*aLayer = aIdx & 0xFF;
*aNetcode = aIdx >> 8;
}
private:
// Build an index from the layer id and the netcode, to store a track in buffer
int idxFromLayNet( int aLayer, int aNetcode ) const
{
return ( aNetcode << 8 ) + ( aLayer & 0xFF );
}
// Track buffer, tracks are grouped by layer+netcode
std::map< int, std::vector<PCB_TRACK*>* > m_map_tracks;
};
@ -88,70 +104,30 @@ public:
TD_TYPE_TRACKEND // specify a teardrop on a rond end of a wide track
};
/**
* TEARDROP_MANAGER Ctor
* @param aBoard is the board to manage
* @param aFrame is the board editor frame
* @param aReporter optional: used to show a progrss bar when refilling zones
*/
TEARDROP_MANAGER( BOARD* aBoard, PCB_EDIT_FRAME* aFrame, PROGRESS_REPORTER* aReporter = nullptr );
TEARDROP_MANAGER( BOARD* aBoard, TOOL_MANAGER* aToolManager );
/**
* Set teardrops on a teardrop free board
* @return the number of teardrop created
* @param aCommitter is a BOARD_COMMIT reference (can be null)
* @param aFollowTracks = true to use a track connected to the initial track connected
* to a pad / via if this initial track is too short to build the teardrop
* @param aFillAfter = true to performa zone fill at end
* Update teardrops on a list of items.
*/
int SetTeardrops( BOARD_COMMIT* aCommitter, bool aFollowTracks, bool aFillAfter );
/**
* Remove all teardrops
* @return the count of removed teardrops
* @param aCommitter is a BOARD_COMMITto handle undo/Redo commands
* @param aCommitAfterRemove = true to commit when removed,
* false if some other changes must be made and the actual commit postponed
* Can be nullptr
*/
int RemoveTeardrops( BOARD_COMMIT* aCommitter, bool aCommitAfterRemove );
private:
/**
* Collect and build the list of all vias from the given board
*/
void collectVias( std::vector< VIAPAD >& aList ) const;
/**
* Build a list of pads candidate for teardrops from the given board
* Pads with no net are not candidate (and have no track connected
* Custom pads are not candidate because one cannot define a teardrop shape
* @param aList is the list of VIAPAD to fill
* @param aDrilledViaPad = true to include drilled shapes
* @param aRoundShapesOnly = true to ignore not round shapes
* @param aIncludeNotDrilled = true to include not drilled pads like SMD
*/
void collectPadsCandidate( std::vector< VIAPAD >& aList,
bool aDrilledViaPad,
bool aRoundShapesOnly,
bool aIncludeNotDrilled ) const;
/**
* Build a list of all teardrops on the current board
* @param aList is the list to populate
*/
void collectTeardrops( std::vector< ZONE* >& aList ) const;
void UpdateTeardrops( BOARD_COMMIT& aCommit, const std::vector<BOARD_ITEM*>* dirtyPadsAndVias,
const std::set<PCB_TRACK*>* dirtyTracks, bool aForceFullUpdate = false );
/**
* Add teardrop on tracks of different sizes connected by their end
*/
int addTeardropsOnTracks( BOARD_COMMIT* aCommitter );
void AddTeardropsOnTracks( BOARD_COMMIT& aCommit, const std::set<PCB_TRACK*>* aTracks,
bool aForceFullUpdate = false );
void DeleteTrackToTrackTeardrops( BOARD_COMMIT& aCommit );
static int GetWidth( BOARD_ITEM* aItem );
static bool IsRound( BOARD_ITEM* aItem );
private:
/**
* @return true if the given aVia + aTrack is located inside a zone of the same netname
* @return true if the given aViaPad + aTrack is located inside a zone of the same netname
*/
bool isViaAndTrackInSameZone( VIAPAD& aVia, PCB_TRACK* aTrack) const;
bool areItemsInSameZone( BOARD_ITEM* aPadOrVia, PCB_TRACK* aTrack) const;
/**
* Compute the curve part points for teardrops connected to a round shape
@ -159,11 +135,10 @@ private:
* and do not give a good curve shape for other pad shapes
* use m_m_heightRatio
*/
void computeCurvedForRoundShape( TEARDROP_PARAMETERS* aCurrParams,
std::vector<VECTOR2I>& aPoly,
int aTrackHalfWidth,
VECTOR2D aTrackDir, VIAPAD& aViaPad,
std::vector<VECTOR2I>& aPts ) const;
void computeCurvedForRoundShape( const TEARDROP_PARAMETERS& aParams,
std::vector<VECTOR2I>& aPoly, int aTrackHalfWidth,
const VECTOR2D& aTrackDir, BOARD_ITEM* aOther,
const VECTOR2I& aOtherPos, std::vector<VECTOR2I>& aPts ) const;
/**
@ -171,26 +146,24 @@ private:
* The Bezier curve control points are not optimized for a special shape,
* so use computeCurvedForRoundShape() for round shapes for better result
*/
void computeCurvedForRectShape( TEARDROP_PARAMETERS* aCurrParams,
std::vector<VECTOR2I>& aPoly, int aTdHeight,
int aTrackHalfWidth, VIAPAD& aViaPad,
std::vector<VECTOR2I>& aPts ) const;
void computeCurvedForRectShape( const TEARDROP_PARAMETERS& aParams,
std::vector<VECTOR2I>& aPoly, int aTdWidth,
int aTrackHalfWidth, std::vector<VECTOR2I>& aPts ) const;
/**
* Compute all teardrop points of the polygon shape
* @return true if the polygonal shape was calculated, false if not buildable
* use m_lengthRatio and m_heightRatio
*/
bool computeTeardropPolygonPoints( TEARDROP_PARAMETERS* aCurrParams,
std::vector<VECTOR2I>& aCorners,
PCB_TRACK* aTrack, VIAPAD& aVia,
bool aFollowTracks,
TRACK_BUFFER& aTrackLookupList) const;
bool computeTeardropPolygon( const TEARDROP_PARAMETERS& aParams,
std::vector<VECTOR2I>& aCorners, PCB_TRACK* aTrack,
BOARD_ITEM* aOther, const VECTOR2I& aOtherPos ) const;
/**
* Compute the 2 points on pad/via of the teardrop shape
* @return false if these 2 points are not found
* @param aLayer is the layer for the teardrop
* @param aViaPad is the teardrop anchor
* @param aItem is the via/pad/track used to build the teardrop
* @param aPos is the via/pad position, or track start or end
* teardrop height = aViaPad size * aHeightRatio
* @param aPts is the buffer that contains initial and final teardrop polygonal shape
* in aPts:
@ -199,9 +172,9 @@ private:
* D ( aPts[3] ) is midpoint behind the aViaPad centre
* m_heightRatio is the factor to calculate the aViaPad teardrop size
*/
bool ComputePointsOnPadVia( TEARDROP_PARAMETERS* aCurrParams,
PCB_LAYER_ID aLayer, VIAPAD& aViaPad,
std::vector<VECTOR2I>& aPts ) const;
bool computeAnchorPoints( const TEARDROP_PARAMETERS& aParams, PCB_LAYER_ID aLayer,
BOARD_ITEM* aItem, const VECTOR2I& aPos,
std::vector<VECTOR2I>& aPts ) const;
/**
* Find a track connected to the end of another track
@ -209,11 +182,10 @@ private:
* @param aMatchType returns the end point id 0, STARTPOINT, ENDPOINT
* @param aTrackRef is the reference track
* @param aEndpoint is the coordinate to test
* @param aTrackLookupList is the buffer of available tracks
* @param tracksRTree is an RTree containing the available tracks
*/
PCB_TRACK* findTouchingTrack( EDA_ITEM_FLAGS& aMatchType, PCB_TRACK* aTrackRef,
const VECTOR2I& aEndPoint,
TRACK_BUFFER& aTrackLookupList ) const;
const VECTOR2I& aEndPoint ) const;
/**
* Creates a teardrop (a ZONE item) from its polygonal shape, track netcode and layer
@ -223,7 +195,7 @@ private:
* (mainly for net info)
*/
ZONE* createTeardrop( TEARDROP_VARIANT aTeardropVariant,
std::vector<VECTOR2I>& aPoints, PCB_TRACK* aTrack) const;
std::vector<VECTOR2I>& aPoints, PCB_TRACK* aTrack ) const;
/**
* Set priority of created teardrops. smaller have bigger priority
@ -236,18 +208,19 @@ private:
* @param aEndPoint is the start point of the track found (always outside the teardrop)
* @param aTrack is the track connected to the pad/via used to search a anchor point
* this reference can be modified if a connected track to the initial track is selected
* @param aViaPad is the via/pad used to build the teardrop
* @param aOther is the via/pad/track used to build the teardrop
* @param aOtherPos is the via/pad position, or track start or end
* @param aEffectiveTeardropLen is the actual teardrop length, that can be smaller than expected
* if the connected track length is too small
* @param aFollowTracks = true to use a connected track to aTrack if aTrack is too small
* @param aTrackLookupList is the list of tracks to explore if aFollowTracks = true
* m_lengthRatio is the length of teardrop (ratio pad/via size/teardrop len)
*/
bool findAnchorPointsOnTrack( TEARDROP_PARAMETERS* aCurrParams,
VECTOR2I& aStartPoint, VECTOR2I& aEndPoint,
PCB_TRACK*& aTrack, VIAPAD& aViaPad,
int* aEffectiveTeardropLen,
bool aFollowTracks, TRACK_BUFFER& aTrackLookupList ) const;
bool findAnchorPointsOnTrack( const TEARDROP_PARAMETERS& aParams, VECTOR2I& aStartPoint,
VECTOR2I& aEndPoint, PCB_TRACK*& aTrack, BOARD_ITEM* aOther,
const VECTOR2I& aOtherPos, int* aEffectiveTeardropLen ) const;
void buildTrackCaches();
private:
int m_tolerance; // max dist between track end point and pad/via
@ -255,51 +228,10 @@ private:
BOARD* m_board;
TOOL_MANAGER* m_toolManager;
TEARDROP_PARAMETERS_LIST* m_prmsList; // the teardrop parameters list, from the board design settings
DRC_RTREE m_tracksRTree;
TRACK_BUFFER m_trackLookupList;
std::vector<ZONE*> m_createdTdList; // list of new created teardrops
PCB_EDIT_FRAME* m_frame;
PROGRESS_REPORTER* m_reporter; // A reporter to show a progress bar if refilling zones
};
// A class to store tracks grouped by layer and netcode
class TRACK_BUFFER
{
public:
TRACK_BUFFER() {}
/**
* Add a track in buffer, in space grouping tracks having the same netcode and the same layer
*/
void AddTrack( PCB_TRACK* aTrack, int aLayer, int aNetcode );
/**
* @return the buffer that stores tracks having the same layer and the same netcode
*/
std::vector<PCB_TRACK*>* GetTrackList( int aLayer, int aNetcode )
{
return m_map_tracks.at( idxFromLayNet( aLayer, aNetcode ) );
}
/**
* @return a reference to the internal buffer
*/
std::map< int, std::vector<PCB_TRACK*>* >& GetBuffer() { return m_map_tracks ; }
static void GetNetcodeAndLayerFromIndex( int aIdx, int* aLayer, int* aNetcode )
{
*aLayer = aIdx & 0xFF;
*aNetcode = aIdx >> 8;
}
private:
// Build an index from the layer id and the netcode, to store a track in buffer
int idxFromLayNet( int aLayer, int aNetcode ) const
{
return ( aNetcode << 8 ) + ( aLayer & 0xFF );
}
// Track buffer, tracks are grouped by layer+netcode
std::map< int, std::vector<PCB_TRACK*>* > m_map_tracks;
};
#endif // ifndef TEARDROP_H

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2021 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2022-2023 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
@ -47,14 +47,15 @@ enum TARGET_TD
class TEARDROP_PARAMETERS
{
public:
TEARDROP_PARAMETERS( TARGET_TD aTdType ):
m_TdType( aTdType ),
m_TdMaxLen( pcbIUScale.mmToIU( 1.0 ) ),
m_TdMaxHeight( pcbIUScale.mmToIU( 2.0 ) ),
m_LengthRatio( 0.5),
m_HeightRatio( 1.0 ),
m_CurveSegCount( 0 ),
m_WidthtoSizeFilterRatio( 0.9 )
TEARDROP_PARAMETERS():
m_Enabled( false ),
m_AllowUseTwoTracks( true ),
m_TdMaxLen( pcbIUScale.mmToIU( 1.0 ) ),
m_TdMaxWidth( pcbIUScale.mmToIU( 2.0 ) ),
m_BestLengthRatio( 0.5),
m_BestWidthRatio( 1.0 ),
m_CurveSegCount( 0 ),
m_WidthtoSizeFilterRatio( 0.9 )
{
}
@ -65,7 +66,7 @@ public:
void SetTeardropMaxSize( int aMaxLen, int aMaxHeight )
{
m_TdMaxLen = aMaxLen;
m_TdMaxHeight = aMaxHeight;
m_TdMaxWidth = aMaxHeight;
}
/**
@ -75,8 +76,8 @@ public:
*/
void SetTeardropSizeRatio( double aLenghtRatio = 0.5, double aHeightRatio = 1.0 )
{
m_LengthRatio = aLenghtRatio;
m_HeightRatio = aHeightRatio;
m_BestLengthRatio = aLenghtRatio;
m_BestWidthRatio = aHeightRatio;
}
/**
@ -91,21 +92,25 @@ public:
bool IsCurved() const { return m_CurveSegCount > 2; }
public:
TARGET_TD m_TdType; /// the type of target for these parameters
bool m_Enabled;
/// True to create teardrops using 2 track segments if the first in too small
bool m_AllowUseTwoTracks;
/// max allowed length for teardrops in IU. <= 0 to disable
int m_TdMaxLen;
/// max allowed height for teardrops in IU. <= 0 to disable
int m_TdMaxHeight;
int m_TdMaxWidth;
/// The length of a teardrop as ratio between length and size of pad/via
double m_LengthRatio;
double m_BestLengthRatio;
/// The height of a teardrop as ratio between height and size of pad/via
double m_HeightRatio;
double m_BestWidthRatio;
/// number of segments to build the curved sides of a teardrop area
/// must be > 2. for values <= 2 a straight line is used
int m_CurveSegCount;
/// The ratio (H/D) between the via/pad size and the track width max value to create a teardrop
/// 1.0 (100 %) always creates a teardrop, 0.0 (0%) never create a teardrop
double m_WidthtoSizeFilterRatio;
/// A filter to exclude pads inside zone fills
bool m_TdOnPadsInZones;
};
@ -128,28 +133,17 @@ public:
bool m_TargetTrack2Track;
/// True to create teardrops for round shapes only
bool m_UseRoundShapesOnly;
/// True to create teardrops using 2 track segments if the first in too small
bool m_AllowUseTwoTracks;
/// the number of segments to apprximate a curve (Bezier curve) in a teardrop
/// Must be > 2, otherwise a line is used
int m_CurveSegCount;
/// Pads inside a zone of the same net do not have teardrop added.
/// if this option is true, these pads will have teardrop added.
bool m_TdOnPadsInZones;
public:
TEARDROP_PARAMETERS_LIST() :
m_TargetViasPads( true ),
m_TargetPadsWithNoHole( true ),
m_TargetTrack2Track( false ),
m_UseRoundShapesOnly( false ),
m_AllowUseTwoTracks( true ),
m_CurveSegCount( 5 ),
m_TdOnPadsInZones( false )
m_UseRoundShapesOnly( false )
{
m_params_list.emplace_back( TARGET_ROUND ); // parameters for TARGET_ROUND
m_params_list.emplace_back( TARGET_RECT ); // parameters for TARGET_RECT
m_params_list.emplace_back( TARGET_TRACK ); // parameters for TARGET_TRACK
m_params_list.emplace_back(); // parameters for TARGET_ROUND
m_params_list.emplace_back(); // parameters for TARGET_RECT
m_params_list.emplace_back(); // parameters for TARGET_TRACK
}
/**

View File

@ -32,6 +32,7 @@
#include <pad.h>
#include <zone_filler.h>
#include <board_commit.h>
#include <drc/drc_rtree.h>
#include "teardrop.h"
#include <geometry/convex_hull.h>
@ -61,104 +62,56 @@ void TRACK_BUFFER::AddTrack( PCB_TRACK* aTrack, int aLayer, int aNetcode )
}
VIAPAD::VIAPAD( PCB_VIA* aVia ) :
m_Parent( aVia )
int TEARDROP_MANAGER::GetWidth( BOARD_ITEM* aItem )
{
m_Pos = aVia->GetPosition();
m_Width = aVia->GetWidth();
m_Drill = aVia->GetDrillValue();
m_NetCode = aVia->GetNetCode();
m_IsRound = true;
m_IsPad = false;
}
VIAPAD::VIAPAD( PAD* aPad ) :
m_Parent( aPad )
{
m_Pos = aPad->GetPosition();
m_Width = std::min( aPad->GetSize().x, aPad->GetSize().y );
m_Drill = std::min( aPad->GetDrillSizeX(), aPad->GetDrillSizeY() );
m_NetCode = aPad->GetNetCode();
m_IsRound = aPad->GetShape() == PAD_SHAPE::CIRCLE ||
( aPad->GetShape() == PAD_SHAPE::OVAL
&& aPad->GetSize().x == aPad->GetSize().y );
m_IsPad = true;
}
VIAPAD::VIAPAD( PCB_TRACK* aTrack, ENDPOINT_T aEndPoint ) :
m_Parent( aTrack )
{
m_Pos = aEndPoint == ENDPOINT_START ? aTrack->GetStart() : aTrack->GetEnd();
m_Width =aTrack->GetWidth();
m_Drill = 0;
m_NetCode = aTrack->GetNetCode();
m_IsRound = true;
m_IsPad = false;
}
void TEARDROP_MANAGER::collectVias( std::vector< VIAPAD >& aList ) const
{
for( PCB_TRACK* item : m_board->Tracks() )
if( aItem->Type() == PCB_VIA_T )
{
if( item->Type() != PCB_VIA_T )
continue;
aList.emplace_back( static_cast<PCB_VIA*>( item ) );
PCB_VIA* via = static_cast<PCB_VIA*>( aItem );
return via->GetWidth();
}
else if( aItem->Type() == PCB_PAD_T )
{
PAD* pad = static_cast<PAD*>( aItem );
return std::min( pad->GetSize().x, pad->GetSize().y );
}
else if( aItem->Type() == PCB_TRACE_T || aItem->Type() == PCB_ARC_T )
{
PCB_TRACK* track = static_cast<PCB_TRACK*>( aItem );
return track->GetWidth();
}
return 0;
}
void TEARDROP_MANAGER::collectPadsCandidate( std::vector< VIAPAD >& aList,
bool aDrilledViaPad,
bool aRoundShapesOnly,
bool aIncludeNotDrilled ) const
bool TEARDROP_MANAGER::IsRound( BOARD_ITEM* aItem )
{
for( FOOTPRINT* fp : m_board->Footprints() )
if( aItem->Type() == PCB_PAD_T )
{
for( PAD* pad : fp->Pads() )
PAD* pad = static_cast<PAD*>( aItem );
return pad->GetShape() == PAD_SHAPE::CIRCLE
|| ( pad->GetShape() == PAD_SHAPE::OVAL && pad->GetSize().x == pad->GetSize().y );
}
return true;
}
void TEARDROP_MANAGER::buildTrackCaches()
{
for( PCB_TRACK* track : m_board->Tracks() )
{
if( track->Type() == PCB_TRACE_T || track->Type() == PCB_ARC_T )
{
if( !pad->IsOnCopperLayer() )
continue;
if( pad->GetNetCode() <= 0 ) // Not connected, so a teardrop cannot be attached
continue;
if( pad->GetShape() == PAD_SHAPE::CUSTOM ) // A teardrop shape cannot be built
continue;
if( aRoundShapesOnly )
{
bool round_shape = pad->GetShape() == PAD_SHAPE::CIRCLE
|| ( pad->GetShape() == PAD_SHAPE::OVAL
&& pad->GetSize().x == pad->GetSize().y );
if( !round_shape )
continue;
}
if( pad->HasHole() && !aDrilledViaPad )
continue;
if( pad->HasHole() || aIncludeNotDrilled )
aList.emplace_back( pad );
m_tracksRTree.Insert( track, track->GetLayer() );
m_trackLookupList.AddTrack( track, track->GetLayer(), track->GetNetCode() );
}
}
}
void TEARDROP_MANAGER::collectTeardrops( std::vector< ZONE* >& aList ) const
{
for( ZONE* zone : m_board->Zones() )
{
if( zone->IsTeardropArea() )
aList.push_back( zone );
}
}
bool TEARDROP_MANAGER::isViaAndTrackInSameZone( VIAPAD& aViapad, PCB_TRACK* aTrack ) const
bool TEARDROP_MANAGER::areItemsInSameZone( BOARD_ITEM* aPadOrVia, PCB_TRACK* aTrack ) const
{
for( ZONE* zone: m_board->Zones() )
{
@ -172,12 +125,12 @@ bool TEARDROP_MANAGER::isViaAndTrackInSameZone( VIAPAD& aViapad, PCB_TRACK* aTra
if( zone->GetNetCode() == aTrack->GetNetCode() )
{
if( zone->Outline()->Contains( VECTOR2I( aViapad.m_Pos ) ) )
if( zone->Outline()->Contains( VECTOR2I( aPadOrVia->GetPosition() ) ) )
{
// Ensure the pad (if it is a pad) can be connected by the zone
if( aViapad.m_IsPad )
// If the first item is a pad, ensure it can be connected to the zone
if( aPadOrVia->Type() == PCB_PAD_T )
{
PAD *pad = static_cast< PAD* >( aViapad.m_Parent );
PAD *pad = static_cast<PAD*>( aPadOrVia );
if( zone->GetPadConnection() == ZONE_CONNECTION::NONE
|| pad->GetZoneConnection() == ZONE_CONNECTION::NONE )
@ -196,52 +149,53 @@ bool TEARDROP_MANAGER::isViaAndTrackInSameZone( VIAPAD& aViapad, PCB_TRACK* aTra
PCB_TRACK* TEARDROP_MANAGER::findTouchingTrack( EDA_ITEM_FLAGS& aMatchType, PCB_TRACK* aTrackRef,
const VECTOR2I& aEndPoint,
TRACK_BUFFER& aTrackLookupList ) const
const VECTOR2I& aEndPoint ) const
{
EDA_ITEM_FLAGS match = 0; // to return the end point EDA_ITEM_FLAGS:
// 0, STARTPOINT, ENDPOINT
int matches = 0; // Count of candidates: only 1 is acceptable
PCB_TRACK* candidate = nullptr; // a reference to the track connected
std::vector<PCB_TRACK*>* currlist = aTrackLookupList.GetTrackList( aTrackRef->GetLayer(),
aTrackRef->GetNetCode() );
for( PCB_TRACK* curr_track: *currlist )
{
if( curr_track == aTrackRef )
continue;
match = curr_track->IsPointOnEnds( aEndPoint, m_tolerance);
if( match )
{
// if faced with a Y junction, choose the track longest segment as candidate
matches++;
if( matches > 1 )
m_tracksRTree.QueryColliding( aTrackRef, aTrackRef->GetLayer(), aTrackRef->GetLayer(),
// Filter:
[&]( BOARD_ITEM* trackItem ) -> bool
{
double previous_len = candidate->GetLength();
double curr_len = curr_track->GetLength();
return trackItem != aTrackRef;
},
// Visitor
[&]( BOARD_ITEM* trackItem ) -> bool
{
PCB_TRACK* curr_track = static_cast<PCB_TRACK*>( trackItem );
if( previous_len >= curr_len )
continue;
}
// IsPointOnEnds() returns 0, EDA_ITEM_FLAGS::STARTPOINT or EDA_ITEM_FLAGS::ENDPOINT
if( EDA_ITEM_FLAGS match = curr_track->IsPointOnEnds( aEndPoint, m_tolerance ) )
{
// if faced with a Y junction, choose the track longest segment as candidate
matches++;
aMatchType = match;
candidate = curr_track;
}
}
if( matches > 1 )
{
double previous_len = candidate->GetLength();
double curr_len = curr_track->GetLength();
if( previous_len >= curr_len )
return true;
}
aMatchType = match;
candidate = curr_track;
}
return true;
},
0 );
return candidate;
}
/**
* @return a vector unit length from aVector
*/
static VECTOR2D NormalizeVector( VECTOR2I aVector )
static VECTOR2D NormalizeVector( const VECTOR2I& aVector )
{
VECTOR2D vect( aVector );
double norm = vect.EuclideanNorm();
@ -254,36 +208,36 @@ static VECTOR2D NormalizeVector( VECTOR2I aVector )
* The Bezier curve control points are optimized for a round pad/via shape,
* and do not give a good curve shape for other pad shapes
*/
void TEARDROP_MANAGER::computeCurvedForRoundShape( TEARDROP_PARAMETERS* aCurrParams,
void TEARDROP_MANAGER::computeCurvedForRoundShape( const TEARDROP_PARAMETERS& aParams,
std::vector<VECTOR2I>& aPoly,
int aTrackHalfWidth,
VECTOR2D aTrackDir, VIAPAD& aViaPad,
int aTrackHalfWidth, const VECTOR2D& aTrackDir,
BOARD_ITEM* aOther, const VECTOR2I& aOtherPos,
std::vector<VECTOR2I>& pts ) const
{
// in pts:
// A and B are points on the track ( pts[0] and pts[1] )
// C and E are points on the aViaPad ( pts[2] and pts[4] )
// D is the aViaPad centre ( pts[3] )
double Vpercent = aCurrParams->m_HeightRatio;
int td_height = aViaPad.m_Width * Vpercent;
double Vpercent = aParams.m_BestWidthRatio;
int td_height = KiROUND( GetWidth( aOther ) * Vpercent );
// First, calculate a aVpercent equivalent to the td_height clamped by aTdMaxHeight
// We cannot use the initial aVpercent because it gives bad shape with points
// on aViaPad calculated for a clamped aViaPad size
if( aCurrParams->m_TdMaxHeight > 0 && aCurrParams->m_TdMaxHeight < td_height )
Vpercent *= (double)aCurrParams->m_TdMaxHeight / td_height;
if( aParams.m_TdMaxWidth > 0 && aParams.m_TdMaxWidth < td_height )
Vpercent *= (double) aParams.m_TdMaxWidth / td_height;
int radius = aViaPad.m_Width / 2;
int radius = GetWidth( aOther ) / 2;
double minVpercent = double( aTrackHalfWidth ) / radius;
double weaken = (Vpercent - minVpercent) / ( 1 - minVpercent ) / radius;
double biasBC = 0.5 * SEG( pts[1], pts[2] ).Length();
double biasAE = 0.5 * SEG( pts[4], pts[0] ).Length();
VECTOR2I vecC = (VECTOR2I)pts[2] - aViaPad.m_Pos;
VECTOR2I vecC = (VECTOR2I)pts[2] - aOtherPos;
VECTOR2I tangentC = VECTOR2I( pts[2].x - vecC.y * biasBC * weaken,
pts[2].y + vecC.x * biasBC * weaken );
VECTOR2I vecE = (VECTOR2I)pts[4] - aViaPad.m_Pos;
VECTOR2I vecE = (VECTOR2I)pts[4] - aOtherPos;
VECTOR2I tangentE = VECTOR2I( pts[4].x + vecE.y * biasAE * weaken,
pts[4].y - vecE.x * biasAE * weaken );
@ -291,9 +245,8 @@ void TEARDROP_MANAGER::computeCurvedForRoundShape( TEARDROP_PARAMETERS* aCurrPar
VECTOR2I tangentA = VECTOR2I( pts[0].x - aTrackDir.x * biasAE, pts[0].y - aTrackDir.y * biasAE );
std::vector<VECTOR2I> curve_pts;
curve_pts.reserve( aCurrParams->m_CurveSegCount );
BEZIER_POLY( pts[1], tangentB, tangentC, pts[2] ).GetPoly( curve_pts, 0,
aCurrParams->m_CurveSegCount );
curve_pts.reserve( aParams.m_CurveSegCount );
BEZIER_POLY( pts[1], tangentB, tangentC, pts[2] ).GetPoly( curve_pts, 0, aParams.m_CurveSegCount );
for( VECTOR2I& corner: curve_pts )
aPoly.push_back( corner );
@ -301,8 +254,7 @@ void TEARDROP_MANAGER::computeCurvedForRoundShape( TEARDROP_PARAMETERS* aCurrPar
aPoly.push_back( pts[3] );
curve_pts.clear();
BEZIER_POLY( pts[4], tangentE, tangentA, pts[0] ).GetPoly( curve_pts, 0,
aCurrParams->m_CurveSegCount );
BEZIER_POLY( pts[4], tangentE, tangentA, pts[0] ).GetPoly( curve_pts, 0, aParams.m_CurveSegCount );
for( VECTOR2I& corner: curve_pts )
aPoly.push_back( corner );
@ -313,10 +265,10 @@ void TEARDROP_MANAGER::computeCurvedForRoundShape( TEARDROP_PARAMETERS* aCurrPar
* Compute the curve part points for teardrops connected to a rectangular/polygonal shape
* The Bezier curve control points are not optimized for a special shape
*/
void TEARDROP_MANAGER::computeCurvedForRectShape( TEARDROP_PARAMETERS* aCurrParams,
std::vector<VECTOR2I>& aPoly, int aTdHeight,
int aTrackHalfWidth, VIAPAD& aViaPad,
std::vector<VECTOR2I>& aPts ) const
void TEARDROP_MANAGER::computeCurvedForRectShape( const TEARDROP_PARAMETERS& aParams,
std::vector<VECTOR2I>& aPoly, int aTdWidth,
int aTrackHalfWidth,
std::vector<VECTOR2I>& aPts ) const
{
// in aPts:
// A and B are points on the track ( pts[0] and pts[1] )
@ -329,7 +281,7 @@ void TEARDROP_MANAGER::computeCurvedForRectShape( TEARDROP_PARAMETERS* aCurrPar
VECTOR2I side2( aPts[4] - aPts[0] ); // vector from track to via
std::vector<VECTOR2I> curve_pts;
curve_pts.reserve( aCurrParams->m_CurveSegCount );
curve_pts.reserve( aParams.m_CurveSegCount );
// Note: This side is from track to via
VECTOR2I ctrl1 = ( aPts[1] + aPts[1] + aPts[2] ) / 3;
@ -338,7 +290,7 @@ void TEARDROP_MANAGER::computeCurvedForRectShape( TEARDROP_PARAMETERS* aCurrPar
// The control points must be moved toward the polygon inside, in order to give a curved shape
// The move vector is perpendicular to the vertex (side 1 or side 2), and its
// value is delta, depending on the sizes of via and track
int delta = ( aTdHeight / 2 - aTrackHalfWidth );
int delta = ( aTdWidth / 2 - aTrackHalfWidth );
delta /= 4; // A scaling factor giving a fine shape, defined from tests.
// However for short sides, the value of delta must be reduced, depending
@ -363,8 +315,7 @@ void TEARDROP_MANAGER::computeCurvedForRectShape( TEARDROP_PARAMETERS* aCurrPar
ctrl2.x += bias.x;
ctrl2.y += bias.y;
BEZIER_POLY( aPts[1], ctrl1, ctrl2, aPts[2] ).GetPoly( curve_pts, 0,
aCurrParams->m_CurveSegCount );
BEZIER_POLY( aPts[1], ctrl1, ctrl2, aPts[2] ).GetPoly( curve_pts, 0, aParams.m_CurveSegCount );
for( VECTOR2I& corner: curve_pts )
aPoly.push_back( corner );
@ -392,65 +343,59 @@ void TEARDROP_MANAGER::computeCurvedForRectShape( TEARDROP_PARAMETERS* aCurrPar
ctrl2.x += bias.x;
ctrl2.y += bias.y;
BEZIER_POLY( aPts[4], ctrl1, ctrl2, aPts[0] ).GetPoly( curve_pts, 0,
aCurrParams->m_CurveSegCount );
BEZIER_POLY( aPts[4], ctrl1, ctrl2, aPts[0] ).GetPoly( curve_pts, 0, aParams.m_CurveSegCount );
for( VECTOR2I& corner: curve_pts )
aPoly.push_back( corner );
}
bool TEARDROP_MANAGER::ComputePointsOnPadVia( TEARDROP_PARAMETERS* aCurrParams,
PCB_LAYER_ID aLayer,
VIAPAD& aViaPad,
std::vector<VECTOR2I>& aPts ) const
bool TEARDROP_MANAGER::computeAnchorPoints( const TEARDROP_PARAMETERS& aParams, PCB_LAYER_ID aLayer,
BOARD_ITEM* aItem, const VECTOR2I& aPos,
std::vector<VECTOR2I>& aPts ) const
{
// Compute the 2 anchor points on pad/via of the teardrop shape
// Compute the 2 anchor points on pad/via/track of the teardrop shape
PAD* pad = ( aViaPad.m_Parent->Type() == PCB_PAD_T ) ? static_cast<PAD*>(aViaPad.m_Parent)
: nullptr;
SHAPE_POLY_SET c_buffer;
// aHeightRatio is the factor to calculate the aViaPad teardrop preferred height
// teardrop height = aViaPad size * aHeightRatio (aHeightRatio <= 1.0)
// For rectangular (and similar) shapes, the preferred_height is calculated from the min
// dim of the rectangle = aViaPad.m_Width
// m_BestWidthRatio is the factor to calculate the teardrop preferred width.
// teardrop width = pad, via or track size * m_BestWidthRatio (m_BestWidthRatio <= 1.0)
// For rectangular (and similar) shapes, the preferred_width is calculated from the min
// dim of the rectangle
int preferred_height = aViaPad.m_Width * aCurrParams->m_HeightRatio;
int preferred_width = KiROUND( GetWidth( aItem ) * aParams.m_BestWidthRatio );
// force_clip_shape = true to force the via/pad polygon to be clipped to follow
// force_clip = true to force the pad/via/track polygon to be clipped to follow
// constraints
// Clipping is also needed for rectangular shapes, because the teardrop shape is
// restricted to a polygonal area smaller than the pad area (the teardrop height
// use the smaller value of X and Y sizes).
bool force_clip_shape = aCurrParams->m_HeightRatio < 1.0;
// Clipping is also needed for rectangular shapes, because the teardrop shape is restricted
// to a polygonal area smaller than the pad area (the teardrop height use the smaller value
// of X and Y sizes).
bool force_clip = aParams.m_BestWidthRatio < 1.0;
// To find the anchor points on via/pad shape, we build the polygonal shape, and clip the polygon
// to the max size (preferred_height or m_TdMaxHeight) by a rectangle centered on the
// axis of the expected teardrop shape.
// To find the anchor points on the pad/via/track shape, we build the polygonal shape, and
// clip the polygon to the max size (preferred_width or m_TdMaxWidth) by a rectangle
// centered on the axis of the expected teardrop shape.
// (only reduce the size of polygonal shape does not give good anchor points)
if( aViaPad.m_IsRound )
if( IsRound( aItem ) )
{
TransformCircleToPolygon( c_buffer, aViaPad.m_Pos, aViaPad.m_Width/2 ,
ARC_LOW_DEF, ERROR_INSIDE, 16 );
TransformCircleToPolygon( c_buffer, aPos, GetWidth( aItem ) / 2, ARC_LOW_DEF,
ERROR_INSIDE, 16 );
}
else // Only PADS can have a not round shape
{
wxCHECK( pad, false );
PAD* pad = static_cast<PAD*>( aItem );
force_clip_shape = true;
force_clip = true;
preferred_height = aViaPad.m_Width * aCurrParams->m_HeightRatio;
preferred_width = KiROUND( GetWidth( pad ) * aParams.m_BestWidthRatio );
pad->TransformShapeToPolygon( c_buffer, aLayer, 0, ARC_LOW_DEF, ERROR_INSIDE );
}
// Clip the pad/via shape to match the m_TdMaxHeight constraint, and for
// not rounded pad, clip the shape at the aViaPad.m_Width, i.e. the value
// of the smallest value between size.x and size.y values.
if( force_clip_shape || ( aCurrParams->m_TdMaxHeight > 0
&& aCurrParams->m_TdMaxHeight < preferred_height ) )
// Clip the pad/via/track shape to match the m_TdMaxWidth constraint, and for non-round pads,
// clip the shape to the smallest of size.x and size.y values.
if( force_clip || ( aParams.m_TdMaxWidth > 0 && aParams.m_TdMaxWidth < preferred_width ) )
{
int halfsize = std::min( aCurrParams->m_TdMaxHeight, preferred_height )/2;
int halfsize = std::min( aParams.m_TdMaxWidth, preferred_width )/2;
// teardrop_axis is the line from anchor point on the track and the end point
// of the teardrop in the pad/via
@ -463,7 +408,7 @@ bool TEARDROP_MANAGER::ComputePointsOnPadVia( TEARDROP_PARAMETERS* aCurrParams,
// Build the constraint polygon: a rectangle with
// length = dist between the point on track and the pad/via pos
// height = m_TdMaxHeight or aViaPad.m_Width
// height = m_TdMaxWidth or aViaPad.m_Width
SHAPE_POLY_SET clipping_rect;
clipping_rect.NewOutline();
@ -585,30 +530,29 @@ bool TEARDROP_MANAGER::ComputePointsOnPadVia( TEARDROP_PARAMETERS* aCurrParams,
}
bool TEARDROP_MANAGER::findAnchorPointsOnTrack( TEARDROP_PARAMETERS* aCurrParams,
bool TEARDROP_MANAGER::findAnchorPointsOnTrack( const TEARDROP_PARAMETERS& aParams,
VECTOR2I& aStartPoint, VECTOR2I& aEndPoint,
PCB_TRACK*& aTrack, VIAPAD& aViaPad,
int* aEffectiveTeardropLen,
bool aFollowTracks,
TRACK_BUFFER& aTrackLookupList ) const
PCB_TRACK*& aTrack, BOARD_ITEM* aOther,
const VECTOR2I& aOtherPos,
int* aEffectiveTeardropLen ) const
{
bool found = true;
VECTOR2I start = aTrack->GetStart(); // one reference point on the track, inside teardrop
VECTOR2I end = aTrack->GetEnd(); // the second reference point on the track, outside teardrop
int radius = aViaPad.m_Width / 2;
int radius = GetWidth( aOther ) / 2;
// Requested length of the teardrop:
int targetLength = aViaPad.m_Width * aCurrParams->m_LengthRatio;
int targetLength = KiROUND( GetWidth( aOther ) * aParams.m_BestLengthRatio );
if( aCurrParams->m_TdMaxLen > 0 )
targetLength = std::min( aCurrParams->m_TdMaxLen, targetLength );
if( aParams.m_TdMaxLen > 0 )
targetLength = std::min( aParams.m_TdMaxLen, targetLength );
// actualTdLen is the distance between start and the teardrop point on the segment from start to end
int actualTdLen;
bool need_swap = false; // true if the start and end points of the current track are swapped
// ensure that start is at the via/pad end
if( SEG( end, aViaPad.m_Pos ).Length() < radius )
if( SEG( end, aOtherPos ).Length() < radius )
{
std::swap( start, end );
need_swap = true;
@ -616,16 +560,14 @@ bool TEARDROP_MANAGER::findAnchorPointsOnTrack( TEARDROP_PARAMETERS* aCurrParams
SHAPE_POLY_SET shapebuffer;
if( aViaPad.m_IsRound )
if( IsRound( aOther ) )
{
TransformCircleToPolygon( shapebuffer, aViaPad.m_Pos, radius,
ARC_LOW_DEF, ERROR_INSIDE, 16 );
TransformCircleToPolygon( shapebuffer, aOtherPos, radius, ARC_LOW_DEF, ERROR_INSIDE, 16 );
}
else
{
PAD* pad = static_cast<PAD*>( aViaPad.m_Parent );
pad->TransformShapeToPolygon( shapebuffer, aTrack->GetLayer(), 0,
ARC_LOW_DEF, ERROR_INSIDE );
static_cast<PAD*>( aOther )->TransformShapeToPolygon( shapebuffer, aTrack->GetLayer(), 0,
ARC_LOW_DEF, ERROR_INSIDE );
}
SHAPE_LINE_CHAIN& outline = shapebuffer.Outline(0);
@ -651,15 +593,15 @@ bool TEARDROP_MANAGER::findAnchorPointsOnTrack( TEARDROP_PARAMETERS* aCurrParams
// If the first track is too short to allow a teardrop having the requested length
// explore the connected track(s), and try to find a anchor point at targetLength from initial start
if( actualTdLen < targetLength && aFollowTracks )
if( actualTdLen < targetLength && aParams.m_AllowUseTwoTracks )
{
int consumed = 0;
while( actualTdLen+consumed < targetLength )
while( actualTdLen + consumed < targetLength )
{
EDA_ITEM_FLAGS matchType;
PCB_TRACK* connected_track = findTouchingTrack( matchType, aTrack, end, aTrackLookupList );
PCB_TRACK* connected_track = findTouchingTrack( matchType, aTrack, end );
if( connected_track == nullptr )
break;
@ -752,21 +694,18 @@ bool TEARDROP_MANAGER::findAnchorPointsOnTrack( TEARDROP_PARAMETERS* aCurrParams
}
bool TEARDROP_MANAGER::computeTeardropPolygonPoints( TEARDROP_PARAMETERS* aCurrParams,
std::vector<VECTOR2I>& aCorners,
PCB_TRACK* aTrack, VIAPAD& aViaPad,
bool aFollowTracks,
TRACK_BUFFER& aTrackLookupList ) const
bool TEARDROP_MANAGER::computeTeardropPolygon( const TEARDROP_PARAMETERS& aParams,
std::vector<VECTOR2I>& aCorners, PCB_TRACK* aTrack,
BOARD_ITEM* aOther, const VECTOR2I& aOtherPos ) const
{
VECTOR2I start, end; // Start and end points of the track anchor of the teardrop
VECTOR2I start, end; // Start and end points of the track anchor of the teardrop
// the start point is inside the teardrop shape
// the end point is outside.
int track_stub_len; // the dist between the start point and the anchor point
// on the track
// Note: aTrack can be modified if the initial track is too short
if( !findAnchorPointsOnTrack( aCurrParams, start, end, aTrack, aViaPad, &track_stub_len,
aFollowTracks, aTrackLookupList ) )
if( !findAnchorPointsOnTrack( aParams, start, end, aTrack, aOther, aOtherPos, &track_stub_len ) )
return false;
// The start and end points must be different to calculate a valid polygon shape
@ -784,9 +723,9 @@ bool TEARDROP_MANAGER::computeTeardropPolygonPoints( TEARDROP_PARAMETERS* aCurrP
// To build a polygonal valid shape pointA and point B must be outside the pad
// It can be inside with some pad shapes having very different X and X sizes
if( !aViaPad.m_IsRound )
if( !IsRound( aOther ) )
{
PAD* pad = static_cast<PAD*>( aViaPad.m_Parent );
PAD* pad = static_cast<PAD*>( aOther );
if( pad->HitTest( pointA ) )
return false;
@ -796,7 +735,7 @@ bool TEARDROP_MANAGER::computeTeardropPolygonPoints( TEARDROP_PARAMETERS* aCurrP
}
// Introduce a last point to cover the via centre to ensure it is seen as connected
VECTOR2I pointD = aViaPad.m_Pos;
VECTOR2I pointD = aOtherPos;
// add a small offset in order to have the aViaPad.m_Pos reference point inside
// the teardrop area, just in case...
int offset = pcbIUScale.mmToIU( 0.001 );
@ -805,28 +744,27 @@ bool TEARDROP_MANAGER::computeTeardropPolygonPoints( TEARDROP_PARAMETERS* aCurrP
VECTOR2I pointC, pointE; // Point on PADVIA outlines
std::vector<VECTOR2I> pts = {pointA, pointB, pointC, pointD, pointE};
ComputePointsOnPadVia( aCurrParams, aTrack->GetLayer(), aViaPad, pts );
computeAnchorPoints( aParams, aTrack->GetLayer(), aOther, aOtherPos, pts );
if( !aCurrParams->IsCurved() )
if( !aParams.IsCurved() )
{
aCorners = pts;
return true;
}
// See if we can use curved teardrop shape
if( aViaPad.m_IsRound )
if( IsRound( aOther ) )
{
computeCurvedForRoundShape( aCurrParams, aCorners, track_halfwidth, vecT, aViaPad, pts );
computeCurvedForRoundShape( aParams, aCorners, track_halfwidth, vecT, aOther, aOtherPos, pts );
}
else
{
int td_height = aViaPad.m_Width * aCurrParams->m_HeightRatio;
int td_width = KiROUND( GetWidth( aOther ) * aParams.m_BestWidthRatio );
if( aCurrParams->m_TdMaxHeight > 0 && aCurrParams->m_TdMaxHeight < td_height )
td_height = aCurrParams->m_TdMaxHeight;
if( aParams.m_TdMaxWidth > 0 && aParams.m_TdMaxWidth < td_width )
td_width = aParams.m_TdMaxWidth;
computeCurvedForRectShape( aCurrParams, aCorners, td_height, track_halfwidth,
aViaPad, pts );
computeCurvedForRectShape( aParams, aCorners, td_width, track_halfwidth, pts );
}
return true;

View File

@ -223,6 +223,7 @@ void GLOBAL_EDIT_TOOL::setTransitions()
Go( &GLOBAL_EDIT_TOOL::EditTracksAndVias, PCB_ACTIONS::editTracksAndVias.MakeEvent() );
Go( &GLOBAL_EDIT_TOOL::EditTextAndGraphics, PCB_ACTIONS::editTextAndGraphics.MakeEvent() );
Go( &GLOBAL_EDIT_TOOL::EditTeardrops, PCB_ACTIONS::editTeardrops.MakeEvent() );
Go( &GLOBAL_EDIT_TOOL::GlobalDeletions, PCB_ACTIONS::globalDeletions.MakeEvent() );
Go( &GLOBAL_EDIT_TOOL::CleanupTracksAndVias, PCB_ACTIONS::cleanupTracksAndVias.MakeEvent() );
Go( &GLOBAL_EDIT_TOOL::CleanupGraphics, PCB_ACTIONS::cleanupGraphics.MakeEvent() );

View File

@ -58,6 +58,7 @@ public:
int EditTracksAndVias( const TOOL_EVENT& aEvent );
int EditTextAndGraphics( const TOOL_EVENT& aEvent );
int EditTeardrops( const TOOL_EVENT& aEvent );
int GlobalDeletions( const TOOL_EVENT& aEvent );
int CleanupTracksAndVias( const TOOL_EVENT& aEvent );
int CleanupGraphics( const TOOL_EVENT& aEvent );

View File

@ -505,6 +505,12 @@ TOOL_ACTION PCB_ACTIONS::editTextAndGraphics( "pcbnew.GlobalEdit.editTextAndGrap
_( "Edit Text and graphics properties globally across board" ),
BITMAPS::text );
TOOL_ACTION PCB_ACTIONS::editTeardrops( "pcbnew.GlobalEdit.editTeardrops",
AS_GLOBAL, 0, "",
_( "Edit Teardrops..." ),
_( "Add, remove or edit teardrops globally across board" ),
BITMAPS::via );
TOOL_ACTION PCB_ACTIONS::globalDeletions( "pcbnew.GlobalEdit.globalDeletions",
AS_GLOBAL, 0, "",
_( "Global Deletions..." ),

View File

@ -358,6 +358,7 @@ public:
static TOOL_ACTION boardSetup;
static TOOL_ACTION editTracksAndVias;
static TOOL_ACTION editTextAndGraphics;
static TOOL_ACTION editTeardrops;
static TOOL_ACTION globalDeletions;
static TOOL_ACTION cleanupTracksAndVias;
static TOOL_ACTION cleanupGraphics;

View File

@ -2437,6 +2437,11 @@ bool PCB_SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibili
zone = static_cast<const ZONE*>( aItem );
// A teardrop is modelled as a property of a via, pad or the board (for track-to-track
// teardrops). The underlying zone is only an implementation detail.
if( zone->IsTeardropArea() && !board()->LegacyTeardrops() )
return false;
// A footprint zone is only selectable within the footprint editor
if( zone->GetParent()
&& zone->GetParent()->Type() == PCB_FOOTPRINT_T

View File

@ -42,6 +42,7 @@
#include "pcb_actions.h"
#include "zone_filler_tool.h"
#include "zone_filler.h"
#include "teardrop/teardrop.h"
#include <profile.h>
ZONE_FILLER_TOOL::ZONE_FILLER_TOOL() :
@ -115,21 +116,23 @@ void ZONE_FILLER_TOOL::singleShotRefocus( wxIdleEvent& )
void ZONE_FILLER_TOOL::FillAllZones( wxWindow* aCaller, PROGRESS_REPORTER* aReporter )
{
PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();
std::vector<ZONE*> toFill;
if( m_fillInProgress )
return;
m_fillInProgress = true;
for( ZONE* zone : board()->Zones() )
toFill.push_back( zone );
PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();
BOARD_COMMIT commit( this );
std::unique_ptr<WX_PROGRESS_REPORTER> reporter;
TEARDROP_MANAGER teardropMgr( board(), m_toolMgr );
std::vector<ZONE*> toFill;
teardropMgr.UpdateTeardrops( commit, nullptr, nullptr, true /* forceFullUpdate */ );
board()->IncrementTimeStamp(); // Clear caches
BOARD_COMMIT commit( this );
std::unique_ptr<WX_PROGRESS_REPORTER> reporter;
for( ZONE* zone : board()->Zones() )
toFill.push_back( zone );
m_filler = std::make_unique<ZONE_FILLER>( board(), &commit );

View File

@ -924,86 +924,97 @@ void ZONE::HatchBorder()
int hatch_line_len = m_borderHatchPitch;
// To have a better look, give a slope depending on the layer
int layer = GetFirstLayer();
int slope_flag = (layer & 1) ? 1 : -1; // 1 or -1
double slope = 0.707106 * slope_flag; // 45 degrees slope
int64_t max_a, min_a;
int layer = GetFirstLayer();
std::vector<int> slope_flags;
if( slope_flag == 1 )
{
max_a = KiROUND( max_y - slope * min_x );
min_a = KiROUND( min_y - slope * max_x );
}
if( IsTeardropArea() )
slope_flags = { 1, -1 };
else if( layer & 1 )
slope_flags = { 1 };
else
slope_flags = { -1 };
for( int slope_flag : slope_flags )
{
max_a = KiROUND( max_y - slope * max_x );
min_a = KiROUND( min_y - slope * min_x );
}
double slope = 0.707106 * slope_flag; // 45 degrees slope
int64_t max_a, min_a;
min_a = (min_a / spacing) * spacing;
// calculate an offset depending on layer number,
// for a better look of hatches on a multilayer board
int offset = (layer * 7) / 8;
min_a += offset;
// loop through hatch lines
std::vector<VECTOR2I> pointbuffer;
pointbuffer.reserve( 256 );
for( int64_t a = min_a; a < max_a; a += spacing )
{
pointbuffer.clear();
// Iterate through all vertices
for( auto iterator = m_Poly->IterateSegmentsWithHoles(); iterator; iterator++ )
if( slope_flag == 1 )
{
const SEG seg = *iterator;
double x, y;
if( FindLineSegmentIntersection( a, slope, seg.A.x, seg.A.y, seg.B.x, seg.B.y, x, y ) )
pointbuffer.emplace_back( KiROUND( x ), KiROUND( y ) );
max_a = KiROUND( max_y - slope * min_x );
min_a = KiROUND( min_y - slope * max_x );
}
else
{
max_a = KiROUND( max_y - slope * max_x );
min_a = KiROUND( min_y - slope * min_x );
}
// sort points in order of descending x (if more than 2) to
// ensure the starting point and the ending point of the same segment
// are stored one just after the other.
if( pointbuffer.size() > 2 )
sort( pointbuffer.begin(), pointbuffer.end(), sortEndsByDescendingX );
min_a = (min_a / spacing) * spacing;
// creates lines or short segments inside the complex polygon
for( size_t ip = 0; ip + 1 < pointbuffer.size(); ip += 2 )
// calculate an offset depending on layer number,
// for a better look of hatches on a multilayer board
int offset = (layer * 7) / 8;
min_a += offset;
// loop through hatch lines
std::vector<VECTOR2I> pointbuffer;
pointbuffer.reserve( 256 );
for( int64_t a = min_a; a < max_a; a += spacing )
{
int dx = pointbuffer[ip + 1].x - pointbuffer[ip].x;
pointbuffer.clear();
// Push only one line for diagonal hatch,
// or for small lines < twice the line length
// else push 2 small lines
if( m_borderStyle == ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_FULL
|| std::abs( dx ) < 2 * hatch_line_len )
// Iterate through all vertices
for( auto iterator = m_Poly->IterateSegmentsWithHoles(); iterator; iterator++ )
{
m_borderHatchLines.emplace_back( SEG( pointbuffer[ip], pointbuffer[ ip + 1] ) );
const SEG seg = *iterator;
double x, y;
if( FindLineSegmentIntersection( a, slope, seg.A.x, seg.A.y, seg.B.x, seg.B.y, x, y ) )
pointbuffer.emplace_back( KiROUND( x ), KiROUND( y ) );
}
else
// sort points in order of descending x (if more than 2) to
// ensure the starting point and the ending point of the same segment
// are stored one just after the other.
if( pointbuffer.size() > 2 )
sort( pointbuffer.begin(), pointbuffer.end(), sortEndsByDescendingX );
// creates lines or short segments inside the complex polygon
for( size_t ip = 0; ip + 1 < pointbuffer.size(); ip += 2 )
{
double dy = pointbuffer[ip + 1].y - pointbuffer[ip].y;
slope = dy / dx;
int dx = pointbuffer[ip + 1].x - pointbuffer[ip].x;
if( dx > 0 )
dx = hatch_line_len;
// Push only one line for diagonal hatch,
// or for small lines < twice the line length
// else push 2 small lines
if( m_borderStyle == ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_FULL
|| std::abs( dx ) < 2 * hatch_line_len )
{
m_borderHatchLines.emplace_back( SEG( pointbuffer[ip], pointbuffer[ ip + 1] ) );
}
else
dx = -hatch_line_len;
{
double dy = pointbuffer[ip + 1].y - pointbuffer[ip].y;
slope = dy / dx;
int x1 = KiROUND( pointbuffer[ip].x + dx );
int x2 = KiROUND( pointbuffer[ip + 1].x - dx );
int y1 = KiROUND( pointbuffer[ip].y + dx * slope );
int y2 = KiROUND( pointbuffer[ip + 1].y - dx * slope );
if( dx > 0 )
dx = hatch_line_len;
else
dx = -hatch_line_len;
m_borderHatchLines.emplace_back( SEG( pointbuffer[ip].x, pointbuffer[ip].y,
x1, y1 ) );
int x1 = KiROUND( pointbuffer[ip].x + dx );
int x2 = KiROUND( pointbuffer[ip + 1].x - dx );
int y1 = KiROUND( pointbuffer[ip].y + dx * slope );
int y2 = KiROUND( pointbuffer[ip + 1].y - dx * slope );
m_borderHatchLines.emplace_back( SEG( pointbuffer[ip+1].x, pointbuffer[ip+1].y,
x2, y2 ) );
m_borderHatchLines.emplace_back( SEG( pointbuffer[ip].x, pointbuffer[ip].y,
x1, y1 ) );
m_borderHatchLines.emplace_back( SEG( pointbuffer[ip+1].x, pointbuffer[ip+1].y,
x2, y2 ) );
}
}
}
}