Pad properties usability enhancements.

Also includes conversion to UNIT_BINDER for pad properties and
pad primitives properties dialogs.

(cherry picked from commit 4a051da)
This commit is contained in:
Jeff Young 2018-05-23 07:11:47 +01:00
parent 0010ad37d1
commit 1569842927
9 changed files with 3219 additions and 3689 deletions

View File

@ -51,7 +51,7 @@ UNIT_BINDER::UNIT_BINDER( EDA_DRAW_FRAME* aParent,
if( textEntry )
textEntry->SetValue( wxT( "0" ) );
m_unitLabel->SetLabel( GetAbbreviatedUnitsLabel( m_units, aUseMils ) );
m_unitLabel->SetLabel( GetAbbreviatedUnitsLabel( m_units, m_useMils ) );
m_value->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( UNIT_BINDER::onSetFocus ), NULL, this );
m_value->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( UNIT_BINDER::onKillFocus ), NULL, this );
@ -59,6 +59,14 @@ UNIT_BINDER::UNIT_BINDER( EDA_DRAW_FRAME* aParent,
}
void UNIT_BINDER::SetUnits( EDA_UNITS_T aUnits, bool aUseMils )
{
m_units = aUnits;
m_useMils = aUseMils;
m_unitLabel->SetLabel( GetAbbreviatedUnitsLabel( m_units, m_useMils ) );
}
void UNIT_BINDER::onSetFocus( wxFocusEvent& aEvent )
{
auto textEntry = dynamic_cast<wxTextEntry*>( m_value );
@ -236,3 +244,11 @@ void UNIT_BINDER::Enable( bool aEnable )
m_unitLabel->Enable( aEnable );
}
void UNIT_BINDER::Show( bool aShow )
{
m_label->Show( aShow );
m_value->Show( aShow );
m_unitLabel->Show( aShow );
}

View File

@ -66,6 +66,8 @@ void WIDGET_NET_SELECTOR::SetSelectedNet ( int aNetcode )
return;
}
}
SetSelection( 0 );
}

View File

@ -58,6 +58,13 @@ public:
int aMin = INT_MIN, int aMax = INT_MAX,
bool aAllowEval = true );
/**
* Function SetUnits
* Normally not needed (as the UNIT_BINDER inherits from the parent frame), but can be
* used to set to DEGREES for angular controls.
*/
virtual void SetUnits( EDA_UNITS_T aUnits, bool aUseMils = false );
/**
* Function SetValue
* Sets new value (in Internal Units) for the text field, taking care of units conversion.
@ -91,10 +98,16 @@ public:
/**
* Function Enable
* Enables/diasables the label, text input widget, and units label.
* Enables/diasables the label, widget and units label.
*/
void Enable( bool aEnable );
/**
* Function Show
* Shows/hides the label, widget and units label.
*/
void Show( bool aShow );
protected:
void onSetFocus( wxFocusEvent& aEvent );

View File

@ -37,23 +37,30 @@
#include <macros.h>
#include <pcb_base_frame.h>
#include <base_units.h>
#include <unit_format.h>
#include <gr_basic.h>
#include <class_board.h>
#include <class_module.h>
#include <dialog_pad_properties.h>
#include <bitmaps.h>
DIALOG_PAD_PRIMITIVES_PROPERTIES::DIALOG_PAD_PRIMITIVES_PROPERTIES(
wxWindow* aParent, PAD_CS_PRIMITIVE * aShape )
: DIALOG_PAD_PRIMITIVES_PROPERTIES_BASE( aParent )
DIALOG_PAD_PRIMITIVES_PROPERTIES::DIALOG_PAD_PRIMITIVES_PROPERTIES( wxWindow* aParent,
PCB_BASE_FRAME* aFrame,
PAD_CS_PRIMITIVE * aShape ) :
DIALOG_PAD_PRIMITIVES_PROPERTIES_BASE( aParent ),
m_shape( aShape ),
m_startX( aFrame, m_startXLabel, m_startXCtrl, m_startXUnits, true ),
m_startY( aFrame, m_startYLabel, m_startYCtrl, m_startYUnits, true ),
m_endX( aFrame, m_endXLabel, m_endXCtrl, m_endXUnits, true ),
m_endY( aFrame, m_endYLabel, m_endYCtrl, m_endYUnits, true ),
m_radius( aFrame, m_radiusLabel, m_radiusCtrl, m_radiusUnits, true ),
m_thickness( aFrame, m_thicknessLabel, m_thicknessCtrl, m_thicknessUnits, true )
{
m_shape = aShape;
TransferDataToWindow();
SetInitialFocus( m_startXCtrl );
m_sdbSizerOK->SetDefault();
GetSizer()->SetSizeHints( this );
FinishDialogSettings();
}
bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataToWindow()
@ -65,40 +72,29 @@ bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataToWindow()
if( m_shape->m_Shape != S_CIRCLE )
m_staticTextInfo->Show( false );
PutValueInLocalUnits( *m_textCtrlThickness, m_shape->m_Thickness );
// Update units and parameters names according to the shape to edit:
wxString unit = GetAbbreviatedUnitsLabel();
m_staticTextPosUnit->SetLabel( unit );
m_staticTextEndUnit->SetLabel( unit );
m_staticTextThicknessUnit->SetLabel( unit );
m_staticTextAngleUnit->SetLabel( wxEmptyString );
m_staticTextAngle->SetLabel( wxEmptyString );
m_thickness.SetValue( m_shape->m_Thickness );
switch( m_shape->m_Shape )
{
case S_SEGMENT: // Segment with rounded ends
SetTitle( _( "Segment" ) );
PutValueInLocalUnits( *m_textCtrPosX, m_shape->m_Start.x );
PutValueInLocalUnits( *m_textCtrPosY, m_shape->m_Start.y );
PutValueInLocalUnits( *m_textCtrEndX, m_shape->m_End.x );
PutValueInLocalUnits( *m_textCtrEndY, m_shape->m_End.y );
m_textCtrAngle->Show( false );
m_staticTextAngleUnit->Show( false );
m_staticTextAngle->Show( false );
m_startX.SetValue( m_shape->m_Start.x );
m_startY.SetValue( m_shape->m_Start.y );
m_endX.SetValue( m_shape->m_End.x );
m_endY.SetValue( m_shape->m_End.y );
m_radius.Show( false );
break;
case S_ARC: // Arc with rounded ends
SetTitle( _( "Arc" ) );
m_staticTextPosEnd->SetLabel( _( "Center" ) );
PutValueInLocalUnits( *m_textCtrEndX, m_shape->m_Start.x ); // Start point of arc
PutValueInLocalUnits( *m_textCtrEndY, m_shape->m_Start.y );
PutValueInLocalUnits( *m_textCtrPosX, m_shape->m_End.x ); // arc center
PutValueInLocalUnits( *m_textCtrPosY, m_shape->m_End.y );
m_textCtrAngle->SetValue( FMT_ANGLE( m_shape->m_ArcAngle ) );
m_staticTextAngle->SetLabel( _( "Angle" ) );
m_staticTextAngleUnit->SetLabel( _( "degree" ) );
m_startX.SetValue( m_shape->m_Start.x ); // Start point of arc
m_startY.SetValue( m_shape->m_Start.y );
m_endX.SetValue( m_shape->m_End.x ); // arc center
m_endY.SetValue( m_shape->m_End.y );
m_radiusLabel->SetLabel( _( "Angle:" ) );
m_radius.SetUnits( DEGREES );
m_radius.SetValue( m_shape->m_ArcAngle );
break;
case S_CIRCLE: // ring or circle
@ -108,28 +104,19 @@ bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataToWindow()
SetTitle( _( "Circle" ) );
// End point does not exist for a circle or ring:
m_textCtrEndX->Show( false );
m_textCtrEndY->Show( false );
m_staticTextPosEnd->Show( false );
m_staticTextEndUnit->Show( false );
m_staticTextEndX->Show( false );
m_staticTextEndY->Show( false );
m_endX.Show( false );
m_endY.Show( false );
// Circle center uses position controls:
m_staticTextPosStart->SetLabel( _( "Center" ) );
PutValueInLocalUnits( *m_textCtrPosX, m_shape->m_Start.x );
PutValueInLocalUnits( *m_textCtrPosY, m_shape->m_Start.y );
PutValueInLocalUnits( *m_textCtrAngle, m_shape->m_Radius );
m_staticTextAngleUnit->SetLabel( unit );
m_staticTextAngle->SetLabel( _( "Radius" ) );
m_staticTextPosStart->SetLabel( _( "Center:" ) );
m_startX.SetValue( m_shape->m_Start.x );
m_startY.SetValue( m_shape->m_Start.y );
m_radius.SetValue( m_shape->m_Radius );
break;
case S_POLYGON: // polygon
SetTitle( "Polygon" );
m_staticTextPosStart->SetLabel( wxEmptyString );
m_staticTextPosEnd->SetLabel( wxEmptyString );
m_staticTextAngle->SetLabel( _( "corners count" ) );
m_textCtrAngle->SetValue( wxString::Format( "%d", m_shape->m_Poly.size() ) );
// polygon has a specific dialog editor. So nothing here
break;
default:
@ -143,36 +130,36 @@ bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataToWindow()
bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataFromWindow()
{
// Transfer data out of the GUI.
m_shape->m_Thickness = ValueFromString( g_UserUnit, m_textCtrlThickness->GetValue() );
m_shape->m_Thickness = m_thickness.GetValue();
switch( m_shape->m_Shape )
{
case S_SEGMENT: // Segment with rounded ends
m_shape->m_Start.x = ValueFromString( g_UserUnit, m_textCtrPosX->GetValue() );
m_shape->m_Start.y = ValueFromString( g_UserUnit, m_textCtrPosY->GetValue() );
m_shape->m_End.x = ValueFromString( g_UserUnit, m_textCtrEndX->GetValue() );
m_shape->m_End.y = ValueFromString( g_UserUnit, m_textCtrEndY->GetValue() );
m_shape->m_Start.x = m_startX.GetValue();
m_shape->m_Start.y = m_startY.GetValue();
m_shape->m_End.x = m_endX.GetValue();
m_shape->m_End.y = m_endY.GetValue();
break;
case S_ARC: // Arc with rounded ends
// Start point of arc
m_shape->m_Start.x = ValueFromString( g_UserUnit, m_textCtrEndX->GetValue() );
m_shape->m_Start.y = ValueFromString( g_UserUnit, m_textCtrEndY->GetValue() );
m_shape->m_Start.x = m_startX.GetValue();
m_shape->m_Start.y = m_startY.GetValue();
// arc center
m_shape->m_End.x = ValueFromString( g_UserUnit, m_textCtrPosX->GetValue() );
m_shape->m_End.y = ValueFromString( g_UserUnit, m_textCtrPosY->GetValue() );
m_shape->m_ArcAngle = ValueFromString( DEGREES, m_textCtrAngle->GetValue() );
m_shape->m_End.x = m_endX.GetValue();
m_shape->m_End.y = m_endY.GetValue();
// arc angle
m_shape->m_ArcAngle = m_radius.GetValue();
break;
case S_CIRCLE: // ring or circle
m_shape->m_Start.x = ValueFromString( g_UserUnit, m_textCtrPosX->GetValue() );
m_shape->m_Start.y = ValueFromString( g_UserUnit, m_textCtrPosY->GetValue() );
//radius
m_shape->m_Radius = ValueFromString( g_UserUnit, m_textCtrAngle->GetValue() );
m_shape->m_Start.x = m_startX.GetValue();
m_shape->m_Start.y = m_startY.GetValue();
m_shape->m_Radius = m_radius.GetValue();
break;
case S_POLYGON: // polygon
// polygon has a specific dialog editor. No nothing here
// polygon has a specific dialog editor. So nothing here
break;
default:
@ -184,26 +171,35 @@ bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataFromWindow()
}
DIALOG_PAD_PRIMITIVE_POLY_PROPS::DIALOG_PAD_PRIMITIVE_POLY_PROPS(
wxWindow* aParent, PAD_CS_PRIMITIVE * aShape )
: DIALOG_PAD_PRIMITIVE_POLY_PROPS_BASE( aParent ),
m_shape( aShape ), m_currshape( *m_shape )
DIALOG_PAD_PRIMITIVE_POLY_PROPS::DIALOG_PAD_PRIMITIVE_POLY_PROPS( wxWindow* aParent,
PCB_BASE_FRAME* aFrame,
PAD_CS_PRIMITIVE * aShape ) :
DIALOG_PAD_PRIMITIVE_POLY_PROPS_BASE( aParent ),
m_shape( aShape ),
m_currshape( *m_shape ),
m_thickness( aFrame, m_thicknessLabel, m_thicknessCtrl, m_thicknessUnits, true )
{
m_addButton->SetBitmap( KiBitmap( small_plus_xpm ) );
m_deleteButton->SetBitmap( KiBitmap( trash_xpm ) );
m_warningIcon->SetBitmap( KiBitmap( dialog_warning_xpm ) );
// Test for acceptable polygon (more than 2 corners, and not self-intersecting) and
// remove any redundant corners. A warning message is displayed if not OK.
doValidate( true );
TransferDataToWindow();
m_sdbSizerOK->SetDefault();
GetSizer()->SetSizeHints( this );
// TODO: move wxEVT_GRID_CELL_CHANGING in wxFormbuilder, when it support it
m_gridCornersList->Connect( wxEVT_GRID_CELL_CHANGING,
wxGridEventHandler( DIALOG_PAD_PRIMITIVE_POLY_PROPS::onCellChanging ), NULL, this );
m_gridCornersList->Connect( wxEVT_GRID_CELL_CHANGING, wxGridEventHandler( DIALOG_PAD_PRIMITIVE_POLY_PROPS::onCellChanging ), NULL, this );
}
DIALOG_PAD_PRIMITIVE_POLY_PROPS::~DIALOG_PAD_PRIMITIVE_POLY_PROPS()
{
m_gridCornersList->Disconnect( wxEVT_GRID_CELL_CHANGING,
wxGridEventHandler( DIALOG_PAD_PRIMITIVE_POLY_PROPS::onCellChanging ), NULL, this );
m_gridCornersList->Disconnect( wxEVT_GRID_CELL_CHANGING, wxGridEventHandler( DIALOG_PAD_PRIMITIVE_POLY_PROPS::onCellChanging ), NULL, this );
}
@ -212,19 +208,7 @@ bool DIALOG_PAD_PRIMITIVE_POLY_PROPS::TransferDataToWindow()
if( m_shape == NULL )
return false;
// Update units and parameters names according to the shape to edit:
wxString unit = GetAbbreviatedUnitsLabel();
m_staticTextThicknessUnit->SetLabel( unit );
PutValueInLocalUnits( *m_textCtrlThickness, m_currshape.m_Thickness );
// Test for acceptable polygon (more than 2 corners, and not self-intersecting)
// A warning message is displayed if not OK
Validate();
// If the number of corners is < 2 (Happens for a new shape, prepare 2 dummy corners
while( m_currshape.m_Poly.size() < 2 )
m_currshape.m_Poly.push_back( wxPoint( 0, 0 ) );
m_thickness.SetValue( m_currshape.m_Thickness );
// Populates the list of corners
int extra_rows = m_currshape.m_Poly.size() - m_gridCornersList->GetNumberRows();
@ -247,10 +231,10 @@ bool DIALOG_PAD_PRIMITIVE_POLY_PROPS::TransferDataToWindow()
msg.Printf( "Corner %d", row+1 );
m_gridCornersList->SetRowLabelValue( row, msg );
msg = StringFromValue( g_UserUnit, m_currshape.m_Poly[row].x );
msg = StringFromValue( GetUserUnits(), m_currshape.m_Poly[row].x, true, true );
m_gridCornersList->SetCellValue( row, 0, msg );
msg = StringFromValue( g_UserUnit, m_currshape.m_Poly[row].y );
msg = StringFromValue( GetUserUnits(), m_currshape.m_Poly[row].y, true, true );
m_gridCornersList->SetCellValue( row, 1, msg );
}
@ -262,21 +246,32 @@ bool DIALOG_PAD_PRIMITIVE_POLY_PROPS::TransferDataFromWindow()
if( !Validate() )
return false;
// Transfer data out of the GUI.
m_currshape.m_Thickness = ValueFromString( g_UserUnit, m_textCtrlThickness->GetValue() );
m_currshape.m_Thickness = m_thickness.GetValue();
*m_shape = m_currshape;
return true;
}
// test for a valid polygon (a not self intersectiong polygon)
bool DIALOG_PAD_PRIMITIVE_POLY_PROPS::Validate()
{
// Don't remove redundant corners while user is editing corner list
return doValidate( false );
}
// test for a valid polygon (a not self intersectiong polygon)
bool DIALOG_PAD_PRIMITIVE_POLY_PROPS::doValidate( bool aRemoveRedundantCorners )
{
// Commit any pending edits
m_gridCornersList->DisableCellEditControl();
if( m_currshape.m_Poly.size() < 3 )
{
m_staticTextValidate->SetLabel( _("Incorrect polygon: less than 3 corners" ) );
m_staticTextValidate->Show( true );
m_warningText->SetLabel( _("Polygon must have at least 3 corners" ) );
m_warningText->Show( true );
m_warningIcon->Show( true );
return false;
}
@ -295,89 +290,107 @@ bool DIALOG_PAD_PRIMITIVE_POLY_PROPS::Validate()
if( polyline.PointCount() < 3 )
{
m_staticTextValidate->SetLabel( _("Incorrect polygon: too few corners after simplification" ) );
m_warningText->SetLabel( _("Polygon must have at least 3 corners\n after simplification" ) );
valid = false;
}
if( valid && polyline.SelfIntersecting() )
{
m_staticTextValidate->SetLabel( _("Incorrect polygon: self intersecting" ) );
m_warningText->SetLabel( _("Polygon may not be self-intersecting" ) );
valid = false;
}
if( valid )
m_staticTextValidate->SetLabel( _("Polygon:" ) );
m_warningIcon->Show( !valid );
m_warningText->Show( !valid );
if( polyline.PointCount() != (int)m_currshape.m_Poly.size() )
{ // Happens after simplification
m_currshape.m_Poly.clear();
if( aRemoveRedundantCorners )
{
if( polyline.PointCount() != (int)m_currshape.m_Poly.size() )
{ // Happens after simplification
m_currshape.m_Poly.clear();
for( int ii = 0; ii < polyline.PointCount(); ++ii )
m_currshape.m_Poly.push_back( wxPoint( polyline.CPoint( ii ).x, polyline.CPoint( ii ).y ) );
for( int ii = 0; ii < polyline.PointCount(); ++ii )
m_currshape.m_Poly.push_back( wxPoint( polyline.CPoint( ii ).x, polyline.CPoint( ii ).y ) );
m_staticTextValidate->SetLabel( _("Polygon: redundant corners removed" ) );
m_warningIcon->Show( true );
m_warningText->Show( true );
m_warningText->SetLabel( _("Note: redundant corners removed" ) );
}
}
return valid;
}
void DIALOG_PAD_PRIMITIVE_POLY_PROPS::onButtonAdd( wxCommandEvent& event )
void DIALOG_PAD_PRIMITIVE_POLY_PROPS::OnButtonAdd( wxCommandEvent& event )
{
// Commit any pending edits
m_gridCornersList->DisableCellEditControl();
// Insert a new corner after the currently selected:
wxArrayInt selections = m_gridCornersList->GetSelectedRows();
int row = -1;
if( m_gridCornersList->GetNumberRows() )
{
wxArrayInt selections = m_gridCornersList->GetSelectedRows();
if( selections.size() > 0 )
{
std::sort( selections.begin(), selections.end() );
row = selections[0];
}
else
{
row = m_gridCornersList->GetGridCursorRow();
}
if( row < 0 )
{
wxMessageBox( _( "Select a corner before adding a new corner" ) );
return;
}
}
else
if( m_gridCornersList->GetNumberRows() == 0 )
row = 0;
m_gridCornersList->SelectRow( row, false );
if( m_currshape.m_Poly.size() == 0 )
m_currshape.m_Poly.push_back( wxPoint(0,0) );
else if( selections.size() > 0 )
row = selections[ selections.size() - 1 ] + 1;
else
m_currshape.m_Poly.insert( m_currshape.m_Poly.begin() + row + 1, wxPoint(0,0) );
row = m_gridCornersList->GetGridCursorRow() + 1;
if( row < 0 )
{
wxMessageBox( _( "Select a corner to add the new corner after." ) );
return;
}
if( m_currshape.m_Poly.size() == 0 || row >= (int) m_currshape.m_Poly.size() )
m_currshape.m_Poly.push_back( wxPoint( 0, 0 ) );
else
m_currshape.m_Poly.insert( m_currshape.m_Poly.begin() + row, wxPoint( 0, 0 ) );
Validate();
TransferDataToWindow();
m_gridCornersList->ForceRefresh();
// Select the new row
m_gridCornersList->SelectRow( row, false );
m_panelPoly->Refresh();
}
void DIALOG_PAD_PRIMITIVE_POLY_PROPS::OnButtonDelete( wxCommandEvent& event )
{
wxArrayInt selections = m_gridCornersList->GetSelectedRows();
std::sort( selections.begin(), selections.end() );
// Commit any pending edits
m_gridCornersList->DisableCellEditControl();
// remove corners:
for( int ii = selections.size()-1; ii >= 0 ; --ii )
wxArrayInt selections = m_gridCornersList->GetSelectedRows();
if( m_gridCornersList->GetNumberRows() == 0 )
return;
if( selections.size() == 0 && m_gridCornersList->GetGridCursorRow() >= 0 )
selections.push_back( m_gridCornersList->GetGridCursorRow() );
if( selections.size() == 0 )
{
m_currshape.m_Poly.erase( m_currshape.m_Poly.begin() + selections[ii] );
wxMessageBox( _( "Select a corner to delete." ) );
return;
}
// Unselect all raws:
m_gridCornersList->SelectRow( -1, false );
// remove corners:
std::sort( selections.begin(), selections.end() );
for( int ii = selections.size()-1; ii >= 0 ; --ii )
m_currshape.m_Poly.erase( m_currshape.m_Poly.begin() + selections[ii] );
Validate();
TransferDataToWindow();
m_gridCornersList->ForceRefresh();
// select the row previous to the last deleted row
m_gridCornersList->SelectRow( std::max( 0, selections[ 0 ] - 1 ) );
m_panelPoly->Refresh();
}
@ -464,22 +477,19 @@ void DIALOG_PAD_PRIMITIVE_POLY_PROPS::onGridSelect( wxGridRangeSelectEvent& even
void DIALOG_PAD_PRIMITIVE_POLY_PROPS::onCellChanging( wxGridEvent& event )
{
int row = event.GetRow();
int col = event.GetCol();
int row = event.GetRow();
int col = event.GetCol();
wxString msg = event.GetString();
if( msg.IsEmpty() )
return;
int value = ValueFromString( g_UserUnit, msg );
if( col == 0 ) // Set the X value
m_currshape.m_Poly[row].x = value;
m_currshape.m_Poly[row].x = ValueFromString( GetUserUnits(), msg, true );
else // Set the Y value
m_currshape.m_Poly[row].y = value;
m_currshape.m_Poly[row].y = ValueFromString( GetUserUnits(), msg, true );
m_currshape.m_Thickness = ValueFromString( g_UserUnit, m_textCtrlThickness->GetValue() );
m_currshape.m_Thickness = m_thickness.GetValue();
Validate();
@ -489,13 +499,17 @@ void DIALOG_PAD_PRIMITIVE_POLY_PROPS::onCellChanging( wxGridEvent& event )
// A dialog to apply geometry transforms to a shape or set of shapes
// (move, rotate around origin, scaling factor, duplication).
DIALOG_PAD_PRIMITIVES_TRANSFORM::DIALOG_PAD_PRIMITIVES_TRANSFORM(
wxWindow* aParent,
std::vector<PAD_CS_PRIMITIVE*>& aList, bool aShowDuplicate )
:DIALOG_PAD_PRIMITIVES_TRANSFORM_BASE( aParent ), m_list( aList )
DIALOG_PAD_PRIMITIVES_TRANSFORM::DIALOG_PAD_PRIMITIVES_TRANSFORM( wxWindow* aParent,
PCB_BASE_FRAME* aFrame,
std::vector<PAD_CS_PRIMITIVE*>& aList,
bool aShowDuplicate ) :
DIALOG_PAD_PRIMITIVES_TRANSFORM_BASE( aParent ),
m_list( aList ),
m_vectorX( aFrame, m_xLabel, m_xCtrl, m_xUnits, true ),
m_vectorY( aFrame, m_yLabel, m_yCtrl, m_yUnits, true ),
m_rotation( aFrame, m_rotationLabel, m_rotationCtrl, m_rotationUnits )
{
wxString unit = GetAbbreviatedUnitsLabel();
m_staticTextMoveUnit->SetLabel( unit );
m_rotation.SetUnits( DEGREES );
if( !aShowDuplicate ) // means no duplicate transform
{
@ -507,6 +521,7 @@ DIALOG_PAD_PRIMITIVES_TRANSFORM::DIALOG_PAD_PRIMITIVES_TRANSFORM(
GetSizer()->SetSizeHints( this );
}
// A helper function in geometry transform
inline void geom_transf( wxPoint& aCoord, wxPoint& aMove, double aScale, double aRotation )
{
@ -516,19 +531,14 @@ inline void geom_transf( wxPoint& aCoord, wxPoint& aMove, double aScale, double
RotatePoint( &aCoord, aRotation );
}
void DIALOG_PAD_PRIMITIVES_TRANSFORM::Transform( std::vector<PAD_CS_PRIMITIVE>* aList, int aDuplicateCount )
{
// Get parameters from dlg:
wxPoint move_vect;
move_vect.x = ValueFromString( g_UserUnit, m_textCtrMoveX->GetValue() );
move_vect.y = ValueFromString( g_UserUnit, m_textCtrMoveY->GetValue() );
wxPoint currMoveVect = move_vect;
wxPoint move_vect( m_vectorX.GetValue(), m_vectorY.GetValue() );
double rotation = m_rotation.GetValue() / 10.0;
double scale = DoubleValueFromString( UNSCALED_UNITS, m_scaleCtrl->GetValue() );
double rotation = DoubleValueFromString( DEGREES, m_textCtrAngle->GetValue() );
double curr_rotation = rotation;
double scale = DoubleValueFromString( UNSCALED_UNITS, m_textCtrlScalingFactor->GetValue() );
// Avoid too small /too large scale, which could create issues:
// Avoid too small / too large scale, which could create issues:
if( scale < 0.01 )
scale = 0.01;
@ -539,6 +549,10 @@ void DIALOG_PAD_PRIMITIVES_TRANSFORM::Transform( std::vector<PAD_CS_PRIMITIVE>*
// shapes are scaled, then moved then rotated.
// if aList != NULL, the initial shape will be duplicated, and transform
// applied to the duplicated shape
wxPoint currMoveVect = move_vect;
double curr_rotation = rotation;
do {
for( unsigned idx = 0; idx < m_list.size(); ++idx )
{

File diff suppressed because it is too large Load Diff

View File

@ -47,8 +47,7 @@
#include <dialog_pad_properties_base.h>
#include <widgets/text_ctrl_eval.h>
#include <pcb_draw_panel_gal.h>
#include <widgets/unit_binder.h>
/**
* class DIALOG_PAD_PROPERTIES, derived from DIALOG_PAD_PROPERTIES_BASE,
@ -66,33 +65,38 @@ public:
private:
PCB_BASE_FRAME* m_parent;
KIGFX::ORIGIN_VIEWITEM* m_axisOrigin;
D_PAD* m_currentPad; // pad currently being edited
D_PAD* m_dummyPad; // a working copy used to show changes
D_PAD* m_padMaster; // The pad used to create new pads in board or
// footprint editor
BOARD* m_board; // the main board: this is the board handled by
// the PCB editor, if running or the dummy
// board used by the footprint editor
// (could happen when the Footprint editor will be run
// alone, outside the board editor
bool m_isFlipped; // true if the parent footprint (therefore pads) is flipped (mirrored)
// in this case, some Y coordinates values must be negated
D_PAD* m_padMaster; // pad used to create new pads in board or footprint editor
BOARD* m_board; // the main board: this is the board handled by the PCB
// editor or the dummy board used by the footprint editor
bool m_isFlipped; // indicates the parent footprint is flipped (mirrored) in
// which case some Y coordinates values must be negated
bool m_canUpdate;
bool m_canEditNetName; // true only if the caller is the board editor
// for free shape pads: the list of primitives (basic shapes),
// in local coordinates, orient 0, coordinates relative to m_Pos
// They are expected to define only one copper area.
std::vector<PAD_CS_PRIMITIVE> m_primitives;
std::vector<PAD_CS_PRIMITIVE> m_primitives; // the list of custom shape primitives (basic
// shapes), in local coords, orient 0
// must define a single copper area
COLOR4D m_selectedColor; // color used to draw selected primitives when
// editing a custom pad shape
std::vector<DRAWSEGMENT*> m_highligth; // shapes highlighted in GAL mode
std::vector<DRAWSEGMENT*> m_highlight; // shapes highlighted in GAL mode
KIGFX::ORIGIN_VIEWITEM* m_axisOrigin; // origin of the preview canvas
static bool m_sketchPreview; // session storage
UNIT_BINDER m_posX, m_posY;
UNIT_BINDER m_sizeX, m_sizeY;
UNIT_BINDER m_offsetX, m_offsetY;
UNIT_BINDER m_padToDie;
UNIT_BINDER m_trapDelta;
UNIT_BINDER m_cornerRadius;
UNIT_BINDER m_holeX, m_holeY;
wxFloatingPointValidator<double> m_OrientValidator;
double m_OrientValue;
static bool m_drawPadOutlineMode; // Stores the pad draw option during a session
COLOR4D m_selectedColor; // Color used to draw selected primitives when
// editing a custom pad shape
double m_OrientValue;
UNIT_BINDER m_clearance;
UNIT_BINDER m_maskClearance, m_pasteClearance;
UNIT_BINDER m_spokeWidth, m_thermalGap;
private:
void prepareCanvas(); // Initialize the canvases (legacy or gal) to display the pad
@ -169,7 +173,8 @@ private:
class DIALOG_PAD_PRIMITIVES_PROPERTIES: public DIALOG_PAD_PRIMITIVES_PROPERTIES_BASE
{
public:
DIALOG_PAD_PRIMITIVES_PROPERTIES( wxWindow* aParent, PAD_CS_PRIMITIVE * aShape );
DIALOG_PAD_PRIMITIVES_PROPERTIES( wxWindow* aParent, PCB_BASE_FRAME* aFrame,
PAD_CS_PRIMITIVE * aShape );
/**
* Function TransferDataFromWindow
@ -186,6 +191,13 @@ private:
// The basic shape currently edited
PAD_CS_PRIMITIVE * m_shape;
UNIT_BINDER m_startX;
UNIT_BINDER m_startY;
UNIT_BINDER m_endX;
UNIT_BINDER m_endY;
UNIT_BINDER m_radius;
UNIT_BINDER m_thickness;
};
@ -200,8 +212,11 @@ class DIALOG_PAD_PRIMITIVE_POLY_PROPS: public DIALOG_PAD_PRIMITIVE_POLY_PROPS_BA
// The working copy of the basic shape currently edited
PAD_CS_PRIMITIVE m_currshape;
UNIT_BINDER m_thickness;
public:
DIALOG_PAD_PRIMITIVE_POLY_PROPS( wxWindow* aParent, PAD_CS_PRIMITIVE * aShape );
DIALOG_PAD_PRIMITIVE_POLY_PROPS( wxWindow* aParent, PCB_BASE_FRAME* aFrame,
PAD_CS_PRIMITIVE * aShape );
~DIALOG_PAD_PRIMITIVE_POLY_PROPS();
/**
@ -224,7 +239,7 @@ private:
// Events handlers:
void OnValidateButton( wxCommandEvent& event );
void onButtonAdd( wxCommandEvent& event ) override;
void OnButtonAdd( wxCommandEvent& event ) override;
void OnButtonDelete( wxCommandEvent& event ) override;
void onPaintPolyPanel( wxPaintEvent& event ) override;
void onPolyPanelResize( wxSizeEvent& event ) override;
@ -234,6 +249,9 @@ private:
{
event.Skip();
}
bool doValidate( bool aRemoveRedundantCorners );
};
@ -247,8 +265,8 @@ private:
class DIALOG_PAD_PRIMITIVES_TRANSFORM : public DIALOG_PAD_PRIMITIVES_TRANSFORM_BASE
{
public:
DIALOG_PAD_PRIMITIVES_TRANSFORM( wxWindow* aParent,
std::vector<PAD_CS_PRIMITIVE*>& aList, bool aShowDuplicate );
DIALOG_PAD_PRIMITIVES_TRANSFORM( wxWindow* aParent, PCB_BASE_FRAME* aFrame,
std::vector<PAD_CS_PRIMITIVE*>& aList, bool aShowDuplicate );
/**
* Apply geometric transform (rotation, move, scale) defined in dialog
@ -266,6 +284,10 @@ public:
private:
std::vector<PAD_CS_PRIMITIVE*>& m_list;
UNIT_BINDER m_vectorX;
UNIT_BINDER m_vectorY;
UNIT_BINDER m_rotation;
};
#endif // #ifndef _DIALOG_PAD_PROPERTIES_H_

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,7 @@
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
class TEXT_CTRL_EVAL;
class WIDGET_NET_SELECTOR;
#include "dialog_shim.h"
#include <wx/string.h>
@ -21,8 +22,8 @@ class TEXT_CTRL_EVAL;
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/textctrl.h>
#include <wx/combobox.h>
#include <wx/choice.h>
#include <wx/statline.h>
#include <wx/sizer.h>
#include <wx/bitmap.h>
#include <wx/image.h>
@ -37,9 +38,11 @@ class TEXT_CTRL_EVAL;
#include <wx/notebook.h>
#include <pcb_base_frame.h>
#include <pcb_draw_panel_gal.h>
#include <wx/statline.h>
#include <wx/dialog.h>
#include <wx/spinctrl.h>
#include <wx/grid.h>
#include <wx/bmpbuttn.h>
///////////////////////////////////////////////////////////////////////////
@ -54,8 +57,7 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM
enum
{
wxID_DIALOG_EDIT_PAD = 1000,
wxID_PADNUMCTRL,
wxID_PADNETNAMECTRL
wxID_PADNUMCTRL
};
wxNotebook* m_notebook;
@ -63,63 +65,55 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM
wxStaticText* m_PadNumText;
wxTextCtrl* m_PadNumCtrl;
wxStaticText* m_PadNameText;
wxTextCtrl* m_PadNetNameCtrl;
WIDGET_NET_SELECTOR* m_PadNetNameCombo;
wxStaticText* m_staticText44;
wxChoice* m_PadType;
wxStaticText* m_staticText45;
wxChoice* m_PadShape;
wxStaticText* m_staticText4;
TEXT_CTRL_EVAL* m_PadPosition_X_Ctrl;
wxStaticText* m_PadPosX_Unit;
wxStaticText* m_staticText41;
TEXT_CTRL_EVAL* m_PadPosition_Y_Ctrl;
wxStaticText* m_PadPosY_Unit;
wxStaticText* m_staticText12;
TEXT_CTRL_EVAL* m_ShapeSize_X_Ctrl;
wxStaticText* m_PadShapeSizeX_Unit;
wxStaticText* m_staticText15;
TEXT_CTRL_EVAL* m_ShapeSize_Y_Ctrl;
wxStaticText* m_PadShapeSizeY_Unit;
wxStaticText* m_posXLabel;
wxTextCtrl* m_posXCtrl;
wxStaticText* m_posXUnits;
wxStaticText* m_posYLabel;
wxTextCtrl* m_posYCtrl;
wxStaticText* m_posYUnits;
wxStaticText* m_sizeXLabel;
wxTextCtrl* m_sizeXCtrl;
wxStaticText* m_sizeXUnits;
wxStaticText* m_sizeYLabel;
wxTextCtrl* m_sizeYCtrl;
wxStaticText* m_sizeYUnits;
wxStaticText* m_PadOrientText;
wxChoice* m_PadOrient;
wxComboBox* m_orientation;
wxStaticText* m_staticText491;
TEXT_CTRL_EVAL* m_PadOrientCtrl;
wxStaticText* m_customOrientUnits;
wxStaticText* m_staticText17;
TEXT_CTRL_EVAL* m_ShapeOffset_X_Ctrl;
wxStaticText* m_PadShapeOffsetX_Unit;
wxStaticText* m_staticText19;
TEXT_CTRL_EVAL* m_ShapeOffset_Y_Ctrl;
wxStaticText* m_PadShapeOffsetY_Unit;
wxStaticText* m_staticText38;
TEXT_CTRL_EVAL* m_LengthPadToDieCtrl;
wxStaticText* m_PadLengthDie_Unit;
wxStaticLine* m_staticline4;
wxStaticLine* m_staticline5;
wxStaticLine* m_staticline6;
wxStaticText* m_staticText21;
TEXT_CTRL_EVAL* m_ShapeDelta_Ctrl;
wxStaticText* m_PadShapeDelta_Unit;
wxStaticText* m_staticText23;
wxChoice* m_trapDeltaDirChoice;
wxStaticLine* m_staticline7;
wxStaticLine* m_staticline8;
wxStaticLine* m_staticline9;
wxStaticText* m_offsetXLabel;
wxTextCtrl* m_offsetXCtrl;
wxStaticText* m_offsetXUnits;
wxStaticText* m_offsetYLabel;
wxTextCtrl* m_offsetYCtrl;
wxStaticText* m_offsetYUnits;
wxStaticText* m_padToDieLabel;
wxTextCtrl* m_padToDieCtrl;
wxStaticText* m_padToDieUnits;
wxStaticText* m_trapDeltaLabel;
wxTextCtrl* m_trapDeltaCtrl;
wxStaticText* m_trapDeltaUnits;
wxStaticText* m_trapAxisLabel;
wxChoice* m_trapAxisCtrl;
wxStaticText* m_staticTextCornerSizeRatio;
TEXT_CTRL_EVAL* m_tcCornerSizeRatio;
wxStaticText* m_staticTextCornerSizeRatioUnit;
wxStaticText* m_staticTextCornerRadius;
wxStaticText* m_staticTextCornerRadiusValue;
wxStaticText* m_staticTextCornerSizeUnit;
wxStaticText* m_staticText47;
wxChoice* m_DrillShapeCtrl;
wxStaticText* m_cornerRadiusLabel;
wxStaticText* m_cornerRadiusValue;
wxStaticText* m_cornerRadiusUnits;
wxStaticText* m_holeShapeLabel;
wxChoice* m_holeShapeCtrl;
wxStaticText* m_staticText51;
wxStaticText* m_textPadDrillX;
TEXT_CTRL_EVAL* m_PadDrill_X_Ctrl;
wxStaticText* m_PadDrill_X_Unit;
wxStaticText* m_textPadDrillY;
TEXT_CTRL_EVAL* m_PadDrill_Y_Ctrl;
wxStaticText* m_PadDrill_Y_Unit;
wxStaticText* m_holeXLabel;
wxTextCtrl* m_holeXCtrl;
wxStaticText* m_holeXUnits;
wxStaticText* m_holeYLabel;
wxTextCtrl* m_holeYCtrl;
wxStaticText* m_holeYUnits;
wxBoxSizer* m_FlippedWarningSizer;
wxStaticBitmap* m_FlippedWarningIcon;
wxStaticText* m_staticText86;
@ -139,15 +133,15 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM
wxPanel* m_localSettingsPanel;
wxStaticText* m_staticTextInfoPosValue;
wxStaticText* m_staticTextInfoNegVal;
wxStaticText* m_staticTextNetClearance;
TEXT_CTRL_EVAL* m_NetClearanceValueCtrl;
wxStaticText* m_NetClearanceUnits;
wxStaticText* m_MaskClearanceTitle;
TEXT_CTRL_EVAL* m_SolderMaskMarginCtrl;
wxStaticText* m_SolderMaskMarginUnits;
wxStaticText* m_staticTextSolderPaste;
TEXT_CTRL_EVAL* m_SolderPasteMarginCtrl;
wxStaticText* m_SolderPasteMarginUnits;
wxStaticText* m_clearanceLabel;
wxTextCtrl* m_clearanceCtrl;
wxStaticText* m_clearanceUnits;
wxStaticText* m_maskClearanceLabel;
wxTextCtrl* m_maskClearanceCtrl;
wxStaticText* m_maskClearanceUnits;
wxStaticText* m_pasteClearanceLabel;
wxTextCtrl* m_pasteClearanceCtrl;
wxStaticText* m_pasteClearanceUnits;
wxStaticText* m_staticTextRatio;
TEXT_CTRL_EVAL* m_SolderPasteMarginRatioCtrl;
wxStaticText* m_SolderPasteRatioMarginUnits;
@ -158,12 +152,12 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM
wxStaticBoxSizer* m_sbSizerZonesSettings;
wxStaticText* m_staticText40;
wxChoice* m_ZoneConnectionChoice;
wxStaticText* m_staticText49;
TEXT_CTRL_EVAL* m_ThermalWidthCtrl;
wxStaticText* m_ThermalWidthUnits;
wxStaticText* m_staticText52;
TEXT_CTRL_EVAL* m_ThermalGapCtrl;
wxStaticText* m_ThermalGapUnits;
wxStaticText* m_spokeWidthLabel;
wxTextCtrl* m_spokeWidthCtrl;
wxStaticText* m_spokeWidthUnits;
wxStaticText* m_thermalGapLabel;
wxTextCtrl* m_thermalGapCtrl;
wxStaticText* m_thermalGapUnits;
wxStaticBoxSizer* m_sbSizerCustomShapedZonesSettings;
wxStaticText* m_staticTextCsZconnTitle;
wxChoice* m_ZoneConnectionCustom;
@ -180,9 +174,8 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM
wxButton* m_buttonDup;
wxButton* m_buttonGeometry;
wxButton* m_buttonImport;
wxStaticText* m_staticModuleSideValue;
wxStaticText* m_staticTitleModuleRot;
wxStaticText* m_staticModuleRotValue;
wxStaticText* m_parentInfoLine1;
wxStaticText* m_parentInfoLine2;
wxPanel* m_panelShowPad;
PCB_DRAW_PANEL_GAL* m_panelShowPadGal;
KIGFX::GAL_DISPLAY_OPTIONS m_galOptions;
@ -230,25 +223,27 @@ class DIALOG_PAD_PRIMITIVES_PROPERTIES_BASE : public DIALOG_SHIM
private:
protected:
wxStaticText* m_staticTextInfo;
wxStaticText* m_staticTextPosStart;
wxStaticText* m_staticTextStartX;
TEXT_CTRL_EVAL* m_textCtrPosX;
wxStaticText* m_staticTextStartY;
TEXT_CTRL_EVAL* m_textCtrPosY;
wxStaticText* m_staticTextPosUnit;
wxStaticText* m_startXLabel;
TEXT_CTRL_EVAL* m_startXCtrl;
wxStaticText* m_startXUnits;
wxStaticText* m_startYLabel;
TEXT_CTRL_EVAL* m_startYCtrl;
wxStaticText* m_startYUnits;
wxStaticText* m_staticTextPosEnd;
wxStaticText* m_staticTextEndX;
TEXT_CTRL_EVAL* m_textCtrEndX;
wxStaticText* m_staticTextEndY;
TEXT_CTRL_EVAL* m_textCtrEndY;
wxStaticText* m_staticTextEndUnit;
wxStaticText* m_staticTextAngle;
TEXT_CTRL_EVAL* m_textCtrAngle;
wxStaticText* m_staticTextAngleUnit;
wxStaticText* m_staticTextThickness;
wxTextCtrl* m_textCtrlThickness;
wxStaticText* m_staticTextThicknessUnit;
wxStaticText* m_endXLabel;
TEXT_CTRL_EVAL* m_endXCtrl;
wxStaticText* m_endXUnits;
wxStaticText* m_endYLabel;
TEXT_CTRL_EVAL* m_endYCtrl;
wxStaticText* m_endYUnits;
wxStaticText* m_radiusLabel;
TEXT_CTRL_EVAL* m_radiusCtrl;
wxStaticText* m_radiusUnits;
wxStaticText* m_thicknessLabel;
wxTextCtrl* m_thicknessCtrl;
wxStaticText* m_thicknessUnits;
wxStaticText* m_staticTextInfo;
wxStaticLine* m_staticline1;
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;
@ -270,16 +265,17 @@ class DIALOG_PAD_PRIMITIVES_TRANSFORM_BASE : public DIALOG_SHIM
protected:
wxStaticText* m_staticTextMove;
wxStaticText* m_staticTextMoveX;
TEXT_CTRL_EVAL* m_textCtrMoveX;
wxStaticText* m_staticTextMoveY;
TEXT_CTRL_EVAL* m_textCtrMoveY;
wxStaticText* m_staticTextMoveUnit;
wxStaticText* m_staticTextAngle;
TEXT_CTRL_EVAL* m_textCtrAngle;
wxStaticText* m_staticTextAngleUnit;
wxStaticText* m_staticTextSF;
TEXT_CTRL_EVAL* m_textCtrlScalingFactor;
wxStaticText* m_xLabel;
TEXT_CTRL_EVAL* m_xCtrl;
wxStaticText* m_xUnits;
wxStaticText* m_yLabel;
TEXT_CTRL_EVAL* m_yCtrl;
wxStaticText* m_yUnits;
wxStaticText* m_rotationLabel;
TEXT_CTRL_EVAL* m_rotationCtrl;
wxStaticText* m_rotationUnits;
wxStaticText* m_scaleLabel;
TEXT_CTRL_EVAL* m_scaleCtrl;
wxStaticText* m_staticTextDupCnt;
wxSpinCtrl* m_spinCtrlDuplicateCount;
wxStaticLine* m_staticline1;
@ -302,17 +298,18 @@ class DIALOG_PAD_PRIMITIVE_POLY_PROPS_BASE : public DIALOG_SHIM
private:
protected:
wxStaticText* m_staticTextCornerListWarning;
wxStaticText* m_staticTextValidate;
wxGrid* m_gridCornersList;
wxButton* m_buttonAdd;
wxButton* m_buttonDelete;
wxBitmapButton* m_addButton;
wxBitmapButton* m_deleteButton;
wxStaticText* m_thicknessLabel;
TEXT_CTRL_EVAL* m_thicknessCtrl;
wxStaticText* m_thicknessUnits;
wxPanel* m_panelPoly;
wxStaticText* m_staticTextThickness;
TEXT_CTRL_EVAL* m_textCtrlThickness;
wxStaticText* m_staticTextThicknessUnit;
wxStaticText* m_staticTextInfo;
wxStaticBitmap* m_warningIcon;
wxStaticText* m_warningText;
wxStaticLine* m_staticline3;
wxStaticText* m_statusLine1;
wxStaticText* m_statusLine2;
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;
wxButton* m_sdbSizerCancel;
@ -320,7 +317,7 @@ class DIALOG_PAD_PRIMITIVE_POLY_PROPS_BASE : public DIALOG_SHIM
// Virtual event handlers, overide them in your derived class
virtual void onGridSelect( wxGridRangeSelectEvent& event ) { event.Skip(); }
virtual void onCellSelect( wxGridEvent& event ) { event.Skip(); }
virtual void onButtonAdd( wxCommandEvent& event ) { event.Skip(); }
virtual void OnButtonAdd( wxCommandEvent& event ) { event.Skip(); }
virtual void OnButtonDelete( wxCommandEvent& event ) { event.Skip(); }
virtual void onPaintPolyPanel( wxPaintEvent& event ) { event.Skip(); }
virtual void onPolyPanelResize( wxSizeEvent& event ) { event.Skip(); }