Remove CurItem() architecture and legacy routers and drawing code.
This commit is contained in:
parent
9d29e94cb5
commit
1e9da7f57b
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -209,9 +209,6 @@ void SCH_SCREEN::DeleteItem( SCH_ITEM* aItem )
|
|||
}
|
||||
else
|
||||
{
|
||||
if( GetCurItem() == aItem )
|
||||
SetCurItem( nullptr );
|
||||
|
||||
m_drawList.Remove( aItem );
|
||||
delete aItem;
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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 ); }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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 );
|
||||
}
|
|
@ -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
|
@ -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 );
|
||||
}
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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() )
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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" ) );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
175
pcbnew/drag.h
175
pcbnew/drag.h
|
@ -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_
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
176
pcbnew/edit.cpp
176
pcbnew/edit.cpp
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 :
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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() );
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -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 );
|
||||
|
||||
};
|
|
@ -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() );
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
|
|
|
@ -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 */
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
}
|
|
@ -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() )
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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() );
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue