Commit bb6795dd authored by jean-pierre charras's avatar jean-pierre charras

Pcbnew: drag functions: serious cleanup and better code. Use now the...

Pcbnew: drag functions: serious cleanup and better code. Use now the connectivity functions to find tracks connected to pads,
and therefore  tracks are now dragged when a end point is inside a pad, not necessary on the pad position.
However, drag functions still need more cleanup.
parent 3668f4cc
...@@ -324,7 +324,7 @@ void Draw3D_ZaxisOblongCylinder( wxPoint aAxis1Pos, wxPoint aAxis2Pos, ...@@ -324,7 +324,7 @@ void Draw3D_ZaxisOblongCylinder( wxPoint aAxis1Pos, wxPoint aAxis2Pos,
// Draw the oblong inner cylinder // Draw the oblong inner cylinder
if( aHeight ) if( aHeight )
Draw3D_VerticalPolygonalCylinder( inner_cornerBuffer, aHeight, Draw3D_VerticalPolygonalCylinder( inner_cornerBuffer, aHeight,
true, aZpos, aBiuTo3DUnits ); aZpos, true, aBiuTo3DUnits );
// Build the horizontal full polygon shape // Build the horizontal full polygon shape
// (outer polygon shape - inner polygon shape) // (outer polygon shape - inner polygon shape)
......
...@@ -155,7 +155,7 @@ void EDA_LIST_DIALOG::SortList() ...@@ -155,7 +155,7 @@ void EDA_LIST_DIALOG::SortList()
{ {
wxArrayString list = m_listBox->GetStrings(); wxArrayString list = m_listBox->GetStrings();
if( list.IsEmpty() <= 0 ) if( list.IsEmpty() )
return; return;
list.Sort( SortItems ); list.Sort( SortItems );
......
...@@ -339,7 +339,16 @@ public: ...@@ -339,7 +339,16 @@ public:
*/ */
void DeletePad( D_PAD* aPad, bool aQuery = true ); void DeletePad( D_PAD* aPad, bool aQuery = true );
void StartMovePad( D_PAD* Pad, wxDC* DC ); /**
* Function StartMovePad
* Initialize a drag or move pad command
* @param aPad = the pad to move or drag
* @param aDC = the current device context
* @param aDragConnectedTracks = true to drag connected tracks,
* false to just move the pad
*/
void StartMovePad( D_PAD* aPad, wxDC* aDC, bool aDragConnectedTracks );
void RotatePad( D_PAD* Pad, wxDC* DC ); void RotatePad( D_PAD* Pad, wxDC* DC );
void PlacePad( D_PAD* Pad, wxDC* DC ); void PlacePad( D_PAD* Pad, wxDC* DC );
void Export_Pad_Settings( D_PAD* aPad ); void Export_Pad_Settings( D_PAD* aPad );
......
...@@ -937,7 +937,16 @@ public: ...@@ -937,7 +937,16 @@ public:
// Footprint edition (see also PCB_BASE_FRAME) // Footprint edition (see also PCB_BASE_FRAME)
void InstallModuleOptionsFrame( MODULE* Module, wxDC* DC ); void InstallModuleOptionsFrame( MODULE* Module, wxDC* DC );
void StartMove_Module( MODULE* module, wxDC* DC );
/**
* Function StartMoveModule
* Initialize a drag or move pad command
* @param aModule = the module to move or drag
* @param aDC = the current device context
* @param aDragConnectedTracks = true to drag connected tracks,
* false to just move the module
*/
void StartMoveModule( MODULE* aModule, wxDC* aDC, bool aDragConnectedTracks );
/** /**
* Function DlgGlobalChange_PadSettings * Function DlgGlobalChange_PadSettings
......
...@@ -184,6 +184,7 @@ set(PCBNEW_CLASS_SRCS ...@@ -184,6 +184,7 @@ set(PCBNEW_CLASS_SRCS
netlist_reader_kicad.cpp netlist_reader_kicad.cpp
onleftclick.cpp onleftclick.cpp
onrightclick.cpp onrightclick.cpp
pad_edition_functions.cpp
pcbnew.cpp pcbnew.cpp
pcbnew_config.cpp pcbnew_config.cpp
pcbplot.cpp pcbplot.cpp
......
...@@ -1807,8 +1807,9 @@ D_PAD* BOARD::GetPad( std::vector<D_PAD*>& aPadList, const wxPoint& aPosition, i ...@@ -1807,8 +1807,9 @@ D_PAD* BOARD::GetPad( std::vector<D_PAD*>& aPadList, const wxPoint& aPosition, i
/** /**
* Function SortPadsByXCoord * Function SortPadsByXCoord
* is used by GetSortedPadListByXCoord to Sort a pad list by x coordinate value. * is used by GetSortedPadListByXCoord to Sort a pad list by x coordinate value.
* This function is used to build ordered pads lists
*/ */
static bool sortPadsByXthenYCoord( D_PAD* const & ref, D_PAD* const & comp ) bool sortPadsByXthenYCoord( D_PAD* const & ref, D_PAD* const & comp )
{ {
if( ref->GetPosition().x == comp->GetPosition().x ) if( ref->GetPosition().x == comp->GetPosition().x )
return ref->GetPosition().y < comp->GetPosition().y; return ref->GetPosition().y < comp->GetPosition().y;
......
...@@ -196,6 +196,12 @@ public: ...@@ -196,6 +196,12 @@ public:
void Flip( const wxPoint& aCentre ); void Flip( const wxPoint& aCentre );
/**
* function IsFlipped
* @return true if the module is flipped, i.e. on the back side of the board
*/
bool IsFlipped() const {return GetLayer() == LAYER_N_BACK; }
bool IsLocked() const bool IsLocked() const
{ {
return (m_ModuleStatus & MODULE_is_LOCKED) != 0; return (m_ModuleStatus & MODULE_is_LOCKED) != 0;
......
...@@ -102,7 +102,7 @@ private: ...@@ -102,7 +102,7 @@ private:
* merge aTrackRef and aCandidate, when possible, * merge aTrackRef and aCandidate, when possible,
* i.e. when they are colinear, same width, and obviously same layer * i.e. when they are colinear, same width, and obviously same layer
*/ */
TRACK* mergeColinearSegmentIfPossible( TRACK* aTrackRef, TRACK* mergeCollinearSegmentIfPossible( TRACK* aTrackRef,
TRACK* aCandidate, int aEndType ); TRACK* aCandidate, int aEndType );
}; };
...@@ -489,7 +489,7 @@ bool TRACKS_CLEANER::clean_segments() ...@@ -489,7 +489,7 @@ bool TRACKS_CLEANER::clean_segments()
} }
} }
// delete intermediate points (merging colinear segments) // merge collinear segments:
for( segment = m_Brd->m_Track; segment; segment = nextsegment ) for( segment = m_Brd->m_Track; segment; segment = nextsegment )
{ {
TRACK* segStart; TRACK* segStart;
...@@ -533,7 +533,7 @@ bool TRACKS_CLEANER::clean_segments() ...@@ -533,7 +533,7 @@ bool TRACKS_CLEANER::clean_segments()
if( flag ) // We have the starting point of the segment is connected to an other segment if( flag ) // We have the starting point of the segment is connected to an other segment
{ {
segDelete = mergeColinearSegmentIfPossible( segment, segStart, FLG_START ); segDelete = mergeCollinearSegmentIfPossible( segment, segStart, FLG_START );
if( segDelete ) if( segDelete )
{ {
...@@ -574,7 +574,7 @@ bool TRACKS_CLEANER::clean_segments() ...@@ -574,7 +574,7 @@ bool TRACKS_CLEANER::clean_segments()
if( flag & 2 ) // We have the ending point of the segment is connected to an other segment if( flag & 2 ) // We have the ending point of the segment is connected to an other segment
{ {
segDelete = mergeColinearSegmentIfPossible( segment, segEnd, FLG_END ); segDelete = mergeCollinearSegmentIfPossible( segment, segEnd, FLG_END );
if( segDelete ) if( segDelete )
{ {
...@@ -593,9 +593,9 @@ bool TRACKS_CLEANER::clean_segments() ...@@ -593,9 +593,9 @@ bool TRACKS_CLEANER::clean_segments()
/** Function used by clean_segments. /** Function used by clean_segments.
* Test alignment of aTrackRef and aCandidate (which must have a common end). * Test if aTrackRef and aCandidate (which must have a common end) are collinear.
* and see if the common point is not on a pad (i.e. if this common point can be removed). * and see if the common point is not on a pad (i.e. if this common point can be removed).
* the ending point of pt_ref is the start point (aEndType == START) * the ending point of aTrackRef is the start point (aEndType == START)
* or the end point (aEndType != START) * or the end point (aEndType != START)
* flags START_ON_PAD and END_ON_PAD must be set before calling this function * flags START_ON_PAD and END_ON_PAD must be set before calling this function
* if the common point can be deleted, this function * if the common point can be deleted, this function
...@@ -604,7 +604,7 @@ bool TRACKS_CLEANER::clean_segments() ...@@ -604,7 +604,7 @@ bool TRACKS_CLEANER::clean_segments()
* and return aCandidate (which can be deleted). * and return aCandidate (which can be deleted).
* else return NULL * else return NULL
*/ */
TRACK* TRACKS_CLEANER::mergeColinearSegmentIfPossible( TRACK* aTrackRef, TRACK* aCandidate, TRACK* TRACKS_CLEANER::mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK* aCandidate,
int aEndType ) int aEndType )
{ {
if( aTrackRef->m_Width != aCandidate->m_Width ) if( aTrackRef->m_Width != aCandidate->m_Width )
......
...@@ -105,7 +105,7 @@ void CONNECTIONS::SearchConnectionsPadsToIntersectingPads() ...@@ -105,7 +105,7 @@ void CONNECTIONS::SearchConnectionsPadsToIntersectingPads()
* D_PAD::m_TracksConnected is cleared before adding items * D_PAD::m_TracksConnected is cleared before adding items
* TRACK::m_PadsConnected is not cleared * TRACK::m_PadsConnected is not cleared
*/ */
void CONNECTIONS::SearchTracksConnectedToPads() void CONNECTIONS::SearchTracksConnectedToPads( bool add_to_padlist, bool add_to_tracklist)
{ {
std::vector<CONNECTED_POINT*> candidates; std::vector<CONNECTED_POINT*> candidates;
...@@ -127,8 +127,11 @@ void CONNECTIONS::SearchTracksConnectedToPads() ...@@ -127,8 +127,11 @@ void CONNECTIONS::SearchTracksConnectedToPads()
if( pad->HitTest( cp_item->GetPoint() ) ) if( pad->HitTest( cp_item->GetPoint() ) )
{ {
cp_item->GetTrack()->m_PadsConnected.push_back( pad ); if( add_to_padlist )
pad->m_TracksConnected.push_back( cp_item->GetTrack() ); cp_item->GetTrack()->m_PadsConnected.push_back( pad );
if( add_to_tracklist )
pad->m_TracksConnected.push_back( cp_item->GetTrack() );
} }
} }
} }
......
...@@ -183,12 +183,16 @@ public: ...@@ -183,12 +183,16 @@ public:
/** /**
* function SearchTracksConnectedToPads * function SearchTracksConnectedToPads
* Explores the list of pads. * Explores the list of pads.
* Adds to m_PadsConnected member of each track the pad(s) connected to * if( add_to_padlist )
* Adds to m_TracksConnected member of each pad the track(s) connected to * adds to m_PadsConnected member of each track the pad(s) connected to
* if add_to_tracklist
* adds to m_TracksConnected member of each pad the track(s) connected to
* D_PAD::m_TracksConnected is cleared before adding items * D_PAD::m_TracksConnected is cleared before adding items
* TRACK::m_PadsConnected is not cleared * TRACK::m_PadsConnected is not cleared
* @param add_to_padlist = true to fill m_PadsConnected member of each track
* @param add_to_tracklist = true to fill m_TracksConnected member of each pad
*/ */
void SearchTracksConnectedToPads(); void SearchTracksConnectedToPads( bool add_to_padlist = true, bool add_to_tracklist = true);
/** /**
* function CollectItemsNearTo * function CollectItemsNearTo
......
...@@ -78,7 +78,7 @@ DIALOG_GENDRILL::DIALOG_GENDRILL( PCB_EDIT_FRAME* parent ) : ...@@ -78,7 +78,7 @@ DIALOG_GENDRILL::DIALOG_GENDRILL( PCB_EDIT_FRAME* parent ) :
int DIALOG_GENDRILL:: m_UnitDrillIsInch = true; int DIALOG_GENDRILL:: m_UnitDrillIsInch = true;
int DIALOG_GENDRILL:: m_ZerosFormat = EXCELLON_WRITER::DECIMAL_FORMAT; int DIALOG_GENDRILL:: m_ZerosFormat = EXCELLON_WRITER::DECIMAL_FORMAT;
bool DIALOG_GENDRILL::m_MinimalHeader = false; bool DIALOG_GENDRILL::m_MinimalHeader = false;
bool DIALOG_GENDRILL::m_Mirror = true; bool DIALOG_GENDRILL::m_Mirror = false;
bool DIALOG_GENDRILL::m_DrillOriginIsAuxAxis = false; bool DIALOG_GENDRILL::m_DrillOriginIsAuxAxis = false;
int DIALOG_GENDRILL:: m_PrecisionFormat = 1; int DIALOG_GENDRILL:: m_PrecisionFormat = 1;
bool DIALOG_GENDRILL::m_createRpt = false; bool DIALOG_GENDRILL::m_createRpt = false;
......
/** /**
* @file drag.h * @file drag.h
* @brief Useful class and functions used to drag tracks * @brief Useful classes and functions used to collect tracks to drag
*/ */
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2004-2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <vector> #include <vector>
#include <wx/gdicmn.h> #include <wx/gdicmn.h>
...@@ -13,62 +36,151 @@ class wxDC; ...@@ -13,62 +36,151 @@ class wxDC;
class EDA_DRAW_PANEL; class EDA_DRAW_PANEL;
class MODULE; class MODULE;
class D_PAD; class D_PAD;
class CONNECTIONS;
/** Helper class to handle a list of track segments to drag /** Helper classes to handle a list of track segments to drag
* and has info to undo/abort the move command * and has info to undo/abort the move command
* a DRAG_SEGM manage one track segment or a via
*/ */
class DRAG_SEGM
/*
* a DRAG_LIST manages the list of track segments to modify
* when the pad or the module is moving
*/
/*
* a DRAG_SEGM_PICKER manage one track segment or a via
*/
class DRAG_SEGM_PICKER
{ {
public: public:
TRACK* m_Segm; /* pointer to the segment a "dragger */ TRACK* m_Track; // pointer to the parent track segment
D_PAD* m_Pad_Start; /* pointer to the pad origin if origin segment of pad */ D_PAD* m_Pad_Start; // pointer to the moving pad
D_PAD* m_Pad_End; /* pointer to the pad end if end segment of pad */ // if the start point should follow this pad
int m_Flag; /* indicator flags */ // or NULL
D_PAD* m_Pad_End; // pointer to the moving pad
// if the end point should follow this pad
// or NULL
bool m_Flag; // flag used in drag vias and drag track segment functions
private: private:
wxPoint m_StartInitialValue; double m_RotationOffset; // initial orientation of the parent module
wxPoint m_EndInitialValue; // For abort: initial m_Start and m_End values for m_Segm // Used to recalculate m_PadStartOffset and m_PadEndOffset
// after a module rotation when dragging
bool m_Flipped; // initial side of the parent module
// Used to recalculate m_PadStartOffset and m_PadEndOffset
// if the module is flipped when dragging
wxPoint m_PadStartOffset; // offset between the pad and the starting point of the track
// usually 0,0, but not always
wxPoint m_PadEndOffset; // offset between the pad and the ending point of the track
// usually 0,0, but not always
wxPoint m_startInitialValue;
wxPoint m_endInitialValue; // For abort command:
// initial m_Start and m_End values for m_Track
public:
DRAG_SEGM_PICKER( TRACK* aTrack );
~DRAG_SEGM_PICKER() {};
/**
* Set auxiliary parameters relative to calucaltions needed
* to find track ends positions while dragging pads
* and when modules are rotated, flipped ..
*/
void SetAuxParameters();
/**
* Calculate track ends position while dragging pads
* and when modules are rotated, flipped ..
* @param aOffset = offset of module or pad position (when moving)
*/
void SetTrackEndsCoordinates(wxPoint aOffset);
void RestoreInitialValues()
{
m_Track->SetStart( m_startInitialValue );
m_Track->SetEnd( m_endInitialValue );
}
};
class DRAG_LIST
{
public: public:
BOARD * m_Brd; // the main board
MODULE * m_Module; // The link to the module to move, or NULL
D_PAD * m_Pad; // The link to the pad to move, or NULL
DRAG_SEGM( TRACK* segm ); std::vector<DRAG_SEGM_PICKER> m_DragList; // The list of DRAG_SEGM_PICKER items
~DRAG_SEGM() {};
void SetInitialValues() public:
DRAG_LIST( BOARD * aPcb )
{ {
m_Segm->m_Start = m_StartInitialValue; m_Brd = aPcb;
m_Segm->m_End = m_EndInitialValue;
} }
/**
* Function ClearList
* clear the .m_Flags of all track segments in m_DragList
* and clear the list.
*/
void ClearList();
/** Build the list of track segments connected to pads of aModule
* in m_DragList
* For each selected track segment the EDIT flag is set
*/
void BuildDragListe( MODULE* aModule );
/** Build the list of track segments connected to aPad
* in m_DragList
* For each selected track segment the EDIT flag is set
*/
void BuildDragListe( D_PAD* aPad );
private:
/** Fills m_DragList with of track segments connected to pads in aConnections
* For each selected track segment the EDIT flag is set
*/
void fillList(CONNECTIONS& aConnections);
}; };
/* Variables */
// a list of DRAG_SEGM items used to move or drag tracks. // Global variables:
// Each DRAG_SEGM item points a segment to move.
extern std::vector<DRAG_SEGM> g_DragSegmentList;
/* Functions */ // a list of DRAG_SEGM_PICKER items used to move or drag tracks.
void DrawSegmentWhileMovingFootprint( EDA_DRAW_PANEL* panel, wxDC* DC ); // Each DRAG_SEGM_PICKER item points a segment to move.
void Build_Drag_Liste( EDA_DRAW_PANEL* panel, wxDC* DC, MODULE* Module ); extern std::vector<DRAG_SEGM_PICKER> g_DragSegmentList;
void Build_1_Pad_SegmentsToDrag( EDA_DRAW_PANEL* panel, wxDC* DC, D_PAD* PtPad );
void Collect_TrackSegmentsToDrag( EDA_DRAW_PANEL* panel, wxDC* DC,
wxPoint& point, int LayerMask, int net_code );
// Functions:
void DrawSegmentWhileMovingFootprint( EDA_DRAW_PANEL* panel, wxDC* DC );
/** /**
* Function EraseDragList * Function EraseDragList
* clear the .m_Flags of all track segments managed by in g_DragSegmentList * clear the .m_Flags of all track segments stored in g_DragSegmentList
* and clear the list. * and clear the list.
* In order to avoid useless memory allocation, the memory is not freed * In order to avoid useless memory reallocation, the memory is not freed
* and will be reused when creating a new list * and will be reused when creating a new list
*/ */
void EraseDragList(); void EraseDragList();
/* Add the segment"Track" to the drag list, and erase it from screen /*
* function used to collect track segments in drag track segment
*/
void Collect_TrackSegmentsToDrag( BOARD* aPcb, wxPoint& point, int LayerMask, int net_code );
/* Add aTrack to the drag list
* flag = STARTPOINT (if the point to drag is the start point of Track) * flag = STARTPOINT (if the point to drag is the start point of Track)
* or ENDPOINT * or ENDPOINT (if the point to drag is the end point of Track)
*/
void AddSegmentToDragList( int flag, TRACK* aTrack );
/*
* Undraw the track segments in list, and set the EDIT flag
* Usually called after the track list is built, to prepare
* the redraw of the list when the mouse is moved
*/ */
void AddSegmentToDragList( EDA_DRAW_PANEL* panel, wxDC* DC, int flag, TRACK* Track ); void UndrawAndMarkSegmentsToDrag( EDA_DRAW_PANEL* aCanvas, wxDC* aDC );
This diff is collapsed.
...@@ -614,8 +614,6 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -614,8 +614,6 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break; break;
case ID_POPUP_PCB_DRAG_MODULE_REQUEST: case ID_POPUP_PCB_DRAG_MODULE_REQUEST:
g_Drag_Pistes_On = true;
case ID_POPUP_PCB_MOVE_MODULE_REQUEST: case ID_POPUP_PCB_MOVE_MODULE_REQUEST:
if( GetCurItem() == NULL ) if( GetCurItem() == NULL )
break; break;
...@@ -625,10 +623,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -625,10 +623,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
SetCurItem( GetCurItem()->GetParent() ); SetCurItem( GetCurItem()->GetParent() );
if( !GetCurItem() || GetCurItem()->Type() != PCB_MODULE_T ) if( !GetCurItem() || GetCurItem()->Type() != PCB_MODULE_T )
{
g_Drag_Pistes_On = false;
break; break;
}
module = (MODULE*) GetCurItem(); module = (MODULE*) GetCurItem();
...@@ -644,7 +639,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -644,7 +639,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
SendMessageToEESCHEMA( module ); SendMessageToEESCHEMA( module );
GetScreen()->SetCrossHairPosition( module->m_Pos ); GetScreen()->SetCrossHairPosition( module->m_Pos );
m_canvas->MoveCursorToCrossHair(); m_canvas->MoveCursorToCrossHair();
StartMove_Module( module, &dc ); StartMoveModule( module, &dc, id == ID_POPUP_PCB_DRAG_MODULE_REQUEST );
break; break;
case ID_POPUP_PCB_GET_AND_MOVE_MODULE_REQUEST: /* get module by name and move it */ case ID_POPUP_PCB_GET_AND_MOVE_MODULE_REQUEST: /* get module by name and move it */
...@@ -665,7 +660,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -665,7 +660,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
SendMessageToEESCHEMA( module ); SendMessageToEESCHEMA( module );
m_canvas->MoveCursorToCrossHair(); m_canvas->MoveCursorToCrossHair();
StartMove_Module( module, &dc ); StartMoveModule( module, &dc, false );
break; break;
case ID_POPUP_PCB_DELETE_MODULE: case ID_POPUP_PCB_DELETE_MODULE:
...@@ -809,9 +804,8 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -809,9 +804,8 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break; break;
} }
g_Drag_Pistes_On = true;
m_canvas->MoveCursorToCrossHair(); m_canvas->MoveCursorToCrossHair();
StartMovePad( (D_PAD*) GetCurItem(), &dc ); StartMovePad( (D_PAD*) GetCurItem(), &dc, true );
break; break;
case ID_POPUP_PCB_MOVE_PAD_REQUEST: case ID_POPUP_PCB_MOVE_PAD_REQUEST:
...@@ -829,9 +823,8 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -829,9 +823,8 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break; break;
} }
g_Drag_Pistes_On = false;
m_canvas->MoveCursorToCrossHair(); m_canvas->MoveCursorToCrossHair();
StartMovePad( (D_PAD*) GetCurItem(), &dc ); StartMovePad( (D_PAD*) GetCurItem(), &dc, false );
break; break;
case ID_POPUP_PCB_EDIT_PAD: case ID_POPUP_PCB_EDIT_PAD:
......
...@@ -566,7 +566,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -566,7 +566,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_POPUP_PCB_MOVE_PAD_REQUEST: case ID_POPUP_PCB_MOVE_PAD_REQUEST:
{ {
m_canvas->MoveCursorToCrossHair(); m_canvas->MoveCursorToCrossHair();
StartMovePad( (D_PAD*) GetScreen()->GetCurItem(), &dc ); StartMovePad( (D_PAD*) GetScreen()->GetCurItem(), &dc, false );
} }
break; break;
......
...@@ -91,9 +91,10 @@ MODULE* PCB_BASE_FRAME::GetModuleByName() ...@@ -91,9 +91,10 @@ MODULE* PCB_BASE_FRAME::GetModuleByName()
} }
void PCB_EDIT_FRAME::StartMove_Module( MODULE* module, wxDC* DC ) void PCB_EDIT_FRAME::StartMoveModule( MODULE* aModule, wxDC* aDC,
bool aDragConnectedTracks )
{ {
if( module == NULL ) if( aModule == NULL )
return; return;
if( s_ModuleInitialCopy ) if( s_ModuleInitialCopy )
...@@ -102,33 +103,37 @@ void PCB_EDIT_FRAME::StartMove_Module( MODULE* module, wxDC* DC ) ...@@ -102,33 +103,37 @@ void PCB_EDIT_FRAME::StartMove_Module( MODULE* module, wxDC* DC )
s_PickedList.ClearItemsList(); // Should be empty, but... s_PickedList.ClearItemsList(); // Should be empty, but...
// Creates a copy of the current module, for abort and undo commands // Creates a copy of the current module, for abort and undo commands
s_ModuleInitialCopy = (MODULE*)module->Clone(); s_ModuleInitialCopy = (MODULE*)aModule->Clone();
s_ModuleInitialCopy->SetParent( GetBoard() ); s_ModuleInitialCopy->SetParent( GetBoard() );
s_ModuleInitialCopy->ClearFlags(); s_ModuleInitialCopy->ClearFlags();
SetCurItem( module ); SetCurItem( aModule );
GetBoard()->m_Status_Pcb &= ~RATSNEST_ITEM_LOCAL_OK; GetBoard()->m_Status_Pcb &= ~RATSNEST_ITEM_LOCAL_OK;
module->SetFlags( IS_MOVED ); aModule->SetFlags( IS_MOVED );
/* Show ratsnest. */ /* Show ratsnest. */
if( GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) ) if( GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) )
DrawGeneralRatsnest( DC ); DrawGeneralRatsnest( aDC );
EraseDragList(); EraseDragList();
if( g_Drag_Pistes_On ) if( aDragConnectedTracks )
{ {
Build_Drag_Liste( m_canvas, DC, module ); DRAG_LIST drglist( GetBoard() );
drglist.BuildDragListe( aModule );
ITEM_PICKER itemWrapper( NULL, UR_CHANGED ); ITEM_PICKER itemWrapper( NULL, UR_CHANGED );
for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ ) for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
{ {
TRACK* segm = g_DragSegmentList[ii].m_Segm; TRACK* segm = g_DragSegmentList[ii].m_Track;
itemWrapper.SetItem( segm ); itemWrapper.SetItem( segm );
itemWrapper.SetLink( segm->Clone() ); itemWrapper.SetLink( segm->Clone() );
itemWrapper.GetLink()->SetState( IN_EDIT, OFF ); itemWrapper.GetLink()->SetState( IN_EDIT, OFF );
s_PickedList.PushItem( itemWrapper ); s_PickedList.PushItem( itemWrapper );
} }
UndrawAndMarkSegmentsToDrag( m_canvas, aDC );
} }
GetBoard()->m_Status_Pcb |= DO_NOT_SHOW_GENERAL_RASTNEST; GetBoard()->m_Status_Pcb |= DO_NOT_SHOW_GENERAL_RASTNEST;
...@@ -136,14 +141,14 @@ void PCB_EDIT_FRAME::StartMove_Module( MODULE* module, wxDC* DC ) ...@@ -136,14 +141,14 @@ void PCB_EDIT_FRAME::StartMove_Module( MODULE* module, wxDC* DC )
m_canvas->SetAutoPanRequest( true ); m_canvas->SetAutoPanRequest( true );
// Erase the module. // Erase the module.
if( DC ) if( aDC )
{ {
module->SetFlags( DO_NOT_DRAW ); aModule->SetFlags( DO_NOT_DRAW );
m_canvas->RefreshDrawingRect( module->GetBoundingBox() ); m_canvas->RefreshDrawingRect( aModule->GetBoundingBox() );
module->ClearFlags( DO_NOT_DRAW ); aModule->ClearFlags( DO_NOT_DRAW );
} }
m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false );
} }
...@@ -169,22 +174,13 @@ void Abort_MoveOrCopyModule( EDA_DRAW_PANEL* Panel, wxDC* DC ) ...@@ -169,22 +174,13 @@ void Abort_MoveOrCopyModule( EDA_DRAW_PANEL* Panel, wxDC* DC )
*/ */
if( module->IsMoving() ) if( module->IsMoving() )
{ {
if( g_Drag_Pistes_On ) /* Restore old position for dragged tracks */
{
/* Erase on screen dragged tracks */
for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
{
pt_segm = g_DragSegmentList[ii].m_Segm;
pt_segm->Draw( Panel, DC, GR_XOR );
}
}
/* Go to old position for dragged tracks */
for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ ) for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
{ {
pt_segm = g_DragSegmentList[ii].m_Segm; pt_segm = g_DragSegmentList[ii].m_Track;
pt_segm->Draw( Panel, DC, GR_XOR );
pt_segm->SetState( IN_EDIT, OFF ); pt_segm->SetState( IN_EDIT, OFF );
g_DragSegmentList[ii].SetInitialValues(); g_DragSegmentList[ii].RestoreInitialValues();
pt_segm->Draw( Panel, DC, GR_OR ); pt_segm->Draw( Panel, DC, GR_OR );
} }
...@@ -213,7 +209,6 @@ void Abort_MoveOrCopyModule( EDA_DRAW_PANEL* Panel, wxDC* DC ) ...@@ -213,7 +209,6 @@ void Abort_MoveOrCopyModule( EDA_DRAW_PANEL* Panel, wxDC* DC )
module->Draw( Panel, DC, GR_OR ); module->Draw( Panel, DC, GR_OR );
} }
g_Drag_Pistes_On = false;
pcbframe->SetCurItem( NULL ); pcbframe->SetCurItem( NULL );
delete s_ModuleInitialCopy; delete s_ModuleInitialCopy;
...@@ -363,7 +358,6 @@ void PCB_EDIT_FRAME::Change_Side_Module( MODULE* Module, wxDC* DC ) ...@@ -363,7 +358,6 @@ void PCB_EDIT_FRAME::Change_Side_Module( MODULE* Module, wxDC* DC )
void PCB_BASE_FRAME::PlaceModule( MODULE* aModule, wxDC* aDC, bool aDoNotRecreateRatsnest ) void PCB_BASE_FRAME::PlaceModule( MODULE* aModule, wxDC* aDC, bool aDoNotRecreateRatsnest )
{ {
TRACK* pt_segm;
wxPoint newpos; wxPoint newpos;
if( aModule == 0 ) if( aModule == 0 )
...@@ -406,23 +400,19 @@ void PCB_BASE_FRAME::PlaceModule( MODULE* aModule, wxDC* aDC, bool aDoNotRecreat ...@@ -406,23 +400,19 @@ void PCB_BASE_FRAME::PlaceModule( MODULE* aModule, wxDC* aDC, bool aDoNotRecreat
if( aDC ) if( aDC )
aModule->Draw( m_canvas, aDC, GR_OR ); aModule->Draw( m_canvas, aDC, GR_OR );
if( g_DragSegmentList.size() ) // Redraw dragged track segments, if any
for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
{ {
/* Redraw dragged track segments */ TRACK * track = g_DragSegmentList[ii].m_Track;
for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ ) track->SetState( IN_EDIT, OFF );
{
pt_segm = g_DragSegmentList[ii].m_Segm;
pt_segm->SetState( IN_EDIT, OFF );
if( aDC ) if( aDC )
pt_segm->Draw( m_canvas, aDC, GR_OR ); track->Draw( m_canvas, aDC, GR_OR );
}
// Delete drag list
EraseDragList();
} }
g_Drag_Pistes_On = false; // Delete drag list
EraseDragList();
m_canvas->SetMouseCapture( NULL, NULL ); m_canvas->SetMouseCapture( NULL, NULL );
if( GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) && !aDoNotRecreateRatsnest ) if( GetBoard()->IsElementVisible( RATSNEST_VISIBLE ) && !aDoNotRecreateRatsnest )
......
This diff is collapsed.
This diff is collapsed.
...@@ -101,7 +101,7 @@ void PCB_EDIT_FRAME::MuWaveCommand( wxDC* DC, const wxPoint& MousePos ) ...@@ -101,7 +101,7 @@ void PCB_EDIT_FRAME::MuWaveCommand( wxDC* DC, const wxPoint& MousePos )
if( module ) if( module )
{ {
StartMove_Module( module, DC ); StartMoveModule( module, DC, false );
} }
m_canvas->MoveCursorToCrossHair(); m_canvas->MoveCursorToCrossHair();
......
...@@ -221,7 +221,7 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) ...@@ -221,7 +221,7 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
} }
else else
{ {
DisplayError( this, wxT( "Internal err: Struct not PCB_TARGET_T" ) ); DisplayError( this, wxT( "OnLeftClick err: not a PCB_TARGET_T" ) );
} }
break; break;
...@@ -333,7 +333,7 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) ...@@ -333,7 +333,7 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
} }
else else
{ {
DisplayError( this, wxT( "Internal err: Struct not PCB_TEXT_T" ) ); DisplayError( this, wxT( "OnLeftClick err: not a PCB_TEXT_T" ) );
} }
break; break;
...@@ -346,7 +346,7 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) ...@@ -346,7 +346,7 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
SetCurItem( DrawStruct ); SetCurItem( DrawStruct );
if( DrawStruct ) if( DrawStruct )
StartMove_Module( (MODULE*) DrawStruct, aDC ); StartMoveModule( (MODULE*) DrawStruct, aDC, false );
} }
else if( DrawStruct->Type() == PCB_MODULE_T ) else if( DrawStruct->Type() == PCB_MODULE_T )
{ {
......
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2011 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
*/
/**
* @file pad_change_functions.cpp
*/
#include <fctsys.h>
#include <class_drawpanel.h>
#include <confirm.h>
#include <trigo.h>
#include <wxBasePcbFrame.h>
#include <pcbnew.h>
#include <class_board.h>
#include <class_module.h>
#include <class_pad.h>
#include <class_board_design_settings.h>
/* Exports the current pad settings to board design settings.
*/
void PCB_BASE_FRAME::Export_Pad_Settings( D_PAD* aPad )
{
if( aPad == NULL )
return;
aPad->DisplayInfo( this );
D_PAD& mp = GetDesignSettings().m_Pad_Master;
mp.SetShape( aPad->GetShape() );
mp.SetAttribute( aPad->GetAttribute() );
mp.SetLayerMask( aPad->GetLayerMask() );
mp.SetOrientation( aPad->GetOrientation() - aPad->GetParent()->GetOrientation() );
mp.SetSize( aPad->GetSize() );
mp.SetDelta( aPad->GetDelta() );
mp.SetOffset( aPad->GetOffset() );
mp.SetDrillSize( aPad->GetDrillSize() );
mp.SetDrillShape( aPad->GetDrillShape() );
}
/* Imports the board design settings to aPad
* - The position, names, and keys are not modifed.
*/
void PCB_BASE_FRAME::Import_Pad_Settings( D_PAD* aPad, bool aDraw )
{
if( aDraw )
{
aPad->SetFlags( DO_NOT_DRAW );
m_canvas->RefreshDrawingRect( aPad->GetBoundingBox() );
aPad->ClearFlags( DO_NOT_DRAW );
}
D_PAD& mp = GetDesignSettings().m_Pad_Master;
aPad->SetShape( mp.GetShape() );
aPad->SetLayerMask( mp.GetLayerMask() );
aPad->SetAttribute( mp.GetAttribute() );
aPad->SetOrientation( mp.GetOrientation() + aPad->GetParent()->GetOrientation() );
aPad->SetSize( mp.GetSize() );
aPad->SetDelta( wxSize( 0, 0 ) );
aPad->SetOffset( mp.GetOffset() );
aPad->SetDrillSize( mp.GetDrillSize() );
aPad->SetDrillShape( mp.GetDrillShape() );
switch( mp.GetShape() )
{
case PAD_TRAPEZOID:
aPad->SetDelta( mp.GetDelta() );
break;
case PAD_CIRCLE:
// ensure size.y == size.x
aPad->SetSize( wxSize( aPad->GetSize().x, aPad->GetSize().x ) );
break;
default:
;
}
switch( mp.GetAttribute() )
{
case PAD_SMD:
case PAD_CONN:
aPad->SetDrillSize( wxSize( 0, 0 ) );
aPad->SetOffset( wxPoint( 0, 0 ) );
break;
default:
;
}
if( aDraw )
m_canvas->RefreshDrawingRect( aPad->GetBoundingBox() );
aPad->GetParent()->SetLastEditTime();
}
/* Add a new pad to aModule.
*/
void PCB_BASE_FRAME::AddPad( MODULE* aModule, bool draw )
{
// Last used pad name (pad num)
wxString lastPadName = GetDesignSettings().m_Pad_Master.GetPadName();
m_Pcb->m_Status_Pcb = 0;
aModule->SetLastEditTime();
D_PAD* pad = new D_PAD( aModule );
// Add the new pad to end of the module pad list.
aModule->m_Pads.PushBack( pad );
// Update the pad properties.
Import_Pad_Settings( pad, false );
pad->SetNetname( wxEmptyString );
pad->SetPosition( GetScreen()->GetCrossHairPosition() );
// Set the relative pad position
// ( pad position for module orient, 0, and relative to the module position)
wxPoint pos0 = pad->GetPosition() - aModule->GetPosition();
RotatePoint( &pos0, -aModule->GetOrientation() );
pad->SetPos0( pos0 );
// Automatically increment the current pad number.
long num = 0;
int ponder = 1;
while( lastPadName.Len() && lastPadName.Last() >= '0' && lastPadName.Last() <= '9' )
{
num += ( lastPadName.Last() - '0' ) * ponder;
lastPadName.RemoveLast();
ponder *= 10;
}
num++; // Use next number for the new pad
lastPadName << num;
pad->SetPadName( lastPadName );
GetDesignSettings().m_Pad_Master.SetPadName(lastPadName);
aModule->CalculateBoundingBox();
pad->DisplayInfo( this );
if( draw )
m_canvas->RefreshDrawingRect( aModule->GetBoundingBox() );
}
/**
* Function DeletePad
* Delete the pad aPad.
* Refresh the modified screen area
* Refresh modified parameters of the parent module (bounding box, last date)
* @param aPad = the pad to delete
* @param aQuery = true to promt for confirmation, false to delete silently
*/
void PCB_BASE_FRAME::DeletePad( D_PAD* aPad, bool aQuery )
{
MODULE* module;
if( aPad == NULL )
return;
module = (MODULE*) aPad->GetParent();
module->SetLastEditTime();
if( aQuery )
{
wxString msg;
msg.Printf( _( "Delete Pad (module %s %s) " ),
GetChars( module->m_Reference->m_Text ),
GetChars( module->m_Value->m_Text ) );
if( !IsOK( this, msg ) )
return;
}
m_Pcb->m_Status_Pcb = 0;
aPad->DeleteStructure();
m_canvas->RefreshDrawingRect( module->GetBoundingBox() );
module->CalculateBoundingBox();
OnModify();
}
// Rotate selected pad 90 degrees.
void PCB_BASE_FRAME::RotatePad( D_PAD* aPad, wxDC* DC )
{
if( aPad == NULL )
return;
MODULE* module = aPad->GetParent();
module->SetLastEditTime();
OnModify();
if( DC )
module->Draw( m_canvas, DC, GR_XOR );
wxSize sz = aPad->GetSize();
EXCHG( sz.x, sz.y );
aPad->SetSize( sz );
sz = aPad->GetDrillSize();
EXCHG( sz.x, sz.y );
aPad->SetDrillSize( sz );
wxPoint pt = aPad->GetOffset();
EXCHG( pt.x, pt.y );
aPad->SetOffset( pt );
aPad->SetOffset( wxPoint( aPad->GetOffset().x, -aPad->GetOffset().y ) );
sz = aPad->GetDelta();
EXCHG( sz.x, sz.y );
sz.x = -sz.x;
aPad->SetDelta( sz );
module->CalculateBoundingBox();
aPad->DisplayInfo( this );
if( DC )
module->Draw( m_canvas, DC, GR_OR );
}
...@@ -58,7 +58,6 @@ COLORS_DESIGN_SETTINGS g_ColorsSettings; ...@@ -58,7 +58,6 @@ COLORS_DESIGN_SETTINGS g_ColorsSettings;
bool Drc_On = true; bool Drc_On = true;
bool g_AutoDeleteOldTrack = true; bool g_AutoDeleteOldTrack = true;
bool g_Drag_Pistes_On;
bool g_Show_Module_Ratsnest; bool g_Show_Module_Ratsnest;
bool g_Raccord_45_Auto = true; bool g_Raccord_45_Auto = true;
bool g_Alternate_Track_Posture = false; bool g_Alternate_Track_Posture = false;
...@@ -107,13 +106,13 @@ bool EDA_APP::OnInit() ...@@ -107,13 +106,13 @@ bool EDA_APP::OnInit()
wxFileName fn; wxFileName fn;
PCB_EDIT_FRAME* frame = NULL; PCB_EDIT_FRAME* frame = NULL;
#ifdef KICAD_SCRIPTING #ifdef KICAD_SCRIPTING
if ( !pcbnewInitPythonScripting() ) if ( !pcbnewInitPythonScripting() )
{ {
return false; return false;
} }
#endif #endif
InitEDA_Appl( wxT( "Pcbnew" ), APP_PCBNEW_T ); InitEDA_Appl( wxT( "Pcbnew" ), APP_PCBNEW_T );
if( m_Checker && m_Checker->IsAnotherRunning() ) if( m_Checker && m_Checker->IsAnotherRunning() )
...@@ -149,10 +148,10 @@ Changing extension to .brd." ), GetChars( fn.GetFullPath() ) ); ...@@ -149,10 +148,10 @@ Changing extension to .brd." ), GetChars( fn.GetFullPath() ) );
frame = new PCB_EDIT_FRAME( NULL, wxT( "Pcbnew" ), wxPoint( 0, 0 ), wxSize( 600, 400 ) ); frame = new PCB_EDIT_FRAME( NULL, wxT( "Pcbnew" ), wxPoint( 0, 0 ), wxSize( 600, 400 ) );
#ifdef KICAD_SCRIPTING #ifdef KICAD_SCRIPTING
ScriptingSetPcbEditFrame(frame); /* give the scripting helpers access to our frame */ ScriptingSetPcbEditFrame(frame); /* give the scripting helpers access to our frame */
#endif #endif
frame->UpdateTitle(); frame->UpdateTitle();
SetTopWindow( frame ); SetTopWindow( frame );
...@@ -224,7 +223,7 @@ int EDA_APP::OnExit() { ...@@ -224,7 +223,7 @@ int EDA_APP::OnExit() {
#if KICAD_SCRIPTING_WXPYTHON #if KICAD_SCRIPTING_WXPYTHON
pcbnewFinishPythonScripting(); pcbnewFinishPythonScripting();
#endif #endif
return 0; return 0;
} }
#endif #endif
......
...@@ -51,7 +51,6 @@ extern wxString g_DocModulesFileName; ...@@ -51,7 +51,6 @@ extern wxString g_DocModulesFileName;
/* variables */ /* variables */
extern bool Drc_On; extern bool Drc_On;
extern bool g_AutoDeleteOldTrack; extern bool g_AutoDeleteOldTrack;
extern bool g_Drag_Pistes_On;
extern bool g_Show_Module_Ratsnest; extern bool g_Show_Module_Ratsnest;
extern bool g_Raccord_45_Auto; extern bool g_Raccord_45_Auto;
extern bool g_Track_45_Only_Allowed; extern bool g_Track_45_Only_Allowed;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment