Remove CurItem() architecture and legacy routers and drawing code.

This commit is contained in:
Jeff Young 2019-05-29 00:23:58 +01:00
parent 9d29e94cb5
commit 1e9da7f57b
82 changed files with 548 additions and 8135 deletions

View File

@ -59,8 +59,6 @@ BASE_SCREEN::BASE_SCREEN( KICAD_T aType ) :
m_FlagModified = false; // Set when any change is made on board.
m_FlagSave = false; // Used in auto save set when an auto save is required.
SetCurItem( NULL );
}

View File

@ -578,10 +578,7 @@ void EDA_DRAW_FRAME::SetMsgPanel( EDA_ITEM* aItem )
void EDA_DRAW_FRAME::UpdateMsgPanel()
{
EDA_ITEM* item = GetScreen()->GetCurItem();
if( item )
SetMsgPanel( item );
GetToolManager()->PostEvent( EVENTS::SelectedItemsModified );
}

View File

@ -674,10 +674,7 @@ void EDA_DRAW_FRAME::SetMsgPanel( EDA_ITEM* aItem )
void EDA_DRAW_FRAME::UpdateMsgPanel()
{
EDA_ITEM* item = GetScreen()->GetCurItem();
if( item )
SetMsgPanel( item );
GetToolManager()->PostEvent( EVENTS::SelectedItemsModified );
}

View File

@ -533,6 +533,7 @@ void EDA_DRAW_PANEL::DoPrepareDC( wxDC& dc )
void EDA_DRAW_PANEL::OnPaint( wxPaintEvent& event )
{
// JEY TODO: this is all OBSOLETE...
if( GetScreen() == NULL )
{
event.Skip();

View File

@ -574,7 +574,6 @@ void LIB_EDIT_FRAME::SetCurPart( LIB_PART* aPart )
return;
m_toolManager->RunAction( EE_ACTIONS::clearSelection, true );
GetScreen()->SetCurItem( nullptr );
if( m_my_part != aPart )
{

View File

@ -209,9 +209,6 @@ void SCH_SCREEN::DeleteItem( SCH_ITEM* aItem )
}
else
{
if( GetCurItem() == aItem )
SetCurItem( nullptr );
m_drawList.Remove( aItem );
delete aItem;
}

View File

@ -81,8 +81,6 @@ void GERBVIEW_FRAME::Erase_Current_DrawLayer( bool query )
if( query && !IsOK( this, msg ) )
return;
SetCurItem( NULL );
if( m_toolManager )
m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD );

View File

@ -45,6 +45,8 @@
#include <gerbview_draw_panel_gal.h>
#include <gal/graphics_abstraction_layer.h>
#include <tool/tool_manager.h>
#include <tool/selection.h>
#include <tools/gerbview_selection_tool.h>
#include <gerbview_painter.h>
#include <view/view.h>
@ -138,10 +140,10 @@ END_EVENT_TABLE()
*/
void GERBVIEW_FRAME::Process_Special_Functions( wxCommandEvent& event )
{
// JEY TODO: OBSOLETE?
int id = event.GetId();
GERBER_DRAW_ITEM* currItem = (GERBER_DRAW_ITEM*) GetScreen()->GetCurItem();
int id = event.GetId();
GERBVIEW_SELECTION_TOOL* selTool = GetToolManager()->GetTool<GERBVIEW_SELECTION_TOOL>();
SELECTION& selection = selTool->GetSelection();
GERBER_DRAW_ITEM* currItem = (GERBER_DRAW_ITEM*) selection.Front();
switch( id )
{

View File

@ -994,26 +994,6 @@ void GERBVIEW_FRAME::SetAuxOrigin( const wxPoint& aPosition )
}
void GERBVIEW_FRAME::SetCurItem( GERBER_DRAW_ITEM* aItem, bool aDisplayInfo )
{
GetScreen()->SetCurItem( aItem );
if( aItem )
{
if( aDisplayInfo )
{
MSG_PANEL_ITEMS items;
aItem->GetMsgPanelInfo( m_UserUnits, items );
SetMsgPanel( items );
}
}
else
{
EraseMsgBox();
}
}
void GERBVIEW_FRAME::SetGridColor( COLOR4D aColor )
{
GetGalCanvas()->GetGAL()->SetGridColor( aColor );

View File

@ -108,18 +108,6 @@ public:
const TITLE_BLOCK& GetTitleBlock() const override;
void SetTitleBlock( const TITLE_BLOCK& aTitleBlock ) override;
/**
* Function SetCurItem
* sets the currently selected item and displays it in the MsgPanel.
* If the given item is NULL then the MsgPanel is erased and there is no
* currently selected item. This function is intended to make the process
* of "selecting" an item more formal, and to indivisibly tie the operation
* of selecting an item to displaying it using GERBER_DRAW_ITEM::Display_Infos().
* @param aItem The GERBER_DRAW_ITEM to make the selected item or NULL if none.
* @param aDisplayInfo = true to display item info, false if not (default = true)
*/
void SetCurItem( GERBER_DRAW_ITEM* aItem, bool aDisplayInfo = true );
/** Install the dialog box for layer selection
* @param aDefaultLayer = Preselection (NB_PCB_LAYERS for "(Deselect)" layer)
* @param aCopperLayerCount = number of copper layers

View File

@ -240,6 +240,28 @@ int GERBVIEW_CONTROL::ShowHelp( const TOOL_EVENT& aEvent )
}
int GERBVIEW_CONTROL::UpdateMessagePanel( const TOOL_EVENT& aEvent )
{
GERBVIEW_SELECTION_TOOL* selTool = m_toolMgr->GetTool<GERBVIEW_SELECTION_TOOL>();
SELECTION& selection = selTool->GetSelection();
if( selection.GetSize() == 1 )
{
EDA_ITEM* item = (EDA_ITEM*) selection.Front();
MSG_PANEL_ITEMS msgItems;
item->GetMsgPanelInfo( m_frame->GetUserUnits(), msgItems );
m_frame->SetMsgPanel( msgItems );
}
else
{
m_frame->EraseMsgBox();
}
return 0;
}
void GERBVIEW_CONTROL::setTransitions()
{
Go( &GERBVIEW_CONTROL::HighlightControl, GERBVIEW_ACTIONS::highlightClear.MakeEvent() );
@ -257,4 +279,8 @@ void GERBVIEW_CONTROL::setTransitions()
Go( &GERBVIEW_CONTROL::DisplayControl, GERBVIEW_ACTIONS::dcodeDisplay.MakeEvent() );
Go( &GERBVIEW_CONTROL::ShowHelp, GERBVIEW_ACTIONS::showHelp.MakeEvent() );
Go( &GERBVIEW_CONTROL::UpdateMessagePanel, EVENTS::SelectedEvent );
Go( &GERBVIEW_CONTROL::UpdateMessagePanel, EVENTS::UnselectedEvent );
Go( &GERBVIEW_CONTROL::UpdateMessagePanel, EVENTS::ClearedEvent );
}

View File

@ -59,6 +59,7 @@ public:
// Miscellaneous
int SwitchUnits( const TOOL_EVENT& aEvent );
int ShowHelp( const TOOL_EVENT& aEvent );
int UpdateMessagePanel( const TOOL_EVENT& aEvent );
///> Sets up handlers for various events.
void setTransitions() override;

View File

@ -452,11 +452,6 @@ bool GERBVIEW_SELECTION_TOOL::selectMultiple()
}
}
if( m_selection.Size() == 1 )
m_frame->SetCurItem( static_cast<GERBER_DRAW_ITEM*>( m_selection.Front() ) );
else
m_frame->SetCurItem( NULL );
// Inform other potentially interested tools
if( !m_selection.Empty() )
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
@ -592,8 +587,6 @@ void GERBVIEW_SELECTION_TOOL::clearSelection()
m_selection.Clear();
m_frame->SetCurItem( NULL );
// Inform other potentially interested tools
m_toolMgr->ProcessEvent( EVENTS::ClearedEvent );
}
@ -727,17 +720,6 @@ void GERBVIEW_SELECTION_TOOL::select( EDA_ITEM* aItem )
m_selection.Add( aItem );
getView()->Add( &m_selection );
selectVisually( aItem );
if( m_selection.Size() == 1 )
{
// Set as the current item, so the information about selection is displayed
m_frame->SetCurItem( static_cast<GERBER_DRAW_ITEM*>( aItem ), true );
}
else if( m_selection.Size() == 2 ) // Check only for 2, so it will not be
{ // called for every next selected item
// If multiple items are selected, do not show the information about the selected item
m_frame->SetCurItem( NULL, true );
}
}
@ -750,10 +732,7 @@ void GERBVIEW_SELECTION_TOOL::unselect( EDA_ITEM* aItem )
m_selection.Remove( aItem );
if( m_selection.Empty() )
{
m_frame->SetCurItem( NULL );
getView()->Remove( &m_selection );
}
}

View File

@ -211,15 +211,6 @@ public:
BASE_SCREEN( KICAD_T aType = SCREEN_T );
~BASE_SCREEN();
/**
* Function SetCurItem
* sets the currently selected object, m_CurrentItem.
* @param aItem Any object derived from EDA_ITEM
*/
void SetCurItem( EDA_ITEM* aItem ) { m_CurrentItem = aItem; }
EDA_ITEM* GetCurItem() const { return m_CurrentItem; }
void InitDataPoints( const wxSize& aPageSizeInternalUnits );
/* general Undo/Redo command control */

View File

@ -75,7 +75,6 @@ public:
protected:
BOARD* m_Pcb;
GENERAL_COLLECTOR* m_Collector;
PCB_GENERAL_SETTINGS m_configSettings;
@ -242,23 +241,6 @@ public:
void ProcessItemSelection( wxCommandEvent& event );
/**
* Function SetCurItem
* sets the currently selected item and displays it in the MsgPanel.
* If the given item is NULL then the MsgPanel is erased and there is no
* currently selected item. This function is intended to make the process
* of "selecting" an item more formal, and to indivisibly tie the operation
* of selecting an item to displaying it using BOARD_ITEM::Display_Infos().
* @param aItem The BOARD_ITEM to make the selected item or NULL if none.
* @param aDisplayInfo = true to display item info, false if not (default = true)
*/
void SetCurItem( BOARD_ITEM* aItem, bool aDisplayInfo = true );
BOARD_ITEM* GetCurItem();
///> @copydoc EDA_DRAW_FRAME::UpdateMsgPanel()
void UpdateMsgPanel() override;
/**
* Function GetCollectorsGuide
* @return GENERAL_COLLECTORS_GUIDE - that considers the global
@ -310,7 +292,6 @@ public:
MODULE* CreateNewModule( const wxString& aModuleName );
void Edit_Module( MODULE* module, wxDC* DC );
void Rotate_Module( wxDC* DC, MODULE* module, double angle, bool incremental );
/**
* Function PlaceModule
@ -318,11 +299,9 @@ public:
* with the new position.
*
* @param aModule A MODULE object point of the module to be placed.
* @param aDC A wxDC object point of the device context to draw \a aModule on
* or NULL if no display screen need updated.
* @param aRecreateRatsnest A bool true redraws the module rats nest.
*/
void PlaceModule( MODULE* aModule, wxDC* aDC, bool aRecreateRatsnest = true );
void PlaceModule( MODULE* aModule, bool aRecreateRatsnest = true );
void InstallPadOptionsFrame( D_PAD* pad );
@ -379,24 +358,6 @@ public:
*/
void Compile_Ratsnest( wxDC* aDC, bool aDisplayStatus );
/**
* Function build_ratsnest_module
* Build a ratsnest relative to one footprint. This is a simplified computation
* used only in move footprint. It is not optimal, but it is fast and sufficient
* to help a footprint placement
* It shows the connections from a pad to the nearest connected pad
* @param aMoveVector = move vector of the footprint being moved.
* @param aModule = module to consider.
*/
void build_ratsnest_module( MODULE *aModule, wxPoint aMoveVector );
/**
* Function TraceModuleRatsNest
* display the rats nest of a moving footprint, computed by
* build_ratsnest_module()
*/
void TraceModuleRatsNest( wxDC* aDC );
/**
* function Displays the general ratsnest
* Only ratsnest with the status bit CH_VISIBLE is set are displayed
@ -406,29 +367,6 @@ public:
*/
void DrawGeneralRatsnest( wxDC* aDC, int aNetcode = 0 );
/**
* Function TraceAirWiresToTargets
* This functions shows airwires to nearest connecting points (pads)
* from the current new track end during track creation
* Uses data prepared by BuildAirWiresTargetsList()
* @param aDC = the current device context
*/
void TraceAirWiresToTargets( wxDC* aDC );
/**
* Function BuildAirWiresTargetsList
* Build a list of candidates that can be a coonection point
* when a track is started.
* This functions prepares data to show airwires to nearest connecting points (pads)
* from the current new track to candidates during track creation
* @param aItemRef = the item connected to the starting point of the new track (track or pad)
* @param aPosition = the position of the new track end (usually the mouse cursor on grid)
* @param aNet = the netcode of the track
*/
void BuildAirWiresTargetsList( BOARD_CONNECTED_ITEM* aItemRef,
const wxPoint& aPosition,
int aNet );
/**
* Function TestNetConnection
* tests the connections relative to \a aNetCode. Track segments are assumed to be

View File

@ -57,24 +57,6 @@ public:
PCB_SCREEN* Next() const { return static_cast<PCB_SCREEN*>( Pnext ); }
/**
* Function GetCurItem
* returns the currently selected BOARD_ITEM, overriding
* BASE_SCREEN::GetCurItem().
* @return BOARD_ITEM* - the one selected, or NULL.
*/
BOARD_ITEM* GetCurItem() const
{
return (BOARD_ITEM*) BASE_SCREEN::GetCurItem();
}
/**
* Function SetCurItem
* sets the currently selected object, m_CurrentItem.
* @param aItem Any object derived from BOARD_ITEM
*/
void SetCurItem( BOARD_ITEM* aItem ) { BASE_SCREEN::SetCurItem( (EDA_ITEM*)aItem ); }
/* full undo redo management : */
// use BASE_SCREEN::ClearUndoRedoList()

View File

@ -53,24 +53,6 @@ public:
* virtual pure in BASE_SCREEN, so it must be defined here
*/
void ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount = -1 ) override;
/**
* Function GetCurItem
* returns the currently selected WORKSHEET_DATAITEM, overriding
* BASE_SCREEN::GetCurItem().
* @return WORKSHEET_DATAITEM* - the one selected, or NULL.
*/
WS_DATA_ITEM* GetCurItem() const
{
return (WS_DATA_ITEM*) BASE_SCREEN::GetCurItem();
}
/**
* Function SetCurItem
* sets the currently selected object, m_CurrentItem.
* @param aItem Any object derived from WORKSHEET_DATAITEM
*/
void SetCurItem( WS_DATA_ITEM* aItem ) { BASE_SCREEN::SetCurItem( (EDA_ITEM*)aItem ); }
};

View File

@ -135,6 +135,7 @@ set( PCBNEW_DIALOGS
dialogs/dialog_set_grid_base.cpp
dialogs/dialog_swap_layers.cpp
dialogs/dialog_swap_layers_base.cpp
dialogs/dialog_target_properties.cpp
dialogs/dialog_target_properties_base.cpp
dialogs/dialog_text_properties.cpp
dialogs/dialog_text_properties_base.cpp
@ -236,16 +237,10 @@ set( PCBNEW_CLASS_SRCS
build_BOM_from_board.cpp
connect.cpp
cross-probing.cpp
deltrack.cpp
dimension.cpp
dragsegm.cpp
drc.cpp
drc_clearance_test_functions.cpp
edit.cpp
edit_track_width.cpp
editrack-part2.cpp
editrack.cpp
event_handlers_tracks_vias_sizes.cpp
files.cpp
footprint_info_impl.cpp
footprint_wizard.cpp
@ -263,16 +258,13 @@ set( PCBNEW_CLASS_SRCS
initpcb.cpp
layer_widget.cpp
load_select_footprint.cpp
magnetic_tracks_functions.cpp
menubar_footprint_editor.cpp
menubar_pcb_editor.cpp
microwave.cpp
minimun_spanning_tree.cpp
netlist.cpp
pad_edit_functions.cpp
pad_naming.cpp
pcb_base_edit_frame.cpp
pcb_footprint_edit_utils.cpp
pcb_layer_box_selector.cpp
pcb_layer_widget.cpp
# pcb_draw_panel_gal.cpp
@ -289,7 +281,6 @@ set( PCBNEW_CLASS_SRCS
specctra_import_export/specctra_export.cpp
specctra_import_export/specctra_import.cpp
specctra_import_export/specctra_keywords.cpp
target_edit.cpp
text_mod_grid_table.cpp
toolbars_footprint_editor.cpp
toolbars_footprint_viewer.cpp

View File

@ -1,278 +0,0 @@
/**
* @file autorout.cpp
* @brief Autorouting command and control.
*/
/*
* 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-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 <fctsys.h>
#include <class_drawpanel.h>
#include <wxPcbStruct.h>
#include <gr_basic.h>
#include <msgpanel.h>
#include <pcbnew.h>
#include <cell.h>
#include <zones.h>
#include <class_board.h>
#include <class_module.h>
#include <class_track.h>
#include <convert_to_biu.h>
#include <autorout.h>
MATRIX_ROUTING_HEAD RoutingMatrix; // routing matrix (grid) to route 2-sided boards
/* init board, route traces*/
void PCB_EDIT_FRAME::Autoroute( wxDC* DC, int mode )
{
int start, stop;
MODULE* Module = NULL;
D_PAD* Pad = NULL;
int autoroute_net_code = -1;
wxString msg;
if( GetBoard()->GetCopperLayerCount() > 1 )
{
g_Route_Layer_TOP = GetScreen()->m_Route_Layer_TOP;
g_Route_Layer_BOTTOM = GetScreen()->m_Route_Layer_BOTTOM;
}
else
{
g_Route_Layer_TOP = g_Route_Layer_BOTTOM = B_Cu;
}
switch( mode )
{
case ROUTE_NET:
if( GetScreen()->GetCurItem() )
{
switch( GetScreen()->GetCurItem()->Type() )
{
case PCB_PAD_T:
Pad = (D_PAD*) GetScreen()->GetCurItem();
autoroute_net_code = Pad->GetNetCode();
break;
default:
break;
}
}
if( autoroute_net_code <= 0 )
{
wxMessageBox( _( "Net not selected" ) ); return;
}
break;
case ROUTE_MODULE:
Module = (MODULE*) GetScreen()->GetCurItem();
if( (Module == NULL) || (Module->Type() != PCB_MODULE_T) )
{
wxMessageBox( _( "Footprint not selected" ) );
return;
}
break;
case ROUTE_PAD:
Pad = (D_PAD*) GetScreen()->GetCurItem();
if( (Pad == NULL) || (Pad->Type() != PCB_PAD_T) )
{
wxMessageBox( _( "Pad not selected" ) );
return;
}
break;
}
if( (GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK ) == 0 )
Compile_Ratsnest( DC, true );
/* Set the flag on the ratsnest to CH_ROUTE_REQ. */
for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
{
RATSNEST_ITEM* ptmp = &GetBoard()->m_FullRatsnest[ii];
ptmp->m_Status &= ~CH_ROUTE_REQ;
switch( mode )
{
case ROUTE_ALL:
ptmp->m_Status |= CH_ROUTE_REQ;
break;
case ROUTE_NET:
if( autoroute_net_code == ptmp->GetNet() )
ptmp->m_Status |= CH_ROUTE_REQ;
break;
case ROUTE_MODULE:
{
D_PAD* pt_pad = (D_PAD*) Module->Pads();
for( ; pt_pad != NULL; pt_pad = pt_pad->Next() )
{
if( ptmp->m_PadStart == pt_pad )
ptmp->m_Status |= CH_ROUTE_REQ;
if( ptmp->m_PadEnd == pt_pad )
ptmp->m_Status |= CH_ROUTE_REQ;
}
break;
}
case ROUTE_PAD:
if( ( ptmp->m_PadStart == Pad ) || ( ptmp->m_PadEnd == Pad ) )
ptmp->m_Status |= CH_ROUTE_REQ;
break;
}
}
start = time( NULL );
/* Calculation of no fixed routing to 5 mils and more. */
RoutingMatrix.m_GridRouting = (int)GetScreen()->GetGridSize().x;
if( RoutingMatrix.m_GridRouting < (5*IU_PER_MILS) )
RoutingMatrix.m_GridRouting = 5*IU_PER_MILS;
/* Calculated ncol and nrow, matrix size for routing. */
RoutingMatrix.ComputeMatrixSize( GetBoard() );
AUTOROUTER_CONTEXT ctx = { this, GetBoard(), RoutingMatrix.m_BrdBox, DC };
m_messagePanel->EraseMsgBox();
/* Map the board */
RoutingMatrix.m_RoutingLayersCount = 1;
if( g_Route_Layer_TOP != g_Route_Layer_BOTTOM )
RoutingMatrix.m_RoutingLayersCount = 2;
if( RoutingMatrix.InitRoutingMatrix() < 0 )
{
wxMessageBox( _( "No memory for autorouting" ) );
RoutingMatrix.UnInitRoutingMatrix(); /* Free memory. */
return;
}
SetStatusText( _( "Place Cells" ) );
PlaceCells( GetBoard(), -1, FORCE_PADS );
/* Construction of the track list for router. */
RoutingMatrix.m_RouteCount = Build_Work( GetBoard() );
// DisplayRoutingMatrix( m_canvas, DC );
Solve( ctx, RoutingMatrix.m_RoutingLayersCount );
/* Free memory. */
FreeQueue();
InitWork(); /* Free memory for the list of router connections. */
RoutingMatrix.UnInitRoutingMatrix();
stop = time( NULL ) - start;
msg.Printf( wxT( "time = %d second%s" ), stop, ( stop == 1 ) ? wxT( "" ) : wxT( "s" ) );
SetStatusText( msg );
}
/* Clear the flag CH_NOROUTABLE which is set to 1 by Solve(),
* when a track was not routed.
* (If this flag is 1 the corresponding track it is not rerouted)
*/
void PCB_EDIT_FRAME::Reset_Noroutable( wxDC* DC )
{
if( ( GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK )== 0 )
Compile_Ratsnest( DC, true );
for( unsigned ii = 0; ii < GetBoard()->GetRatsnestsCount(); ii++ )
{
GetBoard()->m_FullRatsnest[ii].m_Status &= ~CH_UNROUTABLE;
}
}
/* DEBUG Function: displays the routing matrix */
void DisplayRoutingMatrix( EDA_DRAW_PANEL* panel, wxDC* DC )
{
int dcell0;
COLOR4D color;
int maxi = 600 / RoutingMatrix.m_Ncols;
maxi = ( maxi * 3 ) / 4;
if( !maxi )
maxi = 1;
GRSetDrawMode( DC, GR_COPY );
for( int col = 0; col < RoutingMatrix.m_Ncols; col++ )
{
for( int row = 0; row < RoutingMatrix.m_Nrows; row++ )
{
color = COLOR4D::BLACK;
dcell0 = RoutingMatrix.GetCell( row, col, BOTTOM );
if( dcell0 & HOLE )
color = COLOR4D( GREEN );
#if 0
int dcell1 = 0;
if( RoutingMatrix.m_RoutingLayersCount )
dcell1 = GetCell( row, col, TOP );
if( dcell1 & HOLE )
color = COLOR4D( RED );
dcell0 |= dcell1;
#endif
if( ( color == COLOR4D::BLACK ) && ( dcell0 & VIA_IMPOSSIBLE ) )
color = COLOR4D( BLUE );
if( dcell0 & CELL_is_EDGE )
color = COLOR4D( YELLOW );
else if( dcell0 & CELL_is_ZONE )
color = COLOR4D( YELLOW );
#define DRAW_OFFSET_X -20
#define DRAW_OFFSET_Y 20
// if( color )
{
for( int i = 0; i < maxi; i++ )
for( int j = 0; j < maxi; j++ )
GRPutPixel( panel->GetClipBox(), DC,
( col * maxi ) + i + DRAW_OFFSET_X,
( row * maxi ) + j + DRAW_OFFSET_Y, color );
}
}
}
}

View File

@ -1,248 +0,0 @@
/*
* 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) 2012 Wayne Stambaugh <stambaughw@verizon.net>
*
* 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
*/
/**
* @file autorout.h
*/
#ifndef AUTOROUT_H
#define AUTOROUT_H
#include <base_struct.h>
#include <class_eda_rect.h>
#include <layers_id_colors_and_visibility.h>
class BOARD;
class DRAWSEGMENT;
class TRACK;
class D_PAD;
class RATSNEST_ITEM;
class PCB_EDIT_FRAME;
#define TOP 0
#define BOTTOM 1
#define EMPTY 0
#define ILLEGAL -1
/* Autorouter commands. */
enum AUTOPLACEROUTE_OPTIONS
{
PLACE_ALL,
PLACE_OUT_OF_BOARD,
PLACE_INCREMENTAL,
PLACE_1_MODULE,
ROUTE_ALL,
ROUTE_NET,
ROUTE_MODULE,
ROUTE_PAD
};
#define MAX_ROUTING_LAYERS_COUNT 2
#define FORCE_PADS 1 /* Force placement of pads for any Netcode */
/* search statistics */
extern int OpenNodes; /* total number of nodes opened */
extern int ClosNodes; /* total number of nodes closed */
extern int MoveNodes; /* total number of nodes moved */
extern int MaxNodes; /* maximum number of nodes opened at one time */
/* Structures useful to the generation of board as bitmap. */
typedef unsigned char MATRIX_CELL;
typedef int DIST_CELL;
typedef char DIR_CELL;
struct AUTOROUTER_CONTEXT
{
///> Parent frame
PCB_EDIT_FRAME* pcbframe;
///> Board to be routed
BOARD* board;
///> Cached board bounding box
const EDA_RECT bbox;
///> Drawing context
wxDC* dc;
};
/**
* class MATRIX_ROUTING_HEAD
* handle the matrix routing that describes the actual board
*/
class MATRIX_ROUTING_HEAD
{
public:
MATRIX_CELL* m_BoardSide[MAX_ROUTING_LAYERS_COUNT]; // the image map of 2 board sides
DIST_CELL* m_DistSide[MAX_ROUTING_LAYERS_COUNT]; // the image map of 2 board sides:
// distance to cells
DIR_CELL* m_DirSide[MAX_ROUTING_LAYERS_COUNT]; // the image map of 2 board sides:
// pointers back to source
bool m_InitMatrixDone;
int m_RoutingLayersCount; // Number of layers for autorouting (0 or 1)
int m_GridRouting; // Size of grid for autoplace/autoroute
EDA_RECT m_BrdBox; // Actual board bounding box
int m_Nrows, m_Ncols; // Matrix size
int m_MemSize; // Memory requirement, just for statistics
int m_RouteCount; // Number of routes
private:
// a pointer to the current selected cell operation
void (MATRIX_ROUTING_HEAD::* m_opWriteCell)( int aRow, int aCol,
int aSide, MATRIX_CELL aCell);
public:
MATRIX_ROUTING_HEAD();
~MATRIX_ROUTING_HEAD();
void WriteCell( int aRow, int aCol, int aSide, MATRIX_CELL aCell)
{
(*this.*m_opWriteCell)( aRow, aCol, aSide, aCell );
}
/**
* function GetBrdCoordOrigin
* @return the board coordinate corresponding to the
* routing matrix origin ( board coordinate offset )
*/
wxPoint GetBrdCoordOrigin()
{
return m_BrdBox.GetOrigin();
}
/**
* Function ComputeMatrixSize
* calculates the number of rows and columns of dimensions of \a aPcb for routing and
* automatic calculation of area.
* @param aPcb = the physical board
* @param aUseBoardEdgesOnly = true to use board edges only,
* = false to use the full board bounding box (default)
*/
bool ComputeMatrixSize( BOARD* aPcb, bool aUseBoardEdgesOnly = false );
/**
* Function InitBoard
* initializes the data structures.
*
* @return the amount of memory used or -1 if default.
*/
int InitRoutingMatrix();
void UnInitRoutingMatrix();
// Initialize WriteCell to make the aLogicOp
void SetCellOperation( int aLogicOp );
// functions to read/write one cell ( point on grid routing matrix:
MATRIX_CELL GetCell( int aRow, int aCol, int aSide);
void SetCell( int aRow, int aCol, int aSide, MATRIX_CELL aCell);
void OrCell( int aRow, int aCol, int aSide, MATRIX_CELL aCell);
void XorCell( int aRow, int aCol, int aSide, MATRIX_CELL aCell);
void AndCell( int aRow, int aCol, int aSide, MATRIX_CELL aCell);
void AddCell( int aRow, int aCol, int aSide, MATRIX_CELL aCell);
DIST_CELL GetDist( int aRow, int aCol, int aSide );
void SetDist( int aRow, int aCol, int aSide, DIST_CELL );
int GetDir( int aRow, int aCol, int aSide );
void SetDir( int aRow, int aCol, int aSide, int aDir);
// calculate distance (with penalty) of a trace through a cell
int CalcDist(int x,int y,int z ,int side );
// calculate approximate distance (manhattan distance)
int GetApxDist( int r1, int c1, int r2, int c2 );
};
extern MATRIX_ROUTING_HEAD RoutingMatrix; /* 2-sided board */
/* Constants used to trace the cells on the BOARD */
#define WRITE_CELL 0
#define WRITE_OR_CELL 1
#define WRITE_XOR_CELL 2
#define WRITE_AND_CELL 3
#define WRITE_ADD_CELL 4
// Functions:
/* Initialize a color value, the cells included in the board edge of the
* pad surface by pt_pad, with the margin reserved for isolation and the
* half width of the runway
* Parameters:
* Pt_pad: pointer to the description of the pad
* color: mask write in cells
* margin: add a value to the radius or half the score pad
* op_logic: type of writing in the cell (WRITE, OR)
*/
void PlacePad( D_PAD* pt_pad, int type, int marge, int op_logic );
/* Draws a segment of track on the board. */
void TraceSegmentPcb( TRACK* pt_segm, int type, int marge, int op_logic );
void TraceSegmentPcb( DRAWSEGMENT* pt_segm, int type, int marge, int op_logic );
/* Uses the color value of all cells included in the board
* coord of the rectangle ux0, uy0 (top right corner)
* a ux1, uy1 (lower left corner) (coord PCB)
* the rectangle is horizontal (or vertical)
* masque_layer = mask layers;
* op_logic = WRITE_CELL, WRITE_OR_CELL, WRITE_XOR_CELL, WRITE_AND_CELL
*/
void TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1,
LSET side, int color, int op_logic);
/* Same as above, but the rectangle is inclined angle angle. */
void TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1,
double angle, LSET masque_layer,
int color, int op_logic );
/* QUEUE.CPP */
void FreeQueue();
void InitQueue();
void GetQueue( int *, int *, int *, int *, int * );
bool SetQueue( int, int, int, int, int, int, int );
void ReSetQueue( int, int, int, int, int, int, int );
/* WORK.CPP */
void InitWork();
void ReInitWork();
int SetWork( int, int, int , int, int, RATSNEST_ITEM *, int );
void GetWork( int *, int *, int *, int *, int *, RATSNEST_ITEM ** );
void SortWork(); /* order the work items; shortest first */
/* routing_matrix.cpp */
int Build_Work( BOARD * Pcb );
void PlaceCells( BOARD * Pcb, int net_code, int flag = 0 );
#endif // AUTOROUT_H

View File

@ -1,171 +0,0 @@
/**
* @file dist.cpp
* @brief Routines to calculate PCB editor auto routing distances.
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
*
* First copyright (C) Randy Nevin, 1989 (see PCBCA package)
*
* 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 <autorout.h>
#include <cell.h>
/* The tables of distances and keep out areas are established on the basis of a
* 50 units grid size (the pitch between the cells is 50 units).
* The actual distance could be computed by a scaling factor, but this is
* not needed, we can use only reduced values
*/
/* calculate approximate distance (manhattan distance)
*/
int MATRIX_ROUTING_HEAD::GetApxDist( int r1, int c1, int r2, int c2 )
{
int d1, d2; /* row and column deltas */
if( ( d1 = r1 - r2 ) < 0 ) /* get absolute row delta */
d1 = -d1;
if( ( d2 = c1 - c2 ) < 0 ) /* get absolute column delta */
d2 = -d2;
return ( d1+d2 ) * 50;
}
/* distance to go thru a cell (en mils) */
static const int dist[10][10] =
{ /* OT=Otherside, OR=Origin (source) cell */
/*..........N, NE, E, SE, S, SW, W, NW, OT, OR */
/* N */ { 50, 60, 35, 60, 99, 60, 35, 60, 12, 12 },
/* NE */ { 60, 71, 60, 71, 60, 99, 60, 71, 23, 23 },
/* E */ { 35, 60, 50, 60, 35, 60, 99, 60, 12, 12 },
/* SE */ { 60, 71, 60, 71, 60, 71, 60, 99, 23, 23 },
/* S */ { 99, 60, 35, 60, 50, 60, 35, 60, 12, 12 },
/* SW */ { 60, 99, 60, 71, 60, 71, 60, 71, 23, 23 },
/* W */ { 35, 60, 99, 60, 35, 60, 50, 60, 12, 12 },
/* NW */ { 60, 71, 60, 99, 60, 71, 60, 71, 23, 23 },
/* OT */ { 12, 23, 12, 23, 12, 23, 12, 23, 99, 99 },
/* OR */ { 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 }
};
/* penalty for extraneous holes and corners, scaled by sharpness of turn */
static const int penalty[10][10] =
{ /* OT=Otherside, OR=Origin (source) cell */
/*......... N, NE, E, SE, S, SW, W, NW, OT, OR */
/* N */ { 0, 5, 10, 15, 20, 15, 10, 5, 50, 0 },
/* NE */ { 5, 0, 5, 10, 15, 20, 15, 10, 50, 0 },
/* E */ { 10, 5, 0, 5, 10, 15, 20, 15, 50, 0 },
/* SE */ { 15, 10, 5, 0, 5, 10, 15, 20, 50, 0 },
/* S */ { 20, 15, 10, 5, 0, 5, 10, 15, 50, 0 },
/* SW */ { 15, 20, 15, 10, 5, 0, 5, 10, 50, 0 },
/* W */ { 10, 15, 20, 15, 10, 5, 0, 5, 50, 0 },
/* NW */ { 5, 10, 15, 20, 15, 10, 5, 0, 50, 0 },
/* OT */ { 50, 50, 50, 50, 50, 50, 50, 50, 100, 0 },
/* OR */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
/* penalty pour directions preferencielles */
#define PN 20
static const int dir_penalty_TOP[10][10] =
{
/* OT=Otherside, OR=Origin (source) cell */
/*......... N, NE, E, SE, S, SW, W, NW, OT, OR */
/* N */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
/* NE */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
/* E */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
/* SE */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
/* S */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
/* SW */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
/* W */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
/* NW */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
/* OT */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 },
/* OR */ { PN, 0, 0, 0, PN, 0, 0, 0, 0, 0 }
};
static int dir_penalty_BOTTOM[10][10] =
{
/* OT=Otherside, OR=Origin (source) cell */
/*......... N, NE, E, SE, S, SW, W, NW, OT, OR */
/* N */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
/* NE */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
/* E */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
/* SE */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
/* S */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
/* SW */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
/* W */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
/* NW */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
/* OT */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 },
/* OR */ { 0, 0, PN, 0, 0, 0, PN, 0, 0, 0 }
};
/*
** x is the direction to enter the cell of interest.
** y is the direction to exit the cell of interest.
** z is the direction to really exit the cell, if y=FROM_OTHERSIDE.
**
** return the distance of the trace through the cell of interest.
** the calculation is driven by the tables above.
*/
/* calculate distance (with penalty) of a trace through a cell
*/
int MATRIX_ROUTING_HEAD::CalcDist(int x,int y,int z ,int side )
{
int adjust, ldist;
adjust = 0; /* set if hole is encountered */
if( x == EMPTY )
x = 10;
if( y == EMPTY )
{
y = 10;
}
else if( y == FROM_OTHERSIDE )
{
if( z == EMPTY )
z = 10;
adjust = penalty[x-1][z-1];
}
ldist = dist[x-1][y-1] + penalty[x-1][y-1] + adjust;
if( m_RouteCount > 1 )
{
if( side == BOTTOM )
ldist += dir_penalty_TOP[x-1][y-1];
if( side == TOP )
ldist += dir_penalty_BOTTOM[x-1][y-1];
}
return ldist * 10;
}

View File

@ -1,843 +0,0 @@
/**
* @file graphpcb.cpp
* @brief PCB editor autorouting and "graphics" routines.
*/
/*
* 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-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 <fctsys.h>
#include <common.h>
#include <macros.h>
#include <trigo.h>
#include <math_for_graphics.h>
#include <class_board.h>
#include <class_track.h>
#include <class_drawsegment.h>
#include <pcbnew.h>
#include <autorout.h>
#include <cell.h>
void TracePcbLine( int x0, int y0, int x1, int y1, LAYER_NUM layer, int color );
void TraceArc( int ux0, int uy0,
int ux1, int uy1,
double ArcAngle,
int lg, LAYER_NUM layer, int color,
int op_logic );
static void DrawSegmentQcq( int ux0, int uy0,
int ux1, int uy1,
int lg, LAYER_NUM layer, int color,
int op_logic );
static void TraceFilledCircle( int cx, int cy, int radius,
LSET aLayerMask,
int color,
int op_logic );
static void TraceCircle( int ux0, int uy0, int ux1, int uy1, int lg, LAYER_NUM layer,
int color, int op_logic );
// Macro call to update cell.
#define OP_CELL( layer, dy, dx ) \
{ \
if( layer == UNDEFINED_LAYER ) \
{ \
RoutingMatrix.WriteCell( dy, dx, BOTTOM, color ); \
if( RoutingMatrix.m_RoutingLayersCount > 1 ) \
RoutingMatrix.WriteCell( dy, dx, TOP, color ); \
} \
else \
{ \
if( layer == g_Route_Layer_BOTTOM ) \
RoutingMatrix.WriteCell( dy, dx, BOTTOM, color ); \
if( RoutingMatrix.m_RoutingLayersCount > 1 ) \
if( layer == g_Route_Layer_TOP ) \
RoutingMatrix.WriteCell( dy, dx, TOP, color ); \
} \
}
void PlacePad( D_PAD* aPad, int color, int marge, int op_logic )
{
int dx, dy;
wxPoint shape_pos = aPad->ShapePos();
dx = aPad->GetSize().x / 2;
dx += marge;
if( aPad->GetShape() == PAD_SHAPE_CIRCLE )
{
TraceFilledCircle( shape_pos.x, shape_pos.y, dx,
aPad->GetLayerSet(), color, op_logic );
return;
}
dy = aPad->GetSize().y / 2;
dy += marge;
if( aPad->GetShape() == PAD_SHAPE_TRAPEZOID )
{
dx += abs( aPad->GetDelta().y ) / 2;
dy += abs( aPad->GetDelta().x ) / 2;
}
// The pad is a rectangle ( horizontal or vertical )
if( int( aPad->GetOrientation() ) % 900 == 0 )
{
// Orientation turned 90 deg.
if( aPad->GetOrientation() == 900 || aPad->GetOrientation() == 2700 )
{
std::swap( dx, dy );
}
TraceFilledRectangle( shape_pos.x - dx, shape_pos.y - dy,
shape_pos.x + dx, shape_pos.y + dy,
aPad->GetLayerSet(), color, op_logic );
}
else
{
TraceFilledRectangle( shape_pos.x - dx, shape_pos.y - dy,
shape_pos.x + dx, shape_pos.y + dy,
aPad->GetOrientation(),
aPad->GetLayerSet(), color, op_logic );
}
}
/* Set to color the cells included in the circle
* Parameters:
* center: cx, cy.
* radius: a value add to the radius or half the score pad
* aLayerMask: layer occupied
* color: mask write in cells
* op_logic: type of writing in the cell (WRITE, OR)
*/
void TraceFilledCircle( int cx, int cy, int radius,
LSET aLayerMask, int color, int op_logic )
{
int row, col;
int ux0, uy0, ux1, uy1;
int row_max, col_max, row_min, col_min;
int trace = 0;
double fdistmin, fdistx, fdisty;
int tstwrite = 0;
int distmin;
if( aLayerMask[g_Route_Layer_BOTTOM] )
trace = 1; // Trace on BOTTOM
if( aLayerMask[g_Route_Layer_TOP] )
if( RoutingMatrix.m_RoutingLayersCount > 1 )
trace |= 2; // Trace on TOP
if( trace == 0 )
return;
RoutingMatrix.SetCellOperation( op_logic );
cx -= RoutingMatrix.GetBrdCoordOrigin().x;
cy -= RoutingMatrix.GetBrdCoordOrigin().y;
distmin = radius;
// Calculate the bounding rectangle of the circle.
ux0 = cx - radius;
uy0 = cy - radius;
ux1 = cx + radius;
uy1 = cy + radius;
// Calculate limit coordinates of cells belonging to the rectangle.
row_max = uy1 / RoutingMatrix.m_GridRouting;
col_max = ux1 / RoutingMatrix.m_GridRouting;
row_min = uy0 / RoutingMatrix.m_GridRouting; // if (uy0 > row_min*Board.m_GridRouting) row_min++;
col_min = ux0 / RoutingMatrix.m_GridRouting; // if (ux0 > col_min*Board.m_GridRouting) col_min++;
if( row_min < 0 )
row_min = 0;
if( row_max >= (RoutingMatrix.m_Nrows - 1) )
row_max = RoutingMatrix.m_Nrows - 1;
if( col_min < 0 )
col_min = 0;
if( col_max >= (RoutingMatrix.m_Ncols - 1) )
col_max = RoutingMatrix.m_Ncols - 1;
// Calculate coordinate limits of cell belonging to the rectangle.
if( row_min > row_max )
row_max = row_min;
if( col_min > col_max )
col_max = col_min;
fdistmin = (double) distmin * distmin;
for( row = row_min; row <= row_max; row++ )
{
fdisty = (double) ( cy - ( row * RoutingMatrix.m_GridRouting ) );
fdisty *= fdisty;
for( col = col_min; col <= col_max; col++ )
{
fdistx = (double) ( cx - ( col * RoutingMatrix.m_GridRouting ) );
fdistx *= fdistx;
if( fdistmin <= ( fdistx + fdisty ) )
continue;
if( trace & 1 )
RoutingMatrix.WriteCell( row, col, BOTTOM, color );
if( trace & 2 )
RoutingMatrix.WriteCell( row, col, TOP, color );
tstwrite = 1;
}
}
if( tstwrite )
return;
/* If no cell has been written, it affects the 4 neighboring diagonal
* (Adverse event: pad off grid in the center of the 4 neighboring
* diagonal) */
distmin = RoutingMatrix.m_GridRouting / 2 + 1;
fdistmin = ( (double) distmin * distmin ) * 2; // Distance to center point diagonally
for( row = row_min; row <= row_max; row++ )
{
fdisty = (double) ( cy - ( row * RoutingMatrix.m_GridRouting ) );
fdisty *= fdisty;
for( col = col_min; col <= col_max; col++ )
{
fdistx = (double) ( cx - ( col * RoutingMatrix.m_GridRouting ) );
fdistx *= fdistx;
if( fdistmin <= ( fdistx + fdisty ) )
continue;
if( trace & 1 )
RoutingMatrix.WriteCell( row, col, BOTTOM, color );
if( trace & 2 )
RoutingMatrix.WriteCell( row, col, TOP, color );
}
}
}
void TraceSegmentPcb( DRAWSEGMENT* pt_segm, int color, int marge, int op_logic )
{
int half_width = ( pt_segm->GetWidth() / 2 ) + marge;
// Calculate the bounding rectangle of the segment (if H, V or Via)
int ux0 = pt_segm->GetStart().x - RoutingMatrix.GetBrdCoordOrigin().x;
int uy0 = pt_segm->GetStart().y - RoutingMatrix.GetBrdCoordOrigin().y;
int ux1 = pt_segm->GetEnd().x - RoutingMatrix.GetBrdCoordOrigin().x;
int uy1 = pt_segm->GetEnd().y - RoutingMatrix.GetBrdCoordOrigin().y;
LAYER_NUM layer = pt_segm->GetLayer();
if( color == VIA_IMPOSSIBLE )
layer = UNDEFINED_LAYER;
switch( pt_segm->GetShape() )
{
// The segment is here a straight line or a circle or an arc.:
case S_CIRCLE:
TraceCircle( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic );
break;
case S_ARC:
TraceArc( ux0, uy0, ux1, uy1, pt_segm->GetAngle(), half_width, layer, color, op_logic );
break;
// The segment is here a line segment.
default:
DrawSegmentQcq( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic );
break;
}
}
void TraceSegmentPcb( TRACK* aTrack, int color, int marge, int op_logic )
{
int half_width = ( aTrack->GetWidth() / 2 ) + marge;
// Test if VIA (filled circle need to be drawn)
if( aTrack->Type() == PCB_VIA_T )
{
LSET layer_mask;
if( aTrack->IsOnLayer( g_Route_Layer_BOTTOM ) )
layer_mask.set( g_Route_Layer_BOTTOM );
if( aTrack->IsOnLayer( g_Route_Layer_TOP ) )
{
if( !layer_mask.any() )
layer_mask = LSET( g_Route_Layer_TOP );
else
layer_mask.set();
}
if( color == VIA_IMPOSSIBLE )
layer_mask.set();
if( layer_mask.any() )
TraceFilledCircle( aTrack->GetStart().x, aTrack->GetStart().y,
half_width, layer_mask, color, op_logic );
}
else
{
// Calculate the bounding rectangle of the segment
int ux0 = aTrack->GetStart().x - RoutingMatrix.GetBrdCoordOrigin().x;
int uy0 = aTrack->GetStart().y - RoutingMatrix.GetBrdCoordOrigin().y;
int ux1 = aTrack->GetEnd().x - RoutingMatrix.GetBrdCoordOrigin().x;
int uy1 = aTrack->GetEnd().y - RoutingMatrix.GetBrdCoordOrigin().y;
// Ordinary track
PCB_LAYER_ID layer = aTrack->GetLayer();
if( color == VIA_IMPOSSIBLE )
layer = UNDEFINED_LAYER;
DrawSegmentQcq( ux0, uy0, ux1, uy1, half_width, layer, color, op_logic );
}
}
/* Draws a line, if layer = -1 on all layers
*/
void TracePcbLine( int x0, int y0, int x1, int y1, LAYER_NUM layer, int color, int op_logic )
{
int dx, dy, lim;
int cumul, inc, il, delta;
RoutingMatrix.SetCellOperation( op_logic );
if( x0 == x1 ) // Vertical.
{
if( y1 < y0 )
std::swap( y0, y1 );
dy = y0 / RoutingMatrix.m_GridRouting;
lim = y1 / RoutingMatrix.m_GridRouting;
dx = x0 / RoutingMatrix.m_GridRouting;
// Clipping limits of board.
if( ( dx < 0 ) || ( dx >= RoutingMatrix.m_Ncols ) )
return;
if( dy < 0 )
dy = 0;
if( lim >= RoutingMatrix.m_Nrows )
lim = RoutingMatrix.m_Nrows - 1;
for( ; dy <= lim; dy++ )
{
OP_CELL( layer, dy, dx );
}
return;
}
if( y0 == y1 ) // Horizontal
{
if( x1 < x0 )
std::swap( x0, x1 );
dx = x0 / RoutingMatrix.m_GridRouting;
lim = x1 / RoutingMatrix.m_GridRouting;
dy = y0 / RoutingMatrix.m_GridRouting;
// Clipping limits of board.
if( ( dy < 0 ) || ( dy >= RoutingMatrix.m_Nrows ) )
return;
if( dx < 0 )
dx = 0;
if( lim >= RoutingMatrix.m_Ncols )
lim = RoutingMatrix.m_Ncols - 1;
for( ; dx <= lim; dx++ )
{
OP_CELL( layer, dy, dx );
}
return;
}
// Here is some perspective: using the algorithm LUCAS.
if( abs( x1 - x0 ) >= abs( y1 - y0 ) ) // segment slightly inclined/
{
if( x1 < x0 )
{
std::swap( x1, x0 );
std::swap( y1, y0 );
}
dx = x0 / RoutingMatrix.m_GridRouting;
lim = x1 / RoutingMatrix.m_GridRouting;
dy = y0 / RoutingMatrix.m_GridRouting;
inc = 1;
if( y1 < y0 )
inc = -1;
il = lim - dx; cumul = il / 2;
delta = abs( y1 - y0 ) / RoutingMatrix.m_GridRouting;
for( ; dx <= lim; )
{
if( ( dx >= 0 ) && ( dy >= 0 ) &&
( dx < RoutingMatrix.m_Ncols ) &&
( dy < RoutingMatrix.m_Nrows ) )
{
OP_CELL( layer, dy, dx );
}
dx++;
cumul += delta;
if( cumul > il )
{
cumul -= il;
dy += inc;
}
}
}
else
{
if( y1 < y0 )
{
std::swap( x1, x0 );
std::swap( y1, y0 );
}
dy = y0 / RoutingMatrix.m_GridRouting;
lim = y1 / RoutingMatrix.m_GridRouting;
dx = x0 / RoutingMatrix.m_GridRouting;
inc = 1;
if( x1 < x0 )
inc = -1;
il = lim - dy;
cumul = il / 2;
delta = abs( x1 - x0 ) / RoutingMatrix.m_GridRouting;
for( ; dy <= lim; )
{
if( ( dx >= 0 ) && ( dy >= 0 ) && ( dx < RoutingMatrix.m_Ncols ) && ( dy < RoutingMatrix.m_Nrows ) )
{
OP_CELL( layer, dy, dx );
}
dy++;
cumul += delta;
if( cumul > il )
{
cumul -= il;
dx += inc;
}
}
}
}
void TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1,
LSET aLayerMask, int color, int op_logic )
{
int row, col;
int row_min, row_max, col_min, col_max;
int trace = 0;
if( aLayerMask[g_Route_Layer_BOTTOM] )
trace = 1; // Trace on BOTTOM
if( aLayerMask[g_Route_Layer_TOP] && RoutingMatrix.m_RoutingLayersCount > 1 )
trace |= 2; // Trace on TOP
if( trace == 0 )
return;
RoutingMatrix.SetCellOperation( op_logic );
ux0 -= RoutingMatrix.GetBrdCoordOrigin().x;
uy0 -= RoutingMatrix.GetBrdCoordOrigin().y;
ux1 -= RoutingMatrix.GetBrdCoordOrigin().x;
uy1 -= RoutingMatrix.GetBrdCoordOrigin().y;
// Calculating limits coord cells belonging to the rectangle.
row_max = uy1 / RoutingMatrix.m_GridRouting;
col_max = ux1 / RoutingMatrix.m_GridRouting;
row_min = uy0 / RoutingMatrix.m_GridRouting;
if( uy0 > row_min * RoutingMatrix.m_GridRouting )
row_min++;
col_min = ux0 / RoutingMatrix.m_GridRouting;
if( ux0 > col_min * RoutingMatrix.m_GridRouting )
col_min++;
if( row_min < 0 )
row_min = 0;
if( row_max >= ( RoutingMatrix.m_Nrows - 1 ) )
row_max = RoutingMatrix.m_Nrows - 1;
if( col_min < 0 )
col_min = 0;
if( col_max >= ( RoutingMatrix.m_Ncols - 1 ) )
col_max = RoutingMatrix.m_Ncols - 1;
for( row = row_min; row <= row_max; row++ )
{
for( col = col_min; col <= col_max; col++ )
{
if( trace & 1 )
RoutingMatrix.WriteCell( row, col, BOTTOM, color );
if( trace & 2 )
RoutingMatrix.WriteCell( row, col, TOP, color );
}
}
}
void TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1,
double angle, LSET aLayerMask, int color, int op_logic )
{
int row, col;
int cx, cy; // Center of rectangle
int radius; // Radius of the circle
int row_min, row_max, col_min, col_max;
int rotrow, rotcol;
int trace = 0;
if( aLayerMask[g_Route_Layer_BOTTOM] )
trace = 1; // Trace on BOTTOM
if( aLayerMask[g_Route_Layer_TOP] )
{
if( RoutingMatrix.m_RoutingLayersCount > 1 )
trace |= 2; // Trace on TOP
}
if( trace == 0 )
return;
RoutingMatrix.SetCellOperation( op_logic );
ux0 -= RoutingMatrix.GetBrdCoordOrigin().x;
uy0 -= RoutingMatrix.GetBrdCoordOrigin().y;
ux1 -= RoutingMatrix.GetBrdCoordOrigin().x;
uy1 -= RoutingMatrix.GetBrdCoordOrigin().y;
cx = (ux0 + ux1) / 2;
cy = (uy0 + uy1) / 2;
radius = KiROUND( Distance( ux0, uy0, cx, cy ) );
// Calculating coordinate limits belonging to the rectangle.
row_max = ( cy + radius ) / RoutingMatrix.m_GridRouting;
col_max = ( cx + radius ) / RoutingMatrix.m_GridRouting;
row_min = ( cy - radius ) / RoutingMatrix.m_GridRouting;
if( uy0 > row_min * RoutingMatrix.m_GridRouting )
row_min++;
col_min = ( cx - radius ) / RoutingMatrix.m_GridRouting;
if( ux0 > col_min * RoutingMatrix.m_GridRouting )
col_min++;
if( row_min < 0 )
row_min = 0;
if( row_max >= ( RoutingMatrix.m_Nrows - 1 ) )
row_max = RoutingMatrix.m_Nrows - 1;
if( col_min < 0 )
col_min = 0;
if( col_max >= ( RoutingMatrix.m_Ncols - 1 ) )
col_max = RoutingMatrix.m_Ncols - 1;
for( row = row_min; row <= row_max; row++ )
{
for( col = col_min; col <= col_max; col++ )
{
rotrow = row * RoutingMatrix.m_GridRouting;
rotcol = col * RoutingMatrix.m_GridRouting;
RotatePoint( &rotcol, &rotrow, cx, cy, -angle );
if( rotrow <= uy0 )
continue;
if( rotrow >= uy1 )
continue;
if( rotcol <= ux0 )
continue;
if( rotcol >= ux1 )
continue;
if( trace & 1 )
RoutingMatrix.WriteCell( row, col, BOTTOM, color );
if( trace & 2 )
RoutingMatrix.WriteCell( row, col, TOP, color );
}
}
}
/* Fills all cells inside a segment
* half-width = lg, org = ux0,uy0 end = ux1,uy1
* coordinates are in PCB units
*/
void DrawSegmentQcq( int ux0, int uy0, int ux1, int uy1, int lg, LAYER_NUM layer,
int color, int op_logic )
{
int row, col;
int inc;
int row_max, col_max, row_min, col_min;
int demi_pas;
int cx, cy, dx, dy;
RoutingMatrix.SetCellOperation( op_logic );
// Make coordinate ux1 tj > ux0 to simplify calculations
if( ux1 < ux0 )
{
std::swap( ux1, ux0 );
std::swap( uy1, uy0 );
}
// Calculating the incrementing the Y axis
inc = 1;
if( uy1 < uy0 )
inc = -1;
demi_pas = RoutingMatrix.m_GridRouting / 2;
col_min = ( ux0 - lg ) / RoutingMatrix.m_GridRouting;
if( col_min < 0 )
col_min = 0;
col_max = ( ux1 + lg + demi_pas ) / RoutingMatrix.m_GridRouting;
if( col_max > ( RoutingMatrix.m_Ncols - 1 ) )
col_max = RoutingMatrix.m_Ncols - 1;
if( inc > 0 )
{
row_min = ( uy0 - lg ) / RoutingMatrix.m_GridRouting;
row_max = ( uy1 + lg + demi_pas ) / RoutingMatrix.m_GridRouting;
}
else
{
row_min = ( uy1 - lg ) / RoutingMatrix.m_GridRouting;
row_max = ( uy0 + lg + demi_pas ) / RoutingMatrix.m_GridRouting;
}
if( row_min < 0 )
row_min = 0;
if( row_min > ( RoutingMatrix.m_Nrows - 1 ) )
row_min = RoutingMatrix.m_Nrows - 1;
if( row_max < 0 )
row_max = 0;
if( row_max > ( RoutingMatrix.m_Nrows - 1 ) )
row_max = RoutingMatrix.m_Nrows - 1;
dx = ux1 - ux0;
dy = uy1 - uy0;
double angle;
if( dx )
{
angle = ArcTangente( dy, dx );
}
else
{
angle = 900;
if( dy < 0 )
angle = -900;
}
RotatePoint( &dx, &dy, angle ); // dx = length, dy = 0
for( col = col_min; col <= col_max; col++ )
{
int cxr;
cxr = ( col * RoutingMatrix.m_GridRouting ) - ux0;
for( row = row_min; row <= row_max; row++ )
{
cy = (row * RoutingMatrix.m_GridRouting) - uy0;
cx = cxr;
RotatePoint( &cx, &cy, angle );
if( abs( cy ) > lg )
continue; // The point is too far on the Y axis.
/* This point a test is close to the segment: the position
* along the X axis must be tested.
*/
if( ( cx >= 0 ) && ( cx <= dx ) )
{
OP_CELL( layer, row, col );
continue;
}
// Examination of extremities are rounded.
if( ( cx < 0 ) && ( cx >= -lg ) )
{
if( ( ( cx * cx ) + ( cy * cy ) ) <= ( lg * lg ) )
OP_CELL( layer, row, col );
continue;
}
if( ( cx > dx ) && ( cx <= ( dx + lg ) ) )
{
if( ( ( ( cx - dx ) * ( cx - dx ) ) + ( cy * cy ) ) <= ( lg * lg ) )
OP_CELL( layer, row, col );
continue;
}
}
}
}
/* Fills all cells of the routing matrix contained in the circle
* half-width = lg, center = ux0, uy0, ux1,uy1 is a point on the circle.
* coord are in PCB units.
*/
void TraceCircle( int ux0, int uy0, int ux1, int uy1, int lg, LAYER_NUM layer,
int color, int op_logic )
{
int radius, nb_segm;
int x0, y0, // Starting point of the current segment trace.
x1, y1; // End point.
int ii;
int angle;
radius = KiROUND( Distance( ux0, uy0, ux1, uy1 ) );
x0 = x1 = radius;
y0 = y1 = 0;
if( lg < 1 )
lg = 1;
nb_segm = ( 2 * radius ) / lg;
if( nb_segm < 5 )
nb_segm = 5;
if( nb_segm > 100 )
nb_segm = 100;
for( ii = 1; ii < nb_segm; ii++ )
{
angle = (3600 * ii) / nb_segm;
x1 = KiROUND( cosdecideg( radius, angle ) );
y1 = KiROUND( sindecideg( radius, angle ) );
DrawSegmentQcq( x0 + ux0, y0 + uy0, x1 + ux0, y1 + uy0, lg, layer, color, op_logic );
x0 = x1;
y0 = y1;
}
DrawSegmentQcq( x1 + ux0, y1 + uy0, ux0 + radius, uy0, lg, layer, color, op_logic );
}
/* Fills all routing matrix cells contained in the arc
* angle = ArcAngle, half-width lg
* center = ux0,uy0, starting at ux1, uy1. Coordinates are in
* PCB units.
*/
void TraceArc( int ux0, int uy0, int ux1, int uy1, double ArcAngle, int lg,
LAYER_NUM layer, int color, int op_logic )
{
int radius, nb_segm;
int x0, y0, // Starting point of the current segment trace
x1, y1; // End point
int ii;
double angle, StAngle;
radius = KiROUND( Distance( ux0, uy0, ux1, uy1 ) );
x0 = ux1 - ux0;
y0 = uy1 - uy0;
StAngle = ArcTangente( uy1 - uy0, ux1 - ux0 );
if( lg < 1 )
lg = 1;
nb_segm = ( 2 * radius ) / lg;
nb_segm = ( nb_segm * std::abs( ArcAngle ) ) / 3600;
if( nb_segm < 5 )
nb_segm = 5;
if( nb_segm > 100 )
nb_segm = 100;
for( ii = 1; ii <= nb_segm; ii++ )
{
angle = ( ArcAngle * ii ) / nb_segm;
angle += StAngle;
NORMALIZE_ANGLE_POS( angle );
x1 = KiROUND( cosdecideg( radius, angle ) );
y1 = KiROUND( cosdecideg( radius, angle ) );
DrawSegmentQcq( x0 + ux0, y0 + uy0, x1 + ux0, y1 + uy0, lg, layer, color, op_logic );
x0 = x1;
y0 = y1;
}
}

View File

@ -1,173 +0,0 @@
/*
* 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-2016 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 move_and_route_event_functions.cpp
* @brief Routines for automatic displacement and rotation of modules.
*/
#include <algorithm>
#include <fctsys.h>
#include <class_drawpanel.h>
#include <confirm.h>
#include <kicad_string.h>
#include <pcbnew.h>
#include <wxPcbStruct.h>
#include <kicad_device_context.h>
#include <autorout.h>
#include <cell.h>
#include <pcbnew_id.h>
#include <class_board.h>
#include <class_module.h>
typedef enum {
FIXE_MODULE,
FREE_MODULE,
FIXE_ALL_MODULES,
FREE_ALL_MODULES
} SelectFixeFct;
wxString ModulesMaskSelection = wxT( "*" );
/* Called on events (popup menus) relative to automove and autoplace footprints
*/
void PCB_EDIT_FRAME::OnPlaceOrRouteFootprints( wxCommandEvent& event )
{
int id = event.GetId();
if( m_mainToolBar == NULL )
return;
INSTALL_UNBUFFERED_DC( dc, m_canvas );
switch( id )
{
case ID_POPUP_PCB_AUTOROUTE_SELECT_LAYERS:
return;
case ID_POPUP_PCB_AUTOPLACE_FIXE_MODULE:
LockModule( (MODULE*) GetScreen()->GetCurItem(), true );
return;
case ID_POPUP_PCB_AUTOPLACE_FREE_MODULE:
LockModule( (MODULE*) GetScreen()->GetCurItem(), false );
return;
case ID_POPUP_PCB_AUTOPLACE_FREE_ALL_MODULES:
LockModule( NULL, false );
return;
case ID_POPUP_PCB_AUTOPLACE_FIXE_ALL_MODULES:
LockModule( NULL, true );
return;
default: // Abort a current command (if any)
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
break;
}
// Erase ratsnest if needed
if( GetBoard()->IsElementVisible( LAYER_RATSNEST ) )
DrawGeneralRatsnest( &dc );
GetBoard()->m_Status_Pcb |= DO_NOT_SHOW_GENERAL_RASTNEST;
switch( id )
{
case ID_POPUP_PCB_AUTOPLACE_CURRENT_MODULE:
AutoPlaceModule( (MODULE*) GetScreen()->GetCurItem(), PLACE_1_MODULE, &dc );
break;
case ID_POPUP_PCB_AUTOPLACE_ALL_MODULES:
AutoPlaceModule( NULL, PLACE_ALL, &dc );
break;
case ID_POPUP_PCB_AUTOPLACE_NEW_MODULES:
AutoPlaceModule( NULL, PLACE_OUT_OF_BOARD, &dc );
break;
case ID_POPUP_PCB_AUTOPLACE_NEXT_MODULE:
AutoPlaceModule( NULL, PLACE_INCREMENTAL, &dc );
break;
case ID_POPUP_PCB_SPREAD_ALL_MODULES:
if( !IsOK( this,
_("Not locked footprints inside the board will be moved. OK?") ) )
break;
// Fall through
case ID_POPUP_PCB_SPREAD_NEW_MODULES:
if( GetBoard()->m_Modules == NULL )
{
DisplayError( this, _( "No footprint found!" ) );
return;
}
else
{
MODULE* footprint = GetBoard()->m_Modules;
std::vector<MODULE*> footprintList;
for( ; footprint != NULL; footprint = footprint->Next() )
footprintList.push_back( footprint );
SpreadFootprints( &footprintList, id == ID_POPUP_PCB_SPREAD_NEW_MODULES,
true, GetCrossHairPosition() );
}
break;
case ID_POPUP_PCB_AUTOROUTE_ALL_MODULES:
Autoroute( &dc, ROUTE_ALL );
break;
case ID_POPUP_PCB_AUTOROUTE_MODULE:
Autoroute( &dc, ROUTE_MODULE );
break;
case ID_POPUP_PCB_AUTOROUTE_PAD:
Autoroute( &dc, ROUTE_PAD );
break;
case ID_POPUP_PCB_AUTOROUTE_NET:
Autoroute( &dc, ROUTE_NET );
break;
case ID_POPUP_PCB_AUTOROUTE_RESET_UNROUTED:
Reset_Noroutable( &dc );
break;
default:
wxMessageBox( wxT( "OnPlaceOrRouteFootprints command error" ) );
break;
}
GetBoard()->m_Status_Pcb &= ~DO_NOT_SHOW_GENERAL_RASTNEST;
Compile_Ratsnest( &dc, true );
}

View File

@ -1,220 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 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-2015 KiCad Developers, see change_log.txt for contributors.
*
* First copyright (C) Randy Nevin, 1989 (see PCBCA package)
*
* 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 queue.cpp
*/
#include <fctsys.h>
#include <common.h>
#include <pcbnew.h>
#include <autorout.h>
#include <cell.h>
struct PcbQueue /* search queue structure */
{
struct PcbQueue* Next;
int Row; /* current row */
int Col; /* current column */
int Side; /* 0=top, 1=bottom */
int Dist; /* path distance to this cell so far */
int ApxDist; /* approximate distance to target from here */
};
static long qlen = 0; /* current queue length */
static struct PcbQueue* Head = NULL;
static struct PcbQueue* Tail = NULL;
static struct PcbQueue* Save = NULL; /* hold empty queue structs */
/* Free the memory used for storing all the queue */
void FreeQueue()
{
struct PcbQueue* p;
InitQueue();
while( (p = Save) != NULL )
{
Save = p->Next;
delete p;
}
}
/* initialize the search queue */
void InitQueue()
{
struct PcbQueue* p;
while( (p = Head) != NULL )
{
Head = p->Next;
p->Next = Save; Save = p;
}
Tail = NULL;
OpenNodes = ClosNodes = MoveNodes = MaxNodes = qlen = 0;
}
/* get search queue item from list */
void GetQueue( int* r, int* c, int* s, int* d, int* a )
{
struct PcbQueue* p;
if( (p = Head) != NULL ) /* return first item in list */
{
*r = p->Row; *c = p->Col;
*s = p->Side;
*d = p->Dist; *a = p->ApxDist;
if( (Head = p->Next) == NULL )
Tail = NULL;
/* put node on free list */
p->Next = Save; Save = p;
ClosNodes++; qlen--;
}
else /* empty list */
{
*r = *c = *s = *d = *a = ILLEGAL;
}
}
/* add a search node to the list
* :
* 1 - OK
* 0 - Failed to allocate memory.
*/
bool SetQueue( int r, int c, int side, int d, int a, int r2, int c2 )
{
struct PcbQueue* p, * q, * t;
int i, j;
j = 0; // gcc warning fix
if( (p = Save) != NULL ) /* try free list first */
{
Save = p->Next;
}
else if( ( p = (PcbQueue*) operator new( sizeof( PcbQueue ), std::nothrow ) ) == NULL )
{
return 0;
}
p->Row = r;
p->Col = c;
p->Side = side;
i = (p->Dist = d) + (p->ApxDist = a);
p->Next = NULL;
if( (q = Head) != NULL ) /* insert in proper position in list */
{
if( q->Dist + q->ApxDist > i ) /* insert at head */
{
p->Next = q; Head = p;
}
else /* search for proper position */
{
for( t = q, q = q->Next; q && i > ( j = q->Dist + q->ApxDist ); t = q, q = q->Next )
;
if( q && i == j && q->Row == r2 && q->Col == c2 )
{
/* insert after q, which is a goal node */
if( ( p->Next = q->Next ) == NULL )
Tail = p;
q->Next = p;
}
else /* insert in front of q */
{
if( ( p->Next = q ) == NULL )
Tail = p;
t->Next = p;
}
}
}
else /* empty search list */
{
Head = Tail = p;
}
OpenNodes++;
if( ++qlen > MaxNodes )
MaxNodes = qlen;
return 1;
}
/* reposition node in list */
void ReSetQueue( int r, int c, int s, int d, int a, int r2, int c2 )
{
struct PcbQueue* p, * q;
/* first, see if it is already in the list */
for( q = NULL, p = Head; p; q = p, p = p->Next )
{
if( p->Row == r && p->Col == c && p->Side == s )
{
/* old one to remove */
if( q )
{
if( ( q->Next = p->Next ) == NULL )
Tail = q;
}
else if( ( Head = p->Next ) == NULL )
{
Tail = NULL;
}
p->Next = Save;
Save = p;
OpenNodes--;
MoveNodes++;
qlen--;
break;
}
}
if( !p ) /* not found, it has already been closed once */
ClosNodes--; /* we will close it again, but just count once */
/* if it was there, it's gone now; insert it at the proper position */
bool res = SetQueue( r, c, s, d, a, r2, c2 );
(void) res;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,164 +0,0 @@
/*
* 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-2012 KiCad Developers, see change_log.txt for contributors.
*
* First copyright (C) Randy Nevin, 1989 (see PCBCA package)
*
* 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 work.cpp
* @brief Automatic routing routines
*/
#include <fctsys.h>
#include <common.h>
#include <pcbnew.h>
#include <autorout.h>
#include <cell.h>
struct CWORK // a unit of work is a source-target to connect
// this is a ratsnest item in the routing matrix world
{
int m_FromRow; // source row
int m_FromCol; // source column
int m_ToRow; // target row
int m_ToCol; // target column
RATSNEST_ITEM* m_Ratsnest; // Corresponding ratsnest
int m_NetCode; // m_NetCode
int m_ApxDist; // approximate distance
int m_Cost; // cost for sort by length
int m_Priority; // route priority
// the function that calculates the cost of this ratsnest:
void CalculateCost();
};
// the list of ratsnests
static std::vector <CWORK> WorkList;
static unsigned Current = 0;
// initialize the work list
void InitWork()
{
WorkList.clear();
Current = 0;
}
/* add a unit of work to the work list
* :
* 1 if OK
* 0 if memory allocation failed
*/
int SetWork( int r1, int c1,
int n_c,
int r2, int c2,
RATSNEST_ITEM* pt_ch, int pri )
{
CWORK item;
item.m_FromRow = r1;
item.m_FromCol = c1;
item.m_NetCode = n_c;
item.m_ToRow = r2;
item.m_ToCol = c2;
item.m_Ratsnest = pt_ch;
item.m_ApxDist = RoutingMatrix.GetApxDist( r1, c1, r2, c2 );
item.CalculateCost();
item.m_Priority = pri;
WorkList.push_back( item );
return 1;
}
/* fetch a unit of work from the work list */
void GetWork( int* r1, int* c1,
int* n_c,
int* r2, int* c2,
RATSNEST_ITEM** pt_ch )
{
if( Current < WorkList.size() )
{
*r1 = WorkList[Current].m_FromRow;
*c1 = WorkList[Current].m_FromCol;
*n_c = WorkList[Current].m_NetCode;
*r2 = WorkList[Current].m_ToRow;
*c2 = WorkList[Current].m_ToCol;
*pt_ch = WorkList[Current].m_Ratsnest;
Current++;
}
else /* none left */
{
*r1 = *c1 = *r2 = *c2 = ILLEGAL;
*n_c = 0;
*pt_ch = NULL;
}
}
// order the work items; shortest (low cost) first:
bool sort_by_cost( const CWORK& ref, const CWORK& item )
{
if( ref.m_Priority == item.m_Priority )
return ref.m_Cost < item.m_Cost;
return ref.m_Priority >= item.m_Priority;
}
void SortWork()
{
sort( WorkList.begin(), WorkList.end(), sort_by_cost );
}
/* Calculate the cost of a ratsnest:
* cost = (| dx | + | dy |) * disability
* disability = 1 if dx or dy = 0, max if | dx | # | dy |
*/
void CWORK::CalculateCost()
{
int dx, dy, mx, my;
double incl = 1.0;
dx = abs( m_ToCol - m_FromCol );
dy = abs( m_ToRow - m_FromRow );
mx = dx;
my = dy;
if( mx < my )
{
mx = dy; my = dx;
}
if( mx )
incl += (2 * (double) my / mx);
m_Cost = (int) ( ( dx + dy ) * incl );
}

View File

@ -1524,36 +1524,6 @@ int BOARD::SortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount )
}
void BOARD::RedrawAreasOutlines( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, PCB_LAYER_ID aLayer )
{
if( !aDC )
return;
for( int ii = 0; ii < GetAreaCount(); ii++ )
{
ZONE_CONTAINER* edge_zone = GetArea( ii );
if( (aLayer < 0) || ( aLayer == edge_zone->GetLayer() ) )
edge_zone->Draw( panel, aDC, aDrawMode );
}
}
void BOARD::RedrawFilledAreas( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, PCB_LAYER_ID aLayer )
{
if( !aDC )
return;
for( int ii = 0; ii < GetAreaCount(); ii++ )
{
ZONE_CONTAINER* edge_zone = GetArea( ii );
if( (aLayer < 0) || ( aLayer == edge_zone->GetLayer() ) )
edge_zone->DrawFilledArea( panel, aDC, aDrawMode );
}
}
ZONE_CONTAINER* BOARD::HitTestForAnyFilledArea( const wxPoint& aRefPos,
PCB_LAYER_ID aStartLayer, PCB_LAYER_ID aEndLayer, int aNetCode )
{

View File

@ -817,17 +817,6 @@ public:
void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
GR_DRAWMODE aDrawMode, const wxPoint& aOffset = ZeroOffset ) override;
/**
* Function DrawHighLight
* redraws the objects in the board that are associated with the given aNetCode
* and turns on or off the brilliance associated with that net according to the
* current value of global g_HighLight_Status
* @param aDrawPanel is needed for the clipping support.
* @param aDC = the current device context
* @param aNetCode is the net number to highlight or to dim.
*/
void DrawHighLight( EDA_DRAW_PANEL* aDrawPanel, wxDC* aDC, int aNetCode );
/**
* Function Visit
* may be re-implemented for each derived class in order to handle
@ -915,22 +904,6 @@ public:
PCB_LAYER_ID aEndLayer,
int aNetCode );
/**
* Function RedrawAreasOutlines
* Redraw all areas outlines on layer aLayer ( redraw all if aLayer < 0 )
*/
void RedrawAreasOutlines( EDA_DRAW_PANEL* aPanel,
wxDC* aDC,
GR_DRAWMODE aDrawMode,
PCB_LAYER_ID aLayer );
/**
* Function RedrawFilledAreas
* Redraw all filled areas on layer aLayer ( redraw all if aLayer < 0 )
*/
void RedrawFilledAreas( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode,
PCB_LAYER_ID aLayer );
/**
* Function SetAreasNetCodesFromNetNames
* Set the .m_NetCode member of all copper areas, according to the area Net Name

View File

@ -330,18 +330,6 @@ public:
GR_DRAWMODE aDrawMode,
const wxPoint& aOffset = ZeroOffset ) override;
/**
* Function DrawOutlinesWhenMoving
* draws in XOR mode the footprint when moving it to the \a aDC.
* To speed up the drawing, only a simplified shape is drawn
* @param aPanel = draw panel, Used to know the clip box
* @param aDC = Current Device Context
* @param aMoveVector = the offset between the curr position and
* the draw position.
*/
void DrawOutlinesWhenMoving( EDA_DRAW_PANEL* aPanel,
wxDC* aDC, const wxPoint& aMoveVector );
/**
* function TransformPadsShapesWithClearanceToPolygon
* generate pads shapes on layer aLayer as polygons,

View File

@ -195,14 +195,55 @@ BITMAP_DEF PCB_TARGET::GetMenuImage() const
return add_pcb_target_xpm;
}
EDA_ITEM* PCB_TARGET::Clone() const
{
return new PCB_TARGET( *this );
}
void PCB_TARGET::SwapData( BOARD_ITEM* aImage )
{
assert( aImage->Type() == PCB_TARGET_T );
std::swap( *((PCB_TARGET*) this), *((PCB_TARGET*) aImage) );
}
static PCB_TARGET s_TargetCopy( nullptr ); // Used to store "old" values of the current item
// parameters before editing for undo/redo/cancel
void PCB_EDIT_FRAME::PlaceTarget( PCB_TARGET* aTarget, wxDC* DC )
{
if( aTarget == NULL )
return;
aTarget->Draw( m_canvas, DC, GR_OR );
m_canvas->SetMouseCapture( NULL, NULL );
OnModify();
if( aTarget->IsNew() )
{
SaveCopyInUndoList( aTarget, UR_NEW );
aTarget->ClearFlags();
return;
}
if( aTarget->GetEditFlags() == IS_MOVED )
{
SaveCopyInUndoList( aTarget, UR_MOVED,
aTarget->GetPosition() - s_TargetCopy.GetPosition() );
aTarget->ClearFlags();
return;
}
if( (aTarget->GetEditFlags() & IN_EDIT) )
{
aTarget->SwapData( &s_TargetCopy );
SaveCopyInUndoList( aTarget, UR_CHANGED );
aTarget->SwapData( &s_TargetCopy );
}
aTarget->ClearFlags();
}

View File

@ -250,12 +250,10 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
else if( pad == NULL )
{
msg.Printf( _( "%s pin %s not found" ), modName, pinName );
SetCurItem( module );
}
else
{
msg.Printf( _( "%s pin %s found" ), modName, pinName );
SetCurItem( pad );
}
SetStatusText( msg );

View File

@ -1,258 +0,0 @@
/*
* 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) 2012 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2012 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 deltrack.cpp
*/
#include <fctsys.h>
#include <class_drawpanel.h>
#include <confirm.h>
#include <pcb_edit_frame.h>
#include <macros.h>
#include <connectivity/connectivity_data.h>
#include <class_board.h>
#include <class_track.h>
#include <pcbnew.h>
#include <protos.h>
TRACK* PCB_EDIT_FRAME::Delete_Segment( wxDC* DC, TRACK* aTrack )
{
if( aTrack == NULL )
return NULL;
if( aTrack->IsNew() ) // Trace in progress, erase the last segment
{
if( g_CurrentTrackList.GetCount() > 0 )
{
PCB_LAYER_ID previous_layer = GetActiveLayer();
DBG( g_CurrentTrackList.VerifyListIntegrity(); )
// Delete the current trace
ShowNewTrackWhenMovingCursor( m_canvas, DC, wxDefaultPosition, false );
// delete the most recently entered
delete g_CurrentTrackList.PopBack();
if( Settings().m_legacyUseTwoSegmentTracks )
{
// if in 2 track mode, and the next most recent is a segment
// not a via, and the one previous to that is a via, then
// delete up to the via.
if( g_CurrentTrackList.GetCount() >= 2
&& g_CurrentTrackSegment->Type() != PCB_VIA_T
&& g_CurrentTrackSegment->Back()->Type() == PCB_VIA_T )
{
delete g_CurrentTrackList.PopBack();
}
}
while( g_CurrentTrackSegment && g_CurrentTrackSegment->Type() == PCB_VIA_T )
{
delete g_CurrentTrackList.PopBack();
if( g_CurrentTrackSegment && g_CurrentTrackSegment->Type() != PCB_VIA_T )
previous_layer = g_CurrentTrackSegment->GetLayer();
}
// Correct active layer which could change if a via
// has been erased
SetActiveLayer( previous_layer );
UpdateStatusBar();
if( Settings().m_legacyUseTwoSegmentTracks ) // We must have 2 segments or more, or 0
{
if( g_CurrentTrackList.GetCount() == 1
&& g_CurrentTrackSegment->Type() != PCB_VIA_T )
{
delete g_CurrentTrackList.PopBack();
}
}
if( g_CurrentTrackList.GetCount() == 0 )
{
m_canvas->SetMouseCapture( NULL, NULL );
if( GetBoard()->IsHighLightNetON() )
HighLight( DC );
SetCurItem( NULL );
return NULL;
}
else
{
if( m_canvas->IsMouseCaptured() )
m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
return g_CurrentTrackSegment;
}
}
return NULL;
}
int netcode = aTrack->GetNetCode();
// Remove the segment from list, but do not delete it (it will be stored in undo list)
GetBoard()->Remove( aTrack );
GetBoard()->GetConnectivity()->Remove( aTrack );
SaveCopyInUndoList( aTrack, UR_DELETED );
OnModify();
if( GetBoard()->IsElementVisible( LAYER_RATSNEST ) && DC )
{
GRSetDrawMode( DC, GR_XOR );
DrawGeneralRatsnest( DC, 0 );
}
// compute and display the new ratsnest
TestNetConnection( DC, netcode );
SetMsgPanel( GetBoard() );
// redraw the area where the track was
m_canvas->RefreshDrawingRect( aTrack->GetBoundingBox() );
return NULL;
}
void PCB_EDIT_FRAME::Delete_Track( wxDC* DC, TRACK* aTrack )
{
if( aTrack != NULL )
{
Remove_One_Track( DC, aTrack );
OnModify();
}
}
void PCB_EDIT_FRAME::Delete_net( wxDC* DC, TRACK* aTrack )
{
if( aTrack == NULL )
return;
if( !IsOK( this, _( "Delete NET?" ) ) )
return;
PICKED_ITEMS_LIST itemsList;
ITEM_PICKER picker( NULL, UR_DELETED );
int netcode = aTrack->GetNetCode();
/* Search the first item for the given net code */
TRACK* trackList = GetBoard()->m_Track->GetStartNetCode( netcode );
/* Remove all segments having the given net code */
int ii = 0;
TRACK* next_track;
for( TRACK* segm = trackList; segm; segm = next_track, ++ii )
{
next_track = segm->Next();
if( segm->GetNetCode() != netcode )
break;
GetBoard()->GetConnectivity()->Remove( segm );
GetBoard()->m_Track.Remove( segm );
// redraw the area where the track was
m_canvas->RefreshDrawingRect( segm->GetBoundingBox() );
picker.SetItem( segm );
itemsList.PushItem( picker );
}
SaveCopyInUndoList( itemsList, UR_DELETED );
OnModify();
// Erase old ratsnest
if( GetBoard()->IsElementVisible( LAYER_RATSNEST ) )
{
GRSetDrawMode( DC, GR_XOR );
DrawGeneralRatsnest( DC, 0 );
}
TestNetConnection( DC, netcode );
SetMsgPanel( GetBoard() );
}
void PCB_EDIT_FRAME::Remove_One_Track( wxDC* DC, TRACK* pt_segm )
{
int segments_to_delete_count;
if( pt_segm == NULL )
return;
TRACK* trackList = GetBoard()->MarkTrace( GetBoard()->m_Track, pt_segm,
&segments_to_delete_count,
NULL, NULL, true );
if( segments_to_delete_count == 0 )
return;
int net_code = pt_segm->GetNetCode();
PICKED_ITEMS_LIST itemsList;
ITEM_PICKER picker( NULL, UR_DELETED );
int ii = 0;
TRACK* tracksegment = trackList;
TRACK* next_track;
for( ; ii < segments_to_delete_count; ii++, tracksegment = next_track )
{
next_track = tracksegment->Next();
tracksegment->SetState( BUSY, false );
DBG( std::cout << __func__ << ": track " << tracksegment << " status=" \
<< TO_UTF8( TRACK::ShowState( tracksegment->GetStatus() ) ) \
<< std::endl; )
GetBoard()->GetConnectivity()->Remove( tracksegment );
GetBoard()->m_Track.Remove( tracksegment );
// redraw the area where the track was
m_canvas->RefreshDrawingRect( tracksegment->GetBoundingBox() );
picker.SetItem( tracksegment );
itemsList.PushItem( picker );
}
SaveCopyInUndoList( itemsList, UR_DELETED );
if( net_code > 0 )
{
// Erase old ratsnest
if( GetBoard()->IsElementVisible( LAYER_RATSNEST ) )
{
GRSetDrawMode( DC, GR_XOR );
DrawGeneralRatsnest( DC, 0 );
}
// Build and draw the new ratsnest
TestNetConnection( DC, net_code );
}
}

View File

@ -131,7 +131,6 @@ void DIALOG_CLEANUP_TRACKS_AND_VIAS::doCleanup( bool aDryRun )
else if( modified )
{
// Clear undo and redo lists to avoid inconsistencies between lists
m_parentFrame->SetCurItem( NULL );
commit.Push( _( "Board cleanup" ) );
m_parentFrame->GetCanvas()->Refresh( true );

View File

@ -453,7 +453,7 @@ void DIALOG_DRC_CONTROL::doSelectionMenu( const DRC_ITEM* aItem )
m_brdEditor->GetToolManager()->RunAction( PCB_ACTIONS::selectionMenu, true, &items );
// If we got an item, focus on it
BOARD_ITEM* selection = m_brdEditor->GetCurItem();
BOARD_ITEM* selection = items.GetCount() ? items[0] : nullptr;
if( selection && ( selection == first || selection == second ) )
m_brdEditor->GetToolManager()->GetView()->SetCenter( selection->GetPosition() );
@ -594,8 +594,6 @@ void DIALOG_DRC_CONTROL::RedrawDrawPanel()
void DIALOG_DRC_CONTROL::DelDRCMarkers()
{
m_brdEditor->SetCurItem( NULL ); // clear curr item, because it could be a DRC marker
// Clear current selection list to avoid selection of deleted items
m_brdEditor->GetToolManager()->RunAction( PCB_ACTIONS::selectionClear, true );
@ -677,8 +675,7 @@ void DIALOG_DRC_CONTROL::OnDeleteOneClick( wxCommandEvent& event )
if( selectedIndex != wxNOT_FOUND )
{
// Clear the current item. It may be the selected DRC marker.
m_brdEditor->SetCurItem( NULL );
// Clear the selection. It may be the selected DRC marker.
m_brdEditor->GetToolManager()->RunAction( PCB_ACTIONS::selectionClear, true );
ssize_t newIndex = wxNOT_FOUND;

View File

@ -363,9 +363,6 @@ bool DIALOG_EXCHANGE_FOOTPRINTS::processModule( MODULE* aModule, const LIB_ID& a
if( aModule == m_currentModule )
m_currentModule = newModule;
if( aModule == m_parent->GetCurItem() )
m_parent->SetCurItem( newModule );
msg += ": OK";
reporter.Report( msg, REPORTER::RPT_ACTION );
@ -412,7 +409,7 @@ void PCB_EDIT_FRAME::Exchange_Module( MODULE* aSrc, MODULE* aDest, BOARD_COMMIT&
/* place module without ratsnest refresh: this will be made later
* when all modules are on board */
PlaceModule( aDest, nullptr, false );
PlaceModule( aDest, false );
// Copy full placement and pad net names (when possible)
// but not local settings like clearances (use library values)

View File

@ -29,7 +29,8 @@
#include <confirm.h>
#include <kicad_string.h>
#include <pcb_edit_frame.h>
#include <tool/tool_manager.h>
#include <tools/pcb_actions.h>
#include <class_board.h>
#include <class_module.h>
#include <class_marker_pcb.h>
@ -84,6 +85,7 @@ void DIALOG_FIND::onButtonFindItemClick( wxCommandEvent& aEvent )
PCB_SCREEN* screen = parent->GetScreen();
wxPoint pos;
GetToolManager()->RunAction( PCB_ACTIONS::selectionClear, true );
wxString searchString = m_SearchTextCtrl->GetValue();
if( !searchString.IsSameAs( prevSearchString, false ) )
@ -131,7 +133,7 @@ void DIALOG_FIND::onButtonFindItemClick( wxCommandEvent& aEvent )
if( foundItem )
{
parent->SetCurItem( foundItem );
GetToolManager()->RunAction( PCB_ACTIONS::selectItem, true, foundItem );
parent->FocusOnLocation( pos, !m_NoMouseWarpCheckBox->IsChecked(), true );
msg.Printf( _( "\"%s\" found" ), GetChars( searchString ) );
parent->SetStatusText( msg );
@ -155,6 +157,7 @@ void DIALOG_FIND::onButtonFindMarkerClick( wxCommandEvent& aEvent )
wxPoint pos;
foundItem = NULL;
GetToolManager()->RunAction( PCB_ACTIONS::selectionClear, true );
parent->GetCanvas()->GetViewStart( &screen->m_StartVisu.x, &screen->m_StartVisu.y );
MARKER_PCB* marker = parent->GetBoard()->GetMARKER( markerCount++ );
@ -168,7 +171,7 @@ void DIALOG_FIND::onButtonFindMarkerClick( wxCommandEvent& aEvent )
wxString msg;
if( foundItem )
{
parent->SetCurItem( foundItem );
GetToolManager()->RunAction( PCB_ACTIONS::selectItem, true, foundItem );
parent->FocusOnLocation( pos, !m_NoMouseWarpCheckBox->IsChecked() );
msg = _( "Marker found" );
parent->SetStatusText( msg );

View File

@ -100,8 +100,6 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete()
// Clear selection before removing any items
m_Parent->GetToolManager()->RunAction( PCB_ACTIONS::selectionClear, true );
m_Parent->SetCurItem( NULL );
bool delAll = false;
if( m_DelAlls->GetValue() )

View File

@ -30,7 +30,9 @@
#include <connectivity/connectivity_data.h>
#include <view/view.h>
#include <pcb_layer_box_selector.h>
#include <tool/tool_manager.h>
#include <tool/selection.h>
#include <tools/selection_tool.h>
#include "dialog_global_edit_tracks_and_vias_base.h"
// Columns of netclasses grid
@ -218,7 +220,8 @@ void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::buildNetclassesGrid()
bool DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::TransferDataToWindow()
{
auto item = dynamic_cast<BOARD_CONNECTED_ITEM*>( m_parent->GetCurItem() );
SELECTION& selection = GetToolManager()->GetTool<SELECTION_TOOL>()->GetSelection();
auto item = dynamic_cast<BOARD_CONNECTED_ITEM*>( selection.Front() );
m_tracks->SetValue( g_modifyTracks );
m_vias->SetValue( g_modifyVias );

View File

@ -57,7 +57,7 @@
#define NETLIST_DELETEEXTRAFOOTPRINTS_KEY wxT("NetlistDeleteExtraFootprints")
#define NETLIST_DELETESINGLEPADNETS_KEY wxT("NetlistDeleteSinglePadNets")
void PCB_EDIT_FRAME::InstallNetlistFrame( wxDC* DC )
void PCB_EDIT_FRAME::InstallNetlistFrame()
{
wxString netlistName = GetLastNetListRead();

View File

@ -0,0 +1,122 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2019 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 <fctsys.h>
#include <class_drawpanel.h>
#include <pcb_edit_frame.h>
#include <dialog_helpers.h>
#include <base_units.h>
#include <gr_basic.h>
#include <board_commit.h>
#include <class_board.h>
#include <class_pcb_target.h>
#include <pcbnew.h>
#include <dialog_target_properties_base.h>
#include <widgets/unit_binder.h>
class DIALOG_TARGET_PROPERTIES : public DIALOG_TARGET_PROPERTIES_BASE
{
private:
PCB_EDIT_FRAME* m_Parent;
PCB_TARGET* m_Target;
UNIT_BINDER m_Size;
UNIT_BINDER m_Thickness;
public:
DIALOG_TARGET_PROPERTIES( PCB_EDIT_FRAME* aParent, PCB_TARGET* aTarget );
~DIALOG_TARGET_PROPERTIES() { }
private:
bool TransferDataToWindow() override;
bool TransferDataFromWindow() override;
};
void PCB_EDIT_FRAME::ShowTargetOptionsDialog( PCB_TARGET* aTarget )
{
DIALOG_TARGET_PROPERTIES dialog( this, aTarget );
dialog.ShowModal();
}
DIALOG_TARGET_PROPERTIES::DIALOG_TARGET_PROPERTIES( PCB_EDIT_FRAME* aParent, PCB_TARGET* aTarget ) :
DIALOG_TARGET_PROPERTIES_BASE( aParent ),
m_Parent( aParent ),
m_Target( aTarget ),
m_Size( aParent, m_sizeLabel, m_sizeCtrl, m_sizeUnits, true ),
m_Thickness( aParent, m_thicknessLabel, m_thicknessCtrl, m_thicknessUnits, true )
{
m_sdbSizerButtsOK->SetDefault();
SetInitialFocus( m_sizeCtrl );
// Now all widgets have the size fixed, call FinishDialogSettings
FinishDialogSettings();
}
bool DIALOG_TARGET_PROPERTIES::TransferDataToWindow()
{
m_Size.SetValue( m_Target->GetSize() );
m_Thickness.SetValue( m_Target->GetWidth() );
m_TargetShape->SetSelection( m_Target->GetShape() ? 1 : 0 );
return true;
}
bool DIALOG_TARGET_PROPERTIES::TransferDataFromWindow()
{
// Zero-size targets are hard to see/select.
if( !m_Size.Validate( Mils2iu( 1 ), INT_MAX ) )
return false;
BOARD_COMMIT commit( m_Parent );
commit.Modify( m_Target );
// Save old item in undo list, if is is not currently edited (will be later if so)
bool pushCommit = ( m_Target->GetEditFlags() == 0 );
if( m_Target->GetEditFlags() != 0 ) // other edit in progress (MOVE, NEW ..)
m_Target->SetFlags( IN_EDIT ); // set flag in edit to force
// undo/redo/abort proper operation
m_Target->SetWidth( m_Thickness.GetValue() );
m_Target->SetSize( m_Size.GetValue() );
m_Target->SetShape( m_TargetShape->GetSelection() ? 1 : 0 );
if( pushCommit )
commit.Push( _( "Modified alignment target" ) );
return true;
}

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2004-2018 Jean-Pierre Charras jp.charras at wanadoo.fr
* Copyright (C) 2010-2018 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2010-2019 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
@ -53,10 +53,9 @@
* wxFormBuilder.
*/
DIALOG_TEXT_PROPERTIES::DIALOG_TEXT_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent, BOARD_ITEM* aItem,
wxDC* aDC ) :
DIALOG_TEXT_PROPERTIES::DIALOG_TEXT_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent, BOARD_ITEM* aItem ) :
DIALOG_TEXT_PROPERTIES_BASE( aParent ),
m_Parent( aParent ), m_DC( aDC ), m_item( aItem ),
m_Parent( aParent ), m_item( aItem ),
m_edaText( nullptr ), m_modText( nullptr ), m_pcbText( nullptr ),
m_textWidth( aParent, m_SizeXLabel, m_SizeXCtrl, m_SizeXUnits, true ),
m_textHeight( aParent, m_SizeYLabel, m_SizeYCtrl, m_SizeYUnits, true ),
@ -187,18 +186,15 @@ DIALOG_TEXT_PROPERTIES::~DIALOG_TEXT_PROPERTIES()
/**
* Routine for main window class to launch text properties dialog.
*/
void PCB_BASE_EDIT_FRAME::InstallTextOptionsFrame( BOARD_ITEM* aText, wxDC* aDC )
void PCB_BASE_EDIT_FRAME::InstallTextOptionsFrame( BOARD_ITEM* aText )
{
m_canvas->SetIgnoreMouseEvents( true );
#ifndef __WXMAC__
DIALOG_TEXT_PROPERTIES dlg( this, aText, aDC );
#else
// Avoid "writes" in the dialog, creates errors with WxOverlay and NSView
// Raising an Exception - Fixes #891347
DIALOG_TEXT_PROPERTIES dlg( this, aText, NULL );
#endif
DIALOG_TEXT_PROPERTIES dlg( this, aText );
dlg.ShowModal();
m_canvas->MoveCursorToCrossHair();
m_canvas->SetIgnoreMouseEvents( false );
}
@ -369,14 +365,6 @@ bool DIALOG_TEXT_PROPERTIES::TransferDataFromWindow()
if( !pushCommit )
m_item->SetFlags( IN_EDIT );
#ifndef USE_WX_OVERLAY
// Erase old text on screen if context is available
if( m_DC )
{
m_item->Draw( m_Parent->GetCanvas(), m_DC, GR_XOR );
}
#endif
// Set the new text content
if( m_SingleLineText->IsShown() )
{
@ -439,15 +427,7 @@ bool DIALOG_TEXT_PROPERTIES::TransferDataFromWindow()
default: break;
}
#ifndef USE_WX_OVERLAY
// Finally, display new text if there is a context to do so
if( m_DC )
{
m_item->Draw( m_Parent->GetCanvas(), m_DC, GR_OR );
}
#else
m_Parent->Refresh();
#endif
if( pushCommit )
commit.Push( _( "Change text properties" ) );

View File

@ -40,12 +40,11 @@ class TEXTE_PCB;
class DIALOG_TEXT_PROPERTIES : public DIALOG_TEXT_PROPERTIES_BASE
{
public:
DIALOG_TEXT_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent, BOARD_ITEM* aItem, wxDC* aDC = nullptr );
DIALOG_TEXT_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent, BOARD_ITEM* aItem );
~DIALOG_TEXT_PROPERTIES();
private:
PCB_BASE_EDIT_FRAME* m_Parent;
wxDC* m_DC;
BOARD_ITEM* m_item; // TEXTE_MODULE, TEXTE_PCB, or DIMENSION
EDA_TEXT* m_edaText; // always non-null
TEXTE_MODULE* m_modText; // only non-null for TEXTE_MODULEs

View File

@ -1,228 +0,0 @@
/**
* @file dimension.cpp
* @brief Dialog and code for editing a dimension object.
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2016 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 <fctsys.h>
#include <confirm.h>
#include <gr_basic.h>
#include <class_drawpanel.h>
#include <pcb_edit_frame.h>
#include <draw_graphic_text.h>
#include <dialog_helpers.h>
#include <macros.h>
#include <base_units.h>
#include <board_commit.h>
#include <class_board.h>
#include <class_pcb_text.h>
#include <class_dimension.h>
#include <pcbnew.h>
#include <pcb_layer_box_selector.h>
#include <dialogs/dialog_text_properties.h>
/* Local functions */
static void BuildDimension( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
const wxPoint& aPosition, bool aErase );
/* Local variables : */
static int status_dimension; /* Used in dimension creation:
* = 0 : initial value: no dimension in progress
* = 1 : First point created
* = 2 : Second point created, the text must be placed */
/*
* A dimension has this shape:
* It has 2 reference points, and a text
* | |
* | dist |
* |<---------->|
* | |
*
*/
static void AbortBuildDimension( EDA_DRAW_PANEL* Panel, wxDC* aDC )
{
DIMENSION* dimension = (DIMENSION*) Panel->GetScreen()->GetCurItem();
if( dimension )
{
if( dimension->IsNew() )
{
dimension->Draw( Panel, aDC, GR_XOR );
dimension->DeleteStructure();
}
else
{
dimension->Draw( Panel, aDC, GR_OR );
}
}
status_dimension = 0;
((PCB_EDIT_FRAME*)Panel->GetParent())->SetCurItem( NULL );
}
DIMENSION* PCB_EDIT_FRAME::EditDimension( DIMENSION* aDimension, wxDC* aDC )
{
wxPoint pos;
if( aDimension == NULL )
{
const BOARD_DESIGN_SETTINGS& boardSettings = GetBoard()->GetDesignSettings();
status_dimension = 1;
pos = GetCrossHairPosition();
aDimension = new DIMENSION( GetBoard() );
aDimension->SetFlags( IS_NEW );
aDimension->SetLayer( GetActiveLayer() );
aDimension->SetOrigin( pos );
aDimension->SetEnd( pos );
aDimension->Text().SetTextSize( boardSettings.GetTextSize( GetActiveLayer() ) );
aDimension->Text().SetThickness( boardSettings.GetTextThickness( GetActiveLayer() ) );
aDimension->Text().SetItalic( boardSettings.GetTextItalic( GetActiveLayer() ) );
aDimension->SetWidth( boardSettings.GetLineThickness( GetActiveLayer() ) );
aDimension->AdjustDimensionDetails();
aDimension->Draw( m_canvas, aDC, GR_XOR );
m_canvas->SetMouseCapture( BuildDimension, AbortBuildDimension );
return aDimension;
}
// Dimension != NULL
if( status_dimension == 1 )
{
status_dimension = 2;
return aDimension;
}
aDimension->Draw( m_canvas, aDC, GR_OR );
aDimension->ClearFlags();
/* ADD this new item in list */
GetBoard()->Add( aDimension );
// Add store it in undo/redo list
SaveCopyInUndoList( aDimension, UR_NEW );
OnModify();
m_canvas->SetMouseCapture( NULL, NULL );
return NULL;
}
static void BuildDimension( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
const wxPoint& aPosition, bool aErase )
{
PCB_SCREEN* screen = (PCB_SCREEN*) aPanel->GetScreen();
DIMENSION* Dimension = (DIMENSION*) screen->GetCurItem();
wxPoint pos = aPanel->GetParent()->GetCrossHairPosition();
if( Dimension == NULL )
return;
// Erase previous dimension.
if( aErase )
{
Dimension->Draw( aPanel, aDC, GR_XOR );
}
Dimension->SetLayer( screen->m_Active_Layer );
if( status_dimension == 1 )
{
Dimension->m_featureLineDO = pos;
Dimension->m_crossBarF = Dimension->m_featureLineDO;
Dimension->AdjustDimensionDetails();
}
else
{
/* Calculating the direction of travel perpendicular to the selected axis. */
double angle = Dimension->GetAngle() + (M_PI / 2);
wxPoint delta = pos - Dimension->m_featureLineDO;
double depl = ( delta.x * cos( angle ) ) + ( delta.y * sin( angle ) );
Dimension->SetHeight( depl );
}
Dimension->Draw( aPanel, aDC, GR_XOR );
}
void PCB_EDIT_FRAME::ShowDimensionPropertyDialog( DIMENSION* aDimension, wxDC* aDC )
{
if( aDimension == NULL )
return;
DIALOG_TEXT_PROPERTIES dlg( this, aDimension, aDC );
dlg.ShowModal();
}
void PCB_EDIT_FRAME::DeleteDimension( DIMENSION* aDimension, wxDC* aDC )
{
if( aDimension == NULL )
return;
if( aDC )
aDimension->Draw( m_canvas, aDC, GR_XOR );
SaveCopyInUndoList( aDimension, UR_DELETED );
aDimension->UnLink();
OnModify();
}
/* Initialize parameters to move a pcb text
*/
static wxPoint initialTextPosition;
/*
* Place the current dimension text being moving
*/
void PCB_EDIT_FRAME::PlaceDimensionText( DIMENSION* aItem, wxDC* DC )
{
m_canvas->SetMouseCapture( NULL, NULL );
SetCurItem( NULL );
if( aItem == NULL )
return;
aItem->Draw( m_canvas, DC, GR_OR );
OnModify();
wxPoint tmp = aItem->Text().GetTextPos();
aItem->Text().SetTextPos( initialTextPosition );
SaveCopyInUndoList( aItem, UR_CHANGED );
aItem->Text().SetTextPos( tmp );
aItem->ClearFlags();
}

View File

@ -1,175 +0,0 @@
/**
* @file drag.h
* @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-2015 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _DRAG_H_
#define _DRAG_H_
#include <class_track.h>
#include <vector>
class wxDC;
class wxPoint;
class EDA_DRAW_PANEL;
class MODULE;
class D_PAD;
class CONNECTIONS;
/** Helper classes to handle a list of track segments to drag
* and has info to undo/abort the move command
*/
/*
* a DRAG_LIST manages the list of track segments to modify
* when the pad or the module is moving in drag mode
*/
/**
* a DRAG_SEGM_PICKER manage one track segment or a via
*/
class DRAG_SEGM_PICKER
{
public:
TRACK* m_Track; // pointer to the parent track segment
D_PAD* m_Pad_Start; // pointer to the moving pad
// if the start point should follow this pad
// or NULL
D_PAD* m_Pad_End; // pointer to the moving pad
// if the end point should follow this pad
// or NULL
int m_TempFlags; // flag used in drag vias and drag track segment functions
private:
double m_RotationOffset; // initial orientation of the parent module
// 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 calculations 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:
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
std::vector<DRAG_SEGM_PICKER> m_DragList; // The list of DRAG_SEGM_PICKER items
public:
DRAG_LIST( BOARD* aPcb )
{
m_Brd = aPcb;
m_Module = NULL;
m_Pad = NULL;
}
/**
* 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( std::vector<D_PAD*>& aList );
};
// Global variables:
// a list of DRAG_SEGM_PICKER items used to move or drag tracks.
// Each DRAG_SEGM_PICKER item points a segment to move.
extern std::vector<DRAG_SEGM_PICKER> g_DragSegmentList;
// Functions:
void DrawSegmentWhileMovingFootprint( EDA_DRAW_PANEL* panel, wxDC* DC );
/**
* Function EraseDragList
* clear the .m_Flags of all track segments stored in g_DragSegmentList
* and clear the list.
* In order to avoid useless memory reallocation, the memory is not freed
* and will be reused when creating a new list
*/
void EraseDragList();
#endif // _DRAG_H_

View File

@ -1,301 +0,0 @@
/**
* @file dragsegm.cpp
* @brief Classes to find track segments connected to a pad or a module
* for drag commands
*/
/*
* 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 <fctsys.h>
#include <common.h>
#include <trigo.h>
#include <gr_basic.h>
#include <class_drawpanel.h>
#include <pcb_base_frame.h>
#include <macros.h>
#include <drag.h>
#include <pcbnew.h>
#include <class_module.h>
#include <class_board.h>
#include <connectivity/connectivity_data.h>
/* a list of DRAG_SEGM_PICKER items used to move or drag tracks */
std::vector<DRAG_SEGM_PICKER> g_DragSegmentList;
/* helper class to handle a list of track segments to drag or move
*/
DRAG_SEGM_PICKER::DRAG_SEGM_PICKER( TRACK* aTrack )
{
m_Track = aTrack;
m_startInitialValue = m_Track->GetStart();
m_endInitialValue = m_Track->GetEnd();
m_Pad_Start = m_Track->GetState( START_ON_PAD ) ? (D_PAD*)m_Track->start : NULL;
m_Pad_End = m_Track->GetState( END_ON_PAD ) ? (D_PAD*)m_Track->end : NULL;
m_TempFlags = 0;
m_RotationOffset = 0.0;
m_Flipped = false;
}
void DRAG_SEGM_PICKER::SetAuxParameters()
{
MODULE* module = NULL;
if( m_Pad_Start )
{
module = m_Pad_Start->GetParent();
m_PadStartOffset = m_Track->GetStart() - m_Pad_Start->GetPosition();
}
if( m_Pad_End )
{
if( module == NULL )
module = m_Pad_End->GetParent();
m_PadEndOffset = m_Track->GetEnd() - m_Pad_End->GetPosition();
}
if( module )
{
m_Flipped = module->IsFlipped();
m_RotationOffset = module->GetOrientation();
}
}
void DRAG_SEGM_PICKER::SetTrackEndsCoordinates( wxPoint aOffset )
{
// the track start position is the pad position + m_PadStartOffset
// however m_PadStartOffset is known for the initial rotation/flip
// this is also true for track end position and m_PadEndOffset
// Therefore, because rotation/flipping is allowed during a drag
// and move module, we should recalculate the pad offset,
// depending on the current orientation/flip state of the module
// relative to its initial orientation.
// (although most of time, offset is 0,0)
double curr_rot_offset = m_RotationOffset;
MODULE* module = NULL;
bool flip = false;
if( m_Pad_Start )
module = m_Pad_Start->GetParent();
if( module == NULL && m_Pad_End )
module = m_Pad_End->GetParent();
if( module )
{
flip = m_Flipped != module->IsFlipped();
curr_rot_offset = module->GetOrientation() - m_RotationOffset;
if( flip ) // when flipping, module orientation is negated
curr_rot_offset = - module->GetOrientation() - m_RotationOffset;
}
if( m_Pad_Start )
{
wxPoint padoffset = m_PadStartOffset;
if( curr_rot_offset != 0.0 )
RotatePoint(&padoffset, curr_rot_offset);
if( flip )
padoffset.y = -padoffset.y;
m_Track->SetStart( m_Pad_Start->GetPosition() - aOffset + padoffset );
}
if( m_Pad_End )
{
wxPoint padoffset = m_PadEndOffset;
if( curr_rot_offset != 0.0 )
RotatePoint( &padoffset, curr_rot_offset );
if( flip )
padoffset.y = -padoffset.y;
m_Track->SetEnd( m_Pad_End->GetPosition() - aOffset + padoffset );
}
}
// A sort function needed to build ordered pads lists
extern bool sortPadsByXthenYCoord( D_PAD* const & ref, D_PAD* const & comp );
void DRAG_LIST::BuildDragListe( MODULE* aModule )
{
m_Pad = NULL;
m_Module = aModule;
std::vector<D_PAD*> padList;
for( auto pad : aModule->Pads() )
padList.push_back( pad );
sort( padList.begin(), padList.end(), sortPadsByXthenYCoord );
fillList( padList );
}
void DRAG_LIST::BuildDragListe( D_PAD* aPad )
{
m_Pad = aPad;
m_Module = NULL;
// Build connections info
std::vector<D_PAD*> padList;
padList.push_back( aPad );
fillList( padList );
}
// A helper function to sort track list per tracks
bool sort_tracklist( const DRAG_SEGM_PICKER& ref, const DRAG_SEGM_PICKER& tst )
{
return ref.m_Track < tst.m_Track;
}
void DRAG_LIST::fillList( std::vector<D_PAD*>& aList )
{
// clear flags and variables of selected tracks
for( auto pad : aList )
{
auto connectedTracks = m_Brd->GetConnectivity()->GetConnectedTracks( pad );
// store track connected to the pad
for( auto track : connectedTracks )
{
track->start = NULL;
track->end = NULL;
track->SetState( START_ON_PAD|END_ON_PAD|BUSY, false );
}
}
// store tracks connected to pads
for( auto pad : aList )
{
auto connectedTracks = m_Brd->GetConnectivity()->GetConnectedTracks( pad );
// store track connected to the pad
for( auto track : connectedTracks )
{
if( pad->HitTest( track->GetStart() ) )
{
track->start = pad;
track->SetState( START_ON_PAD, true );
}
if( pad->HitTest( track->GetEnd() ) )
{
track->end = pad;
track->SetState( END_ON_PAD, true );
}
DRAG_SEGM_PICKER wrapper( track );
m_DragList.push_back( wrapper );
}
}
// remove duplicate in m_DragList:
// a track can be stored more than once if connected to 2 overlapping pads, or
// each track end connected to 2 moving pads
// to avoid artifact in draw function, items should be not duplicated
// However, there is not a lot of items to be removed, so there ir no optimization.
// sort the drag list by track pointers
sort( m_DragList.begin(), m_DragList.end(), sort_tracklist );
// Explore the list, merge duplicates
for( int ii = 0; ii < (int)m_DragList.size()-1; ii++ )
{
int jj = ii+1;
if( m_DragList[ii].m_Track != m_DragList[jj].m_Track )
continue;
// duplicate found: merge info and remove duplicate
if( m_DragList[ii].m_Pad_Start == NULL )
m_DragList[ii].m_Pad_Start = m_DragList[jj].m_Pad_Start;
if( m_DragList[ii].m_Pad_End == NULL )
m_DragList[ii].m_Pad_End = m_DragList[jj].m_Pad_End;
m_DragList.erase( m_DragList.begin() + jj );
ii--;
}
// Initialize pad offsets and other params
for( unsigned ii = 0; ii < m_DragList.size(); ii++ )
m_DragList[ii].SetAuxParameters();
// Copy the list in global list
g_DragSegmentList = m_DragList;
}
void DRAG_LIST::ClearList()
{
for( unsigned ii = 0; ii < m_DragList.size(); ii++ )
m_DragList[ii].m_Track->ClearFlags();
m_DragList.clear();
m_Module = NULL;
m_Pad = NULL;
}
// Redraw the list of segments stored in g_DragSegmentList, while moving a footprint
void DrawSegmentWhileMovingFootprint( EDA_DRAW_PANEL* panel, wxDC* DC )
{
for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
{
TRACK* track = g_DragSegmentList[ii].m_Track;
#ifndef USE_WX_OVERLAY
track->Draw( panel, DC, GR_XOR ); // erase from screen at old position
#endif
g_DragSegmentList[ii].SetTrackEndsCoordinates( g_Offset_Module );
track->Draw( panel, DC, GR_XOR );
}
}
void EraseDragList()
{
for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
g_DragSegmentList[ii].m_Track->ClearFlags();
g_DragSegmentList.clear();
}

View File

@ -24,11 +24,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file edit.cpp
* @brief Edit PCB implementation.
*/
#include <fctsys.h>
#include <pgm_base.h>
#include <kiface_i.h>
@ -63,6 +58,7 @@
#include <tool/tool_manager.h>
#include <tools/pcb_actions.h>
#include <dialogs/dialog_text_properties.h>
// Handles the selection of command events.
void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
@ -70,7 +66,6 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
int id = event.GetId();
INSTALL_UNBUFFERED_DC( dc, m_canvas );
MODULE* module;
auto displ_opts = (PCB_DISPLAY_OPTIONS*)GetDisplayOptions();
m_canvas->CrossHairOff( &dc );
@ -168,7 +163,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_GET_NETLIST:
InstallNetlistFrame( &dc );
InstallNetlistFrame();
break;
case ID_AUX_TOOLBAR_PCB_SELECT_LAYER_PAIR:
@ -187,11 +182,11 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_MENU_PCB_UPDATE_FOOTPRINTS:
InstallExchangeModuleFrame( dynamic_cast<MODULE*>( GetCurItem() ), true, false );
InstallExchangeModuleFrame( nullptr, true, false );
break;
case ID_MENU_PCB_EXCHANGE_FOOTPRINTS:
InstallExchangeModuleFrame( dynamic_cast<MODULE*>( GetCurItem() ), false, false );
InstallExchangeModuleFrame( nullptr, false, false );
break;
case ID_MENU_PCB_SWAP_LAYERS:
@ -252,34 +247,6 @@ void PCB_EDIT_FRAME::SwitchLayer( wxDC* DC, PCB_LAYER_ID layer )
if( layer != B_Cu && layer != F_Cu && layer >= GetBoard()->GetCopperLayerCount() - 1 )
return;
}
EDA_ITEM* current = GetScreen()->GetCurItem();
// See if we are drawing a segment; if so, add a via?
if( GetToolId() == ID_TRACK_BUTT && current )
{
if( current->Type() == PCB_TRACE_T && current->IsNew() )
{
// Want to set the routing layers so that it switches properly -
// see the implementation of Other_Layer_Route - the working
// layer is used to 'start' the via and set the layer masks appropriately.
GetScreen()->m_Route_Layer_TOP = curLayer;
GetScreen()->m_Route_Layer_BOTTOM = layer;
SetActiveLayer( curLayer );
if( Other_Layer_Route( (TRACK*) GetScreen()->GetCurItem(), DC ) )
{
if( displ_opts->m_ContrastModeDisplay )
m_canvas->Refresh();
}
// if the via was allowed by DRC, then the layer swap has already
// been done by Other_Layer_Route(). if via not allowed, then
// return now so assignment to setActiveLayer() below doesn't happen.
return;
}
}
}
// Is yet more checking required? E.g. when the layer to be selected
@ -296,6 +263,7 @@ void PCB_EDIT_FRAME::SwitchLayer( wxDC* DC, PCB_LAYER_ID layer )
void PCB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent )
{
// JEY TODO: obsolete?
int id = aEvent.GetId();
int lastToolID = GetToolId();
@ -333,10 +301,6 @@ void PCB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent )
if( displ_opts->m_DisplayZonesMode != 0 )
DisplayInfoMessage( this, _( "Warning: zone display is OFF!!!" ) );
if( !GetBoard()->IsHighLightNetON() && (GetBoard()->GetHighLightNetCode() > 0 ) )
HighLight( &dc );
break;
case ID_PCB_KEEPOUT_BUTT:
@ -403,119 +367,17 @@ void PCB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent )
}
void PCB_EDIT_FRAME::moveExact()
{
wxPoint translation;
double rotation;
ROTATION_ANCHOR rotationAnchor = ROTATE_AROUND_ITEM_ANCHOR;
DIALOG_MOVE_EXACT dialog( this, translation, rotation, rotationAnchor );
int ret = dialog.ShowModal();
if( ret == wxID_OK )
{
if( BOARD_ITEM* item = GetScreen()->GetCurItem() )
{
// When a pad is modified, the full footprint is saved
BOARD_ITEM* itemToSave = item;
if( item->Type() == PCB_PAD_T )
itemToSave = item->GetParent();
// Could be moved or rotated
SaveCopyInUndoList( itemToSave, UR_CHANGED );
item->Move( translation );
switch( rotationAnchor )
{
case ROTATE_AROUND_ITEM_ANCHOR:
item->Rotate( item->GetPosition(), rotation );
break;
case ROTATE_AROUND_USER_ORIGIN:
item->Rotate( GetScreen()->m_O_Curseur, rotation );
break;
case ROTATE_AROUND_AUX_ORIGIN:
item->Rotate( GetAuxOrigin(), rotation );
break;
default:
wxFAIL_MSG( "Rotation choice shouldn't have been available in this context." );
}
m_canvas->Refresh();
}
}
m_canvas->MoveCursorToCrossHair();
}
class LEGACY_ARRAY_CREATOR: public ARRAY_CREATOR
{
public:
LEGACY_ARRAY_CREATOR( PCB_BASE_EDIT_FRAME& editFrame ):
ARRAY_CREATOR( editFrame ),
m_item( m_parent.GetScreen()->GetCurItem() )
{}
private:
int getNumberOfItemsToArray() const override
{
// only handle single items
return (m_item != NULL) ? 1 : 0;
}
BOARD_ITEM* getNthItemToArray( int n ) const override
{
wxASSERT_MSG( n == 0, "Legacy array tool can only handle a single item" );
return m_item;
}
BOARD* getBoard() const override
{
return m_parent.GetBoard();
}
MODULE* getModule() const override
{
return dynamic_cast<MODULE*>( m_item->GetParent() );
}
wxPoint getRotationCentre() const override
{
return m_item->GetCenter();
}
void finalise() override
{
m_parent.GetCanvas()->Refresh();
}
BOARD_ITEM* m_item; // only have the one
};
void PCB_BASE_EDIT_FRAME::createArray()
{
LEGACY_ARRAY_CREATOR array_creator( *this );
array_creator.Invoke();
}
void PCB_EDIT_FRAME::OnEditItemRequest( wxDC* aDC, BOARD_ITEM* aItem )
void PCB_EDIT_FRAME::OnEditItemRequest( BOARD_ITEM* aItem )
{
switch( aItem->Type() )
{
case PCB_TRACE_T:
case PCB_VIA_T:
Edit_TrackSegm_Width( aDC, static_cast<TRACK*>( aItem ) );
Edit_TrackSegm_Width( static_cast<TRACK*>( aItem ) );
break;
case PCB_TEXT_T:
InstallTextOptionsFrame( aItem, aDC );
InstallTextOptionsFrame( aItem );
break;
case PCB_PAD_T:
@ -523,19 +385,19 @@ void PCB_EDIT_FRAME::OnEditItemRequest( wxDC* aDC, BOARD_ITEM* aItem )
break;
case PCB_MODULE_T:
InstallFootprintPropertiesDialog( static_cast<MODULE*>( aItem ), aDC );
InstallFootprintPropertiesDialog( static_cast<MODULE*>( aItem ) );
break;
case PCB_TARGET_T:
ShowTargetOptionsDialog( static_cast<PCB_TARGET*>( aItem ), aDC );
ShowTargetOptionsDialog( static_cast<PCB_TARGET*>( aItem ) );
break;
case PCB_DIMENSION_T:
ShowDimensionPropertyDialog( static_cast<DIMENSION*>( aItem ), aDC );
ShowDimensionPropertyDialog( static_cast<DIMENSION*>( aItem ) );
break;
case PCB_MODULE_TEXT_T:
InstallTextOptionsFrame( aItem, aDC );
InstallTextOptionsFrame( aItem );
break;
case PCB_LINE_T:
@ -543,7 +405,7 @@ void PCB_EDIT_FRAME::OnEditItemRequest( wxDC* aDC, BOARD_ITEM* aItem )
break;
case PCB_ZONE_AREA_T:
Edit_Zone_Params( aDC, static_cast<ZONE_CONTAINER*>( aItem ) );
Edit_Zone_Params( static_cast<ZONE_CONTAINER*>( aItem ) );
break;
default:
@ -552,12 +414,12 @@ void PCB_EDIT_FRAME::OnEditItemRequest( wxDC* aDC, BOARD_ITEM* aItem )
}
void PCB_EDIT_FRAME::HighLight( wxDC* DC )
void PCB_EDIT_FRAME::ShowDimensionPropertyDialog( DIMENSION* aDimension )
{
if( GetBoard()->IsHighLightNetON() )
GetBoard()->HighLightOFF();
else
GetBoard()->HighLightON();
if( aDimension == NULL )
return;
GetBoard()->DrawHighLight( m_canvas, DC, GetBoard()->GetHighLightNetCode() );
DIALOG_TEXT_PROPERTIES dlg( this, aDimension );
dlg.ShowModal();
}

View File

@ -22,16 +22,11 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file edit_track_width.cpp
* @brief Functions to modify sizes of segment, track, net, all vias and/or all tracks.
*/
#include <fctsys.h>
#include <gr_basic.h>
#include <class_drawpanel.h>
#include <pcb_edit_frame.h>
#include <pcbnew_id.h>
#include <class_board.h>
#include <class_track.h>
@ -40,8 +35,8 @@
int PCB_EDIT_FRAME::SetTrackSegmentWidth( TRACK* aTrackItem,
PICKED_ITEMS_LIST* aItemsListPicker,
bool aUseNetclassValue )
PICKED_ITEMS_LIST* aItemsListPicker,
bool aUseNetclassValue )
{
int return_code = TRACK_ACTION_NONE;
int initial_width;
@ -167,10 +162,9 @@ int PCB_EDIT_FRAME::SetTrackSegmentWidth( TRACK* aTrackItem,
/**
* Function Edit_TrackSegm_Width
* Modify one track segment width or one via diameter (using DRC control).
* @param aDC = the curred device context (can be NULL)
* @param aTrackItem = the track segment or via to modify
*/
void PCB_EDIT_FRAME::Edit_TrackSegm_Width( wxDC* aDC, TRACK* aTrackItem )
void PCB_EDIT_FRAME::Edit_TrackSegm_Width( TRACK* aTrackItem )
{
PICKED_ITEMS_LIST itemsListPicker;
bool changed = !SetTrackSegmentWidth( aTrackItem, &itemsListPicker, false );
@ -178,72 +172,133 @@ void PCB_EDIT_FRAME::Edit_TrackSegm_Width( wxDC* aDC, TRACK* aTrackItem )
if( !changed || aTrackItem->GetEditFlags() )
return; // No change
// The segment has changed: redraw it and save it in undo list
if( aDC )
{
TRACK* oldsegm = (TRACK*) itemsListPicker.GetPickedItemLink( 0 );
wxASSERT( oldsegm );
m_canvas->CrossHairOff( aDC ); // Erase cursor shape
oldsegm->Draw( m_canvas, aDC, GR_XOR ); // Erase old track shape
aTrackItem->Draw( m_canvas, aDC, GR_OR ); // Display new track shape
m_canvas->CrossHairOn( aDC ); // Display cursor shape
}
SaveCopyInUndoList( itemsListPicker, UR_CHANGED );
}
void PCB_EDIT_FRAME::Edit_Track_Width( wxDC* aDC, TRACK* aTrackSegment )
void PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event( wxCommandEvent& event )
{
/* Modify a full track (a trace) width (using DRC control).
* a full track is the set of track segments between 2 nodes: pads or a node that has
* more than 2 segments connected
* aDC = the curred device context (can be NULL)
* aTrackSegment = a via or a track belonging to the trace to change
int ii;
int id = event.GetId();
/* Note: none of these events require aborting the current command (if any)
* (like move, edit or block command)
* so we do not test for a current command in progress and call
* m_canvas->m_endMouseCaptureCallback( m_canvas, &dc );
*/
TRACK* pt_track;
int nb_segm;
if( aTrackSegment == NULL )
return;
pt_track = GetBoard()->MarkTrace( GetBoard()->m_Track, aTrackSegment, &nb_segm,
NULL, NULL, true );
PICKED_ITEMS_LIST itemsListPicker;
bool change = false;
for( int ii = 0; ii < nb_segm; ii++, pt_track = pt_track->Next() )
switch( id )
{
pt_track->SetState( BUSY, false );
case ID_AUX_TOOLBAR_PCB_SELECT_AUTO_WIDTH:
GetDesignSettings().m_UseConnectedTrackWidth =
not GetDesignSettings().m_UseConnectedTrackWidth;
break;
if( !SetTrackSegmentWidth( pt_track, &itemsListPicker, false ) )
change = true;
}
case ID_POPUP_PCB_SELECT_USE_NETCLASS_VALUES:
GetDesignSettings().m_UseConnectedTrackWidth = false;
GetDesignSettings().SetTrackWidthIndex( 0 );
GetDesignSettings().SetViaSizeIndex( 0 );
break;
if( !change )
return;
case ID_POPUP_PCB_SELECT_AUTO_WIDTH:
m_canvas->MoveCursorToCrossHair();
GetDesignSettings().m_UseConnectedTrackWidth = true;
break;
// Some segment have changed: redraw them and save in undo list
if( aDC )
{
m_canvas->CrossHairOff( aDC ); // Erase cursor shape
case ID_POPUP_PCB_SELECT_WIDTH1: // this is the default Netclass selection
case ID_POPUP_PCB_SELECT_WIDTH2: // this is a custom value selection
case ID_POPUP_PCB_SELECT_WIDTH3:
case ID_POPUP_PCB_SELECT_WIDTH4:
case ID_POPUP_PCB_SELECT_WIDTH5:
case ID_POPUP_PCB_SELECT_WIDTH6:
case ID_POPUP_PCB_SELECT_WIDTH7:
case ID_POPUP_PCB_SELECT_WIDTH8:
case ID_POPUP_PCB_SELECT_WIDTH9:
case ID_POPUP_PCB_SELECT_WIDTH10:
case ID_POPUP_PCB_SELECT_WIDTH11:
case ID_POPUP_PCB_SELECT_WIDTH12:
case ID_POPUP_PCB_SELECT_WIDTH13:
case ID_POPUP_PCB_SELECT_WIDTH14:
case ID_POPUP_PCB_SELECT_WIDTH15:
case ID_POPUP_PCB_SELECT_WIDTH16:
m_canvas->MoveCursorToCrossHair();
GetDesignSettings().m_UseConnectedTrackWidth = false;
ii = id - ID_POPUP_PCB_SELECT_WIDTH1;
GetDesignSettings().SetTrackWidthIndex( ii );
break;
for( unsigned ii = 0; ii < itemsListPicker.GetCount(); ii++ )
case ID_POPUP_PCB_SELECT_VIASIZE1: // this is the default Netclass selection
case ID_POPUP_PCB_SELECT_VIASIZE2: // this is a custom value selection
case ID_POPUP_PCB_SELECT_VIASIZE3:
case ID_POPUP_PCB_SELECT_VIASIZE4:
case ID_POPUP_PCB_SELECT_VIASIZE5:
case ID_POPUP_PCB_SELECT_VIASIZE6:
case ID_POPUP_PCB_SELECT_VIASIZE7:
case ID_POPUP_PCB_SELECT_VIASIZE8:
case ID_POPUP_PCB_SELECT_VIASIZE9:
case ID_POPUP_PCB_SELECT_VIASIZE10:
case ID_POPUP_PCB_SELECT_VIASIZE11:
case ID_POPUP_PCB_SELECT_VIASIZE12:
case ID_POPUP_PCB_SELECT_VIASIZE13:
case ID_POPUP_PCB_SELECT_VIASIZE14:
case ID_POPUP_PCB_SELECT_VIASIZE15:
case ID_POPUP_PCB_SELECT_VIASIZE16:
// select the new current value for via size (via diameter)
m_canvas->MoveCursorToCrossHair();
ii = id - ID_POPUP_PCB_SELECT_VIASIZE1;
GetDesignSettings().SetViaSizeIndex( ii );
break;
case ID_AUX_TOOLBAR_PCB_TRACK_WIDTH:
ii = m_SelTrackWidthBox->GetSelection();
if( ii == int( m_SelTrackWidthBox->GetCount() - 2 ) )
{
TRACK* segm = (TRACK*) itemsListPicker.GetPickedItemLink( ii );
segm->Draw( m_canvas, aDC, GR_XOR ); // Erase old track shape
segm = (TRACK*) itemsListPicker.GetPickedItem( ii );
segm->Draw( m_canvas, aDC, GR_OR ); // Display new track shape
// fixme: commit!
// segm->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
// this is the separator
m_SelTrackWidthBox->SetSelection( GetDesignSettings().GetTrackWidthIndex() );
}
else if( ii == int( m_SelTrackWidthBox->GetCount() - 1 ) )
{
m_SelTrackWidthBox->SetSelection( GetDesignSettings().GetTrackWidthIndex() );
DoShowBoardSetupDialog( _( "Tracks & Vias" ) );
}
else
GetDesignSettings().SetTrackWidthIndex( ii );
m_canvas->CrossHairOn( aDC ); // Display cursor shape
break;
case ID_AUX_TOOLBAR_PCB_VIA_SIZE:
ii = m_SelViaSizeBox->GetSelection();
if( ii == int( m_SelViaSizeBox->GetCount() - 2 ) )
{
// this is the separator
m_SelViaSizeBox->SetSelection( GetDesignSettings().GetViaSizeIndex() );
}
else if( ii == int( m_SelViaSizeBox->GetCount() - 1 ) )
{
m_SelViaSizeBox->SetSelection( GetDesignSettings().GetViaSizeIndex() );
DoShowBoardSetupDialog( _( "Tracks & Vias" ) );
}
else
GetDesignSettings().SetViaSizeIndex( ii );
break;
default:
wxLogDebug( wxT( "PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event() error") );
break;
}
SaveCopyInUndoList( itemsListPicker, UR_CHANGED );
// Refresh track in progress, if any, by forcing a mouse event,
// to call the current function attached to the mouse
/*if( m_canvas->IsMouseCaptured() )
{
wxMouseEvent event(wxEVT_MOTION);
wxPostEvent( m_canvas, event );
}*/
//+hp
//Refresh canvas, that we can see changes instantly. I use this because it dont,t throw mouse up-left corner.
if( m_canvas->IsMouseCaptured() )
m_canvas->Refresh();
}

View File

@ -1,511 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2015 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 editrack-part2.cpp
*/
#include <fctsys.h>
#include <gr_basic.h>
#include <class_drawpanel.h>
#include <confirm.h>
#include <pcb_edit_frame.h>
#include <class_board.h>
#include <class_module.h>
#include <class_track.h>
#include <class_marker_pcb.h>
#include <pcbnew.h>
#include <drc.h>
#include <connectivity/connectivity_data.h>
bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC )
{
unsigned itmp;
if( aTrack == NULL )
{
if( GetActiveLayer() != GetScreen()->m_Route_Layer_TOP )
SetActiveLayer( GetScreen()->m_Route_Layer_TOP );
else
SetActiveLayer( GetScreen()->m_Route_Layer_BOTTOM );
UpdateStatusBar();
return true;
}
// Avoid more than one via on the current location:
if( GetBoard()->GetViaByPosition( g_CurrentTrackSegment->GetEnd(),
g_CurrentTrackSegment->GetLayer() ) )
return false;
for( TRACK* segm = g_FirstTrackSegment; segm; segm = segm->Next() )
{
if( segm->Type() == PCB_VIA_T && g_CurrentTrackSegment->GetEnd() == segm->GetStart() )
return false;
}
// Is the current segment Ok (no DRC error) ?
if( Settings().m_legacyDrcOn )
{
if( BAD_DRC==m_drc->DrcOnCreatingTrack( g_CurrentTrackSegment, GetBoard()->m_Track ) )
// DRC error, the change layer is not made
return false;
// Handle 2 segments.
if( Settings().m_legacyUseTwoSegmentTracks && g_CurrentTrackSegment->Back() )
{
if( BAD_DRC == m_drc->DrcOnCreatingTrack( g_CurrentTrackSegment->Back(),
GetBoard()->m_Track ) )
return false;
}
}
/* Save current state before placing a via.
* If the via cannot be placed this current state will be reused
*/
itmp = g_CurrentTrackList.GetCount();
Begin_Route( g_CurrentTrackSegment, DC );
m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
// create the via
VIA* via = new VIA( GetBoard() );
via->SetFlags( IS_NEW );
via->SetViaType( GetDesignSettings().m_CurrentViaType );
via->SetNetCode( GetBoard()->GetHighLightNetCode() );
via->SetPosition( g_CurrentTrackSegment->GetEnd() );
// for microvias, the size and hole will be changed later.
via->SetWidth( GetDesignSettings().GetCurrentViaSize());
via->SetDrill( GetDesignSettings().GetCurrentViaDrill() );
// Usual via is from copper to component.
// layer pair is B_Cu and F_Cu.
via->SetLayerPair( B_Cu, F_Cu );
PCB_LAYER_ID first_layer = GetActiveLayer();
PCB_LAYER_ID last_layer;
// prepare switch to new active layer:
if( first_layer != GetScreen()->m_Route_Layer_TOP )
last_layer = GetScreen()->m_Route_Layer_TOP;
else
last_layer = GetScreen()->m_Route_Layer_BOTTOM;
// Adjust the actual via layer pair
switch( via->GetViaType() )
{
case VIA_BLIND_BURIED:
via->SetLayerPair( first_layer, last_layer );
break;
case VIA_MICROVIA: // from external to the near neighbor inner layer
{
PCB_LAYER_ID last_inner_layer = ToLAYER_ID( ( GetBoard()->GetCopperLayerCount() - 2 ) );
if( first_layer == B_Cu )
last_layer = last_inner_layer;
else if( first_layer == F_Cu )
last_layer = In1_Cu;
else if( first_layer == last_inner_layer )
last_layer = B_Cu;
else if( first_layer == In1_Cu )
last_layer = F_Cu;
// else error: will be removed later
via->SetLayerPair( first_layer, last_layer );
// Update diameter and hole size, which where set previously
// for normal vias
NETINFO_ITEM* net = via->GetNet();
via->SetWidth( net->GetMicroViaSize() );
via->SetDrill( net->GetMicroViaDrillSize() );
}
break;
default:
break;
}
if( Settings().m_legacyDrcOn &&
BAD_DRC == m_drc->DrcOnCreatingTrack( via, GetBoard()->m_Track ) )
{
// DRC fault: the Via cannot be placed here ...
delete via;
m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
// delete the track(s) added in Begin_Route()
while( g_CurrentTrackList.GetCount() > itmp )
{
Delete_Segment( DC, g_CurrentTrackSegment );
}
SetCurItem( g_CurrentTrackSegment, false );
// Refresh DRC diag, erased by previous calls
if( m_drc->GetCurrentMarker() )
SetMsgPanel( m_drc->GetCurrentMarker() );
return false;
}
SetActiveLayer( last_layer );
TRACK* lastNonVia = g_CurrentTrackSegment;
/* A new via was created. It was Ok.
*/
g_CurrentTrackList.PushBack( via );
/* The via is now in linked list and we need a new track segment
* after the via, starting at via location.
* it will become the new current segment (from via to the mouse cursor)
*/
TRACK* track = (TRACK*)lastNonVia->Clone();
/* the above creates a new segment from the last entered segment, with the
* current width, flags, netcode, etc... values.
* layer, start and end point are not correct,
* and will be modified next
*/
// set the layer to the new value
track->SetLayer( GetActiveLayer() );
/* the start point is the via position and the end point is the cursor
* which also is on the via (will change when moving mouse)
*/
track->SetEnd( via->GetStart() );
track->SetStart( via->GetStart() );
g_CurrentTrackList.PushBack( track );
if( Settings().m_legacyUseTwoSegmentTracks )
{
// Create a second segment (we must have 2 track segments to adjust)
g_CurrentTrackList.PushBack( (TRACK*)g_CurrentTrackSegment->Clone() );
}
m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
SetMsgPanel( via );
UpdateStatusBar();
return true;
}
static void ListSetState( EDA_ITEM* Start, int NbItem, STATUS_FLAGS State,
bool onoff );
void DrawTraces( EDA_DRAW_PANEL* panel, wxDC* DC, TRACK* aTrackList, int nbsegment,
GR_DRAWMODE draw_mode )
{
// preserve the start of the list for debugging.
for( TRACK* track = aTrackList; nbsegment > 0 && track; nbsegment--, track = track->Next() )
{
track->Draw( panel, DC, draw_mode );
}
}
/*
* This function try to remove an old track, when a new track is created,
* and the old track is no more needed
*/
int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC* aDC,
TRACK* aNewTrack,
int aNewTrackSegmentsCount,
PICKED_ITEMS_LIST* aItemsListPicker )
{
TRACK* StartTrack, * EndTrack;
TRACK* pt_segm;
TRACK* pt_del;
int nb_segm, nbconnect;
wxPoint start;
wxPoint end;
LSET startmasklayer, endmasklayer;
int netcode = aNewTrack->GetNetCode();
// Reconstruct the complete track (the new track has to start on a segment of track).
// Note: aNewTrackSegmentsCount conatins the number of new track segments
ListSetState( aNewTrack, aNewTrackSegmentsCount, BUSY, false );
/* If the new track begins with a via, complete the track segment using
* the following segment as a reference because a via is often a hub of
* segments, and does not characterize track.
*/
if( aNewTrack->Type() == PCB_VIA_T && ( aNewTrackSegmentsCount > 1 ) )
aNewTrack = aNewTrack->Next();
// When MarkTrace try to find the entire track, if the starting segment
// is fully inside a pad, MarkTrace does not find correctly the full trace,
// because the entire track is the set of segments between 2 nodes
// (pads or point connecting more than 2 items)
// so use another (better) starting segment in this case
TRACK* track_segment = aNewTrack;
for( int ii = 0; ii < aNewTrackSegmentsCount; ii++ )
{
D_PAD* pad_st = m_Pcb->GetPad( aNewTrack->GetStart() );
D_PAD* pad_end = m_Pcb->GetPad( aNewTrack->GetEnd() );
if( pad_st && pad_st == pad_end )
track_segment = aNewTrack->Next();
else
break;
}
// Mark the full trace containing track_segment, and recalculate the
// beginning of the trace, and the number of segments, as the new trace
// can contain also already existing track segments
aNewTrack = GetBoard()->MarkTrace( GetBoard()->m_Track, track_segment,
&aNewTrackSegmentsCount,
nullptr, nullptr, true );
wxASSERT( aNewTrack );
TRACK* bufStart = m_Pcb->m_Track->GetStartNetCode( netcode ); // Beginning of tracks of the net
TRACK* bufEnd = bufStart->GetEndNetCode( netcode ); // End of tracks of the net
// Flags for cleaning the net.
for( pt_del = bufStart; pt_del; pt_del = pt_del->Next() )
{
// printf( "track %p turning off BUSY | IN_EDIT | IS_LINKED\n", pt_del );
pt_del->SetState( BUSY | IN_EDIT | IS_LINKED, false );
if( pt_del == bufEnd ) // Last segment reached
break;
}
if( aNewTrack->GetEndSegments( aNewTrackSegmentsCount, &StartTrack, &EndTrack ) == 0 )
return 0;
if( ( StartTrack == NULL ) || ( EndTrack == NULL ) )
return 0;
start = StartTrack->GetStart();
end = EndTrack->GetEnd();
// The start and end points cannot be the same.
if( start == end )
return 0;
// Determine layers interconnected these points.
startmasklayer = StartTrack->GetLayerSet();
endmasklayer = EndTrack->GetLayerSet();
// There may be a via or a pad on the end points.
pt_segm = m_Pcb->m_Track->GetVia( NULL, start, startmasklayer );
if( pt_segm )
startmasklayer |= pt_segm->GetLayerSet();
if( StartTrack->start && ( StartTrack->start->Type() == PCB_PAD_T ) )
{
// Start on pad.
D_PAD* pad = (D_PAD*) StartTrack->start;
startmasklayer |= pad->GetLayerSet();
}
pt_segm = m_Pcb->m_Track->GetVia( NULL, end, endmasklayer );
if( pt_segm )
endmasklayer |= pt_segm->GetLayerSet();
if( EndTrack->end && ( EndTrack->end->Type() == PCB_PAD_T ) )
{
D_PAD* pad = (D_PAD*) EndTrack->end;
endmasklayer |= pad->GetLayerSet();
}
// Mark as deleted a new track (which is not involved in the search for other connections)
ListSetState( aNewTrack, aNewTrackSegmentsCount, IS_DELETED, true );
/* A segment must be connected to the starting point, otherwise
* it is unnecessary to analyze the other point
*/
pt_segm = GetTrack( bufStart, bufEnd, start, startmasklayer );
if( pt_segm == NULL ) // Not connected to the track starting point.
{
// Clear the delete flag.
ListSetState( aNewTrack, aNewTrackSegmentsCount, IS_DELETED, false );
return 0;
}
/* Marking a list of candidate segmented connect to endpoint
* Note: the vias are not taken into account because they do
* not define a track, since they are on an intersection.
*/
for( pt_del = bufStart, nbconnect = 0; ; )
{
pt_segm = GetTrack( pt_del, bufEnd, end, endmasklayer );
if( pt_segm == NULL )
break;
if( pt_segm->Type() != PCB_VIA_T )
{
if( pt_segm->GetState( IS_LINKED ) == 0 )
{
pt_segm->SetState( IS_LINKED, true );
nbconnect++;
}
}
if( pt_del == bufEnd )
break;
pt_del = pt_segm->Next();
}
if( nbconnect == 0 )
{
// Clear used flags
for( pt_del = bufStart; pt_del; pt_del = pt_del->Next() )
{
pt_del->SetState( BUSY | IS_DELETED | IN_EDIT | IS_LINKED, false );
if( pt_del == bufEnd ) // Last segment reached
break;
}
return 0;
}
// Mark trace as edited (which does not involve searching for other tracks)
ListSetState( aNewTrack, aNewTrackSegmentsCount, IS_DELETED, false );
ListSetState( aNewTrack, aNewTrackSegmentsCount, IN_EDIT, true );
// Test all marked segments.
while( nbconnect )
{
for( pt_del = bufStart; pt_del; pt_del = pt_del->Next() )
{
if( pt_del->GetState( IS_LINKED ) )
break;
if( pt_del == bufEnd ) // Last segment reached
break;
}
nbconnect--;
if( pt_del )
pt_del->SetState( IS_LINKED, false );
pt_del = GetBoard()->MarkTrace( GetBoard()->m_Track, pt_del, &nb_segm,
NULL, NULL, true );
/* Test if the marked track is redundant, i.e. if one of marked segments
* is connected to the starting point of the new track.
*/
pt_segm = pt_del;
for( int ii = 0; pt_segm && (ii < nb_segm); pt_segm = pt_segm->Next(), ii++ )
{
if( pt_segm->GetState( BUSY ) == 0 )
break;
if( pt_segm->GetStart() == start || pt_segm->GetEnd() == start )
{
// Marked track can be erased.
TRACK* NextS;
DrawTraces( m_canvas, aDC, pt_del, nb_segm, GR_XOR | GR_HIGHLIGHT );
for( int jj = 0; jj < nb_segm; jj++, pt_del = NextS )
{
NextS = pt_del->Next();
if( aItemsListPicker )
{
pt_del->UnLink();
pt_del->SetStatus( 0 );
pt_del->ClearFlags();
GetBoard()->GetConnectivity()->Remove( pt_del );
ITEM_PICKER picker( pt_del, UR_DELETED );
aItemsListPicker->PushItem( picker );
}
else
{
GetBoard()->GetConnectivity()->Remove( pt_del );
pt_del->DeleteStructure();
}
}
// Clean up flags.
for( pt_del = m_Pcb->m_Track; pt_del != NULL; pt_del = pt_del->Next() )
{
if( pt_del->GetState( IN_EDIT ) )
{
pt_del->SetState( IN_EDIT, false );
if( aDC )
pt_del->Draw( m_canvas, aDC, GR_OR );
}
pt_del->SetState( IN_EDIT | IS_LINKED, false );
}
return 1;
}
}
// Clear BUSY flag here because the track did not get marked.
ListSetState( pt_del, nb_segm, BUSY, false );
}
// Clear used flags
for( pt_del = m_Pcb->m_Track; pt_del; pt_del = pt_del->Next() )
{
pt_del->SetState( BUSY | IS_DELETED | IN_EDIT | IS_LINKED, false );
if( pt_del == bufEnd ) // Last segment reached
break;
}
return 0;
}
/* Set the bits of .m_State member to on/off value, using bit mask State
* of a list of EDA_ITEM
*/
static void ListSetState( EDA_ITEM* Start, int NbItem, STATUS_FLAGS State,
bool onoff )
{
for( ; (Start != NULL ) && ( NbItem > 0 ); NbItem--, Start = Start->Next() )
{
Start->SetState( State, onoff );
}
}

View File

@ -1,843 +0,0 @@
/*
* 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) 2012 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2012 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 editrack.cpp
*/
#include <fctsys.h>
#include <class_drawpanel.h>
#include <trigo.h>
#include <pcb_edit_frame.h>
#include <pcbnew.h>
#include <drc.h>
#include <protos.h>
#include <class_board.h>
#include <class_track.h>
#include <class_zone.h>
#include <connectivity/connectivity_data.h>
static void Abort_Create_Track( EDA_DRAW_PANEL* panel, wxDC* DC );
void ShowNewTrackWhenMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
const wxPoint& aPosition, bool aErase );
static void ComputeBreakPoint( TRACK* track, int SegmentCount, wxPoint end );
// A PICKED_ITEMS_LIST to store tracks which are modified/added/deleted
// during a track editing:
static PICKED_ITEMS_LIST s_ItemsListPicker;
/* Function called to abort a track creation
*/
static void Abort_Create_Track( EDA_DRAW_PANEL* Panel, wxDC* DC )
{
PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) Panel->GetParent();
BOARD* pcb = frame->GetBoard();
TRACK* track = dyn_cast<TRACK*>( frame->GetCurItem() );
if( track )
{
// Erase the current drawing
ShowNewTrackWhenMovingCursor( Panel, DC, wxDefaultPosition, false );
if( pcb->IsHighLightNetON() )
frame->HighLight( DC );
pcb->PopHighLight();
if( pcb->IsHighLightNetON() )
pcb->DrawHighLight( Panel, DC, pcb->GetHighLightNetCode() );
frame->ClearMsgPanel();
// Undo pending changes (mainly a lock point creation) and clear the
// undo picker list:
frame->PutDataInPreviousState( &s_ItemsListPicker, false, false );
s_ItemsListPicker.ClearListAndDeleteItems();
// Delete current (new) track
g_CurrentTrackList.DeleteAll();
}
frame->SetCurItem( NULL );
}
/*
* This function starts a new track segment.
* If a new track segment is in progress, ends this current new segment,
* and created a new one.
*/
TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC )
{
TRACK* trackOnStartPoint = NULL;
LSET layerMask( GetScreen()->m_Active_Layer );
wxPoint pos = GetCrossHairPosition();
BOARD_CONNECTED_ITEM* lockPoint;
if( aTrack == NULL ) // Starting a new track segment
{
m_canvas->SetMouseCapture( ShowNewTrackWhenMovingCursor, Abort_Create_Track );
// Prepare the undo command info
s_ItemsListPicker.ClearListAndDeleteItems(); // Should not be necessary, but...
GetBoard()->PushHighLight();
// erase old highlight
if( GetBoard()->IsHighLightNetON() )
HighLight( aDC );
g_CurrentTrackList.PushBack( new TRACK( GetBoard() ) );
g_CurrentTrackSegment->SetFlags( IS_NEW );
GetBoard()->SetHighLightNet( 0 );
// Search for a starting point of the new track, a track or pad
lockPoint = GetBoard()->GetLockPoint( pos, layerMask );
D_PAD* pad = NULL;
if( lockPoint ) // An item (pad or track) is found
{
if( lockPoint->Type() == PCB_PAD_T )
{
pad = (D_PAD*) lockPoint;
// A pad is found: put the starting point on pad center
pos = pad->GetPosition();
GetBoard()->SetHighLightNet( pad->GetNetCode() );
}
else // A track segment is found
{
trackOnStartPoint = (TRACK*) lockPoint;
GetBoard()->SetHighLightNet( trackOnStartPoint->GetNetCode() );
GetBoard()->CreateLockPoint( pos, trackOnStartPoint, &s_ItemsListPicker );
}
}
else
{
// Not a starting point, but a filled zone area can exist. This is also a
// good starting point.
ZONE_CONTAINER* zone;
zone = GetBoard()->HitTestForAnyFilledArea( pos,
GetScreen()-> m_Active_Layer,
GetScreen()-> m_Active_Layer,
-1 );
if( zone )
GetBoard()->SetHighLightNet( zone->GetNetCode() );
}
DBG( g_CurrentTrackList.VerifyListIntegrity() );
int net = -1;
if( lockPoint )
net = lockPoint->GetNetCode();
BuildAirWiresTargetsList( lockPoint, wxPoint( 0, 0 ), net );
DBG( g_CurrentTrackList.VerifyListIntegrity() );
GetBoard()->HighLightON();
GetBoard()->DrawHighLight( m_canvas, aDC, GetBoard()->GetHighLightNetCode() );
// Display info about track Net class, and init track and vias sizes:
g_CurrentTrackSegment->SetNetCode( GetBoard()->GetHighLightNetCode() );
SetCurrentNetClass( g_CurrentTrackSegment->GetNetClassName() );
g_CurrentTrackSegment->SetLayer( GetScreen()->m_Active_Layer );
g_CurrentTrackSegment->SetWidth( GetDesignSettings().GetCurrentTrackWidth() );
if( GetDesignSettings().m_UseConnectedTrackWidth )
{
if( trackOnStartPoint && trackOnStartPoint->Type() == PCB_TRACE_T )
g_CurrentTrackSegment->SetWidth( trackOnStartPoint->GetWidth());
}
g_CurrentTrackSegment->SetStart( pos );
g_CurrentTrackSegment->SetEnd( pos );
if( pad )
{
// Useful to display track length, if the pad has a die length:
g_CurrentTrackSegment->SetState( BEGIN_ONPAD, true );
g_CurrentTrackSegment->start = pad;
}
if( Settings().m_legacyUseTwoSegmentTracks )
{
// Create 2nd segment
g_CurrentTrackList.PushBack( (TRACK*)g_CurrentTrackSegment->Clone() );
DBG( g_CurrentTrackList.VerifyListIntegrity(); );
g_CurrentTrackSegment->start = g_FirstTrackSegment;
g_FirstTrackSegment->end = g_CurrentTrackSegment;
g_FirstTrackSegment->SetState( BEGIN_ONPAD | END_ONPAD, false );
}
DBG( g_CurrentTrackList.VerifyListIntegrity(); );
SetMsgPanel( g_CurrentTrackSegment );
SetCurItem( g_CurrentTrackSegment, false );
m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false );
if( Settings().m_legacyDrcOn )
{
if( BAD_DRC == m_drc->DrcOnCreatingTrack( g_CurrentTrackSegment, GetBoard()->m_Track ) )
{
return g_CurrentTrackSegment;
}
}
}
else // Track in progress : segment coordinates are updated by ShowNewTrackWhenMovingCursor.
{
// Test for a D.R.C. error:
if( Settings().m_legacyDrcOn )
{
if( BAD_DRC == m_drc->DrcOnCreatingTrack( g_CurrentTrackSegment, GetBoard()->m_Track ) )
return NULL;
// We must handle 2 segments
if( Settings().m_legacyUseTwoSegmentTracks && g_CurrentTrackSegment->Back() )
{
if( BAD_DRC == m_drc->DrcOnCreatingTrack( g_CurrentTrackSegment->Back(),
GetBoard()->m_Track ) )
return NULL;
}
}
/* Current track is Ok: current segment is kept, and a new one is
* created unless the current segment is null, or 2 last are null
* if this is a 2 segments track build.
*/
bool CanCreateNewSegment = true;
if( !Settings().m_legacyUseTwoSegmentTracks && g_CurrentTrackSegment->IsNull() )
CanCreateNewSegment = false;
if( Settings().m_legacyUseTwoSegmentTracks && g_CurrentTrackSegment->IsNull()
&& g_CurrentTrackSegment->Back()
&& g_CurrentTrackSegment->Back()->IsNull() )
CanCreateNewSegment = false;
if( CanCreateNewSegment )
{
// Erase old track on screen
DBG( g_CurrentTrackList.VerifyListIntegrity(); );
ShowNewTrackWhenMovingCursor( m_canvas, aDC, wxDefaultPosition, false );
DBG( g_CurrentTrackList.VerifyListIntegrity(); );
if( g_Raccord_45_Auto )
Add45DegreeSegment( aDC );
TRACK* previousTrack = g_CurrentTrackSegment;
TRACK* newTrack = (TRACK*)g_CurrentTrackSegment->Clone();
g_CurrentTrackList.PushBack( newTrack );
newTrack->SetFlags( IS_NEW );
newTrack->SetState( BEGIN_ONPAD | END_ONPAD, false );
newTrack->start = previousTrack->end;
DBG( g_CurrentTrackList.VerifyListIntegrity(); );
newTrack->SetStart( newTrack->GetEnd() );
newTrack->SetLayer( GetScreen()->m_Active_Layer );
if( !GetDesignSettings().m_UseConnectedTrackWidth )
newTrack->SetWidth( GetDesignSettings().GetCurrentTrackWidth() );
DBG( g_CurrentTrackList.VerifyListIntegrity(); );
// Show the new position
ShowNewTrackWhenMovingCursor( m_canvas, aDC, wxDefaultPosition, false );
}
}
SetCurItem( g_CurrentTrackSegment, false );
return g_CurrentTrackSegment;
}
bool PCB_EDIT_FRAME::Add45DegreeSegment( wxDC* aDC )
{
int dx0, dy0, dx1, dy1;
if( g_CurrentTrackList.GetCount() < 2 )
return false; // There must be 2 segments.
TRACK* curTrack = g_CurrentTrackSegment;
TRACK* prevTrack = curTrack->Back();
// Test if we have 2 consecutive track segments ( not via ) to connect.
if( curTrack->Type() != PCB_TRACE_T || prevTrack->Type() != PCB_TRACE_T )
{
return false;
}
int segm_step_45 = KiROUND( GetScreen()->GetGridSize().x / 2 );
if( segm_step_45 < ( curTrack->GetWidth() * 2 ) )
segm_step_45 = curTrack->GetWidth() * 2;
// Test if the segments are horizontal or vertical.
dx0 = prevTrack->GetEnd().x - prevTrack->GetStart().x;
dy0 = prevTrack->GetEnd().y - prevTrack->GetStart().y;
dx1 = curTrack->GetEnd().x - curTrack->GetStart().x;
dy1 = curTrack->GetEnd().y - curTrack->GetStart().y;
// Segments should have a min length.
if( std::max( abs( dx0 ), abs( dy0 ) ) < ( segm_step_45 * 2 ) )
return false;
if( std::max( abs( dx1 ), abs( dy1 ) ) < ( segm_step_45 * 2 ) )
return false;
// Create a new segment and connect it with the previous 2 segments.
TRACK* newTrack = (TRACK*)curTrack->Clone();
newTrack->SetStart( prevTrack->GetEnd() );
newTrack->SetEnd( curTrack->GetStart() );
if( dx0 == 0 ) // Previous segment is Vertical
{
if( dy1 != 0 ) // 2 segments are not 90 degrees.
{
delete newTrack;
return false;
}
/* Calculate coordinates the connection point.
* The new segment connects the 1st vertical segment and the 2nd
* horizontal segment.
*/
if( dy0 > 0 )
newTrack->SetStart( wxPoint(newTrack->GetStart().x, newTrack->GetStart().y -segm_step_45) );
else
newTrack->SetStart( wxPoint(newTrack->GetStart().x, newTrack->GetStart().y + segm_step_45) );
if( dx1 > 0 )
newTrack->SetEnd( wxPoint(newTrack->GetEnd().x + segm_step_45, newTrack->GetEnd().y) );
else
newTrack->SetEnd( wxPoint(newTrack->GetEnd().x - segm_step_45, newTrack->GetEnd().y) );
if( Settings().m_legacyDrcOn &&
BAD_DRC == m_drc->DrcOnCreatingTrack( curTrack, GetBoard()->m_Track ) )
{
delete newTrack;
return false;
}
prevTrack->SetEnd( newTrack->GetStart());
curTrack->SetStart( newTrack->GetEnd());
g_CurrentTrackList.Insert( newTrack, curTrack );
return true;
}
if( dy0 == 0 ) // Previous segment is horizontal
{
if( dx1 != 0 ) // 2 segments are not 90 degrees
{
delete newTrack;
return false;
}
/* Calculate the coordinates of the point of connection:
* A new segment has been created, connecting segment 1
* (horizontal) and segment 2 (vertical)
*/
if( dx0 > 0 )
newTrack->SetStart( wxPoint(newTrack->GetStart().x - segm_step_45 , newTrack->GetStart().y));
else
newTrack->SetStart( wxPoint(newTrack->GetStart().x + segm_step_45, newTrack->GetStart().y) );
if( dy1 > 0 )
newTrack->SetEnd( wxPoint(newTrack->GetEnd().x, newTrack->GetEnd().y + segm_step_45) );
else
newTrack->SetEnd( wxPoint(newTrack->GetEnd().x, newTrack->GetEnd().y - segm_step_45) );
if( Settings().m_legacyDrcOn &&
BAD_DRC == m_drc->DrcOnCreatingTrack( newTrack, GetBoard()->m_Track ) )
{
delete newTrack;
return false;
}
prevTrack->SetEnd( newTrack->GetStart());
curTrack->SetStart( newTrack->GetEnd());
g_CurrentTrackList.Insert( newTrack, curTrack );
return true;
}
return false;
}
TRACK* LocateIntrusion( TRACK* listStart, TRACK* aTrack, LAYER_NUM aLayer, const wxPoint& aRef )
{
int net = aTrack->GetNetCode();
int width = aTrack->GetWidth();
TRACK* found = NULL;
for( TRACK* track = listStart; track; track = track->Next() )
{
if( track->Type() == PCB_TRACE_T ) // skip vias
{
if( track->GetState( BUSY | IS_DELETED ) )
continue;
if( aLayer != track->GetLayer() )
continue;
if( track->GetNetCode() == net )
continue;
// TRACK::HitTest
int dist = (width + track->GetWidth()) / 2 + aTrack->GetClearance( track );
if( !TestSegmentHit( aRef, track->GetStart(), track->GetEnd(), dist ) )
continue;
found = track;
// prefer intrusions from the side, not the end
wxPoint pos = aRef - track->GetStart();
wxPoint vec = track->GetEnd() - track->GetStart();
double tmp = (double) pos.x * vec.x + (double) pos.y * vec.y;
if( tmp >= 0 && tmp <= (double) vec.x * vec.x + (double) vec.y * vec.y )
break;
}
}
return found;
}
/**
* Function PushTrack
* detects if the mouse is pointing into a conflicting track.
* In this case, it tries to push the new track out of the conflicting track's
* clearance zone. This gives us a cheap mechanism for drawing tracks that
* tightly follow others, independent of grid settings.
*
* KNOWN BUGS:
* - we do the same sort of search and calculation up to three times:
* 1) we search for magnetic hits (in controle.cpp)
* 2) we check if there's a DRC violation in the making (also controle.cpp)
* 3) we try to fix the DRC violation (here)
* - if we have a magnetic hit and a DRC violation at the same time, we choose
* the magnetic hit instead of solving the violation
* - should locate conflicting tracks also when we're crossing over them
*/
static void PushTrack( EDA_DRAW_PANEL* panel )
{
PCB_SCREEN* screen = (PCB_SCREEN*) panel->GetParent()->GetScreen();
BOARD* pcb = ( (PCB_BASE_FRAME*) (panel->GetParent()) )->GetBoard();
wxPoint cursor = panel->GetParent()->GetCrossHairPosition();
wxPoint cv, vec, n;
TRACK* track = g_CurrentTrackSegment;
TRACK* other;
double det;
int dist;
double f;
other = LocateIntrusion( pcb->m_Track, track, screen->m_Active_Layer, panel->GetParent()->RefPos( true ) );
// are we currently pointing into a conflicting trace ?
if( !other )
return;
if( other->GetNetCode() == track->GetNetCode() )
return;
cv = cursor - other->GetStart();
vec = other->GetEnd() - other->GetStart();
det = (double) cv.x * vec.y - (double) cv.y * vec.x;
// cursor is right at the center of the old track
if( !det )
return;
dist = (track->GetWidth() + 1) / 2 + (other->GetWidth() + 1) / 2 + track->GetClearance( other ) + 2;
/*
* DRC wants >, so +1.
* We may have a quantization error of 1/sqrt(2), so +1 again.
*/
// Vector "n" is perpendicular to "other", pointing towards the cursor.
if( det > 0 )
{
n.x = vec.y;
n.y = -vec.x;
}
else
{
n.x = -vec.y;
n.y = vec.x;
}
f = dist / hypot( double(n.x), double(n.y) );
n.x = KiROUND( f * n.x );
n.y = KiROUND( f * n.y );
wxPoint hp = track->GetEnd();
FindBestGridPointOnTrack( &hp, cursor, other );
track->SetEnd( hp + n );
}
//Helper function: Draws Via circle and Via Clearance circle.
inline void DrawViaCirclesWhenEditingNewTrack( EDA_RECT* aPanelClipBox,
wxDC* aDC, const wxPoint& aPos,
int aViaRadius,
int aViaRadiusWithClearence,
COLOR4D aColor)
{
//Current viasize clearance circle
GRCircle( aPanelClipBox, aDC, aPos.x, aPos.y, aViaRadiusWithClearence, aColor );
//Current viasize circle
GRCircle( aPanelClipBox, aDC, aPos.x, aPos.y, aViaRadius, aColor );
}
/* Redraw the current track being created when the mouse cursor is moved
*/
void ShowNewTrackWhenMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
bool aErase )
{
// DBG( g_CurrentTrackList.VerifyListIntegrity(); );
PCB_SCREEN* screen = (PCB_SCREEN*) aPanel->GetScreen();
PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) aPanel->GetParent();
auto displ_opts = (PCB_DISPLAY_OPTIONS*) aPanel-> GetDisplayOptions();
bool tmp = displ_opts->m_DisplayPcbTrackFill;
displ_opts->m_DisplayPcbTrackFill = true;
auto showTrackClearanceMode = displ_opts->m_ShowTrackClearanceMode;
if ( g_FirstTrackSegment == NULL )
return;
NETCLASSPTR netclass = g_FirstTrackSegment->GetNetClass();
if( showTrackClearanceMode != PCB_DISPLAY_OPTIONS::DO_NOT_SHOW_CLEARANCE )
displ_opts->m_ShowTrackClearanceMode = PCB_DISPLAY_OPTIONS::SHOW_CLEARANCE_ALWAYS;
// Values to Via circle
int boardViaRadius = frame->GetDesignSettings().GetCurrentViaSize()/2;
int viaRadiusWithClearence = boardViaRadius+netclass->GetClearance();
EDA_RECT* panelClipBox=aPanel->GetClipBox();
#ifndef USE_WX_OVERLAY
// Erase old track
if( aErase )
{
DrawTraces( aPanel, aDC, g_FirstTrackSegment, g_CurrentTrackList.GetCount(), GR_XOR );
frame->TraceAirWiresToTargets( aDC );
if( showTrackClearanceMode >= PCB_DISPLAY_OPTIONS::SHOW_CLEARANCE_NEW_TRACKS_AND_VIA_AREAS )
{
COLOR4D color = frame->Settings().Colors().GetLayerColor( g_CurrentTrackSegment->GetLayer() );
DrawViaCirclesWhenEditingNewTrack( panelClipBox, aDC, g_CurrentTrackSegment->GetEnd(),
boardViaRadius, viaRadiusWithClearence, color);
}
}
#endif
// MacOSX seems to need this.
if( g_CurrentTrackList.GetCount() == 0 )
return;
// Set track parameters, that can be modified while creating the track
g_CurrentTrackSegment->SetLayer( screen->m_Active_Layer );
if( !frame->GetDesignSettings().m_UseConnectedTrackWidth )
g_CurrentTrackSegment->SetWidth( frame->GetDesignSettings().GetCurrentTrackWidth() );
if( frame->Settings().m_legacyUseTwoSegmentTracks )
{
TRACK* previous_track = g_CurrentTrackSegment->Back();
if( previous_track && previous_track->Type()==PCB_TRACE_T )
{
previous_track->SetLayer( screen->m_Active_Layer );
if( !frame->GetDesignSettings().m_UseConnectedTrackWidth )
previous_track->SetWidth( frame->GetDesignSettings().GetCurrentTrackWidth() );
}
}
if( frame->Settings().m_legacyUse45DegreeTracks )
{
if( frame->Settings().m_legacyUseTwoSegmentTracks )
{
g_CurrentTrackSegment->SetEnd( frame->GetCrossHairPosition() );
if( frame->Settings().m_legacyDrcOn )
PushTrack( aPanel );
ComputeBreakPoint( g_CurrentTrackSegment,
g_CurrentTrackList.GetCount(),
g_CurrentTrackSegment->GetEnd() );
}
else
{
/* Calculate of the end of the path for the permitted directions:
* horizontal, vertical or 45 degrees.
*/
wxPoint hp = g_CurrentTrackSegment->GetEnd();
hp = CalculateSegmentEndPoint( frame->GetCrossHairPosition(),
g_CurrentTrackSegment->GetStart() );
g_CurrentTrackSegment->SetEnd(hp);
}
}
else // Here the angle is arbitrary
{
g_CurrentTrackSegment->SetEnd( frame->GetCrossHairPosition() );
}
// Redraw the new track
DBG( g_CurrentTrackList.VerifyListIntegrity(); );
DrawTraces( aPanel, aDC, g_FirstTrackSegment, g_CurrentTrackList.GetCount(), GR_XOR );
if( showTrackClearanceMode >= PCB_DISPLAY_OPTIONS::SHOW_CLEARANCE_NEW_TRACKS_AND_VIA_AREAS )
{
COLOR4D color = frame->Settings().Colors().GetLayerColor(g_CurrentTrackSegment->GetLayer());
//Via diameter must have taken what we are using, rather than netclass value.
DrawViaCirclesWhenEditingNewTrack( panelClipBox, aDC, g_CurrentTrackSegment->GetEnd(),
boardViaRadius, viaRadiusWithClearence, color);
}
/* Display info about current segment and the full new track:
* Choose the interesting segment: because we are using a 2 segments step,
* the last segment can be null, and the previous segment can be the
* interesting segment.
*/
TRACK* isegm = g_CurrentTrackSegment;
if( isegm->GetLength() == 0 && g_CurrentTrackSegment->Back() )
isegm = g_CurrentTrackSegment->Back();
// display track info:
frame->SetMsgPanel( isegm );
wxString msg;
// Display current segments count (number of segments in this new track):
msg.Printf( "%d", g_CurrentTrackList.GetCount() );
frame->AppendMsgPanel( _( "Segs Count" ), msg, DARKCYAN );
displ_opts->m_ShowTrackClearanceMode = showTrackClearanceMode;
displ_opts->m_DisplayPcbTrackFill = tmp;
frame->BuildAirWiresTargetsList( NULL, g_CurrentTrackSegment->GetEnd(),
g_CurrentTrackSegment->GetNetCode() );
frame->TraceAirWiresToTargets( aDC );
}
wxPoint CalculateSegmentEndPoint( const wxPoint& aPosition, const wxPoint& aOrigin )
{
// Determine end point for a segment direction 0, 90, or 45 degrees
// depending on it's position from the origin \a aOrigin and \a aPosition.
wxPoint endPoint;
int deltax = aPosition.x - aOrigin.x;
int deltay = aPosition.y - aOrigin.y;
deltax = abs( deltax );
deltay = abs( deltay );
int angle = 45;
if( deltax >= deltay )
{
if( deltax == 0 )
angle = 0;
else if( ( (deltay << 6 ) / deltax ) < 26 )
angle = 0;
}
else
{
angle = 45;
if( deltay == 0 )
angle = 90;
else if( ( (deltax << 6 ) / deltay ) < 26 )
angle = 90;
}
switch( angle )
{
case 0:
endPoint.x = aPosition.x;
endPoint.y = aOrigin.y;
break;
case 45:
deltax = std::min( deltax, deltay );
deltay = deltax;
// Recalculate the signs for deltax and deltaY.
if( ( aPosition.x - aOrigin.x ) < 0 )
deltax = -deltax;
if( ( aPosition.y - aOrigin.y ) < 0 )
deltay = -deltay;
endPoint.x = aOrigin.x + deltax;
endPoint.y = aOrigin.y + deltay;
break;
case 90:
endPoint.x = aOrigin.x;
endPoint.y = aPosition.y;
break;
}
return endPoint;
}
/**
* Compute new track angle based on previous track.
*/
void ComputeBreakPoint( TRACK* track, int SegmentCount, wxPoint end )
{
int iDx = 0;
int iDy = 0;
int iAngle = 0;
if( SegmentCount <= 0 )
return;
if( track == NULL )
return;
TRACK* newTrack = track;
track = track->Back();
SegmentCount--;
if( track )
{
iDx = end.x - track->GetStart().x;
iDy = end.y - track->GetStart().y;
iDx = abs( iDx );
iDy = abs( iDy );
}
TRACK* lastTrack = track ? track->Back() : NULL;
if( lastTrack )
{
if(( (lastTrack->GetEnd().x == lastTrack->GetStart().x)
|| (lastTrack->GetEnd().y == lastTrack->GetStart().y) )
&& !g_Alternate_Track_Posture)
{
iAngle = 45;
}
}
else
{
if( g_Alternate_Track_Posture )
{
iAngle = 45;
}
}
if( iAngle == 0 )
{
if( iDx >= iDy )
iAngle = 0;
else
iAngle = 90;
}
if( track == NULL )
iAngle = -1;
switch( iAngle )
{
case -1:
break;
case 0:
if( ( end.x - track->GetStart().x ) < 0 )
track->SetEnd(wxPoint( end.x + iDy, track->GetStart().y));
else
track->SetEnd(wxPoint( end.x - iDy, track->GetStart().y));
break;
case 45:
iDx = std::min( iDx, iDy );
iDy = iDx;
// Recalculate the signs for deltax and deltaY.
if( ( end.x - track->GetStart().x ) < 0 )
iDx = -iDx;
if( ( end.y - track->GetStart().y ) < 0 )
iDy = -iDy;
track->SetEnd(wxPoint(track->GetStart().x + iDx, track->GetStart().y + iDy));
break;
case 90:
if( ( end.y - track->GetStart().y ) < 0 )
track->SetEnd(wxPoint(track->GetStart().x , end.y + iDx));
else
track->SetEnd(wxPoint(track->GetStart().x , end.y - iDx));
break;
}
if( track )
{
if( track->IsNull() )
track->SetEnd( end );
newTrack->SetStart( track->GetEnd() );
}
newTrack->SetEnd( end );
}

View File

@ -1,172 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2009-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2012 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 event_handlers_tracks_vias_sizes.cpp
* @brief Handlers for popup and toolbars events relative to the tracks and vias sizes.
*/
#include <fctsys.h>
#include <class_drawpanel.h>
#include <confirm.h>
#include <pcb_edit_frame.h>
#include <dialog_helpers.h>
#include <pcbnew_id.h>
#include <pcbnew.h>
#include <class_board.h>
#include <class_module.h>
/* Event handler for tracks and vias size selection (and some options)
* relative to toolbars and popup events
*/
void PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event( wxCommandEvent& event )
{
int ii;
int id = event.GetId();
/* Note: none of these events require aborting the current command (if any)
* (like move, edit or block command)
* so we do not test for a current command in progress and call
* m_canvas->m_endMouseCaptureCallback( m_canvas, &dc );
*/
switch( id )
{
case ID_AUX_TOOLBAR_PCB_SELECT_AUTO_WIDTH:
GetDesignSettings().m_UseConnectedTrackWidth =
not GetDesignSettings().m_UseConnectedTrackWidth;
break;
case ID_POPUP_PCB_SELECT_USE_NETCLASS_VALUES:
GetDesignSettings().m_UseConnectedTrackWidth = false;
GetDesignSettings().SetTrackWidthIndex( 0 );
GetDesignSettings().SetViaSizeIndex( 0 );
break;
case ID_POPUP_PCB_SELECT_AUTO_WIDTH:
m_canvas->MoveCursorToCrossHair();
GetDesignSettings().m_UseConnectedTrackWidth = true;
break;
case ID_POPUP_PCB_SELECT_WIDTH1: // this is the default Netclass selection
case ID_POPUP_PCB_SELECT_WIDTH2: // this is a custom value selection
case ID_POPUP_PCB_SELECT_WIDTH3:
case ID_POPUP_PCB_SELECT_WIDTH4:
case ID_POPUP_PCB_SELECT_WIDTH5:
case ID_POPUP_PCB_SELECT_WIDTH6:
case ID_POPUP_PCB_SELECT_WIDTH7:
case ID_POPUP_PCB_SELECT_WIDTH8:
case ID_POPUP_PCB_SELECT_WIDTH9:
case ID_POPUP_PCB_SELECT_WIDTH10:
case ID_POPUP_PCB_SELECT_WIDTH11:
case ID_POPUP_PCB_SELECT_WIDTH12:
case ID_POPUP_PCB_SELECT_WIDTH13:
case ID_POPUP_PCB_SELECT_WIDTH14:
case ID_POPUP_PCB_SELECT_WIDTH15:
case ID_POPUP_PCB_SELECT_WIDTH16:
m_canvas->MoveCursorToCrossHair();
GetDesignSettings().m_UseConnectedTrackWidth = false;
ii = id - ID_POPUP_PCB_SELECT_WIDTH1;
GetDesignSettings().SetTrackWidthIndex( ii );
break;
case ID_POPUP_PCB_SELECT_VIASIZE1: // this is the default Netclass selection
case ID_POPUP_PCB_SELECT_VIASIZE2: // this is a custom value selection
case ID_POPUP_PCB_SELECT_VIASIZE3:
case ID_POPUP_PCB_SELECT_VIASIZE4:
case ID_POPUP_PCB_SELECT_VIASIZE5:
case ID_POPUP_PCB_SELECT_VIASIZE6:
case ID_POPUP_PCB_SELECT_VIASIZE7:
case ID_POPUP_PCB_SELECT_VIASIZE8:
case ID_POPUP_PCB_SELECT_VIASIZE9:
case ID_POPUP_PCB_SELECT_VIASIZE10:
case ID_POPUP_PCB_SELECT_VIASIZE11:
case ID_POPUP_PCB_SELECT_VIASIZE12:
case ID_POPUP_PCB_SELECT_VIASIZE13:
case ID_POPUP_PCB_SELECT_VIASIZE14:
case ID_POPUP_PCB_SELECT_VIASIZE15:
case ID_POPUP_PCB_SELECT_VIASIZE16:
// select the new current value for via size (via diameter)
m_canvas->MoveCursorToCrossHair();
ii = id - ID_POPUP_PCB_SELECT_VIASIZE1;
GetDesignSettings().SetViaSizeIndex( ii );
break;
case ID_AUX_TOOLBAR_PCB_TRACK_WIDTH:
ii = m_SelTrackWidthBox->GetSelection();
if( ii == int( m_SelTrackWidthBox->GetCount() - 2 ) )
{
// this is the separator
m_SelTrackWidthBox->SetSelection( GetDesignSettings().GetTrackWidthIndex() );
}
else if( ii == int( m_SelTrackWidthBox->GetCount() - 1 ) )
{
m_SelTrackWidthBox->SetSelection( GetDesignSettings().GetTrackWidthIndex() );
DoShowBoardSetupDialog( _( "Tracks & Vias" ) );
}
else
GetDesignSettings().SetTrackWidthIndex( ii );
break;
case ID_AUX_TOOLBAR_PCB_VIA_SIZE:
ii = m_SelViaSizeBox->GetSelection();
if( ii == int( m_SelViaSizeBox->GetCount() - 2 ) )
{
// this is the separator
m_SelViaSizeBox->SetSelection( GetDesignSettings().GetViaSizeIndex() );
}
else if( ii == int( m_SelViaSizeBox->GetCount() - 1 ) )
{
m_SelViaSizeBox->SetSelection( GetDesignSettings().GetViaSizeIndex() );
DoShowBoardSetupDialog( _( "Tracks & Vias" ) );
}
else
GetDesignSettings().SetViaSizeIndex( ii );
break;
default:
wxLogDebug( wxT( "PCB_EDIT_FRAME::Tracks_and_Vias_Size_Event() error") );
break;
}
// Refresh track in progress, if any, by forcing a mouse event,
// to call the current function attached to the mouse
/*if( m_canvas->IsMouseCaptured() )
{
wxMouseEvent event(wxEVT_MOTION);
wxPostEvent( m_canvas, event );
}*/
//+hp
//Refresh canvas, that we can see changes instantly. I use this because it dont,t throw mouse up-left corner.
if( m_canvas->IsMouseCaptured() )
m_canvas->Refresh();
}

View File

@ -226,7 +226,6 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent,
SetScreen( new PCB_SCREEN( GetPageSettings().GetSizeIU() ) );
GetScreen()->SetMaxUndoItems( m_UndoRedoCountMax );
GetScreen()->SetCurItem( NULL );
GetScreen()->AddGrid( m_UserGridSize, EDA_UNITS_T::UNSCALED_UNITS, ID_POPUP_GRID_USER );
GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
@ -933,27 +932,6 @@ void FOOTPRINT_EDIT_FRAME::CommonSettingsChanged()
}
void FOOTPRINT_EDIT_FRAME::UpdateMsgPanel()
{
// If a item is currently selected, displays the item info.
// If nothing selected, display the current footprint info
BOARD_ITEM* item = GetScreen()->GetCurItem();
if( !item )
item = GetBoard()->m_Modules;
MSG_PANEL_ITEMS items;
if( item )
{
item->GetMsgPanelInfo( m_UserUnits, items );
SetMsgPanel( items );
}
else
ClearMsgPanel();
}
void FOOTPRINT_EDIT_FRAME::OnSaveFootprintAsPng( wxCommandEvent& event )
{
wxString fullFileName;

View File

@ -173,7 +173,7 @@ public:
void OnUpdateInsertModuleInBoard( wxUpdateUIEvent& aEvent );
///> @copydoc PCB_BASE_EDIT_FRAME::OnEditItemRequest()
void OnEditItemRequest( wxDC* aDC, BOARD_ITEM* aItem ) override;
void OnEditItemRequest( BOARD_ITEM* aItem ) override;
/**
* Called from the main toolbar to load a footprint from board mainly to edit it.
@ -363,15 +363,6 @@ public:
*/
void SyncLibraryTree( bool aProgress );
/**
* Redraw the message panel.
*
* If a item is currently selected, displays the item info.
* If nothing selected, display the current footprint info, or
* clear the message panel if nothing is edited
*/
void UpdateMsgPanel() override;
void KiwayMailIn( KIWAY_EXPRESS& mail ) override;
void SyncMenusAndToolbars() override;

View File

@ -48,7 +48,6 @@
#include <ratsnest_data.h>
#include <pcbnew.h>
#include <protos.h>
#include <pcbnew_id.h>
#include <footprint_edit_frame.h>
#include <footprint_viewer_frame.h>
@ -476,9 +475,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_MODEDIT_EDIT_MODULE_PROPERTIES:
if( GetBoard()->m_Modules )
{
SetCurItem( GetBoard()->m_Modules );
editFootprintProperties( (MODULE*) GetScreen()->GetCurItem() );
editFootprintProperties( GetBoard()->m_Modules );
m_canvas->Refresh();
}
break;
@ -507,8 +504,6 @@ void FOOTPRINT_EDIT_FRAME::editFootprintProperties( MODULE* aModule )
DIALOG_FOOTPRINT_FP_EDITOR dialog( this, aModule );
dialog.ShowModal();
GetScreen()->GetCurItem()->ClearFlags();
updateTitle(); // in case of a name change...
}
@ -587,7 +582,7 @@ void FOOTPRINT_EDIT_FRAME::OnVerticalToolbar( wxCommandEvent& aEvent )
}
void FOOTPRINT_EDIT_FRAME::OnEditItemRequest( wxDC* aDC, BOARD_ITEM* aItem )
void FOOTPRINT_EDIT_FRAME::OnEditItemRequest( BOARD_ITEM* aItem )
{
switch( aItem->Type() )
{
@ -603,7 +598,7 @@ void FOOTPRINT_EDIT_FRAME::OnEditItemRequest( wxDC* aDC, BOARD_ITEM* aItem )
break;
case PCB_MODULE_TEXT_T:
InstallTextOptionsFrame( aItem, aDC );
InstallTextOptionsFrame( aItem );
break;
case PCB_MODULE_EDGE_T :

View File

@ -327,7 +327,7 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module( const wxString& aName )
// Display info :
SetMsgPanel( module );
PlaceModule( module, NULL );
PlaceModule( module );
module->SetPosition( wxPoint( 0, 0 ) );
@ -849,7 +849,7 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintToBoard( bool aAddNew )
commit.Add( newmodule );
pcbframe->SetCrossHairPosition( wxPoint( 0, 0 ) );
pcbframe->PlaceModule( newmodule, NULL );
pcbframe->PlaceModule( newmodule );
newmodule->SetPosition( wxPoint( 0, 0 ) );
pcbframe->SetCrossHairPosition( cursor_pos );
newmodule->SetTimeStamp( GetNewTimeStamp() );
@ -860,7 +860,6 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintToBoard( bool aAddNew )
}
newmodule->ClearFlags();
pcbframe->SetCurItem( NULL );
// @todo LEGACY should be unnecessary
mainpcb->m_Status_Pcb = 0;

View File

@ -412,7 +412,6 @@ void FOOTPRINT_VIEWER_FRAME::ClickOnFootprintList( wxCommandEvent& event )
// Delete the current footprint (MUST reset tools first)
GetToolManager()->ResetTools( TOOL_BASE::MODEL_RELOAD );
SetCurItem( nullptr );
GetBoard()->m_Modules.DeleteAll();
LIB_ID id;
@ -499,7 +498,7 @@ void FOOTPRINT_VIEWER_FRAME::AddFootprintToPCB( wxCommandEvent& event )
commit.Add( newmodule );
pcbframe->SetCrossHairPosition( wxPoint( 0, 0 ) );
pcbframe->PlaceModule( newmodule, NULL );
pcbframe->PlaceModule( newmodule );
newmodule->SetPosition( wxPoint( 0, 0 ) );
pcbframe->SetCrossHairPosition( cursor_pos );
newmodule->SetTimeStamp( GetNewTimeStamp() );
@ -509,7 +508,6 @@ void FOOTPRINT_VIEWER_FRAME::AddFootprintToPCB( wxCommandEvent& event )
pcbframe->GetToolManager()->RunAction( PCB_ACTIONS::placeModule, true, newmodule );
newmodule->ClearFlags();
pcbframe->SetCurItem( NULL );
}
}
@ -784,7 +782,6 @@ void FOOTPRINT_VIEWER_FRAME::SelectAndViewFootprint( int aMode )
m_footprintList->EnsureVisible( selection );
setCurFootprintName( m_footprintList->GetString( (unsigned) selection ) );
SetCurItem( NULL );
// Delete the current footprint
GetBoard()->m_Modules.DeleteAll();
@ -820,22 +817,6 @@ void FOOTPRINT_VIEWER_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg )
}
void FOOTPRINT_VIEWER_FRAME::UpdateMsgPanel()
{
BOARD_ITEM* footprint = GetBoard()->m_Modules;
if( footprint )
{
MSG_PANEL_ITEMS items;
footprint->GetMsgPanelInfo( m_UserUnits, items );
SetMsgPanel( items );
}
else
ClearMsgPanel();
}
void FOOTPRINT_VIEWER_FRAME::ApplyDisplaySettingsToGAL()
{
auto painter = static_cast<KIGFX::PCB_PAINTER*>( GetGalCanvas()->GetView()->GetPainter() );

View File

@ -60,13 +60,6 @@ public:
bool GetAutoZoom() const { return m_autoZoom; }
void SetAutoZoom( bool aEnable ) { m_autoZoom = aEnable; }
/**
* redraws the message panel.
* display the current footprint info, or
* clear the message panel if nothing is loaded
*/
void UpdateMsgPanel() override;
/**
* Function ReCreateLibraryList
*

View File

@ -102,8 +102,6 @@ void FOOTPRINT_WIZARD_FRAME::ReloadFootprint()
if( !footprintWizard )
return;
SetCurItem( NULL );
m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD );
// Delete the current footprint

View File

@ -66,8 +66,6 @@ bool PCB_EDIT_FRAME::Clear_Pcb( bool aQuery )
SetElementVisibility( LAYER_GRID, showGrid );
SetElementVisibility( LAYER_RATSNEST, showRats );
SetCurItem( NULL );
// clear filename, to avoid overwriting an old file
GetBoard()->SetFileName( wxEmptyString );
@ -123,8 +121,6 @@ bool FOOTPRINT_EDIT_FRAME::Clear_Pcb( bool aQuery )
board->SynchronizeNetsAndNetClasses();
SetBoard( board );
SetCurItem( NULL );
// clear filename, to avoid overwriting an old file
GetBoard()->SetFileName( wxEmptyString );

View File

@ -23,11 +23,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file load_select_footprint.cpp
* @brief Footprints selection and loading functions.
*/
#include <functional>
using namespace std::placeholders;
@ -50,12 +45,13 @@ using namespace std::placeholders;
#include <class_board.h>
#include <class_module.h>
#include <io_mgr.h>
#include <connectivity/connectivity_data.h>
#include <pcbnew.h>
#include <footprint_edit_frame.h>
#include <footprint_info.h>
#include <footprint_info_impl.h>
#include <dialog_choose_footprint.h>
#include <dialog_get_footprint_by_name.h>
#include <footprint_viewer_frame.h>
#include <wildcards_and_files_ext.h>
#include <widgets/progress_reporter.h>
@ -112,8 +108,6 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule )
if( aModule == NULL )
return false;
SetCurItem( NULL );
if( !Clear_Pcb( true ) )
return false;
@ -135,7 +129,7 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule )
newModule->ClearAllNets();
SetCrossHairPosition( wxPoint( 0, 0 ) );
PlaceModule( newModule, NULL );
PlaceModule( newModule );
newModule->SetPosition( wxPoint( 0, 0 ) ); // cursor in GAL may not be initialized at the moment
// Put it on FRONT layer,
@ -145,7 +139,8 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule )
// Put it in orientation 0,
// because this is the default orientation in ModEdit, and in libs
Rotate_Module( NULL, newModule, 0, false );
newModule->SetOrientation( 0 );
Zoom_Automatique( false );
m_adapter->SetPreselectNode( newModule->GetFPID(), 0 );
@ -158,11 +153,8 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule )
ReCreateHToolbar();
Update3DView();
updateView();
m_canvas->Refresh();
m_treePane->GetLibTree()->Refresh(); // update any previously-highlighted items
return true;
@ -427,12 +419,108 @@ bool FOOTPRINT_EDIT_FRAME::SaveLibraryAs( const wxString& aLibraryPath )
return false;
}
msg = wxString::Format(
_( "Footprint library \"%s\" saved as \"%s\"." ),
GetChars( curLibPath ), GetChars( dstLibPath ) );
msg = wxString::Format( _( "Footprint library \"%s\" saved as \"%s\"." ),
curLibPath,
dstLibPath );
DisplayInfoMessage( this, msg );
SetStatusText( wxEmptyString );
return true;
}
static MODULE* s_ModuleInitialCopy = NULL; // Copy of module for abort/undo command
static PICKED_ITEMS_LIST s_PickedList; // a pick-list to save initial module
// and dragged tracks
MODULE* PCB_BASE_FRAME::GetFootprintFromBoardByReference()
{
wxString moduleName;
MODULE* module = NULL;
wxArrayString fplist;
// Build list of available fp references, to display them in dialog
for( MODULE* fp = GetBoard()->m_Modules; fp; fp = fp->Next() )
fplist.Add( fp->GetReference() + wxT(" ( ") + fp->GetValue() + wxT(" )") );
fplist.Sort();
DIALOG_GET_FOOTPRINT_BY_NAME dlg( this, fplist );
if( dlg.ShowModal() != wxID_OK ) //Aborted by user
return NULL;
moduleName = dlg.GetValue();
moduleName.Trim( true );
moduleName.Trim( false );
if( !moduleName.IsEmpty() )
{
module = GetBoard()->m_Modules;
while( module )
{
if( module->GetReference().CmpNoCase( moduleName ) == 0 )
break;
module = module->Next();
}
}
return module;
}
void PCB_BASE_FRAME::PlaceModule( MODULE* aModule, bool aRecreateRatsnest )
{
wxPoint newpos;
if( aModule == 0 )
return;
OnModify();
if( aModule->IsNew() )
{
SaveCopyInUndoList( aModule, UR_NEW );
}
else if( aModule->IsMoving() )
{
ITEM_PICKER picker( aModule, UR_CHANGED );
picker.SetLink( s_ModuleInitialCopy );
s_PickedList.PushItem( picker );
s_ModuleInitialCopy = NULL; // the picker is now owner of s_ModuleInitialCopy.
}
if( s_PickedList.GetCount() )
{
SaveCopyInUndoList( s_PickedList, UR_UNSPECIFIED );
// Clear list, but DO NOT delete items, because they are owned by the saved undo
// list and they therefore in use
s_PickedList.ClearItemsList();
}
auto displ_opts = (PCB_DISPLAY_OPTIONS*)GetDisplayOptions();
newpos = GetCrossHairPosition();
aModule->SetPosition( newpos );
aModule->ClearFlags();
delete s_ModuleInitialCopy;
s_ModuleInitialCopy = NULL;
if( aRecreateRatsnest )
m_Pcb->GetConnectivity()->Update( aModule );
if( ( GetBoard()->IsElementVisible( LAYER_RATSNEST ) || displ_opts->m_Show_Module_Ratsnest )
&& aRecreateRatsnest )
Compile_Ratsnest( nullptr, true );
SetMsgPanel( aModule );
}

View File

@ -1,304 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2009-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2015 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 magnetic_tracks_functions.cpp
*/
/* functions used to control the cursor position, when creating a track
* and when the "magnetic tracks" option is on
* (the current created track is kept near existing tracks
* the distance is the clearance between tracks)
*/
#include <fctsys.h>
#include <pcbnew.h>
#include <pcb_edit_frame.h>
#include <macros.h>
#include <class_board.h>
#include <class_track.h>
#include <pcbnew_id.h>
/**
* Function Join
* finds the point where line segment (b1,b0) intersects with segment (a1,a0).
* If that point would be outside of (a0,a1), the respective endpoint is used.
* Join returns the point in "res" and "true" if a suitable point was found,
* "false" if both lines are parallel or if the length of either segment is zero.
*/
static bool Join( wxPoint* aIntersectPoint, wxPoint a0, wxPoint a1, wxPoint b0, wxPoint b1 )
{
/* References:
http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/
http://www.gekkou.co.uk/blogs/monologues/2007/12/13/1197586800000.html
*/
double denom;
double t;
// if either segment is zero length
if( a1.x==a0.x && a1.y==a0.y )
return false;
if( b1.x==b0.x && b1.y==b0.y )
return false;
a1 -= a0;
b1 -= b0;
b0 -= a0;
denom = (double) b1.y * a1.x - (double) b1.x * a1.y;
if( !denom )
{
return false; // parallel
}
t = ((double) b1.y * b0.x - (double) b1.x * b0.y ) / denom;
t = std::min( std::max( t, 0.0 ), 1.0 );
aIntersectPoint->x = KiROUND( a0.x + t * a1.x );
aIntersectPoint->y = KiROUND( a0.y + t * a1.y );
return true;
}
/*
* "Project" finds the projection of a grid point on a track. This is the point
* from where we want to draw new orthogonal tracks when starting on a track.
*/
bool FindBestGridPointOnTrack( wxPoint* aNearPos, wxPoint on_grid, const TRACK* track )
{
if( track->GetStart ()== track->GetEnd() )
return false;
wxPoint vec = track->GetEnd() - track->GetStart();
double t = double( on_grid.x - track->GetStart().x ) * vec.x +
double( on_grid.y - track->GetStart().y ) * vec.y;
t /= (double) vec.x * vec.x + (double) vec.y * vec.y;
t = std::min( std::max( t, 0.0 ), 1.0 );
aNearPos->x = KiROUND( track->GetStart().x + t * vec.x );
aNearPos->y = KiROUND( track->GetStart().y + t * vec.y );
return true;
}
/**
* Function Magnetize
* tests to see if there are any magnetic items within near reach of the given
* "curpos". If yes, then curpos is adjusted appropriately according to that
* near magnetic item and true is returned.
* @param frame = the current frame
* @param aCurrentTool = the current tool id (from vertical right toolbar)
* @param aGridSize = the current grid size
* @param on_grid = the on grid position near initial position ( often on_grid = curpos)
* @param curpos The initial position, and what to adjust if a change is needed.
* @return bool - true if the position was adjusted magnetically, else false.
*/
bool Magnetize( PCB_BASE_EDIT_FRAME* frame, int aCurrentTool, wxSize aGridSize,
wxPoint on_grid, wxPoint* curpos )
{
// Note: only used for routing in the Legacy Toolset
// Can be greatly simplified when the Legacy Toolset is retired.
bool doCheckNet = frame->Settings().m_magneticPads != CAPTURE_ALWAYS && frame->Settings().m_legacyDrcOn;
bool doCheckLayer = aCurrentTool == ID_TRACK_BUTT;
bool doTrack = false;
bool doPad = false;
bool amMovingVia = false;
BOARD* m_Pcb = frame->GetBoard();
TRACK* currTrack = g_CurrentTrackSegment;
BOARD_ITEM* currItem = frame->GetCurItem();
PCB_SCREEN* screen = frame->GetScreen();
wxPoint pos = frame->RefPos( true );
// D( printf( "currTrack=%p currItem=%p currTrack->Type()=%d currItem->Type()=%d\n", currTrack, currItem, currTrack ? currTrack->Type() : 0, currItem ? currItem->Type() : 0 ); )
if( !currTrack && currItem && currItem->Type()==PCB_VIA_T && currItem->GetFlags() )
{
// moving a VIA
currTrack = (TRACK*) currItem;
amMovingVia = true;
return false; // comment this return out and play with it.
}
else if( currItem != currTrack )
{
currTrack = NULL;
}
if( frame->Settings().m_magneticPads == CAPTURE_ALWAYS )
doPad = true;
if( frame->Settings().m_magneticTracks == CAPTURE_ALWAYS )
doTrack = true;
if( aCurrentTool == ID_TRACK_BUTT || amMovingVia )
{
int q = CAPTURE_CURSOR_IN_TRACK_TOOL;
if( frame->Settings().m_magneticPads == q )
doPad = true;
if( frame->Settings().m_magneticTracks == q )
doTrack = true;
}
// The search precedence order is pads, then tracks/vias
if( doPad )
{
D_PAD* pad;
if( doCheckLayer )
pad = m_Pcb->GetPad( pos, LSET( screen->m_Active_Layer ) );
else
pad = m_Pcb->GetPad( pos );
if( pad )
{
if( doCheckNet && currTrack && currTrack->GetNetCode() != pad->GetNetCode() )
return false;
*curpos = pad->GetPosition();
return true;
}
}
// after pads, only track & via tests remain, skip them if not desired
if( doTrack )
{
PCB_LAYER_ID layer = screen->m_Active_Layer;
for( TRACK* via = m_Pcb->m_Track;
via && (via = via->GetVia( *curpos, layer )) != NULL;
via = via->Next() )
{
if( via != currTrack ) // a via cannot influence itself
{
if( !doCheckNet || !currTrack || currTrack->GetNetCode() == via->GetNetCode() )
{
*curpos = via->GetStart();
// D(printf("via hit\n");)
return true;
}
}
}
if( !currTrack )
{
LSET layers( layer );
TRACK* track = m_Pcb->GetVisibleTrack( m_Pcb->m_Track, pos, layers );
if( !track || track->Type() != PCB_TRACE_T )
{
return false;
}
return FindBestGridPointOnTrack( curpos, on_grid, track );
}
/*
* In two segment mode, ignore the final segment if it's inside a grid square.
*/
if( !amMovingVia && currTrack && frame->Settings().m_legacyUseTwoSegmentTracks && currTrack->Back()
&& currTrack->GetStart().x - aGridSize.x < currTrack->GetEnd().x
&& currTrack->GetStart().x + aGridSize.x > currTrack->GetEnd().x
&& currTrack->GetStart().y - aGridSize.y < currTrack->GetEnd().y
&& currTrack->GetStart().y + aGridSize.y > currTrack->GetEnd().y )
{
currTrack = currTrack->Back();
}
for( TRACK* track = m_Pcb->m_Track; track; track = track->Next() )
{
if( track->Type() != PCB_TRACE_T )
continue;
if( doCheckNet && currTrack && currTrack->GetNetCode() != track->GetNetCode() )
continue;
if( m_Pcb->IsLayerVisible( track->GetLayer() ) == false )
continue;
// omit the layer check if moving a via
if( !amMovingVia && !track->IsOnLayer( layer ) )
continue;
if( !track->HitTest( *curpos ) )
continue;
if( Join( curpos, track->GetStart(), track->GetEnd(), currTrack->GetStart(), currTrack->GetEnd() ) )
{
return true;
}
if( aCurrentTool == ID_TRACK_BUTT || amMovingVia )
{
// At this point we have a drawing mouse on a track, we are drawing
// a new track and that new track is parallel to the track the
// mouse is on. Find the nearest end point of the track under mouse
// to the mouse and return that.
double distStart = GetLineLength( *curpos, track->GetStart() );
double distEnd = GetLineLength( *curpos, track->GetEnd() );
// if track not via, or if its a via dragging but not with its adjacent track
if( currTrack->Type() != PCB_VIA_T ||
( currTrack->GetStart() != track->GetStart() && currTrack->GetStart() != track->GetEnd() ))
{
double max_dist = currTrack->GetWidth() / 2.0f;
if( distStart <= max_dist )
{
// D(printf("nearest end is start\n");)
*curpos = track->GetStart();
return true;
}
if( distEnd <= max_dist )
{
// D(printf("nearest end is end\n");)
*curpos = track->GetEnd();
return true;
}
// @todo otherwise confine curpos such that it stays centered within "track"
}
}
}
}
return false;
}

View File

@ -1,145 +0,0 @@
/**
* @file minimun_spanning_tree.cpp
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2011 Jean-Pierre Charras
* Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
*
* derived from this article:
* http://compprog.wordpress.com/2007/11/09/minimal-spanning-trees-prims-algorithm
*
* 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 <limits.h>
#include <minimun_spanning_tree.h>
#include <class_pad.h>
/*
* The class MIN_SPAN_TREE calculates the rectilinear minimum spanning tree
* of a set of points (pads usually having the same net)
* using the Prim's algorithm.
*/
/*
* Prim's Algorithm
* Step 0
* Pick any vertex as a starting vertex. (Call it S).
* Mark it with any given flag, say 1.
*
* Step 1
* Find the nearest neighbour of S (call it P1).
* Mark both P1 and the edge SP1.
* cheapest unmarked edge in the graph that doesn't close a marked circuit.
* Mark this edge.
*
* Step 2
* Find the nearest unmarked neighbour to the marked subgraph
* (i.e., the closest vertex to any marked vertex).
* Mark it and the edge connecting the vertex.
*
* Step 3
* Repeat Step 2 until all vertices are marked.
* The marked subgraph is a minimum spanning tree.
*/
MIN_SPAN_TREE::MIN_SPAN_TREE()
{
MSP_Init( 0 );
}
void MIN_SPAN_TREE::MSP_Init( int aNodesCount )
{
m_Size = std::max( aNodesCount, 1 );
inTree.clear();
linkedTo.clear();
distTo.clear();
if( m_Size == 0 )
return;
// Reserve space in memory
inTree.reserve( m_Size );
linkedTo.reserve( m_Size );
distTo.reserve( m_Size );
// Initialize values:
for( int ii = 0; ii < m_Size; ii++ )
{
// Initialise dist with infinity:
distTo.push_back( INT_MAX );
// Mark all nodes as NOT beeing in the minimum spanning tree:
inTree.push_back( 0 );
linkedTo.push_back( 0 );
}
}
/* updateDistances(int target)
* should be called immediately after target is added to the tree;
* updates dist so that the values are correct (goes through target's
* neighbours making sure that the distances between them and the tree
* are indeed minimum)
*/
void MIN_SPAN_TREE::updateDistances( int target )
{
for( int ii = 0; ii < m_Size; ++ii )
{
if( !inTree[ii] ) // no need to evaluate weight for already in tree items
{
int weight = GetWeight( target, ii );
if( (weight > 0) && (distTo[ii] > weight ) )
{
distTo[ii] = weight;
linkedTo[ii] = target;
}
}
}
}
void MIN_SPAN_TREE::BuildTree()
{
// Add the first node to the tree
inTree[0] = 1;
updateDistances( 0 );
for( int treeSize = 1; treeSize < m_Size; ++treeSize )
{
// Find the node with the smallest distance to the tree
int min = -1;
for( int ii = 0; ii < m_Size; ++ii )
{
if( !inTree[ii] )
{
if( (min == -1) || (distTo[min] > distTo[ii]) )
min = ii;
}
}
inTree[min] = 1;
updateDistances( min );
}
}

View File

@ -1,101 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2011-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2012 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 minimun_spanning_tree.h
*/
#include <vector>
/**
* @brief The class MIN_SPAN_TREE calculates the rectilinear minimum spanning tree
* of a set of points (pads usually having the same net)
* this class is an abstract class because you must provide the function
* int GetWeight( int aItem1, int aItem2 )
* that calculate the distance between 2 items
* MIN_SPAN_TREE does not know anything about the actual items to link
* by the tree
*/
class MIN_SPAN_TREE
{
protected:
int m_Size; /* The number of nodes in the graph
*/
private:
std::vector<char> inTree; /* inTree[ii] is a flag set to 1 if the node ii
* is already in the minimum spanning tree; 0 otherwise
*/
std::vector<int> linkedTo; /* linkedTo[ii] holds the index of the node ii would have to be
* linked to in order to get a distance of d[ii]
* NOTE: linkedTo[0] is the starting point of the tree
* linkedTo[1] is the first linked point to use
* ii and linkedTo[ii] are the 2 ends of an edge in the graph
*/
std::vector<int> distTo; /* distTo[ii] is the distance between node ii and the minimum spanning
* tree;
* this is initially infinity (INT_MAX);
* if ii is already in the tree, then d[ii] is undefined;
* this is just a temporary variable. It's not necessary but speeds
* up execution considerably (by a factor of n)
*/
public:
MIN_SPAN_TREE();
void MSP_Init( int aNodesCount );
void BuildTree();
int GetWhoTo( int aIdx )
{
return linkedTo[aIdx];
}
int GetDist( int aIdx )
{
return distTo[aIdx];
}
/**
* Function GetWeight
* calculates the weight between 2 items
* NOTE: The weight between a node and itself should be 0
* It is virtual pure, you must provide your GetWeight function
* @param aItem1 = first item
* @param aItem2 = other item
* @return the weight between items ( usually the distance )
*/
virtual int GetWeight( int aItem1, int aItem2 ) = 0;
private:
/**
* Function updateDistances
* should be called immediately after target is added to the tree;
* updates d so that the values are correct (goes through target's
* neighbours making sure that the distances between them and the tree
* are indeed minimum)
* @param aTarget = index of curr item
*/
void updateDistances( int aTarget );
};

View File

@ -97,11 +97,8 @@ void PCB_EDIT_FRAME::OnNetlistChanged( BOARD_NETLIST_UPDATER& aUpdater,
{
BOARD* board = GetBoard();
SetCurItem( nullptr );
SetMsgPanel( board );
TOOL_MANAGER* toolManager = GetToolManager();
// Update rendered tracks and vias net labels
auto view = GetGalCanvas()->GetView();
@ -115,7 +112,7 @@ void PCB_EDIT_FRAME::OnNetlistChanged( BOARD_NETLIST_UPDATER& aUpdater,
wxPoint areaPosition = GetCrossHairPosition();
EDA_RECT bbox = board->GetBoundingBox();
toolManager->RunAction( PCB_ACTIONS::selectionClear, true );
GetToolManager()->RunAction( PCB_ACTIONS::selectionClear, true );
SpreadFootprints( &newFootprints, false, false, areaPosition, false );
@ -123,15 +120,15 @@ void PCB_EDIT_FRAME::OnNetlistChanged( BOARD_NETLIST_UPDATER& aUpdater,
if( !newFootprints.empty() )
{
for( MODULE* footprint : newFootprints )
toolManager->RunAction( PCB_ACTIONS::selectItem, true, footprint );
GetToolManager()->RunAction( PCB_ACTIONS::selectItem, true, footprint );
*aRunDragCommand = true;
// Now fix a reference point to move the footprints.
// We use the first footprint in list as reference point
// The graphic cursor will be on this fp when moving the footprints.
SELECTION_TOOL* selTool = toolManager->GetTool<SELECTION_TOOL>();
SELECTION& selection = selTool->GetSelection();
SELECTION_TOOL* selTool = GetToolManager()->GetTool<SELECTION_TOOL>();
SELECTION& selection = selTool->GetSelection();
selection.SetReferencePoint( newFootprints[0]->GetPosition() );
}

View File

@ -74,7 +74,7 @@ public:
* @param aDC = the current device context
* @param aItem = a pointer to the BOARD_ITEM to edit
*/
virtual void OnEditItemRequest( wxDC* aDC, BOARD_ITEM* aItem ) = 0;
virtual void OnEditItemRequest( BOARD_ITEM* aItem ) = 0;
// Undo buffer handling
@ -169,7 +169,7 @@ public:
*/
void SetRotationAngle( int aRotationAngle );
void InstallTextOptionsFrame( BOARD_ITEM* aText, wxDC* aDC );
void InstallTextOptionsFrame( BOARD_ITEM* aText );
void InstallGraphicItemPropertiesDialog( BOARD_ITEM* aItem );
///> @copydoc EDA_DRAW_FRAME::UseGalCanvas()
@ -188,14 +188,6 @@ protected:
/// Is undo/redo operation currently blocked?
bool m_undoRedoBlocked;
/**
* Function createArray
* Create an array of the selected item (invokes the dialogue)
* This function is shared between pcbnew and modedit, as it is virtually
* the same
*/
void createArray();
void unitsChangeRefresh() override;
};

View File

@ -4,7 +4,7 @@
* Copyright (C) 2018 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-2018 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2019 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
@ -24,10 +24,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file basepcbframe.cpp
*/
#include <fctsys.h>
#include <kiface_i.h>
#include <eda_base_frame.h>
@ -39,7 +35,7 @@
#include <base_units.h>
#include <msgpanel.h>
#include <pgm_base.h>
#include <3d_viewer/eda_3d_viewer.h> // To include VIEWER3D_FRAMENAME
#include <3d_viewer/eda_3d_viewer.h> // To include VIEWER3D_FRAMENAME
#include <pcbnew.h>
#include <fp_lib_table.h>
@ -101,7 +97,6 @@ PCB_BASE_FRAME::PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrame
m_configSettings( aFrameType )
{
m_UserGridSize = wxPoint( (int) 10 * IU_PER_MILS, (int) 10 * IU_PER_MILS );
m_Collector = new GENERAL_COLLECTOR();
m_FastGrid1 = 0;
m_FastGrid2 = 0;
@ -121,7 +116,6 @@ PCB_BASE_FRAME::~PCB_BASE_FRAME()
else
m_canvasType = GetGalCanvas()->GetBackend();
delete m_Collector;
delete m_Pcb;
}
@ -192,8 +186,7 @@ FP_LIB_TABLE* PROJECT::PcbFootprintLibs()
}
catch( const IO_ERROR& ioe )
{
DisplayErrorMessage( nullptr,
_( "Error loading project footprint libraries" ),
DisplayErrorMessage( nullptr, _( "Error loading project footprint libraries" ),
ioe.What() );
}
}
@ -454,8 +447,8 @@ bool PCB_BASE_FRAME::CreateAndShow3D_Frame( bool aForceRecreateIfNotOwner )
return true;
}
// Raising the window does not show the window on Windows if iconized.
// This should work on any platform.
// Raising the window does not show the window on Windows if iconized. This should work
// on any platform.
if( draw3DFrame->IsIconized() )
draw3DFrame->Iconize( false );
@ -479,38 +472,30 @@ void PCB_BASE_FRAME::SwitchLayer( wxDC* DC, PCB_LAYER_ID layer )
if( layer == preslayer )
return;
// Copper layers cannot be selected unconditionally; how many
// of those layers are currently enabled needs to be checked.
// Copper layers cannot be selected unconditionally; how many of those layers are
// currently enabled needs to be checked.
if( IsCopperLayer( layer ) )
{
// If only one copper layer is enabled, the only such layer
// that can be selected to is the "Copper" layer (so the
// selection of any other copper layer is disregarded).
// If only one copper layer is enabled, the only such layer that can be selected to
// is the "Copper" layer (so the selection of any other copper layer is disregarded).
if( m_Pcb->GetCopperLayerCount() < 2 )
{
if( layer != B_Cu )
{
return;
}
}
// If more than one copper layer is enabled, the "Copper"
// and "Component" layers can be selected, but the total
// number of copper layers determines which internal
// If more than one copper layer is enabled, the "Copper" and "Component" layers
// can be selected, but the total number of copper layers determines which internal
// layers are also capable of being selected.
else
{
if( ( layer != B_Cu ) && ( layer != F_Cu )
&& ( layer >= m_Pcb->GetCopperLayerCount() - 1 ) )
{
if( layer != B_Cu && layer != F_Cu && layer >= ( m_Pcb->GetCopperLayerCount() - 1 ) )
return;
}
}
}
// Is yet more checking required? E.g. when the layer to be selected
// is a non-copper layer, or when switching between a copper layer
// and a non-copper layer, or vice-versa?
// Is yet more checking required? E.g. when the layer to be selected is a non-copper
// layer, or when switching between a copper layer and a non-copper layer, or vice-versa?
// ...
GetScreen()->m_Active_Layer = layer;
@ -618,52 +603,16 @@ void PCB_BASE_FRAME::ProcessItemSelection( wxCommandEvent& aEvent )
{
int id = aEvent.GetId();
// index into the collector list:
int itemNdx = id - ID_POPUP_PCB_ITEM_SELECTION_START;
if( id >= ID_POPUP_PCB_ITEM_SELECTION_START && id <= ID_POPUP_PCB_ITEM_SELECTION_END )
{
BOARD_ITEM* item = (*m_Collector)[itemNdx];
int itemNdx = id - ID_POPUP_PCB_ITEM_SELECTION_START;
// JEY TODO: is this still called? Or do we do this in the selection tool?
m_canvas->SetAbortRequest( false );
#if 0 && defined (DEBUG)
item->Show( 0, std::cout );
#endif
SetCurItem( item );
}
}
void PCB_BASE_FRAME::SetCurItem( BOARD_ITEM* aItem, bool aDisplayInfo )
{
GetScreen()->SetCurItem( aItem );
if( aDisplayInfo )
UpdateMsgPanel();
}
void PCB_BASE_FRAME::UpdateMsgPanel()
{
BOARD_ITEM* item = GetScreen()->GetCurItem();
MSG_PANEL_ITEMS items;
if( item )
item->GetMsgPanelInfo( m_UserUnits, items );
else // show general information about the board
GetGalCanvas()->GetMsgPanelInfo( m_UserUnits, items );
SetMsgPanel( items );
}
BOARD_ITEM* PCB_BASE_FRAME::GetCurItem()
{
return GetScreen()->GetCurItem();
}
GENERAL_COLLECTORS_GUIDE PCB_BASE_FRAME::GetCollectorsGuide()
{
GENERAL_COLLECTORS_GUIDE guide( m_Pcb->GetVisibleLayers(), GetActiveLayer(),
@ -833,10 +782,10 @@ void PCB_BASE_FRAME::LoadSettings( wxConfigBase* aCfg )
double tmp;
aCfg->Read( baseCfgName + UserGridSizeXEntry, &tmp, 0.01 );
m_UserGridSize.x = From_User_Unit( userGridUnits, tmp );
m_UserGridSize.x = (int) From_User_Unit( userGridUnits, tmp );
aCfg->Read( baseCfgName + UserGridSizeYEntry, &tmp, 0.01 );
m_UserGridSize.y = From_User_Unit( userGridUnits, tmp );
m_UserGridSize.y = (int) From_User_Unit( userGridUnits, tmp );
aCfg->Read( baseCfgName + DisplayPadFillEntry, &m_DisplayOptions.m_DisplayPadFill, true );
aCfg->Read( baseCfgName + DisplayViaFillEntry, &m_DisplayOptions.m_DisplayViaFill, true );
@ -987,8 +936,10 @@ void PCB_BASE_FRAME::UseGalCanvas()
EDA_DRAW_PANEL_GAL* galCanvas = GetGalCanvas();
if( m_toolManager )
{
m_toolManager->SetEnvironment( m_Pcb, GetGalCanvas()->GetView(),
GetGalCanvas()->GetViewControls(), this );
}
SetBoard( m_Pcb );

View File

@ -1240,7 +1240,7 @@ void PCB_EDIT_FRAME::PythonPluginsReload()
}
void PCB_EDIT_FRAME::InstallFootprintPropertiesDialog( MODULE* Module, wxDC* DC )
void PCB_EDIT_FRAME::InstallFootprintPropertiesDialog( MODULE* Module )
{
if( Module == NULL )
return;
@ -1268,7 +1268,6 @@ void PCB_EDIT_FRAME::InstallFootprintPropertiesDialog( MODULE* Module, wxDC* DC
FOOTPRINT_EDIT_FRAME* editor = (FOOTPRINT_EDIT_FRAME*) Kiway().Player( FRAME_PCB_MODULE_EDITOR, true );
editor->Load_Module_From_BOARD( Module );
SetCurItem( NULL );
editor->Show( true );
editor->Raise(); // Iconize( false );
@ -1279,7 +1278,6 @@ void PCB_EDIT_FRAME::InstallFootprintPropertiesDialog( MODULE* Module, wxDC* DC
FOOTPRINT_EDIT_FRAME* editor = (FOOTPRINT_EDIT_FRAME*) Kiway().Player( FRAME_PCB_MODULE_EDITOR, true );
editor->LoadModuleFromLibrary( Module->GetFPID() );
SetCurItem( NULL );
editor->Show( true );
editor->Raise(); // Iconize( false );

View File

@ -909,7 +909,7 @@ public:
void Start_Move_DrawItem( DRAWSEGMENT* drawitem, wxDC* DC );
// Footprint editing (see also PCB_BASE_FRAME)
void InstallFootprintPropertiesDialog( MODULE* Module, wxDC* DC );
void InstallFootprintPropertiesDialog( MODULE* Module );
int InstallExchangeModuleFrame( MODULE* aModule, bool updateMode, bool selectedMode );
@ -934,13 +934,7 @@ public:
* @param aDC = the current device context
* @param aItem = a pointer to the BOARD_ITEM to edit
*/
void OnEditItemRequest( wxDC* aDC, BOARD_ITEM* aItem ) override;
/**
* Function HighLight.
* highlights the net at the current cursor position.
*/
void HighLight( wxDC* DC );
void OnEditItemRequest( BOARD_ITEM* aItem ) override;
/**
* Function IsMicroViaAcceptable
@ -954,105 +948,15 @@ public:
*/
bool IsMicroViaAcceptable();
/**
* Function Other_Layer_Route
* operates in one of two ways. If argument track is NULL, then swap the
* active layer between m_Route_Layer_TOP and m_Route_Layer_BOTTOM. If a
* track is in progress (track is not NULL), and if DRC allows it, place
* a via on the end of the current track, and then swap the current active
* layer and start a new segment on the new layer.
* @param track A TRACK* to append the via to or NULL.
* @param DC A device context to draw on.
* @return bool - true if the operation was successful, else false such as
* the case where DRC would not allow a via.
*/
bool Other_Layer_Route( TRACK* track, wxDC* DC );
/**
* Function Delete_Segment
* removes a track segment.
* If a new track is in progress: delete the current new segment.
* Otherwise, delete segment under the mouse cursor.
*/
TRACK* Delete_Segment( wxDC* DC, TRACK* Track );
void Delete_Track( wxDC* DC, TRACK* Track );
void Delete_net( wxDC* DC, TRACK* Track );
/**
* Function Remove_One_Track
* removes 1 track/
* The leading segment is removed and all adjacent segments
* until a pad or a junction point of more than 2 segments is found
*/
void Remove_One_Track( wxDC* DC, TRACK* pt_segm );
/**
* Function Edit_Track_Width
* Modify a full track width (using DRC control).
* a full track is the set of track segments between 2 ends: pads or a
* point that has more than 2 segments ends connected
* @param aDC = the curred device context (can be NULL)
* @param aTrackSegment = a segment or via on the track to change
*/
void Edit_Track_Width( wxDC* aDC, TRACK* aTrackSegment );
/**
* Function Edit_TrackSegm_Width
* Modify one track segment width or one via diameter (using DRC control).
* @param aDC = the current device context (can be NULL)
* @param aTrackItem = the track segment or via to modify
*/
void Edit_TrackSegm_Width( wxDC* aDC, TRACK* aTrackItem );
/**
* Function Begin_Route
* Starts a new track and/or establish of a new track point.
*
* For a new track:
* - Search the netname of the new track from the starting point
* if it is on a pad or an existing track
* - Highlight all this net
* If a track is in progress:
* - Call DRC
* - If DRC is OK: finish the track segment and starts a new one.
* @param aTrack = the current track segment, or NULL to start a new track
* @param aDC = the current device context
* @return a pointer to the new track segment or null if not created (DRC error)
*/
TRACK* Begin_Route( TRACK* aTrack, wxDC* aDC );
void Edit_TrackSegm_Width( TRACK* aTrackItem );
void SwitchLayer( wxDC* DC, PCB_LAYER_ID layer ) override;
/**
* Function Add45DegreeSegment
* adds a track segment between 2 tracks segments if these 2 segments
* make a 90 deg angle, in order to have 45 deg track segments
* Its only works on horizontal or vertical segments.
*
* @param aDC The wxDC device context to draw on.
* @return A bool value true if ok or false if not.
*/
bool Add45DegreeSegment( wxDC* aDC );
/**
* Function EraseRedundantTrack
* Called after creating a track
* Remove (if exists) the old track that have the same starting and the
* same ending point as the new created track
* (this is the redunding track)
* @param aDC = the current device context (can be NULL)
* @param aNewTrack = the new created track (a pointer to a segment of the
* track list)
* @param aNewTrackSegmentsCount = number of segments in this new track
* @param aItemsListPicker = the list picker to use for an undo command
* (can be NULL)
*/
int EraseRedundantTrack( wxDC* aDC,
TRACK* aNewTrack,
int aNewTrackSegmentsCount,
PICKED_ITEMS_LIST* aItemsListPicker );
/**
* Function SetTrackSegmentWidth
* Modify one track segment width or one via diameter (using DRC control).
@ -1102,7 +1006,7 @@ public:
* Function Edit_Zone_Params
* Edit params (layer, clearance, ...) for a zone outline
*/
void Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* zone_container );
void Edit_Zone_Params( ZONE_CONTAINER* zone_container );
/**
* Function Delete_Zone
@ -1118,22 +1022,16 @@ public:
void Delete_Zone_Contour( wxDC* DC, ZONE_CONTAINER* zone_container );
// Target handling
PCB_TARGET* CreateTarget( wxDC* DC );
void DeleteTarget( PCB_TARGET* aTarget, wxDC* DC );
void PlaceTarget( PCB_TARGET* aTarget, wxDC* DC );
void ShowTargetOptionsDialog( PCB_TARGET* aTarget, wxDC* DC );
void ShowTargetOptionsDialog( PCB_TARGET* aTarget );
// Dimension handling:
void ShowDimensionPropertyDialog( DIMENSION* aDimension, wxDC* aDC );
DIMENSION* EditDimension( DIMENSION* aDimension, wxDC* aDC );
void DeleteDimension( DIMENSION* aDimension, wxDC* aDC );
void BeginMoveDimensionText( DIMENSION* aItem, wxDC* DC );
void PlaceDimensionText( DIMENSION* aItem, wxDC* DC );
void ShowDimensionPropertyDialog( DIMENSION* aDimension );
// netlist handling:
void InstallNetlistFrame( wxDC* DC );
void InstallNetlistFrame();
/**
* Function FetchNetlistFromSchematic
@ -1227,15 +1125,6 @@ public:
bool aPrepareUndoCommand = true );
/**
* Function Show_1_Ratsnest
* draw ratsnest.
*
* The net edge pad with mouse or module locates the mouse.
* Delete the ratsnest if no module or pad is selected.
*/
void Show_1_Ratsnest( EDA_ITEM* item, wxDC* DC );
/**
* Function Clean_Pcb
* Clean up the board (remove redundant vias, not connected tracks

View File

@ -1,233 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2015 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 <fctsys.h>
#include <gr_basic.h>
#include <class_drawpanel.h>
#include <confirm.h>
#include <pcb_edit_frame.h>
#include <trigo.h>
#include <macros.h>
#include <class_board.h>
#include <class_module.h>
#include <pcbnew.h>
#include <drag.h>
#include <dialog_get_footprint_by_name.h>
#include <connectivity/connectivity_data.h>
static MODULE* s_ModuleInitialCopy = NULL; // Copy of module for abort/undo command
static PICKED_ITEMS_LIST s_PickedList; // a pick-list to save initial module
// and dragged tracks
MODULE* PCB_BASE_FRAME::GetFootprintFromBoardByReference()
{
wxString moduleName;
MODULE* module = NULL;
wxArrayString fplist;
// Build list of available fp references, to display them in dialog
for( MODULE* fp = GetBoard()->m_Modules; fp; fp = fp->Next() )
fplist.Add( fp->GetReference() + wxT(" ( ") + fp->GetValue() + wxT(" )") );
fplist.Sort();
DIALOG_GET_FOOTPRINT_BY_NAME dlg( this, fplist );
if( dlg.ShowModal() != wxID_OK ) //Aborted by user
return NULL;
moduleName = dlg.GetValue();
moduleName.Trim( true );
moduleName.Trim( false );
if( !moduleName.IsEmpty() )
{
module = GetBoard()->m_Modules;
while( module )
{
if( module->GetReference().CmpNoCase( moduleName ) == 0 )
break;
module = module->Next();
}
}
return module;
}
void PCB_BASE_FRAME::PlaceModule( MODULE* aModule, wxDC* aDC, bool aRecreateRatsnest )
{
wxPoint newpos;
if( aModule == 0 )
return;
OnModify();
if( aModule->IsNew() )
{
SaveCopyInUndoList( aModule, UR_NEW );
}
else if( aModule->IsMoving() )
{
ITEM_PICKER picker( aModule, UR_CHANGED );
picker.SetLink( s_ModuleInitialCopy );
s_PickedList.PushItem( picker );
s_ModuleInitialCopy = NULL; // the picker is now owner of s_ModuleInitialCopy.
}
if( s_PickedList.GetCount() )
{
SaveCopyInUndoList( s_PickedList, UR_UNSPECIFIED );
// Clear list, but DO NOT delete items, because they are owned by the saved undo
// list and they therefore in use
s_PickedList.ClearItemsList();
}
auto displ_opts = (PCB_DISPLAY_OPTIONS*)GetDisplayOptions();
if( displ_opts->m_Show_Module_Ratsnest && aDC )
TraceModuleRatsNest( aDC );
newpos = GetCrossHairPosition();
aModule->SetPosition( newpos );
aModule->ClearFlags();
delete s_ModuleInitialCopy;
s_ModuleInitialCopy = NULL;
if( aDC )
aModule->Draw( m_canvas, aDC, GR_OR );
// Redraw dragged track segments, if any
bool isDragged = g_DragSegmentList.size() > 0;
for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
{
TRACK * track = g_DragSegmentList[ii].m_Track;
track->SetState( IN_EDIT, false );
track->ClearFlags();
if( aDC )
track->Draw( m_canvas, aDC, GR_OR );
}
// Delete drag list
EraseDragList();
m_canvas->SetMouseCapture( NULL, NULL );
if( aRecreateRatsnest )
{
if( isDragged ) // Some tracks have positions modified: rebuild the connectivity
m_Pcb->GetConnectivity()->Build(m_Pcb);
else // Only pad positions are modified: rebuild the connectivity only for this footprint (faster)
m_Pcb->GetConnectivity()->Update( aModule );
}
if( ( GetBoard()->IsElementVisible( LAYER_RATSNEST ) || displ_opts->m_Show_Module_Ratsnest )
&& aRecreateRatsnest )
Compile_Ratsnest( aDC, true );
if( aDC )
m_canvas->Refresh();
SetMsgPanel( aModule );
}
/*
* Rotate the footprint angle degrees in the direction < 0.
* If incremental == true, the rotation is made from the last orientation,
* If the module is placed in the absolute orientation angle.
* If DC == NULL, the component does not redraw.
* Otherwise, it erases and redraws turns
*/
void PCB_BASE_FRAME::Rotate_Module( wxDC* DC, MODULE* module, double angle, bool incremental )
{
if( module == NULL )
return;
OnModify();
if( !module->IsMoving() ) // This is a simple rotation, no other edit in progress
{
if( DC ) // Erase footprint to screen
{
module->SetFlags( DO_NOT_DRAW );
m_canvas->RefreshDrawingRect( module->GetBoundingBox() );
module->ClearFlags( DO_NOT_DRAW );
if( GetBoard()->IsElementVisible( LAYER_RATSNEST ) )
DrawGeneralRatsnest( DC );
}
}
else
{
if( DC )
{
module->DrawOutlinesWhenMoving( m_canvas, DC, g_Offset_Module );
DrawSegmentWhileMovingFootprint( m_canvas, DC );
}
}
if( incremental )
module->SetOrientation( module->GetOrientation() + angle );
else
module->SetOrientation( angle );
SetMsgPanel( module );
m_Pcb->GetConnectivity()->Update( module );
if( DC )
{
if( !module->IsMoving() )
{
// not beiing moved: redraw the module and update ratsnest
module->Draw( m_canvas, DC, GR_OR );
if( GetBoard()->IsElementVisible( LAYER_RATSNEST ) )
Compile_Ratsnest( DC, true );
}
else
{
// Beiing moved: just redraw it
module->DrawOutlinesWhenMoving( m_canvas, DC, g_Offset_Module );
DrawSegmentWhileMovingFootprint( m_canvas, DC );
}
if( module->GetEditFlags() == 0 ) // module not in edit: redraw full screen
m_canvas->Refresh();
}
}

View File

@ -4,7 +4,7 @@
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2019 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
@ -24,11 +24,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file pcb_legacy_draw_utils.cpp
* @brief functions (and helper functions) to redraw the current board in legacy canvas.
*/
#include <fctsys.h>
#include <class_drawpanel.h>
#include <pcb_edit_frame.h>
@ -223,9 +218,6 @@ void BOARD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* DC, GR_DRAWMODE aDrawMode, const
Trace_Pads_Only( aPanel, DC, module, 0, 0, layerMask, aDrawMode );
}
if( IsHighLightNetON() )
DrawHighLight( aPanel, DC, GetHighLightNetCode() );
// draw the BOARD's markers last, otherwise the high light will erase any marker on a pad
for( unsigned i = 0; i < m_markers.size(); ++i )
{
@ -234,49 +226,6 @@ void BOARD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* DC, GR_DRAWMODE aDrawMode, const
}
void BOARD::DrawHighLight( EDA_DRAW_PANEL* am_canvas, wxDC* DC, int aNetCode )
{
GR_DRAWMODE draw_mode;
if( IsHighLightNetON() )
draw_mode = GR_HIGHLIGHT | GR_OR;
else
draw_mode = GR_AND | GR_HIGHLIGHT;
// Redraw zones
for( int ii = 0; ii < GetAreaCount(); ii++ )
{
ZONE_CONTAINER* zone = GetArea( ii );
if( zone->GetNetCode() == aNetCode )
{
zone->Draw( am_canvas, DC, draw_mode );
}
}
// Redraw any pads that have aNetCode
for( MODULE* module = m_Modules; module; module = module->Next() )
{
for( D_PAD* pad = module->PadsList(); pad; pad = pad->Next() )
{
if( pad->GetNetCode() == aNetCode )
{
pad->Draw( am_canvas, DC, draw_mode );
}
}
}
// Redraw track and vias that have aNetCode
for( TRACK* seg = m_Track; seg; seg = seg->Next() )
{
if( seg->GetNetCode() == aNetCode )
{
seg->Draw( am_canvas, DC, draw_mode );
}
}
}
/* Trace the pads of a module in sketch mode.
* Used to display pads when when the module visibility is set to not visible
* and we want to see pad through.

View File

@ -1,82 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2007 Jean-Pierre Charras, jp.charras@wanadoo.fr
* Copyright (C) 1992-2012 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 pcbnew/protos.h
*/
#ifndef PROTO_H
#define PROTO_H
#include <gr_basic.h>
class wxDC;
class wxPoint;
class EDA_DRAW_PANEL;
class BOARD_ITEM;
class TRACK;
class MODULE;
/***************/
/* TRPISTE.CPP */
/***************/
/**
* Function DrawTraces
* Draws n consecutive track segments in list.
* Useful to show a track when it is a chain of segments
* (for instance when creating a new track)
*
* @param panel A EDA_DRAW_ITEM pointer to the canvas.
* @param DC A wxDC pointer of the device context used for drawing.
* @param aStartTrace First segment
* @param nbsegment Number of segments in list
* @param mode_color Drawing mode (GRXOR, GROR ..)
*/
void DrawTraces( EDA_DRAW_PANEL* panel,
wxDC* DC,
TRACK* aStartTrace,
int nbsegment,
GR_DRAWMODE mode_color );
void ShowNewTrackWhenMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
bool aErase );
/**
* Determine end point for a segment direction 0, 90, or 45 degrees
* depending on it's position from the origin \a aOrigin and \a aPosition.
*/
wxPoint CalculateSegmentEndPoint( const wxPoint& aPosition, const wxPoint& aOrigin );
/**
* Finds the projection of a grid point on a track. This is the point
* from where we want to draw new orthogonal tracks when starting on a track.
*/
bool FindBestGridPointOnTrack( wxPoint* res, wxPoint on_grid, const TRACK* track );
TRACK* LocateIntrusion( TRACK* listStart, TRACK* aTrack, LAYER_NUM aLayer, const wxPoint& aRef );
#endif /* #define PROTO_H */

View File

@ -52,6 +52,7 @@
*/
void PCB_BASE_FRAME::Compile_Ratsnest( wxDC* aDC, bool aDisplayStatus )
{
// JEY TODO: does this ever get called with a real DC?
GetBoard()->GetConnectivity()->RecalculateRatsnest();
GetBoard()->m_Status_Pcb = 0; // we want a full ratsnest computation, from the scratch
@ -87,6 +88,7 @@ void PCB_BASE_FRAME::Compile_Ratsnest( wxDC* aDC, bool aDisplayStatus )
*/
void PCB_BASE_FRAME::DrawGeneralRatsnest( wxDC* aDC, int aNetcode )
{
// JEY TODO: probalby obsolete (we don't really have DCs anymore)
if( ( m_Pcb->m_Status_Pcb & DO_NOT_SHOW_GENERAL_RASTNEST ) )
{
return;
@ -148,146 +150,3 @@ void PCB_BASE_FRAME::DrawGeneralRatsnest( wxDC* aDC, int aNetcode )
}
}
void PCB_BASE_FRAME::TraceModuleRatsNest( wxDC* DC )
{
if( DC == NULL )
return;
COLOR4D tmpcolor = Settings().Colors().GetItemColor( LAYER_RATSNEST );
for( const auto& l : GetBoard()->GetConnectivity()->GetDynamicRatsnest() )
{
GRLine( m_canvas->GetClipBox(), DC, wxPoint( l.a.x, l.a.y ), wxPoint( l.b.x,
l.b.y ), 0, tmpcolor );
}
}
/*
* PCB_BASE_FRAME::BuildAirWiresTargetsList and
* PCB_BASE_FRAME::TraceAirWiresToTargets
* are 2 function to show the near connecting points when
* a new track is created, by displaying g_MaxLinksShowed airwires
* between the on grid mouse cursor and these connecting points
* during the creation of a track
*/
/* Buffer to store pads coordinates when creating a track.
* these pads are members of the net
* and when the mouse is moved, the g_MaxLinksShowed links to neighbors are
* drawn
*/
static wxPoint s_CursorPos; // Coordinate of the moving point (mouse cursor and
// end of current track segment)
/* Function BuildAirWiresTargetsList
* Build a list of candidates that can be a coonection point
* when a track is started.
* This functions prepares data to show airwires to nearest connecting points (pads)
* from the current new track to candidates during track creation
*/
static BOARD_CONNECTED_ITEM* s_ref = nullptr;
static int s_refNet = -1;
void PCB_BASE_FRAME::BuildAirWiresTargetsList( BOARD_CONNECTED_ITEM* aItemRef,
const wxPoint& aPosition, int aNet )
{
s_CursorPos = aPosition; // needed for sort_by_distance
s_ref = aItemRef;
s_refNet = aNet;
}
static MODULE movedModule( nullptr );
void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule, wxPoint aMoveVector )
{
auto connectivity = GetBoard()->GetConnectivity();
movedModule = *aModule;
movedModule.Move( -aMoveVector );
connectivity->ClearDynamicRatsnest();
connectivity->BlockRatsnestItems( { aModule } );
connectivity->ComputeDynamicRatsnest( { &movedModule } );
}
void PCB_BASE_FRAME::TraceAirWiresToTargets( wxDC* aDC )
{
auto connectivity = GetBoard()->GetConnectivity();
auto displ_opts = (PCB_DISPLAY_OPTIONS*) GetDisplayOptions();
auto targets = connectivity->NearestUnconnectedTargets( s_ref, s_CursorPos, s_refNet );
if( aDC == NULL )
return;
GRSetDrawMode( aDC, GR_XOR );
for( int i = 0; i < std::min( (int) displ_opts->m_MaxLinksShowed, (int) targets.size() ); i++ )
{
auto p = targets[i];
GRLine( m_canvas->GetClipBox(), aDC, s_CursorPos, wxPoint( p.x, p.y ), 0, YELLOW );
}
}
// Redraw in XOR mode the outlines of the module.
void MODULE::DrawOutlinesWhenMoving( EDA_DRAW_PANEL* panel, wxDC* DC,
const wxPoint& aMoveVector )
{
int pad_fill_tmp;
D_PAD* pt_pad;
DrawEdgesOnly( panel, DC, aMoveVector, GR_XOR );
auto displ_opts = (PCB_DISPLAY_OPTIONS*) ( panel->GetDisplayOptions() );
// Show pads in sketch mode to speedu up drawings
pad_fill_tmp = displ_opts->m_DisplayPadFill;
displ_opts->m_DisplayPadFill = true;
pt_pad = PadsList();
for( ; pt_pad != NULL; pt_pad = pt_pad->Next() )
pt_pad->Draw( panel, DC, GR_XOR, aMoveVector );
displ_opts->m_DisplayPadFill = pad_fill_tmp;
if( displ_opts->m_Show_Module_Ratsnest )
{
PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) panel->GetParent();
frame->build_ratsnest_module( this, aMoveVector );
frame->TraceModuleRatsNest( DC );
}
}
void PCB_EDIT_FRAME::Show_1_Ratsnest( EDA_ITEM* item, wxDC* DC )
{
if( item && item->Type() == PCB_MODULE_T )
{
auto mod = static_cast<MODULE*> (item);
for( auto pad : mod->Pads() )
{
pad->SetLocalRatsnestVisible( !pad->GetLocalRatsnestVisible() );
}
}
else
{
auto modules = GetBoard()->Modules();
for( auto mod : modules )
{
for( auto pad : mod->Pads() )
{
pad->SetLocalRatsnestVisible( false );
}
}
}
m_canvas->Refresh();
}

View File

@ -95,9 +95,6 @@ void PCB_EDIT_FRAME::ImportSpecctraSession( wxCommandEvent& event )
bool PCB_EDIT_FRAME::ImportSpecctraSession( const wxString& fullFileName )
{
SetCurItem( NULL );
// To avoid issues with undo/redo lists (dangling pointers)
// clear the lists
// todo: use undo/redo feature

View File

@ -1,271 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2013 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
*/
/**
* @file target_edit.cpp
* @brief Functions to edit targets (class #PCB_TARGET).
*/
#include <fctsys.h>
#include <class_drawpanel.h>
#include <pcb_edit_frame.h>
#include <dialog_helpers.h>
#include <base_units.h>
#include <gr_basic.h>
#include <board_commit.h>
#include <class_board.h>
#include <class_pcb_target.h>
#include <pcbnew.h>
#include <dialog_target_properties_base.h>
#include <widgets/unit_binder.h>
// Routines Locales
static void AbortMoveAndEditTarget( EDA_DRAW_PANEL* Panel, wxDC* DC );
static void ShowTargetShapeWhileMovingMouse( EDA_DRAW_PANEL* aPanel,
wxDC* aDC,
const wxPoint& aPosition,
bool aErase );
// Local variables :
static int MireDefaultSize = Millimeter2iu( 5 );
static PCB_TARGET s_TargetCopy( NULL ); // Used to store "old" values of the current item
// parameters before editing for undo/redo/cancel
/**********************************/
/* class DIALOG_TARGET_PROPERTIES */
/**********************************/
class DIALOG_TARGET_PROPERTIES : public DIALOG_TARGET_PROPERTIES_BASE
{
private:
PCB_EDIT_FRAME* m_Parent;
wxDC* m_DC;
PCB_TARGET* m_Target;
UNIT_BINDER m_Size;
UNIT_BINDER m_Thickness;
public:
DIALOG_TARGET_PROPERTIES( PCB_EDIT_FRAME* aParent, PCB_TARGET* aTarget, wxDC* aDC );
~DIALOG_TARGET_PROPERTIES() { }
private:
bool TransferDataToWindow() override;
bool TransferDataFromWindow() override;
};
void PCB_EDIT_FRAME::ShowTargetOptionsDialog( PCB_TARGET* aTarget, wxDC* DC )
{
DIALOG_TARGET_PROPERTIES dialog( this, aTarget, DC );
dialog.ShowModal();
}
DIALOG_TARGET_PROPERTIES::DIALOG_TARGET_PROPERTIES( PCB_EDIT_FRAME* aParent, PCB_TARGET* aTarget,
wxDC* aDC ) :
DIALOG_TARGET_PROPERTIES_BASE( aParent ),
m_Parent( aParent ),
m_DC( aDC ),
m_Target( aTarget ),
m_Size( aParent, m_sizeLabel, m_sizeCtrl, m_sizeUnits, true ),
m_Thickness( aParent, m_thicknessLabel, m_thicknessCtrl, m_thicknessUnits, true )
{
m_sdbSizerButtsOK->SetDefault();
SetInitialFocus( m_sizeCtrl );
// Now all widgets have the size fixed, call FinishDialogSettings
FinishDialogSettings();
}
bool DIALOG_TARGET_PROPERTIES::TransferDataToWindow()
{
m_Size.SetValue( m_Target->GetSize() );
m_Thickness.SetValue( m_Target->GetWidth() );
m_TargetShape->SetSelection( m_Target->GetShape() ? 1 : 0 );
return true;
}
bool DIALOG_TARGET_PROPERTIES::TransferDataFromWindow()
{
// Zero-size targets are hard to see/select.
if( !m_Size.Validate( Mils2iu( 1 ), INT_MAX ) )
return false;
BOARD_COMMIT commit( m_Parent );
commit.Modify( m_Target );
if( m_DC )
m_Target->Draw( m_Parent->GetCanvas(), m_DC, GR_XOR );
// Save old item in undo list, if is is not currently edited (will be later if so)
bool pushCommit = ( m_Target->GetEditFlags() == 0 );
if( m_Target->GetEditFlags() != 0 ) // other edit in progress (MOVE, NEW ..)
m_Target->SetFlags( IN_EDIT ); // set flag in edit to force
// undo/redo/abort proper operation
m_Target->SetWidth( m_Thickness.GetValue() );
m_Target->SetSize( m_Size.GetValue() );
m_Target->SetShape( m_TargetShape->GetSelection() ? 1 : 0 );
if( m_DC )
m_Target->Draw( m_Parent->GetCanvas(), m_DC, ( m_Target->IsMoving() ) ? GR_XOR : GR_OR );
if( pushCommit )
commit.Push( _( "Modified alignment target" ) );
return true;
}
void PCB_EDIT_FRAME::DeleteTarget( PCB_TARGET* aTarget, wxDC* DC )
{
if( aTarget == NULL )
return;
aTarget->Draw( m_canvas, DC, GR_XOR );
SaveCopyInUndoList( aTarget, UR_DELETED );
aTarget->UnLink();
}
static void AbortMoveAndEditTarget( EDA_DRAW_PANEL* Panel, wxDC* DC )
{
BASE_SCREEN* screen = Panel->GetScreen();
PCB_TARGET* target = (PCB_TARGET*) screen->GetCurItem();
( (PCB_EDIT_FRAME*) Panel->GetParent() )->SetCurItem( NULL );
Panel->SetMouseCapture( NULL, NULL );
if( target == NULL )
return;
target->Draw( Panel, DC, GR_XOR );
if( target->IsNew() ) // If it is new, delete it
{
target->Draw( Panel, DC, GR_XOR );
target->DeleteStructure();
target = NULL;
}
else // it is an existing item: retrieve initial values of parameters
{
if( ( target->GetEditFlags() & (IN_EDIT | IS_MOVED) ) )
{
target->SetPosition( s_TargetCopy.GetPosition() );
target->SetWidth( s_TargetCopy.GetWidth() );
target->SetSize( s_TargetCopy.GetSize() );
target->SetShape( s_TargetCopy.GetShape() );
}
target->ClearFlags();
target->Draw( Panel, DC, GR_OR );
}
}
PCB_TARGET* PCB_EDIT_FRAME::CreateTarget( wxDC* DC )
{
PCB_TARGET* target = new PCB_TARGET( GetBoard() );
target->SetFlags( IS_NEW );
GetBoard()->Add( target );
target->SetLayer( Edge_Cuts );
target->SetWidth( GetDesignSettings().GetLineThickness( Edge_Cuts ) );
target->SetSize( MireDefaultSize );
target->SetPosition( GetCrossHairPosition() );
PlaceTarget( target, DC );
return target;
}
void PCB_EDIT_FRAME::PlaceTarget( PCB_TARGET* aTarget, wxDC* DC )
{
if( aTarget == NULL )
return;
aTarget->Draw( m_canvas, DC, GR_OR );
m_canvas->SetMouseCapture( NULL, NULL );
SetCurItem( NULL );
OnModify();
if( aTarget->IsNew() )
{
SaveCopyInUndoList( aTarget, UR_NEW );
aTarget->ClearFlags();
return;
}
if( aTarget->GetEditFlags() == IS_MOVED )
{
SaveCopyInUndoList( aTarget, UR_MOVED,
aTarget->GetPosition() - s_TargetCopy.GetPosition() );
aTarget->ClearFlags();
return;
}
if( (aTarget->GetEditFlags() & IN_EDIT) )
{
aTarget->SwapData( &s_TargetCopy );
SaveCopyInUndoList( aTarget, UR_CHANGED );
aTarget->SwapData( &s_TargetCopy );
}
aTarget->ClearFlags();
}
// Redraw the contour of the track while moving the mouse
static void ShowTargetShapeWhileMovingMouse( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
const wxPoint& aPosition, bool aErase )
{
BASE_SCREEN* screen = aPanel->GetScreen();
PCB_TARGET* target = (PCB_TARGET*) screen->GetCurItem();
if( target == NULL )
return;
if( aErase )
target->Draw( aPanel, aDC, GR_XOR );
target->SetPosition( aPanel->GetParent()->GetCrossHairPosition() );
target->Draw( aPanel, aDC, GR_XOR );
}

View File

@ -411,7 +411,7 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
text = textMod;
DIALOG_TEXT_PROPERTIES textDialog( m_frame, textMod, NULL );
DIALOG_TEXT_PROPERTIES textDialog( m_frame, textMod );
bool cancelled;
RunMainStack([&]() {
@ -448,7 +448,7 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
textPcb->SetTextPos( (wxPoint) cursorPos );
RunMainStack([&]() {
m_frame->InstallTextOptionsFrame( textPcb, NULL );
m_frame->InstallTextOptionsFrame( textPcb );
} );
if( textPcb->GetText().IsEmpty() )

View File

@ -643,7 +643,7 @@ int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
// Do not handle undo buffer, it is done by the properties dialogs @todo LEGACY
// Display properties dialog provided by the legacy canvas frame
editFrame->OnEditItemRequest( NULL, item );
editFrame->OnEditItemRequest( item );
// Notify other tools of the changes
m_toolMgr->ProcessEvent( EVENTS::SelectedItemsModified );
@ -1253,8 +1253,6 @@ int EDIT_TOOL::ExchangeFootprints( const TOOL_EVENT& aEvent )
MODULE* mod = (selection.Empty() ? nullptr : selection.FirstOfKind<MODULE> () );
frame()->SetCurItem( mod );
// Footprint exchange could remove modules, so they have to be
// removed from the selection first
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
@ -1403,18 +1401,15 @@ int EDIT_TOOL::editFootprintInFpEditor( const TOOL_EVENT& aEvent )
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
editFrame->SetCurItem( mod );
if( editFrame->GetCurItem()->GetTimeStamp() == 0 ) // Module Editor needs a non null timestamp
if( mod->GetTimeStamp() == 0 ) // Module Editor needs a non null timestamp
{
editFrame->GetCurItem()->SetTimeStamp( GetNewTimeStamp() );
mod->SetTimeStamp( GetNewTimeStamp() );
editFrame->OnModify();
}
FOOTPRINT_EDIT_FRAME* editor = (FOOTPRINT_EDIT_FRAME*) editFrame->Kiway().Player( FRAME_PCB_MODULE_EDITOR, true );
auto editor = (FOOTPRINT_EDIT_FRAME*) editFrame->Kiway().Player( FRAME_PCB_MODULE_EDITOR, true );
editor->Load_Module_From_BOARD( (MODULE*) editFrame->GetCurItem() );
editFrame->SetCurItem( NULL ); // the current module could be deleted by
editor->Load_Module_From_BOARD( mod );
editor->Show( true );
editor->Raise(); // Iconize( false );

View File

@ -229,9 +229,8 @@ void MICROWAVE_TOOL::createInductorBetween( const VECTOR2I& aStart, const VECTOR
wxString errorMessage;
auto inductorModule = std::unique_ptr<MODULE>(
CreateMicrowaveInductor( pattern, &frame, errorMessage )
);
auto inductorModule = std::unique_ptr<MODULE>( CreateMicrowaveInductor( pattern, &frame,
errorMessage ) );
if( inductorModule )
{
@ -253,7 +252,7 @@ void MICROWAVE_TOOL::createInductorBetween( const VECTOR2I& aStart, const VECTOR
else
{
// at this point, we can save the module
frame.SetCurItem( inductorModule.get() );
m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, inductorModule.get() );
BOARD_COMMIT commit( this );
commit.Add( inductorModule.release() );

View File

@ -993,6 +993,28 @@ void PCBNEW_CONTROL::updateGrid()
}
int PCBNEW_CONTROL::UpdateMessagePanel( const TOOL_EVENT& aEvent )
{
SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
SELECTION& selection = selTool->GetSelection();
if( selection.GetSize() == 1 )
{
EDA_ITEM* item = (EDA_ITEM*) selection.Front();
MSG_PANEL_ITEMS msgItems;
item->GetMsgPanelInfo( m_frame->GetUserUnits(), msgItems );
m_frame->SetMsgPanel( msgItems );
}
else
{
m_frame->ClearMsgPanel();
}
return 0;
}
void PCBNEW_CONTROL::setTransitions()
{
Go( &PCBNEW_CONTROL::Print, ACTIONS::print.MakeEvent() );
@ -1046,6 +1068,10 @@ void PCBNEW_CONTROL::setTransitions()
Go( &PCBNEW_CONTROL::AppendBoardFromFile, PCB_ACTIONS::appendBoard.MakeEvent() );
Go( &PCBNEW_CONTROL::Paste, ACTIONS::paste.MakeEvent() );
Go( &PCBNEW_CONTROL::UpdateMessagePanel, EVENTS::SelectedEvent );
Go( &PCBNEW_CONTROL::UpdateMessagePanel, EVENTS::UnselectedEvent );
Go( &PCBNEW_CONTROL::UpdateMessagePanel, EVENTS::ClearedEvent );
}

View File

@ -97,6 +97,7 @@ public:
int AppendBoard( PLUGIN& pi, wxString& fileName );
int ShowHelp( const TOOL_EVENT& aEvent );
int ToBeDone( const TOOL_EVENT& aEvent );
int UpdateMessagePanel( const TOOL_EVENT& aEvent );
///> Sets up handlers for various events.
void setTransitions() override;

View File

@ -665,14 +665,6 @@ bool SELECTION_TOOL::selectMultiple()
}
}
if( m_frame )
{
if( m_selection.Size() == 1 )
m_frame->SetCurItem( static_cast<BOARD_ITEM*>( m_selection.Front() ) );
else
m_frame->SetCurItem( NULL );
}
// Inform other potentially interested tools
if( !m_selection.Empty() )
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
@ -1365,9 +1357,6 @@ void SELECTION_TOOL::clearSelection()
m_selection.SetIsHover( false );
m_selection.ClearReferencePoint();
if( m_frame )
m_frame->SetCurItem( NULL );
m_locked = true;
// Inform other potentially interested tools
@ -1771,20 +1760,6 @@ void SELECTION_TOOL::select( BOARD_ITEM* aItem )
highlight( aItem, SELECTED, m_selection );
view()->Update( &m_selection );
if( m_frame )
{
if( m_selection.Size() == 1 )
{
// Set as the current item, so the information about selection is displayed
m_frame->SetCurItem( aItem, true );
}
else if( m_selection.Size() == 2 ) // Check only for 2, so it will not be
{ // called for every next selected item
// If multiple items are selected, do not show the information about the selected item
m_frame->SetCurItem( NULL, true );
}
}
}
@ -1793,9 +1768,6 @@ void SELECTION_TOOL::unselect( BOARD_ITEM* aItem )
unhighlight( aItem, SELECTED, m_selection );
view()->Update( &m_selection );
if( m_frame && m_frame->GetCurItem() == aItem )
m_frame->SetCurItem( NULL );
if( m_selection.Empty() )
m_locked = true;
}

View File

@ -688,7 +688,6 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks()
if( isModified )
{
// Clear undo and redo lists to avoid inconsistencies between lists
SetCurItem( NULL );
commit.Push( _( "Board cleanup" ) );
Compile_Ratsnest( NULL, true );
}

View File

@ -472,9 +472,6 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
break;
}
// It is possible that we are going to replace the selected item, so clear it
SetCurItem( NULL );
switch( aList->GetPickedItemStatus( ii ) )
{
case UR_CHANGED: /* Exchange old and new data for each item */

View File

@ -38,7 +38,6 @@
#include <pcbnew.h>
#include <zones.h>
#include <pcbnew_id.h>
#include <protos.h>
#include <zones_functions_for_undo_redo.h>
#include <drc.h>
#include <connectivity/connectivity_data.h>
@ -52,7 +51,7 @@ static PICKED_ITEMS_LIST s_PickedList; // a picked list to save zones for und
static PICKED_ITEMS_LIST s_AuxiliaryList; // a picked list to store zones that are deleted or added when combined
void PCB_EDIT_FRAME::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* aZone )
void PCB_EDIT_FRAME::Edit_Zone_Params( ZONE_CONTAINER* aZone )
{
int dialogResult;
ZONE_SETTINGS zoneInfo = GetZoneSettings();
@ -112,8 +111,6 @@ void PCB_EDIT_FRAME::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* aZone )
for( int ii = 0; ii < GetBoard()->GetAreaCount(); ii++ )
{
ZONE_CONTAINER* edge_zone = GetBoard()->GetArea( ii );
edge_zone->Draw( m_canvas, DC, GR_XOR );
GetGalCanvas()->GetView()->Update( edge_zone );
}
@ -127,9 +124,6 @@ void PCB_EDIT_FRAME::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* aZone )
// Combine zones if possible
GetBoard()->OnAreaPolygonModified( &s_AuxiliaryList, aZone );
// Redraw the real new zone outlines
GetBoard()->RedrawAreasOutlines( m_canvas, DC, GR_OR, UNDEFINED_LAYER );
UpdateCopyOfZonesList( s_PickedList, s_AuxiliaryList, GetBoard() );
// refill zones with the new properties applied