From 26d0f01592ead45a4125dbb9bde3fc3a97bcdbc8 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 10:34:00 +0200 Subject: [PATCH 001/123] Removed EDA_DRAW_FRAME::SetGalCanvasActive() [it may be misleading], added EDA_DRAW_PANEL_GAL::GetBackend(). --- common/draw_frame.cpp | 5 +---- common/draw_panel_gal.cpp | 9 +++------ include/class_draw_panel_gal.h | 11 ++++++++++- include/draw_frame.h | 1 - 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/common/draw_frame.cpp b/common/draw_frame.cpp index 182e54fb6f..0d8030953f 100644 --- a/common/draw_frame.cpp +++ b/common/draw_frame.cpp @@ -1033,10 +1033,7 @@ void EDA_DRAW_FRAME::UseGalCanvas( bool aEnable ) m_auimgr.GetPane( wxT( "DrawFrameGal" ) ).Show( aEnable ); m_auimgr.Update(); - SetGalCanvasActive( aEnable ); - - if( aEnable ) - GetGalCanvas()->SetFocus(); + m_galCanvasActive = aEnable; } //-----< BASE_SCREEN API moved here >-------------------------------------------- diff --git a/common/draw_panel_gal.cpp b/common/draw_panel_gal.cpp index 1b293c63ac..6966a635df 100644 --- a/common/draw_panel_gal.cpp +++ b/common/draw_panel_gal.cpp @@ -51,7 +51,7 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin wxWindow( aParentWindow, aWindowId, aPosition, aSize ) { m_gal = NULL; - m_currentGal = GAL_TYPE_NONE; + m_backend = GAL_TYPE_NONE; m_view = NULL; m_painter = NULL; m_eventDispatcher = NULL; @@ -92,8 +92,6 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin m_pendingRefresh = false; m_drawing = false; Connect( wxEVT_TIMER, wxTimerEventHandler( EDA_DRAW_PANEL_GAL::onRefreshTimer ), NULL, this ); - - this->SetFocus(); } @@ -204,7 +202,7 @@ void EDA_DRAW_PANEL_GAL::StopDrawing() void EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType ) { // Do not do anything if the currently used GAL is correct - if( aGalType == m_currentGal && m_gal != NULL ) + if( aGalType == m_backend && m_gal != NULL ) return; // Prevent refreshing canvas during backend switch @@ -235,7 +233,7 @@ void EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType ) if( m_view ) m_view->SetGAL( m_gal ); - m_currentGal = aGalType; + m_backend = aGalType; } @@ -244,7 +242,6 @@ void EDA_DRAW_PANEL_GAL::onEvent( wxEvent& aEvent ) if( !m_eventDispatcher ) { aEvent.Skip(); - return; } else { diff --git a/include/class_draw_panel_gal.h b/include/class_draw_panel_gal.h index 16de3a139c..2fe0d3e094 100644 --- a/include/class_draw_panel_gal.h +++ b/include/class_draw_panel_gal.h @@ -68,6 +68,15 @@ public: */ void SwitchBackend( GalType aGalType ); + /** + * Function GetBackend + * Returns the type of backend currently used by GAL canvas. + */ + inline GalType GetBackend() const + { + return m_backend; + } + /** * Function GetGAL() * Returns a pointer to the GAL instance used in the panel. @@ -159,7 +168,7 @@ protected: KIGFX::WX_VIEW_CONTROLS* m_viewControls; /// Currently used GAL - GalType m_currentGal; + GalType m_backend; /// Processes and forwards events to tools TOOL_DISPATCHER* m_eventDispatcher; diff --git a/include/draw_frame.h b/include/draw_frame.h index 6608c4b634..829c9317b5 100644 --- a/include/draw_frame.h +++ b/include/draw_frame.h @@ -675,7 +675,6 @@ public: * @return True for GAL-based canvas, false for standard canvas. */ bool IsGalCanvasActive() const { return m_galCanvasActive; } - void SetGalCanvasActive( bool aState ) { m_galCanvasActive = aState; } /** * Function GetGalCanvas From 20558f53870e664ab793f5bdae38805238277f49 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 10:57:32 +0200 Subject: [PATCH 002/123] Created a specialization of EDA_DRAW_PANEL_GAL: PCB_DRAW_PANEL_GAL. Moved View related routines & fields from PCB_{BASE,EDIT}_FRAME & BOARD to PCB_DRAW_PANEL_GAL. --- common/draw_panel_gal.cpp | 22 ++ include/class_draw_panel_gal.h | 16 +- include/wxBasePcbFrame.h | 4 - include/wxPcbStruct.h | 18 -- pcbnew/CMakeLists.txt | 1 + pcbnew/basepcbframe.cpp | 141 +--------- pcbnew/class_board.cpp | 7 - pcbnew/class_board.h | 20 -- pcbnew/dialogs/dialog_general_options.cpp | 2 +- pcbnew/initpcb.cpp | 3 - pcbnew/pcb_draw_panel_gal.cpp | 315 ++++++++++++++++++++++ pcbnew/pcb_draw_panel_gal.h | 73 +++++ pcbnew/pcbframe.cpp | 210 +++------------ pcbnew/router/router_tool.cpp | 2 +- pcbnew/tools/drawing_tool.cpp | 3 +- pcbnew/tools/pcbnew_control.cpp | 2 +- 16 files changed, 476 insertions(+), 363 deletions(-) create mode 100644 pcbnew/pcb_draw_panel_gal.cpp create mode 100644 pcbnew/pcb_draw_panel_gal.h diff --git a/common/draw_panel_gal.cpp b/common/draw_panel_gal.cpp index 6966a635df..975d17c513 100644 --- a/common/draw_panel_gal.cpp +++ b/common/draw_panel_gal.cpp @@ -199,6 +199,28 @@ void EDA_DRAW_PANEL_GAL::StopDrawing() } +void EDA_DRAW_PANEL_GAL::SetHighContrastLayer( LAYER_NUM aLayer ) +{ + // Set display settings for high contrast mode + KIGFX::RENDER_SETTINGS* rSettings = m_view->GetPainter()->GetSettings(); + + SetTopLayer( aLayer ); + + rSettings->ClearActiveLayers(); + rSettings->SetActiveLayer( aLayer ); + + m_view->UpdateAllLayersColor(); +} + + +void EDA_DRAW_PANEL_GAL::SetTopLayer( LAYER_NUM aLayer ) +{ + m_view->ClearTopLayers(); + m_view->SetTopLayer( aLayer ); + m_view->UpdateAllLayersOrder(); +} + + void EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType ) { // Do not do anything if the currently used GAL is correct diff --git a/include/class_draw_panel_gal.h b/include/class_draw_panel_gal.h index 2fe0d3e094..b698c91e1e 100644 --- a/include/class_draw_panel_gal.h +++ b/include/class_draw_panel_gal.h @@ -30,9 +30,9 @@ #ifndef PANELGAL_WXSTRUCT_H #define PANELGAL_WXSTRUCT_H -#include #include - +#include +#include #include class BOARD; @@ -133,6 +133,18 @@ public: */ void StopDrawing(); + /** + * Function SetHighContrastLayer + * Takes care of display settings for the given layer to be displayed in high contrast mode. + */ + virtual void SetHighContrastLayer( LAYER_NUM aLayer ); + + /** + * Function SetTopLayer + * Moves the selected layer to the top, so it is displayed above all others. + */ + virtual void SetTopLayer( LAYER_NUM aLayer ); + protected: void onPaint( wxPaintEvent& WXUNUSED( aEvent ) ); void onSize( wxSizeEvent& aEvent ); diff --git a/include/wxBasePcbFrame.h b/include/wxBasePcbFrame.h index d95bdfc64c..e5ab27d1c0 100644 --- a/include/wxBasePcbFrame.h +++ b/include/wxBasePcbFrame.h @@ -110,10 +110,6 @@ protected: MODULE* loadFootprint( const FPID& aFootprintId ) throw( IO_ERROR, PARSE_ERROR ); - ///> Rendering order of layers on GAL-based canvas (lower index in the array - ///> means that layer is displayed closer to the user, ie. on the top). - static const LAYER_NUM GAL_LAYER_ORDER[]; - public: PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 8153fd9d5e..3cba461273 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -531,18 +531,6 @@ public: */ virtual void OnModify(); - /** - * Function SetHighContrastLayer - * takes care of display settings for the given layer to be displayed in high contrast mode. - */ - void SetHighContrastLayer( LAYER_ID aLayer ); - - /** - * Function SetTopLayer - * moves the selected layer to the top, so it is displayed above all others. - */ - void SetTopLayer( LAYER_ID aLayer ); - /** * Function SetActiveLayer * will change the currently active layer to \a aLayer and also @@ -890,12 +878,6 @@ public: /// @copydoc PCB_BASE_FRAME::SetBoard() void SetBoard( BOARD* aBoard ); - /** - * Function ViewReloadBoard - * adds all items from the current board to the VIEW, so they can be displayed by GAL. - */ - void ViewReloadBoard( const BOARD* aBoard ) const; - // Drc control /* function GetDrcController diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index d01059707e..f8253fb31f 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -221,6 +221,7 @@ set( PCBNEW_CLASS_SRCS pad_edition_functions.cpp pcbnew_config.cpp pcbplot.cpp + pcb_draw_panel_gal.cpp plot_board_layers.cpp plot_brditems_plotter.cpp print_board_functions.cpp diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index f45df75edb..fadf3e1774 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -51,7 +51,7 @@ #include #include -#include +#include #include #include #include @@ -75,82 +75,6 @@ static const wxChar DisplayModuleTextEntry[] = wxT( "DiModTx" ); static const wxChar FastGrid1Entry[] = wxT( "FastGrid1" ); static const wxChar FastGrid2Entry[] = wxT( "FastGrid2" ); -const LAYER_NUM PCB_BASE_FRAME::GAL_LAYER_ORDER[] = -{ - ITEM_GAL_LAYER( GP_OVERLAY ), - ITEM_GAL_LAYER( DRC_VISIBLE ), - NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ), - Dwgs_User, Cmts_User, Eco1_User, Eco2_User, Edge_Cuts, - - // UNUSED_LAYER_29, UNUSED_LAYER_30, UNUSED_LAYER_31, - - ITEM_GAL_LAYER( MOD_TEXT_FR_VISIBLE ), - ITEM_GAL_LAYER( MOD_REFERENCES_VISIBLE), ITEM_GAL_LAYER( MOD_VALUES_VISIBLE ), - - ITEM_GAL_LAYER( RATSNEST_VISIBLE ), - ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), - ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ), - - NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( PAD_FR_VISIBLE ), F_Mask, - NETNAMES_GAL_LAYER( F_Cu ), F_Cu, - F_SilkS, F_Paste, F_Adhes, - -#if 0 // was: - NETNAMES_GAL_LAYER( LAYER_15_NETNAMES_VISIBLE ), LAYER_N_15, - NETNAMES_GAL_LAYER( LAYER_14_NETNAMES_VISIBLE ), LAYER_N_14, - NETNAMES_GAL_LAYER( LAYER_13_NETNAMES_VISIBLE ), LAYER_N_13, - NETNAMES_GAL_LAYER( LAYER_12_NETNAMES_VISIBLE ), LAYER_N_12, - NETNAMES_GAL_LAYER( LAYER_11_NETNAMES_VISIBLE ), LAYER_N_11, - NETNAMES_GAL_LAYER( LAYER_10_NETNAMES_VISIBLE ), LAYER_N_10, - NETNAMES_GAL_LAYER( LAYER_9_NETNAMES_VISIBLE ), LAYER_N_9, - NETNAMES_GAL_LAYER( LAYER_8_NETNAMES_VISIBLE ), LAYER_N_8, - NETNAMES_GAL_LAYER( LAYER_7_NETNAMES_VISIBLE ), LAYER_N_7, - NETNAMES_GAL_LAYER( LAYER_6_NETNAMES_VISIBLE ), LAYER_N_6, - NETNAMES_GAL_LAYER( LAYER_5_NETNAMES_VISIBLE ), LAYER_N_5, - NETNAMES_GAL_LAYER( LAYER_4_NETNAMES_VISIBLE ), LAYER_N_4, - NETNAMES_GAL_LAYER( LAYER_3_NETNAMES_VISIBLE ), LAYER_N_3, - NETNAMES_GAL_LAYER( LAYER_2_NETNAMES_VISIBLE ), LAYER_N_2, -#else - - NETNAMES_GAL_LAYER( In1_Cu ), In1_Cu, - NETNAMES_GAL_LAYER( In2_Cu ), In2_Cu, - NETNAMES_GAL_LAYER( In3_Cu ), In3_Cu, - NETNAMES_GAL_LAYER( In4_Cu ), In4_Cu, - NETNAMES_GAL_LAYER( In5_Cu ), In5_Cu, - NETNAMES_GAL_LAYER( In6_Cu ), In6_Cu, - NETNAMES_GAL_LAYER( In7_Cu ), In7_Cu, - NETNAMES_GAL_LAYER( In8_Cu ), In8_Cu, - NETNAMES_GAL_LAYER( In9_Cu ), In9_Cu, - NETNAMES_GAL_LAYER( In10_Cu ), In10_Cu, - NETNAMES_GAL_LAYER( In11_Cu ), In11_Cu, - NETNAMES_GAL_LAYER( In12_Cu ), In12_Cu, - NETNAMES_GAL_LAYER( In13_Cu ), In13_Cu, - NETNAMES_GAL_LAYER( In14_Cu ), In14_Cu, - NETNAMES_GAL_LAYER( In15_Cu ), In15_Cu, - NETNAMES_GAL_LAYER( In16_Cu ), In16_Cu, - NETNAMES_GAL_LAYER( In17_Cu ), In17_Cu, - NETNAMES_GAL_LAYER( In18_Cu ), In18_Cu, - NETNAMES_GAL_LAYER( In19_Cu ), In19_Cu, - NETNAMES_GAL_LAYER( In20_Cu ), In20_Cu, - NETNAMES_GAL_LAYER( In21_Cu ), In21_Cu, - NETNAMES_GAL_LAYER( In22_Cu ), In22_Cu, - NETNAMES_GAL_LAYER( In23_Cu ), In23_Cu, - NETNAMES_GAL_LAYER( In24_Cu ), In24_Cu, - NETNAMES_GAL_LAYER( In25_Cu ), In25_Cu, - NETNAMES_GAL_LAYER( In26_Cu ), In26_Cu, - NETNAMES_GAL_LAYER( In27_Cu ), In27_Cu, - NETNAMES_GAL_LAYER( In28_Cu ), In28_Cu, - NETNAMES_GAL_LAYER( In29_Cu ), In29_Cu, - NETNAMES_GAL_LAYER( In30_Cu ), In30_Cu, -#endif - NETNAMES_GAL_LAYER( PAD_BK_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( PAD_BK_VISIBLE ), B_Mask, - NETNAMES_GAL_LAYER( B_Cu ), B_Cu, - - B_Adhes, B_Paste, B_SilkS, - ITEM_GAL_LAYER( MOD_TEXT_BK_VISIBLE ), - ITEM_GAL_LAYER( WORKSHEET ) -}; - BEGIN_EVENT_TABLE( PCB_BASE_FRAME, EDA_DRAW_FRAME ) EVT_MENU_RANGE( ID_POPUP_PCB_ITEM_SELECTION_START, ID_POPUP_PCB_ITEM_SELECTION_END, @@ -193,16 +117,6 @@ PCB_BASE_FRAME::PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrame m_FastGrid1 = 0; m_FastGrid2 = 0; - SetGalCanvas( new EDA_DRAW_PANEL_GAL( - this, -1, wxPoint( 0, 0 ), m_FrameSize, - EDA_DRAW_PANEL_GAL::GAL_TYPE_CAIRO ) ); - - // GAL should not be active yet - GetGalCanvas()->StopDrawing(); - - // Hide by default, it has to be explicitly shown - GetGalCanvas()->Hide(); - m_auxiliaryToolBar = NULL; } @@ -253,8 +167,11 @@ FP_LIB_TABLE* PROJECT::PcbFootprintLibs() void PCB_BASE_FRAME::SetBoard( BOARD* aBoard ) { - delete m_Pcb; - m_Pcb = aBoard; + if( m_Pcb != aBoard ) + { + delete m_Pcb; + m_Pcb = aBoard; + } } @@ -847,52 +764,6 @@ void PCB_BASE_FRAME::LoadSettings( wxConfigBase* aCfg ) if( m_DisplayModText < LINE || m_DisplayModText > SKETCH ) m_DisplayModText = FILLED; - // Apply display settings for GAL - KIGFX::VIEW* view = GetGalCanvas()->GetView(); - - // Set rendering order and properties of layers - for( LAYER_NUM i = 0; i < (int) DIM(GAL_LAYER_ORDER); ++i ) - { - LAYER_NUM layer = GAL_LAYER_ORDER[i]; - wxASSERT( layer < KIGFX::VIEW::VIEW_MAX_LAYERS ); - - view->SetLayerOrder( layer, i ); - - if( IsCopperLayer( layer ) ) - { - // Copper layers are required for netname layers - view->SetRequired( GetNetnameLayer( layer ), layer ); - view->SetLayerTarget( layer, KIGFX::TARGET_CACHED ); - } - else if( IsNetnameLayer( layer ) ) - { - // Netnames are drawn only when scale is sufficient (level of details) - // so there is no point in caching them - view->SetLayerTarget( layer, KIGFX::TARGET_NONCACHED ); - } - } - - // Some more required layers settings - view->SetRequired( ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ) ); - view->SetRequired( ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ) ); - view->SetRequired( NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ) ); - - view->SetRequired( NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( PAD_FR_VISIBLE ) ); - view->SetRequired( F_Adhes, ITEM_GAL_LAYER( PAD_FR_VISIBLE ) ); - view->SetRequired( F_Paste, ITEM_GAL_LAYER( PAD_FR_VISIBLE ) ); - view->SetRequired( F_Mask, ITEM_GAL_LAYER( PAD_FR_VISIBLE ) ); - - view->SetRequired( NETNAMES_GAL_LAYER( PAD_BK_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( PAD_BK_VISIBLE ) ); - view->SetRequired( B_Adhes, ITEM_GAL_LAYER( PAD_BK_VISIBLE ) ); - view->SetRequired( B_Paste, ITEM_GAL_LAYER( PAD_BK_VISIBLE ) ); - view->SetRequired( B_Mask, ITEM_GAL_LAYER( PAD_BK_VISIBLE ) ); - - view->SetRequired( ITEM_GAL_LAYER( PAD_FR_VISIBLE ), ITEM_GAL_LAYER( MOD_FR_VISIBLE ) ); - view->SetRequired( ITEM_GAL_LAYER( PAD_BK_VISIBLE ), ITEM_GAL_LAYER( MOD_BK_VISIBLE ) ); - - view->SetLayerTarget( ITEM_GAL_LAYER( GP_OVERLAY ), KIGFX::TARGET_OVERLAY ); - view->SetLayerTarget( ITEM_GAL_LAYER( RATSNEST_VISIBLE ), KIGFX::TARGET_OVERLAY ); - // WxWidgets 2.9.1 seems call setlocale( LC_NUMERIC, "" ) // when reading doubles in config, // but forget to back to current locale. So we call SetLocaleTo_Default diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 8e3ac850cd..f1d304817c 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -106,11 +106,6 @@ BOARD::BOARD() : // Initialize ratsnest m_ratsnest = new RN_DATA( this ); - m_ratsnestViewItem = new KIGFX::RATSNEST_VIEWITEM( m_ratsnest ); - - // Initialize view item for displaying worksheet frame - m_worksheetViewItem = new KIGFX::WORKSHEET_VIEWITEM( &m_paper, &m_titles ); - m_worksheetViewItem->SetFileName( std::string( m_fileName.mb_str() ) ); } @@ -122,8 +117,6 @@ BOARD::~BOARD() Delete( area_to_remove ); } - delete m_worksheetViewItem; - delete m_ratsnestViewItem; delete m_ratsnest; m_FullRatsnest.clear(); diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index 3bc5c0b73f..3cc7c35731 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -198,8 +198,6 @@ private: EDA_RECT m_BoundingBox; NETINFO_LIST m_NetInfo; ///< net info list (name, design constraints .. RN_DATA* m_ratsnest; - KIGFX::RATSNEST_VIEWITEM* m_ratsnestViewItem; ///< VIEW_ITEM that draws ratsnest - KIGFX::WORKSHEET_VIEWITEM* m_worksheetViewItem; ///< VIEW_ITEM that draws worksheet frame BOARD_DESIGN_SETTINGS m_designSettings; ZONE_SETTINGS m_zoneSettings; @@ -313,24 +311,6 @@ public: return m_ratsnest; } - /** - * Function GetRatsnestViewItem() - * returns VIEW_ITEM responsible for drawing the ratsnest for the board. - */ - KIGFX::RATSNEST_VIEWITEM* GetRatsnestViewItem() const - { - return m_ratsnestViewItem; - } - - /** - * Function GetWorksheetViewItem() - * returns VIEW_ITEM responsible for drawing the worksheet frame. - */ - KIGFX::WORKSHEET_VIEWITEM* GetWorksheetViewItem() const - { - return m_worksheetViewItem; - } - /** * Function DeleteMARKERs * deletes ALL MARKERS from the board. diff --git a/pcbnew/dialogs/dialog_general_options.cpp b/pcbnew/dialogs/dialog_general_options.cpp index 9adc32bdf6..9004aecf26 100644 --- a/pcbnew/dialogs/dialog_general_options.cpp +++ b/pcbnew/dialogs/dialog_general_options.cpp @@ -228,7 +228,7 @@ void PCB_EDIT_FRAME::OnSelectOptionToolbar( wxCommandEvent& event ) // Apply new display options to the GAL canvas (this is faster than recaching) settings->LoadDisplayOptions( DisplayOpt ); - SetHighContrastLayer( GetActiveLayer() ); + GetGalCanvas()->SetHighContrastLayer( GetActiveLayer() ); m_canvas->Refresh(); break; diff --git a/pcbnew/initpcb.cpp b/pcbnew/initpcb.cpp index 05ac3198f4..d0d6ba49e7 100644 --- a/pcbnew/initpcb.cpp +++ b/pcbnew/initpcb.cpp @@ -61,9 +61,6 @@ bool PCB_EDIT_FRAME::Clear_Pcb( bool aQuery ) // Update display GetBoard()->SetVisibleLayers( LSET().set() ); - // Set currently selected layer to be shown in high contrast mode, when enabled` - SetHighContrastLayer( GetScreen()->m_Active_Layer ); - ReFillLayerWidget(); Zoom_Automatique( false ); diff --git a/pcbnew/pcb_draw_panel_gal.cpp b/pcbnew/pcb_draw_panel_gal.cpp new file mode 100644 index 0000000000..778570b1e5 --- /dev/null +++ b/pcbnew/pcb_draw_panel_gal.cpp @@ -0,0 +1,315 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 CERN + * @author Maciej Suminski + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "pcb_draw_panel_gal.h" +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +const LAYER_NUM GAL_LAYER_ORDER[] = +{ + ITEM_GAL_LAYER( GP_OVERLAY ), + ITEM_GAL_LAYER( DRC_VISIBLE ), + NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ), + Dwgs_User, Cmts_User, Eco1_User, Eco2_User, Edge_Cuts, + + ITEM_GAL_LAYER( MOD_TEXT_FR_VISIBLE ), + ITEM_GAL_LAYER( MOD_REFERENCES_VISIBLE), ITEM_GAL_LAYER( MOD_VALUES_VISIBLE ), + + ITEM_GAL_LAYER( RATSNEST_VISIBLE ), + ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), + ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ), + + NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( PAD_FR_VISIBLE ), F_Mask, + NETNAMES_GAL_LAYER( F_Cu ), F_Cu, + F_SilkS, F_Paste, F_Adhes, + +#if 0 // was: + NETNAMES_GAL_LAYER( LAYER_15_NETNAMES_VISIBLE ), LAYER_N_15, + NETNAMES_GAL_LAYER( LAYER_14_NETNAMES_VISIBLE ), LAYER_N_14, + NETNAMES_GAL_LAYER( LAYER_13_NETNAMES_VISIBLE ), LAYER_N_13, + NETNAMES_GAL_LAYER( LAYER_12_NETNAMES_VISIBLE ), LAYER_N_12, + NETNAMES_GAL_LAYER( LAYER_11_NETNAMES_VISIBLE ), LAYER_N_11, + NETNAMES_GAL_LAYER( LAYER_10_NETNAMES_VISIBLE ), LAYER_N_10, + NETNAMES_GAL_LAYER( LAYER_9_NETNAMES_VISIBLE ), LAYER_N_9, + NETNAMES_GAL_LAYER( LAYER_8_NETNAMES_VISIBLE ), LAYER_N_8, + NETNAMES_GAL_LAYER( LAYER_7_NETNAMES_VISIBLE ), LAYER_N_7, + NETNAMES_GAL_LAYER( LAYER_6_NETNAMES_VISIBLE ), LAYER_N_6, + NETNAMES_GAL_LAYER( LAYER_5_NETNAMES_VISIBLE ), LAYER_N_5, + NETNAMES_GAL_LAYER( LAYER_4_NETNAMES_VISIBLE ), LAYER_N_4, + NETNAMES_GAL_LAYER( LAYER_3_NETNAMES_VISIBLE ), LAYER_N_3, + NETNAMES_GAL_LAYER( LAYER_2_NETNAMES_VISIBLE ), LAYER_N_2, +#else + NETNAMES_GAL_LAYER( In1_Cu ), In1_Cu, + NETNAMES_GAL_LAYER( In2_Cu ), In2_Cu, + NETNAMES_GAL_LAYER( In3_Cu ), In3_Cu, + NETNAMES_GAL_LAYER( In4_Cu ), In4_Cu, + NETNAMES_GAL_LAYER( In5_Cu ), In5_Cu, + NETNAMES_GAL_LAYER( In6_Cu ), In6_Cu, + NETNAMES_GAL_LAYER( In7_Cu ), In7_Cu, + NETNAMES_GAL_LAYER( In8_Cu ), In8_Cu, + NETNAMES_GAL_LAYER( In9_Cu ), In9_Cu, + NETNAMES_GAL_LAYER( In10_Cu ), In10_Cu, + NETNAMES_GAL_LAYER( In11_Cu ), In11_Cu, + NETNAMES_GAL_LAYER( In12_Cu ), In12_Cu, + NETNAMES_GAL_LAYER( In13_Cu ), In13_Cu, + NETNAMES_GAL_LAYER( In14_Cu ), In14_Cu, + NETNAMES_GAL_LAYER( In15_Cu ), In15_Cu, + NETNAMES_GAL_LAYER( In16_Cu ), In16_Cu, + NETNAMES_GAL_LAYER( In17_Cu ), In17_Cu, + NETNAMES_GAL_LAYER( In18_Cu ), In18_Cu, + NETNAMES_GAL_LAYER( In19_Cu ), In19_Cu, + NETNAMES_GAL_LAYER( In20_Cu ), In20_Cu, + NETNAMES_GAL_LAYER( In21_Cu ), In21_Cu, + NETNAMES_GAL_LAYER( In22_Cu ), In22_Cu, + NETNAMES_GAL_LAYER( In23_Cu ), In23_Cu, + NETNAMES_GAL_LAYER( In24_Cu ), In24_Cu, + NETNAMES_GAL_LAYER( In25_Cu ), In25_Cu, + NETNAMES_GAL_LAYER( In26_Cu ), In26_Cu, + NETNAMES_GAL_LAYER( In27_Cu ), In27_Cu, + NETNAMES_GAL_LAYER( In28_Cu ), In28_Cu, + NETNAMES_GAL_LAYER( In29_Cu ), In29_Cu, + NETNAMES_GAL_LAYER( In30_Cu ), In30_Cu, +#endif + NETNAMES_GAL_LAYER( PAD_BK_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( PAD_BK_VISIBLE ), B_Mask, + NETNAMES_GAL_LAYER( B_Cu ), B_Cu, + + B_Adhes, B_Paste, B_SilkS, + ITEM_GAL_LAYER( MOD_TEXT_BK_VISIBLE ), + ITEM_GAL_LAYER( WORKSHEET ) +}; + + +PCB_DRAW_PANEL_GAL::PCB_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWindowId, + const wxPoint& aPosition, const wxSize& aSize, + GalType aGalType ) : +EDA_DRAW_PANEL_GAL( aParentWindow, aWindowId, aPosition, aSize, aGalType ) +{ + m_worksheet = NULL; + m_ratsnest = NULL; + + // Set rendering order and properties of layers + for( LAYER_NUM i = 0; (unsigned) i < sizeof(GAL_LAYER_ORDER) / sizeof(LAYER_NUM); ++i ) + { + LAYER_NUM layer = GAL_LAYER_ORDER[i]; + wxASSERT( layer < KIGFX::VIEW::VIEW_MAX_LAYERS ); + + m_view->SetLayerOrder( layer, i ); + + if( IsCopperLayer( layer ) ) + { + // Copper layers are required for netname layers + m_view->SetRequired( GetNetnameLayer( layer ), layer ); + m_view->SetLayerTarget( layer, KIGFX::TARGET_CACHED ); + } + else if( IsNetnameLayer( layer ) ) + { + // Netnames are drawn only when scale is sufficient (level of details) + // so there is no point in caching them + m_view->SetLayerTarget( layer, KIGFX::TARGET_NONCACHED ); + } + } + + // Some more required layers settings + m_view->SetRequired( ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ) ); + m_view->SetRequired( ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ) ); + m_view->SetRequired( NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ) ); + + m_view->SetRequired( NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( PAD_FR_VISIBLE ) ); + m_view->SetRequired( F_Adhes, ITEM_GAL_LAYER( PAD_FR_VISIBLE ) ); + m_view->SetRequired( F_Paste, ITEM_GAL_LAYER( PAD_FR_VISIBLE ) ); + m_view->SetRequired( F_Mask, ITEM_GAL_LAYER( PAD_FR_VISIBLE ) ); + + m_view->SetRequired( NETNAMES_GAL_LAYER( PAD_BK_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( PAD_BK_VISIBLE ) ); + m_view->SetRequired( B_Adhes, ITEM_GAL_LAYER( PAD_BK_VISIBLE ) ); + m_view->SetRequired( B_Paste, ITEM_GAL_LAYER( PAD_BK_VISIBLE ) ); + m_view->SetRequired( B_Mask, ITEM_GAL_LAYER( PAD_BK_VISIBLE ) ); + + m_view->SetRequired( ITEM_GAL_LAYER( PAD_FR_VISIBLE ), ITEM_GAL_LAYER( MOD_FR_VISIBLE ) ); + m_view->SetRequired( ITEM_GAL_LAYER( PAD_BK_VISIBLE ), ITEM_GAL_LAYER( MOD_BK_VISIBLE ) ); + + m_view->SetLayerTarget( ITEM_GAL_LAYER( GP_OVERLAY ), KIGFX::TARGET_OVERLAY ); + m_view->SetLayerTarget( ITEM_GAL_LAYER( RATSNEST_VISIBLE ), KIGFX::TARGET_OVERLAY ); + + // Load display options (such as filled/outline display of items) + static_cast( m_view->GetPainter()->GetSettings() )->LoadDisplayOptions( DisplayOpt ); +} + + +PCB_DRAW_PANEL_GAL::~PCB_DRAW_PANEL_GAL() +{ + delete m_worksheet; + delete m_ratsnest; +} + + +void PCB_DRAW_PANEL_GAL::DisplayBoard( const BOARD* aBoard ) +{ + m_view->Clear(); + + // Load zones + for( int i = 0; i < aBoard->GetAreaCount(); ++i ) + m_view->Add( (KIGFX::VIEW_ITEM*) ( aBoard->GetArea( i ) ) ); + + // Load drawings + for( BOARD_ITEM* drawing = aBoard->m_Drawings; drawing; drawing = drawing->Next() ) + m_view->Add( drawing ); + + // Load tracks + for( TRACK* track = aBoard->m_Track; track; track = track->Next() ) + m_view->Add( track ); + + // Load modules and its additional elements + for( MODULE* module = aBoard->m_Modules; module; module = module->Next() ) + { + module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, m_view, _1 ) ); + m_view->Add( module ); + } + + // Segzones (equivalent of ZONE_CONTAINER for legacy boards) + for( SEGZONE* zone = aBoard->m_Zone; zone; zone = zone->Next() ) + m_view->Add( zone ); + + // Ratsnest + if( m_ratsnest ) + { + m_view->Remove( m_ratsnest ); + delete m_ratsnest; + } + + m_ratsnest = new KIGFX::RATSNEST_VIEWITEM( aBoard->GetRatsnest() ); + m_view->Add( m_ratsnest ); + + // Load layer color setup from PCB data + static_cast( m_view->GetPainter()->GetSettings() )->ImportLegacyColors( aBoard->GetColorsSettings() ); + + m_view->RecacheAllItems( true ); +} + + +void PCB_DRAW_PANEL_GAL::SetWorksheet( KIGFX::WORKSHEET_VIEWITEM* aWorksheet ) +{ + if( m_worksheet ) + { + m_view->Remove( m_worksheet ); + delete m_worksheet; + } + + m_worksheet = aWorksheet; + m_view->Add( m_worksheet ); + + // Limit panning to the size of worksheet frame + m_viewControls->SetPanBoundary( aWorksheet->ViewBBox() ); +} + + +void PCB_DRAW_PANEL_GAL::SetHighContrastLayer( LAYER_ID aLayer ) +{ + // Set display settings for high contrast mode + KIGFX::RENDER_SETTINGS* rSettings = m_view->GetPainter()->GetSettings(); + + SetTopLayer( aLayer ); + + rSettings->ClearActiveLayers(); + rSettings->SetActiveLayer( aLayer ); + + if( IsCopperLayer( aLayer ) ) + { + // Bring some other layers to the front in case of copper layers and make them colored + // fixme do not like the idea of storing the list of layers here, + // should be done in some other way I guess.. + LAYER_NUM layers[] = { + GetNetnameLayer( aLayer ), ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ), + ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ), + ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ), + ITEM_GAL_LAYER( GP_OVERLAY ), ITEM_GAL_LAYER( RATSNEST_VISIBLE ) + }; + + for( unsigned int i = 0; i < sizeof( layers ) / sizeof( LAYER_NUM ); ++i ) + rSettings->SetActiveLayer( layers[i] ); + + // Pads should be shown too + if( aLayer == B_Cu ) + { + rSettings->SetActiveLayer( ITEM_GAL_LAYER( PAD_BK_VISIBLE ) ); + rSettings->SetActiveLayer( NETNAMES_GAL_LAYER( PAD_BK_NETNAMES_VISIBLE ) ); + } + else if( aLayer == F_Cu ) + { + rSettings->SetActiveLayer( ITEM_GAL_LAYER( PAD_FR_VISIBLE ) ); + rSettings->SetActiveLayer( NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE ) ); + } + } + + m_view->UpdateAllLayersColor(); +} + + +void PCB_DRAW_PANEL_GAL::SetTopLayer( LAYER_ID aLayer ) +{ + m_view->ClearTopLayers(); + m_view->SetTopLayer( aLayer ); + + if( IsCopperLayer( aLayer ) ) + { + // Bring some other layers to the front in case of copper layers and make them colored + // fixme do not like the idea of storing the list of layers here, + // should be done in some other way I guess.. + LAYER_NUM layers[] = { + GetNetnameLayer( aLayer ), ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ), + ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ), + ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ), + ITEM_GAL_LAYER( GP_OVERLAY ), ITEM_GAL_LAYER( RATSNEST_VISIBLE ), Dwgs_User, + ITEM_GAL_LAYER( DRC_VISIBLE ) + }; + + for( unsigned int i = 0; i < sizeof( layers ) / sizeof( LAYER_NUM ); ++i ) + { + m_view->SetTopLayer( layers[i] ); + } + + // Pads should be shown too + if( aLayer == B_Cu ) + { + m_view->SetTopLayer( ITEM_GAL_LAYER( PAD_BK_VISIBLE ) ); + m_view->SetTopLayer( NETNAMES_GAL_LAYER( PAD_BK_NETNAMES_VISIBLE ) ); + } + else if( aLayer == F_Cu ) + { + m_view->SetTopLayer( ITEM_GAL_LAYER( PAD_FR_VISIBLE ) ); + m_view->SetTopLayer( NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE ) ); + } + } + + m_view->UpdateAllLayersOrder(); +} diff --git a/pcbnew/pcb_draw_panel_gal.h b/pcbnew/pcb_draw_panel_gal.h new file mode 100644 index 0000000000..9682b21f13 --- /dev/null +++ b/pcbnew/pcb_draw_panel_gal.h @@ -0,0 +1,73 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 CERN + * @author Maciej Suminski + * + * 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 PCB_DRAW_PANEL_GAL_H_ +#define PCB_DRAW_PANEL_GAL_H_ + +#include + +namespace KIGFX +{ + class WORKSHEET_VIEWITEM; + class RATSNEST_VIEWITEM; +} + +class PCB_DRAW_PANEL_GAL : public EDA_DRAW_PANEL_GAL +{ +public: + PCB_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWindowId, const wxPoint& aPosition, + const wxSize& aSize, GalType aGalType = GAL_TYPE_OPENGL ); + + virtual ~PCB_DRAW_PANEL_GAL(); + + /** + * Function DisplayBoard + * adds all items from the current board to the VIEW, so they can be displayed by GAL. + * @param aBoard is the PCB to be loaded. + */ + void DisplayBoard( const BOARD* aBoard ); + + /** + * Function SetWorksheet + * Sets (or updates) worksheet used by the draw panel. + * @param aWorksheet is the worksheet to be used. + * The object is then owned by PCB_DRAW_PANEL_GAL. + */ + void SetWorksheet( KIGFX::WORKSHEET_VIEWITEM* aWorksheet ); + + ///> @copydoc EDA_DRAW_PANEL_GAL::SetHighContrastLayer() + virtual void SetHighContrastLayer( LAYER_ID aLayer ); + + ///> @copydoc EDA_DRAW_PANEL_GAL::SetTopLayer() + virtual void SetTopLayer( LAYER_ID aLayer ); + +protected: + ///> Currently used worksheet + KIGFX::WORKSHEET_VIEWITEM* m_worksheet; + + ///> Ratsnest view item + KIGFX::RATSNEST_VIEWITEM* m_ratsnest; +}; + +#endif /* PCB_DRAW_PANEL_GAL_H_ */ diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 9d709e8ad8..0add833fc1 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -76,7 +76,7 @@ #define PYTHONCONSOLE_STRID wxT( "PythonPanel" ) #endif -#include +#include #include // Keys used in read/write config @@ -174,9 +174,9 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME ) EVT_MENU( ID_MENU_PCB_SHOW_3D_FRAME, PCB_EDIT_FRAME::Show3D_Frame ) // Switching canvases - EVT_MENU( ID_MENU_CANVAS_DEFAULT, PCB_EDIT_FRAME::SwitchCanvas ) - EVT_MENU( ID_MENU_CANVAS_CAIRO, PCB_EDIT_FRAME::SwitchCanvas ) - EVT_MENU( ID_MENU_CANVAS_OPENGL, PCB_EDIT_FRAME::SwitchCanvas ) + EVT_MENU( ID_MENU_CANVAS_DEFAULT, PCB_EDIT_FRAME::SwitchCanvas ) + EVT_MENU( ID_MENU_CANVAS_CAIRO, PCB_EDIT_FRAME::SwitchCanvas ) + EVT_MENU( ID_MENU_CANVAS_OPENGL, PCB_EDIT_FRAME::SwitchCanvas ) // Menu Get Design Rules Editor EVT_MENU( ID_MENU_PCB_SHOW_DESIGN_RULES_DIALOG, PCB_EDIT_FRAME::ShowDesignRulesEditor ) @@ -330,6 +330,16 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : for ( int i = 0; i < 10; i++ ) m_Macros[i].m_Record.clear(); + // Create GAL canvas + SetGalCanvas( new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), m_FrameSize, + PCB_DRAW_PANEL_GAL::GAL_TYPE_CAIRO ) ); + + // GAL should not be active yet + GetGalCanvas()->StopDrawing(); + + // Hide by default, it has to be explicitly shown + GetGalCanvas()->Hide(); + SetBoard( new BOARD() ); // Create the PCB_LAYER_WIDGET *after* SetBoard(): @@ -404,7 +414,6 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : lyrs.BestSize( m_Layers->GetBestSize() ); lyrs.Caption( _( "Visibles" ) ); - if( m_mainToolBar ) // The main horizontal toolbar { m_auimgr.AddPane( m_mainToolBar, @@ -480,84 +489,36 @@ void PCB_EDIT_FRAME::SetBoard( BOARD* aBoard ) if( IsGalCanvasActive() ) { - ViewReloadBoard( aBoard ); + static_cast( GetGalCanvas() )->DisplayBoard( aBoard ); + aBoard->GetRatsnest()->Recalculate(); + + // Prepare worksheet template + KIGFX::WORKSHEET_VIEWITEM* worksheet = new KIGFX::WORKSHEET_VIEWITEM( &aBoard->GetPageSettings(), + &aBoard->GetTitleBlock() ); + worksheet->SetSheetName( std::string( GetScreenDesc().mb_str() ) ); + + BASE_SCREEN* screen = GetScreen(); + + if( screen != NULL ) + { + worksheet->SetSheetNumber( screen->m_ScreenNumber ); + worksheet->SetSheetCount( screen->m_NumberOfScreens ); + } + + // PCB_DRAW_PANEL_GAL takes ownership of the worksheet + static_cast( GetGalCanvas() )->SetWorksheet( worksheet ); // update the tool manager with the new board and its view. - m_toolManager->SetEnvironment( aBoard, GetGalCanvas()->GetView(), - GetGalCanvas()->GetViewControls(), this ); - m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD ); + if( m_toolManager ) + { + m_toolManager->SetEnvironment( aBoard, GetGalCanvas()->GetView(), + GetGalCanvas()->GetViewControls(), this ); + m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD ); + } } } -void PCB_EDIT_FRAME::ViewReloadBoard( const BOARD* aBoard ) const -{ - KIGFX::VIEW* view = GetGalCanvas()->GetView(); - view->Clear(); - - // All of PCB drawing elements should be added to the VIEW - // in order to be displayed - - // Load zones - for( int i = 0; i < aBoard->GetAreaCount(); ++i ) - view->Add( (KIGFX::VIEW_ITEM*) ( aBoard->GetArea( i ) ) ); - - // Load drawings - for( BOARD_ITEM* drawing = aBoard->m_Drawings; drawing; drawing = drawing->Next() ) - view->Add( drawing ); - - // Load tracks - for( TRACK* track = aBoard->m_Track; track; track = track->Next() ) - view->Add( track ); - - // Load modules and its additional elements - for( MODULE* module = aBoard->m_Modules; module; module = module->Next() ) - { - module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) ); - view->Add( module ); - } - - // Segzones (equivalent of ZONE_CONTAINER for legacy boards) - for( SEGZONE* zone = aBoard->m_Zone; zone; zone = zone->Next() ) - view->Add( zone ); - - KIGFX::WORKSHEET_VIEWITEM* worksheet = aBoard->GetWorksheetViewItem(); - worksheet->SetSheetName( std::string( GetScreenDesc().mb_str() ) ); - - BASE_SCREEN* screen = GetScreen(); - - if( screen != NULL ) - { - worksheet->SetSheetNumber( screen->m_ScreenNumber ); - worksheet->SetSheetCount( screen->m_NumberOfScreens ); - } - - view->Add( worksheet ); - view->Add( aBoard->GetRatsnestViewItem() ); - aBoard->GetRatsnest()->Recalculate(); - - // Apply layer coloring scheme & display options - if( view->GetPainter() ) - { - KIGFX::PCB_RENDER_SETTINGS* settings = - static_cast( view->GetPainter()->GetSettings() ); - - // Load layers' colors from PCB data - settings->ImportLegacyColors( m_Pcb->GetColorsSettings() ); - - // Load display options (such as filled/outline display of items) - settings->LoadDisplayOptions( DisplayOpt ); - } - - // Limit panning to the size of worksheet frame - GetGalCanvas()->GetViewControls()->SetPanBoundary( aBoard->GetWorksheetViewItem()->ViewBBox() ); - view->RecacheAllItems( true ); - - if( IsGalCanvasActive() ) - GetGalCanvas()->Refresh(); -} - - bool PCB_EDIT_FRAME::isAutoSaveRequired() const { return GetScreen()->IsSave(); @@ -676,12 +637,7 @@ void PCB_EDIT_FRAME::UseGalCanvas( bool aEnable ) if( aEnable ) { - ViewReloadBoard( m_Pcb ); - GetGalCanvas()->GetView()->RecacheAllItems(); - - m_toolManager->SetEnvironment( m_Pcb, GetGalCanvas()->GetView(), - GetGalCanvas()->GetViewControls(), this ); - m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD ); + SetBoard( m_Pcb ); GetGalCanvas()->StartDrawing(); } @@ -824,97 +780,11 @@ bool PCB_EDIT_FRAME::IsMicroViaAcceptable() } -void PCB_EDIT_FRAME::SetHighContrastLayer( LAYER_ID aLayer ) -{ - // Set display settings for high contrast mode - KIGFX::VIEW* view = GetGalCanvas()->GetView(); - KIGFX::RENDER_SETTINGS* rSettings = view->GetPainter()->GetSettings(); - - SetTopLayer( aLayer ); - - rSettings->ClearActiveLayers(); - rSettings->SetActiveLayer( aLayer ); - - if( IsCopperLayer( aLayer ) ) - { - // Bring some other layers to the front in case of copper layers and make them colored - // fixme do not like the idea of storing the list of layers here, - // should be done in some other way I guess.. - LAYER_NUM layers[] = { - GetNetnameLayer( aLayer ), ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ), - ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ), - ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ), - ITEM_GAL_LAYER( GP_OVERLAY ), ITEM_GAL_LAYER( RATSNEST_VISIBLE ) - }; - - for( unsigned i = 0; i < DIM( layers ); ++i ) - rSettings->SetActiveLayer( layers[i] ); - - // Pads should be shown too - if( aLayer == B_Cu ) - { - rSettings->SetActiveLayer( ITEM_GAL_LAYER( PAD_BK_VISIBLE ) ); - rSettings->SetActiveLayer( NETNAMES_GAL_LAYER( PAD_BK_NETNAMES_VISIBLE ) ); - } - else if( aLayer == F_Cu ) - { - rSettings->SetActiveLayer( ITEM_GAL_LAYER( PAD_FR_VISIBLE ) ); - rSettings->SetActiveLayer( NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE ) ); - } - } - - view->UpdateAllLayersColor(); -} - - -void PCB_EDIT_FRAME::SetTopLayer( LAYER_ID aLayer ) -{ - // Set display settings for high contrast mode - KIGFX::VIEW* view = GetGalCanvas()->GetView(); - - view->ClearTopLayers(); - view->SetTopLayer( aLayer ); - - if( IsCopperLayer( aLayer ) ) - { - // Bring some other layers to the front in case of copper layers and make them colored - // fixme do not like the idea of storing the list of layers here, - // should be done in some other way I guess.. - LAYER_NUM layers[] = { - GetNetnameLayer( aLayer ), ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ), - ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ), - ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ), - ITEM_GAL_LAYER( GP_OVERLAY ), ITEM_GAL_LAYER( RATSNEST_VISIBLE ), Dwgs_User, - ITEM_GAL_LAYER( DRC_VISIBLE ) - }; - - for( unsigned i = 0; i < DIM( layers ); ++i ) - { - view->SetTopLayer( layers[i] ); - } - - // Pads should be shown too - if( aLayer == B_Cu ) - { - view->SetTopLayer( ITEM_GAL_LAYER( PAD_BK_VISIBLE ) ); - view->SetTopLayer( NETNAMES_GAL_LAYER( PAD_BK_NETNAMES_VISIBLE ) ); - } - else if( aLayer == F_Cu ) - { - view->SetTopLayer( ITEM_GAL_LAYER( PAD_FR_VISIBLE ) ); - view->SetTopLayer( NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE ) ); - } - } - - view->UpdateAllLayersOrder(); -} - - void PCB_EDIT_FRAME::SetActiveLayer( LAYER_ID aLayer, bool doLayerWidgetUpdate ) { ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer = aLayer; - SetHighContrastLayer( aLayer ); + GetGalCanvas()->SetHighContrastLayer( aLayer ); if( doLayerWidgetUpdate ) syncLayerWidgetLayer(); diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index e1c7f90ab8..7416c14c17 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -578,7 +578,7 @@ void ROUTER_TOOL::performRouting() else if( evt->IsAction( &ACT_PlaceThroughVia ) ) { m_router->ToggleViaPlacement(); - frame->SetTopLayer( ToLAYER_ID( m_router->GetCurrentLayer() ) ); + frame->GetGalCanvas()->SetTopLayer( ToLAYER_ID( m_router->GetCurrentLayer() ) ); m_router->Move( m_endSnapPoint, m_endItem ); } else if( evt->IsAction( &ACT_SwitchPosture ) ) diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index db5d6900e8..d9d0147266 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -27,6 +27,7 @@ #include "common_actions.h" #include +#include #include #include #include @@ -1085,7 +1086,7 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) // Apply the selected settings zone = new ZONE_CONTAINER( m_board ); zoneInfo.ExportSetting( *zone ); - m_frame->SetTopLayer( zoneInfo.m_CurrentZone_Layer ); + m_frame->GetGalCanvas()->SetTopLayer( zoneInfo.m_CurrentZone_Layer ); // Add the first point zone->Outline()->Start( zoneInfo.m_CurrentZone_Layer, diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index 80cf1511d5..1eaf5da907 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -190,7 +190,7 @@ int PCBNEW_CONTROL::HighContrastMode( TOOL_EVENT& aEvent ) DisplayOpt.ContrastModeDisplay = !DisplayOpt.ContrastModeDisplay; settings->LoadDisplayOptions( DisplayOpt ); - m_frame->SetHighContrastLayer( m_frame->GetActiveLayer() ); + m_frame->GetGalCanvas()->SetHighContrastLayer( m_frame->GetActiveLayer() ); setTransitions(); From cabec6dbeb447cbcd4a278065febbe94fbd0c55a Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 10:57:32 +0200 Subject: [PATCH 003/123] Fixed switching between GAL canvases error. --- pcbnew/pcbframe.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 0add833fc1..272d951675 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -489,12 +489,15 @@ void PCB_EDIT_FRAME::SetBoard( BOARD* aBoard ) if( IsGalCanvasActive() ) { - static_cast( GetGalCanvas() )->DisplayBoard( aBoard ); + PCB_DRAW_PANEL_GAL* drawPanel = static_cast( GetGalCanvas() ); + + drawPanel->DisplayBoard( aBoard ); aBoard->GetRatsnest()->Recalculate(); // Prepare worksheet template - KIGFX::WORKSHEET_VIEWITEM* worksheet = new KIGFX::WORKSHEET_VIEWITEM( &aBoard->GetPageSettings(), - &aBoard->GetTitleBlock() ); + KIGFX::WORKSHEET_VIEWITEM* worksheet; + worksheet = new KIGFX::WORKSHEET_VIEWITEM( &aBoard->GetPageSettings(), + &aBoard->GetTitleBlock() ); worksheet->SetSheetName( std::string( GetScreenDesc().mb_str() ) ); BASE_SCREEN* screen = GetScreen(); @@ -506,13 +509,13 @@ void PCB_EDIT_FRAME::SetBoard( BOARD* aBoard ) } // PCB_DRAW_PANEL_GAL takes ownership of the worksheet - static_cast( GetGalCanvas() )->SetWorksheet( worksheet ); + drawPanel->SetWorksheet( worksheet ); // update the tool manager with the new board and its view. if( m_toolManager ) { - m_toolManager->SetEnvironment( aBoard, GetGalCanvas()->GetView(), - GetGalCanvas()->GetViewControls(), this ); + m_toolManager->SetEnvironment( aBoard, drawPanel->GetView(), + drawPanel->GetViewControls(), this ); m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD ); } } @@ -638,7 +641,7 @@ void PCB_EDIT_FRAME::UseGalCanvas( bool aEnable ) if( aEnable ) { SetBoard( m_Pcb ); - + GetGalCanvas()->GetView()->RecacheAllItems( true ); GetGalCanvas()->StartDrawing(); } } From b934b11a6022861cda6eb8ab1a0b91848ede7a65 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 10:57:32 +0200 Subject: [PATCH 004/123] Minor changes (removed an unnecessary event handler and two function calls that had no real influence). --- common/draw_panel_gal.cpp | 10 +--------- include/class_draw_panel_gal.h | 3 +-- pcbnew/pcbframe.cpp | 6 ------ 3 files changed, 2 insertions(+), 17 deletions(-) diff --git a/common/draw_panel_gal.cpp b/common/draw_panel_gal.cpp index 975d17c513..3b96ef58cf 100644 --- a/common/draw_panel_gal.cpp +++ b/common/draw_panel_gal.cpp @@ -81,7 +81,6 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin Connect( wxEVT_MIDDLE_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); Connect( wxEVT_MIDDLE_DCLICK, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); Connect( wxEVT_MOUSEWHEEL, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_CHAR_HOOK, wxEventHandler( EDA_DRAW_PANEL_GAL::skipEvent ) ); Connect( wxEVT_CHAR, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); Connect( wxEVT_ENTER_WINDOW, wxEventHandler( EDA_DRAW_PANEL_GAL::onEnter ), NULL, this ); Connect( KIGFX::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE, @@ -158,7 +157,7 @@ void EDA_DRAW_PANEL_GAL::onRefreshTimer( wxTimerEvent& aEvent ) } -void EDA_DRAW_PANEL_GAL::Refresh( bool eraseBackground, const wxRect* rect ) +void EDA_DRAW_PANEL_GAL::Refresh( bool aEraseBackground, const wxRect* aRect ) { if( m_pendingRefresh ) return; @@ -279,10 +278,3 @@ void EDA_DRAW_PANEL_GAL::onEnter( wxEvent& aEvent ) // Getting focus is necessary in order to receive key events properly SetFocus(); } - - -void EDA_DRAW_PANEL_GAL::skipEvent( wxEvent& aEvent ) -{ - // This is necessary for CHAR_HOOK event to generate KEY_UP and KEY_DOWN events - aEvent.Skip(); -} diff --git a/include/class_draw_panel_gal.h b/include/class_draw_panel_gal.h index b698c91e1e..bed6af0890 100644 --- a/include/class_draw_panel_gal.h +++ b/include/class_draw_panel_gal.h @@ -108,7 +108,7 @@ public: } /// @copydoc wxWindow::Refresh() - void Refresh( bool eraseBackground = true, const wxRect* rect = NULL ); + void Refresh( bool aEraseBackground = true, const wxRect* aRect = NULL ); /** * Function SetEventDispatcher() @@ -151,7 +151,6 @@ protected: void onEvent( wxEvent& aEvent ); void onEnter( wxEvent& aEvent ); void onRefreshTimer ( wxTimerEvent& aEvent ); - void skipEvent( wxEvent& aEvent ); static const int MinRefreshPeriod = 17; ///< 60 FPS. diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 272d951675..4b61ec562a 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -334,12 +334,6 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : SetGalCanvas( new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), m_FrameSize, PCB_DRAW_PANEL_GAL::GAL_TYPE_CAIRO ) ); - // GAL should not be active yet - GetGalCanvas()->StopDrawing(); - - // Hide by default, it has to be explicitly shown - GetGalCanvas()->Hide(); - SetBoard( new BOARD() ); // Create the PCB_LAYER_WIDGET *after* SetBoard(): From 3544d30b54db107b82ababda35b022f3f588c2e3 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:22:42 +0200 Subject: [PATCH 005/123] Initial version of GAL-based module viewer in pcbnew. --- pcbnew/class_module.cpp | 8 +++++-- pcbnew/modview_frame.cpp | 43 +++++++++++++++++++++++++++++++++++ pcbnew/modview_frame.h | 3 +++ pcbnew/pcb_draw_panel_gal.cpp | 12 ++++++++-- pcbnew/pcb_draw_panel_gal.h | 8 +++++++ 5 files changed, 70 insertions(+), 4 deletions(-) diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index 0e3f015d39..bc01aa1bcb 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -448,8 +448,12 @@ const EDA_RECT MODULE::GetBoundingBox() const // Add the Clearance shape size: (shape around the pads when the // clearance is shown. Not optimized, but the draw cost is small // (perhaps smaller than optimization). - int biggest_clearance = GetBoard()->GetDesignSettings().GetBiggestClearanceValue(); - area.Inflate( biggest_clearance ); + BOARD* board = GetBoard(); + if( board ) + { + int biggest_clearance = board->GetDesignSettings().GetBiggestClearanceValue(); + area.Inflate( biggest_clearance ); + } return area; } diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp index 1f80fe663e..9a762e5377 100644 --- a/pcbnew/modview_frame.cpp +++ b/pcbnew/modview_frame.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include <3d_viewer.h> #include @@ -54,6 +55,8 @@ #include #include +#include + #define NEXT_PART 1 #define NEW_PART 0 @@ -141,7 +144,14 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent m_footprintList = new wxListBox( this, ID_MODVIEW_FOOTPRINT_LIST, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_HSCROLL ); + // Create GAL canvas + EDA_DRAW_FRAME* drawFrame = static_cast( aParent ); + PCB_DRAW_PANEL_GAL* drawPanel = new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), m_FrameSize, + drawFrame->GetGalCanvas()->GetBackend() ); + SetGalCanvas( drawPanel ); + SetBoard( new BOARD() ); + drawPanel->DisplayBoard( m_Pcb ); // Ensure all layers and items are visible: GetBoard()->SetVisibleAlls(); @@ -207,6 +217,8 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent // Manage the draw panel, right pane. m_auimgr.AddPane( m_canvas, wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() ); + m_auimgr.AddPane( (wxWindow*) GetGalCanvas(), + wxAuiPaneInfo().Name( wxT( "DrawFrameGal" ) ).CentrePane().Hide() ); // Manage the message panel, bottom pane. m_auimgr.AddPane( m_messagePanel, @@ -244,6 +256,8 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent #endif Show( true ); + + UseGalCanvas( drawFrame->IsGalCanvasActive() ); } @@ -421,6 +435,22 @@ void FOOTPRINT_VIEWER_FRAME::ClickOnFootprintList( wxCommandEvent& event ) } UpdateTitle(); + + if( IsGalCanvasActive() ) + { + KIGFX::VIEW* view = GetGalCanvas()->GetView(); + view->Clear(); + + // Load modules and its additional elements + for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() ) + { + module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) ); + view->Add( module ); + } + +// view->Add( loadFootprint( id ) ); + } + Zoom_Automatique( false ); m_canvas->Refresh(); Update3D_Frame(); @@ -827,3 +857,16 @@ void FOOTPRINT_VIEWER_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg ) if( module ) SetMsgPanel( module ); } + + +void FOOTPRINT_VIEWER_FRAME::UseGalCanvas( bool aEnable ) +{ + EDA_DRAW_FRAME::UseGalCanvas( aEnable ); + + if( aEnable ) + { + SetBoard( m_Pcb ); + + GetGalCanvas()->StartDrawing(); + } +} diff --git a/pcbnew/modview_frame.h b/pcbnew/modview_frame.h index aaa04afaf7..0301cfd52f 100644 --- a/pcbnew/modview_frame.h +++ b/pcbnew/modview_frame.h @@ -170,6 +170,9 @@ private: void SaveCopyInUndoList( BOARD_ITEM*, UNDO_REDO_T, const wxPoint& ) {} void SaveCopyInUndoList( const PICKED_ITEMS_LIST&, UNDO_REDO_T, const wxPoint &) {} + ///> @copydoc EDA_DRAW_FRAME::UseGalCanvas() + virtual void UseGalCanvas( bool aEnable ); + DECLARE_EVENT_TABLE() }; diff --git a/pcbnew/pcb_draw_panel_gal.cpp b/pcbnew/pcb_draw_panel_gal.cpp index 778570b1e5..2c60634453 100644 --- a/pcbnew/pcb_draw_panel_gal.cpp +++ b/pcbnew/pcb_draw_panel_gal.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -210,8 +211,7 @@ void PCB_DRAW_PANEL_GAL::DisplayBoard( const BOARD* aBoard ) m_ratsnest = new KIGFX::RATSNEST_VIEWITEM( aBoard->GetRatsnest() ); m_view->Add( m_ratsnest ); - // Load layer color setup from PCB data - static_cast( m_view->GetPainter()->GetSettings() )->ImportLegacyColors( aBoard->GetColorsSettings() ); + UseColorScheme( aBoard->GetColorsSettings() ); m_view->RecacheAllItems( true ); } @@ -233,6 +233,14 @@ void PCB_DRAW_PANEL_GAL::SetWorksheet( KIGFX::WORKSHEET_VIEWITEM* aWorksheet ) } +void PCB_DRAW_PANEL_GAL::UseColorScheme( const COLORS_DESIGN_SETTINGS* aSettings ) +{ + KIGFX::PCB_RENDER_SETTINGS* rs; + rs = static_cast( m_view->GetPainter()->GetSettings() ); + rs->ImportLegacyColors( aSettings ); +} + + void PCB_DRAW_PANEL_GAL::SetHighContrastLayer( LAYER_ID aLayer ) { // Set display settings for high contrast mode diff --git a/pcbnew/pcb_draw_panel_gal.h b/pcbnew/pcb_draw_panel_gal.h index 9682b21f13..fa32cde04a 100644 --- a/pcbnew/pcb_draw_panel_gal.h +++ b/pcbnew/pcb_draw_panel_gal.h @@ -32,6 +32,7 @@ namespace KIGFX class WORKSHEET_VIEWITEM; class RATSNEST_VIEWITEM; } +class COLORS_DESIGN_SETTINGS; class PCB_DRAW_PANEL_GAL : public EDA_DRAW_PANEL_GAL { @@ -56,6 +57,13 @@ public: */ void SetWorksheet( KIGFX::WORKSHEET_VIEWITEM* aWorksheet ); + /** + * Function UseColorScheme + * Applies layer color settings. + * @param aSettings are the new settings. + */ + void UseColorScheme( const COLORS_DESIGN_SETTINGS* aSettings ); + ///> @copydoc EDA_DRAW_PANEL_GAL::SetHighContrastLayer() virtual void SetHighContrastLayer( LAYER_ID aLayer ); From cbfe3d0b6ee8f9f43c22bd8a16a0724fa1d5343b Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:22:42 +0200 Subject: [PATCH 006/123] Fixed VIEW::SetViewport(). --- common/view/view.cpp | 18 +++++++----------- pcbnew/class_pad.cpp | 2 +- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/common/view/view.cpp b/common/view/view.cpp index f877164c5b..44d808e4ed 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -252,9 +252,7 @@ void VIEW::SetGAL( GAL* aGal ) clearGroupCache(); // every target has to be refreshed - MarkTargetDirty( TARGET_CACHED ); - MarkTargetDirty( TARGET_NONCACHED ); - MarkTargetDirty( TARGET_OVERLAY ); + MarkDirty(); // force the new GAL to display the current viewport. SetCenter( m_center ); @@ -279,7 +277,7 @@ void VIEW::SetViewport( const BOX2D& aViewport, bool aKeepAspect ) VECTOR2D ssize = ToWorld( m_gal->GetScreenPixelSize(), false ); VECTOR2D centre = aViewport.Centre(); VECTOR2D vsize = aViewport.GetSize(); - double zoom = 1.0 / std::min( fabs( vsize.x / ssize.x ), fabs( vsize.y / ssize.y ) ); + double zoom = 1.0 / std::max( fabs( vsize.x / ssize.x ), fabs( vsize.y / ssize.y ) ); SetCenter( centre ); SetScale( GetScale() * zoom ); @@ -305,7 +303,7 @@ void VIEW::SetScale( double aScale, const VECTOR2D& aAnchor ) m_scale = aScale; // Redraw everything after the viewport has changed - MarkTargetDirty( TARGET_CACHED ); + MarkDirty(); } @@ -317,7 +315,7 @@ void VIEW::SetCenter( const VECTOR2D& aCenter ) m_gal->ComputeWorldScreenMatrix(); // Redraw everything after the viewport has changed - MarkTargetDirty( TARGET_CACHED ); + MarkDirty(); } @@ -574,7 +572,7 @@ struct VIEW::drawItem } VIEW* view; - int layer, layersCount, layers[VIEW_MAX_LAYERS]; + int layer, layers[VIEW_MAX_LAYERS]; }; @@ -734,9 +732,7 @@ void VIEW::ClearTargets() m_gal->ClearTarget( TARGET_NONCACHED ); m_gal->ClearTarget( TARGET_CACHED ); - MarkTargetDirty( TARGET_NONCACHED ); - MarkTargetDirty( TARGET_CACHED ); - MarkTargetDirty( TARGET_OVERLAY ); + MarkDirty(); } if( IsTargetDirty( TARGET_OVERLAY ) ) @@ -855,7 +851,7 @@ void VIEW::sortLayers() sort( m_orderedLayers.begin(), m_orderedLayers.end(), compareRenderingOrder ); - MarkTargetDirty( TARGET_CACHED ); + MarkDirty(); } diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index 36239b7be0..a65bd54784 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -924,7 +924,7 @@ void D_PAD::ViewGetLayers( int aLayers[], int& aCount ) const unsigned int D_PAD::ViewGetLOD( int aLayer ) const { - // Netnames and soldermasks will be shown only if zoom is appropriate + // Netnames will be shown only if zoom is appropriate if( IsNetnameLayer( aLayer ) ) { return ( 100000000 / std::max( m_Size.x, m_Size.y ) ); From a4ef6a37fe9ee6d26dfb021deca8eadd03966830 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:22:42 +0200 Subject: [PATCH 007/123] Added autozooming and display of the last chosen module for module viewer using GAL. --- pcbnew/modview_frame.cpp | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp index 9a762e5377..13134fe54f 100644 --- a/pcbnew/modview_frame.cpp +++ b/pcbnew/modview_frame.cpp @@ -151,7 +151,6 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent SetGalCanvas( drawPanel ); SetBoard( new BOARD() ); - drawPanel->DisplayBoard( m_Pcb ); // Ensure all layers and items are visible: GetBoard()->SetVisibleAlls(); @@ -178,6 +177,7 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent id.SetLibNickname( getCurNickname() ); id.SetFootprintName( getCurFootprintName() ); GetBoard()->Add( loadFootprint( id ) ); + drawPanel->DisplayBoard( m_Pcb ); } if( m_canvas ) @@ -438,17 +438,13 @@ void FOOTPRINT_VIEWER_FRAME::ClickOnFootprintList( wxCommandEvent& event ) if( IsGalCanvasActive() ) { - KIGFX::VIEW* view = GetGalCanvas()->GetView(); - view->Clear(); + static_cast( GetGalCanvas() )->DisplayBoard( m_Pcb ); - // Load modules and its additional elements - for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() ) - { - module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) ); - view->Add( module ); - } - -// view->Add( loadFootprint( id ) ); + // Autozoom + m_Pcb->ComputeBoundingBox( false ); + EDA_RECT boardBbox = m_Pcb->GetBoundingBox(); + GetGalCanvas()->GetView()->SetViewport( BOX2D( boardBbox.GetOrigin(), + boardBbox.GetSize() ) ); } Zoom_Automatique( false ); @@ -864,9 +860,5 @@ void FOOTPRINT_VIEWER_FRAME::UseGalCanvas( bool aEnable ) EDA_DRAW_FRAME::UseGalCanvas( aEnable ); if( aEnable ) - { - SetBoard( m_Pcb ); - GetGalCanvas()->StartDrawing(); - } } From 03f45022320c69777e908ae34c6de1945b0b2b83 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:22:42 +0200 Subject: [PATCH 008/123] Fixed toolbar buttons for zooming in GAL canvas. --- pcbnew/tools/pcbnew_control.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index 1eaf5da907..49d2629206 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -80,9 +80,9 @@ int PCBNEW_CONTROL::ZoomInOutCenter( TOOL_EVENT& aEvent ) KIGFX::VIEW* view = m_frame->GetGalCanvas()->GetView(); double zoomScale = 1.0; - if( aEvent.IsAction( &COMMON_ACTIONS::zoomIn ) ) + if( aEvent.IsAction( &COMMON_ACTIONS::zoomInCenter ) ) zoomScale = 1.3; - else if( aEvent.IsAction( &COMMON_ACTIONS::zoomOut ) ) + else if( aEvent.IsAction( &COMMON_ACTIONS::zoomOutCenter ) ) zoomScale = 0.7; view->SetScale( view->GetScale() * zoomScale ); From c416f5a1e5202d1ff16a977ba1932ed3ca10e8e0 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:22:42 +0200 Subject: [PATCH 009/123] Removed a redundant pointer to EDA_EDIT_FRAME. --- common/tool/tool_dispatcher.cpp | 10 +++++----- include/tool/tool_dispatcher.h | 5 +---- pcbnew/tools/pcb_tools.cpp | 2 +- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp index 4e66a1271c..89c09a16ec 100644 --- a/common/tool/tool_dispatcher.cpp +++ b/common/tool/tool_dispatcher.cpp @@ -88,8 +88,8 @@ struct TOOL_DISPATCHER::BUTTON_STATE }; -TOOL_DISPATCHER::TOOL_DISPATCHER( TOOL_MANAGER* aToolMgr, PCB_BASE_FRAME* aEditFrame ) : - m_toolMgr( aToolMgr ), m_editFrame( aEditFrame ) +TOOL_DISPATCHER::TOOL_DISPATCHER( TOOL_MANAGER* aToolMgr ) : + m_toolMgr( aToolMgr ) { m_buttons.push_back( new BUTTON_STATE( BUT_LEFT, wxEVT_LEFT_DOWN, wxEVT_LEFT_UP, wxEVT_LEFT_DCLICK ) ); @@ -118,7 +118,7 @@ void TOOL_DISPATCHER::ResetState() KIGFX::VIEW* TOOL_DISPATCHER::getView() { - return m_editFrame->GetGalCanvas()->GetView(); + return static_cast( m_toolMgr->GetEditFrame() )->GetGalCanvas()->GetView(); } @@ -229,7 +229,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) { motion = true; m_lastMousePos = pos; - m_editFrame->UpdateStatusBar(); + static_cast( m_toolMgr->GetEditFrame() )->UpdateStatusBar(); } for( unsigned int i = 0; i < m_buttons.size(); i++ ) @@ -245,7 +245,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) // TODO That's a big ugly workaround, somehow DRAWPANEL_GAL loses focus // after second LMB click and currently I have no means to do better debugging if( type == wxEVT_LEFT_UP ) - m_editFrame->GetGalCanvas()->SetFocus(); + static_cast( m_toolMgr->GetEditFrame() )->GetGalCanvas()->SetFocus(); #endif /* __APPLE__ */ } diff --git a/include/tool/tool_dispatcher.h b/include/tool/tool_dispatcher.h index 8ecd893db1..bea510bc0b 100644 --- a/include/tool/tool_dispatcher.h +++ b/include/tool/tool_dispatcher.h @@ -56,7 +56,7 @@ public: * @param aToolMgr: tool manager instance the events will be sent to * @param aEditFrame: the frame wx events come from */ - TOOL_DISPATCHER( TOOL_MANAGER* aToolMgr, PCB_BASE_FRAME* aEditFrame ); + TOOL_DISPATCHER( TOOL_MANAGER* aToolMgr ); virtual ~TOOL_DISPATCHER(); /** @@ -128,9 +128,6 @@ private: ///> Instance of tool manager that cooperates with the dispatcher. TOOL_MANAGER* m_toolMgr; - - ///> Instance of wxFrame that is the source of UI events. - PCB_BASE_FRAME* m_editFrame; }; #endif diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index eaefa97678..cde76c1591 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -47,7 +47,7 @@ void PCB_EDIT_FRAME::setupTools() { // Create the manager and dispatcher & route draw panel events to the dispatcher m_toolManager = new TOOL_MANAGER; - m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager, this ); + m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager ); GetGalCanvas()->SetEventDispatcher( m_toolDispatcher ); // Connect handlers to toolbar buttons From 7c812664f36170a3c2549f5e11cf64f5f0795db0 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:22:42 +0200 Subject: [PATCH 010/123] TOOL_ACTIONs are automagically registered by TOOL_MANAGER upon its construction. --- common/tool/action_manager.cpp | 11 ++--------- common/tool/tool_manager.cpp | 5 +++++ include/tool/tool_action.h | 15 --------------- pcbnew/tools/pcb_tools.cpp | 5 ----- 4 files changed, 7 insertions(+), 29 deletions(-) diff --git a/common/tool/action_manager.cpp b/common/tool/action_manager.cpp index 444143b0fb..b065cb2d55 100644 --- a/common/tool/action_manager.cpp +++ b/common/tool/action_manager.cpp @@ -44,8 +44,6 @@ ACTION_MANAGER::~ACTION_MANAGER() void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction ) { - // Check if the TOOL_ACTION was not registered before - assert( aAction->GetId() == -1 ); // TOOL_ACTIONs are supposed to be named [appName.]toolName.actionName (with dots between) // action name without specifying at least toolName is not valid assert( aAction->GetName().find( '.', 0 ) != std::string::npos ); @@ -54,15 +52,14 @@ void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction ) assert( m_actionNameIndex.find( aAction->m_name ) == m_actionNameIndex.end() ); assert( m_actionIdIndex.find( aAction->m_id ) == m_actionIdIndex.end() ); - aAction->setId( MakeActionId( aAction->m_name ) ); + if( aAction->m_id == -1 ) + aAction->m_id = MakeActionId( aAction->m_name ); m_actionNameIndex[aAction->m_name] = aAction; m_actionIdIndex[aAction->m_id] = aAction; if( aAction->HasHotKey() ) m_actionHotKeys[aAction->m_currentHotKey].push_back( aAction ); - - aAction->setActionMgr( this ); } @@ -71,10 +68,6 @@ void ACTION_MANAGER::UnregisterAction( TOOL_ACTION* aAction ) m_actionNameIndex.erase( aAction->m_name ); m_actionIdIndex.erase( aAction->m_id ); - // Indicate that the ACTION_MANAGER no longer care about the object - aAction->setActionMgr( NULL ); - aAction->setId( -1 ); - if( aAction->HasHotKey() ) { std::list& actions = m_actionHotKeys[aAction->m_currentHotKey]; diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index 605f8505b3..abfd66b566 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -99,6 +99,11 @@ TOOL_MANAGER::TOOL_MANAGER() : m_model( NULL ), m_view( NULL ), m_viewControls( NULL ), m_editFrame( NULL ) { m_actionMgr = new ACTION_MANAGER( this ); + + // Register known actions + std::list& actionList = GetActionList(); + BOOST_FOREACH( TOOL_ACTION* action, actionList ) + RegisterAction( action ); } diff --git a/include/tool/tool_action.h b/include/tool/tool_action.h index 4097fd2f7f..152cf52928 100644 --- a/include/tool/tool_action.h +++ b/include/tool/tool_action.h @@ -189,18 +189,6 @@ public: private: friend class ACTION_MANAGER; - /// Assigns an unique identifier. It is given by an instance of ACTION_MANAGER. - void setId( int aId ) - { - m_id = aId; - } - - /// Assigns ACTION_MANAGER object that handles the TOOL_ACTION. - void setActionMgr( ACTION_MANAGER* aManager ) - { - m_actionMgr = aManager; - } - /// Name of the action (convention is: app.[tool.]action.name) std::string m_name; @@ -225,9 +213,6 @@ private: /// Unique ID for fast matching. Assigned by ACTION_MANAGER. int m_id; - /// Action manager that handles this TOOL_ACTION. - ACTION_MANAGER* m_actionMgr; - /// Origin of the action // const TOOL_BASE* m_origin; diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index cde76c1591..df0fc1a4ab 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -60,11 +60,6 @@ void PCB_EDIT_FRAME::setupTools() wxCommandEventHandler( PCB_EDIT_FRAME::onGenericCommand ), NULL, this ); #endif - // Register actions - std::list& actionList = m_toolManager->GetActionList(); - BOOST_FOREACH( TOOL_ACTION* action, actionList ) - m_toolManager->RegisterAction( action ); - // Register tools m_toolManager->RegisterTool( new SELECTION_TOOL ); m_toolManager->RegisterTool( new ROUTER_TOOL ); From d3b2e50200de2ab394a784e9be5c3ef62304c356 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:22:42 +0200 Subject: [PATCH 011/123] Alternative approach to handling events and commands by TOOL_DISPATCHER. Event handlers are (dis)connected depending on the active view. TOOL_DISPATCHER inherits from wxEvtHandler, so now it receives events directly instead of being fed by external handlers. --- common/draw_panel_gal.cpp | 85 ++++++++++++++++++++------------- common/tool/tool_dispatcher.cpp | 2 + include/class_draw_panel_gal.h | 13 ++--- include/tool/tool_dispatcher.h | 4 +- include/wxPcbStruct.h | 2 +- pcbnew/pcbframe.cpp | 6 +++ pcbnew/tools/pcb_tools.cpp | 31 ++---------- 7 files changed, 73 insertions(+), 70 deletions(-) diff --git a/common/draw_panel_gal.cpp b/common/draw_panel_gal.cpp index 3b96ef58cf..e960accb9b 100644 --- a/common/draw_panel_gal.cpp +++ b/common/draw_panel_gal.cpp @@ -41,6 +41,8 @@ #include #include +#include + #ifdef __WXDEBUG__ #include #endif /* __WXDEBUG__ */ @@ -50,6 +52,7 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin GalType aGalType ) : wxWindow( aParentWindow, aWindowId, aPosition, aSize ) { + m_parent = aParentWindow; m_gal = NULL; m_backend = GAL_TYPE_NONE; m_view = NULL; @@ -67,24 +70,8 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin m_viewControls = new KIGFX::WX_VIEW_CONTROLS( m_view, this ); - Connect( wxEVT_SIZE, wxSizeEventHandler( EDA_DRAW_PANEL_GAL::onSize ), NULL, this ); - - /* Generic events for the Tool Dispatcher */ - Connect( wxEVT_MOTION, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_LEFT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_LEFT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_LEFT_DCLICK, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_RIGHT_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_RIGHT_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_RIGHT_DCLICK, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_MIDDLE_UP, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_MIDDLE_DOWN, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_MIDDLE_DCLICK, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_MOUSEWHEEL, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_CHAR, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); - Connect( wxEVT_ENTER_WINDOW, wxEventHandler( EDA_DRAW_PANEL_GAL::onEnter ), NULL, this ); - Connect( KIGFX::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE, - wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), NULL, this ); + Connect( wxEVT_SIZE, wxSizeEventHandler( EDA_DRAW_PANEL_GAL::onSize ), NULL, this ); + Connect( wxEVT_ENTER_WINDOW, wxEventHandler( EDA_DRAW_PANEL_GAL::onEnter ), NULL, this ); // Set up timer that prevents too frequent redraw commands m_refreshTimer.SetOwner( this ); @@ -180,6 +167,53 @@ void EDA_DRAW_PANEL_GAL::Refresh( bool aEraseBackground, const wxRect* aRect ) } +void EDA_DRAW_PANEL_GAL::SetEventDispatcher( TOOL_DISPATCHER* aEventDispatcher ) +{ + m_eventDispatcher = aEventDispatcher; + + const wxEventType events[] = + { + wxEVT_LEFT_UP, wxEVT_LEFT_DOWN, wxEVT_LEFT_DCLICK, + wxEVT_RIGHT_UP, wxEVT_RIGHT_DOWN, wxEVT_RIGHT_DCLICK, + wxEVT_MIDDLE_UP, wxEVT_MIDDLE_DOWN, wxEVT_MIDDLE_DCLICK, + wxEVT_MOTION, wxEVT_MOUSEWHEEL, wxEVT_CHAR, KIGFX::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE + }; + + const wxEventType commands[] = + { +#if wxCHECK_VERSION( 3, 0, 0 ) + wxEVT_TOOL +#else + wxEVT_COMMAND_MENU_SELECTED, wxEVT_COMMAND_TOOL_CLICKED +#endif + }; + + if( m_eventDispatcher ) + { + BOOST_FOREACH( wxEventType eventType, events ) + Connect( eventType, wxEventHandler( TOOL_DISPATCHER::DispatchWxEvent ), + NULL, m_eventDispatcher ); + + BOOST_FOREACH( wxEventType eventType, commands ) + m_parent->Connect( eventType, + wxCommandEventHandler( TOOL_DISPATCHER::DispatchWxCommand ), + NULL, m_eventDispatcher ); + } + else + { + // While loops are used to be sure, that we are removing all event handlers + BOOST_FOREACH( wxEventType eventType, events ) + while( Disconnect( eventType, wxEventHandler( TOOL_DISPATCHER::DispatchWxEvent ), + NULL, m_eventDispatcher ) ); + + BOOST_FOREACH( wxEventType eventType, commands ) + while( m_parent->Disconnect( eventType, + wxCommandEventHandler( TOOL_DISPATCHER::DispatchWxCommand ), + NULL, m_eventDispatcher ) ); + } +} + + void EDA_DRAW_PANEL_GAL::StartDrawing() { m_pendingRefresh = false; @@ -258,21 +292,6 @@ void EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType ) } -void EDA_DRAW_PANEL_GAL::onEvent( wxEvent& aEvent ) -{ - if( !m_eventDispatcher ) - { - aEvent.Skip(); - } - else - { - m_eventDispatcher->DispatchWxEvent( aEvent ); - } - - Refresh(); -} - - void EDA_DRAW_PANEL_GAL::onEnter( wxEvent& aEvent ) { // Getting focus is necessary in order to receive key events properly diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp index 89c09a16ec..7a3320460b 100644 --- a/common/tool/tool_dispatcher.cpp +++ b/common/tool/tool_dispatcher.cpp @@ -281,6 +281,8 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) if( evt ) m_toolMgr->ProcessEvent( *evt ); + static_cast( m_toolMgr->GetEditFrame() )->GetGalCanvas()->Refresh(); + // pass the event to the GUI, it might still be interested in it aEvent.Skip(); } diff --git a/include/class_draw_panel_gal.h b/include/class_draw_panel_gal.h index bed6af0890..66793adf04 100644 --- a/include/class_draw_panel_gal.h +++ b/include/class_draw_panel_gal.h @@ -114,11 +114,10 @@ public: * Function SetEventDispatcher() * Sets a dispatcher that processes events and forwards them to tools. * @param aEventDispatcher is the object that will be used for dispatching events. + * DRAW_PANEL_GAL does not take over the ownership. Passing NULL disconnects all event + * handlers from the DRAW_PANEL_GAL and parent frame. */ - void SetEventDispatcher( TOOL_DISPATCHER* aEventDispatcher ) - { - m_eventDispatcher = aEventDispatcher; - } + void SetEventDispatcher( TOOL_DISPATCHER* aEventDispatcher ); /** * Function StartDrawing() @@ -148,12 +147,14 @@ public: protected: void onPaint( wxPaintEvent& WXUNUSED( aEvent ) ); void onSize( wxSizeEvent& aEvent ); - void onEvent( wxEvent& aEvent ); void onEnter( wxEvent& aEvent ); - void onRefreshTimer ( wxTimerEvent& aEvent ); + void onRefreshTimer( wxTimerEvent& aEvent ); static const int MinRefreshPeriod = 17; ///< 60 FPS. + /// Pointer to the parent window + wxWindow* m_parent; + /// Last timestamp when the panel was refreshed wxLongLong m_lastRefresh; diff --git a/include/tool/tool_dispatcher.h b/include/tool/tool_dispatcher.h index bea510bc0b..8a7289e56c 100644 --- a/include/tool/tool_dispatcher.h +++ b/include/tool/tool_dispatcher.h @@ -26,7 +26,7 @@ #define __TOOL_DISPATCHER_H #include - +#include #include class TOOL_MANAGER; @@ -47,7 +47,7 @@ class VIEW; * - issues TOOL_EVENTS to the tool manager */ -class TOOL_DISPATCHER +class TOOL_DISPATCHER : public wxEvtHandler { public: /** diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 3cba461273..4620fc2767 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -120,9 +120,9 @@ protected: bool m_useCmpFileForFpNames; ///< is true, use the .cmp file from CvPcb, else use the netlist // to know the footprint name of components. + // Functions that handle the Tool Framework (de)initalization void setupTools(); void destroyTools(); - void onGenericCommand( wxCommandEvent& aEvent ); // we'll use lower case function names for private member functions. void createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu* aPopMenu ); diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 4b61ec562a..66f939663d 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -636,8 +636,14 @@ void PCB_EDIT_FRAME::UseGalCanvas( bool aEnable ) { SetBoard( m_Pcb ); GetGalCanvas()->GetView()->RecacheAllItems( true ); + GetGalCanvas()->SetEventDispatcher( m_toolDispatcher ); GetGalCanvas()->StartDrawing(); } + else + { + // Redirect all events to the legacy canvas + GetGalCanvas()->SetEventDispatcher( NULL ); + } } diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index df0fc1a4ab..83fda666db 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -22,10 +22,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include -#include -#include - #include #include @@ -33,7 +29,7 @@ #include #include -#include +//#include #include "selection_tool.h" #include "edit_tool.h" @@ -47,18 +43,9 @@ void PCB_EDIT_FRAME::setupTools() { // Create the manager and dispatcher & route draw panel events to the dispatcher m_toolManager = new TOOL_MANAGER; + m_toolManager->SetEnvironment( NULL, GetGalCanvas()->GetView(), + GetGalCanvas()->GetViewControls(), this ); m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager ); - GetGalCanvas()->SetEventDispatcher( m_toolDispatcher ); - - // Connect handlers to toolbar buttons -#if wxCHECK_VERSION( 3, 0, 0 ) - Connect( wxEVT_TOOL, wxCommandEventHandler( PCB_EDIT_FRAME::onGenericCommand ), NULL, this ); -#else - Connect( wxEVT_COMMAND_MENU_SELECTED, - wxCommandEventHandler( PCB_EDIT_FRAME::onGenericCommand ), NULL, this ); - Connect( wxEVT_COMMAND_TOOL_CLICKED, - wxCommandEventHandler( PCB_EDIT_FRAME::onGenericCommand ), NULL, this ); -#endif // Register tools m_toolManager->RegisterTool( new SELECTION_TOOL ); @@ -67,9 +54,6 @@ void PCB_EDIT_FRAME::setupTools() m_toolManager->RegisterTool( new DRAWING_TOOL ); m_toolManager->RegisterTool( new POINT_EDITOR ); m_toolManager->RegisterTool( new PCBNEW_CONTROL ); - - m_toolManager->SetEnvironment( NULL, GetGalCanvas()->GetView(), - GetGalCanvas()->GetViewControls(), this ); m_toolManager->ResetTools( TOOL_BASE::RUN ); // Run the selection tool, it is supposed to be always active @@ -82,12 +66,3 @@ void PCB_EDIT_FRAME::destroyTools() delete m_toolManager; delete m_toolDispatcher; } - - -void PCB_EDIT_FRAME::onGenericCommand( wxCommandEvent& aEvent ) -{ - if( IsGalCanvasActive() ) - m_toolDispatcher->DispatchWxCommand( aEvent ); - else - aEvent.Skip(); -} From a7807c4ee16f0d1f30c2cd22acbc32561af3db8f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:22:42 +0200 Subject: [PATCH 012/123] Rework to support multiple views with OpenGL GAL canvas. --- common/gal/opengl/opengl_compositor.cpp | 67 ++++++++++++------------- common/gal/opengl/opengl_gal.cpp | 29 +++++------ common/gal/opengl/vertex_container.cpp | 7 ++- common/view/view.cpp | 2 +- include/gal/opengl/opengl_compositor.h | 15 +++--- include/gal/opengl/opengl_gal.h | 14 +----- include/gal/opengl/vertex_container.h | 2 +- 7 files changed, 62 insertions(+), 74 deletions(-) diff --git a/common/gal/opengl/opengl_compositor.cpp b/common/gal/opengl/opengl_compositor.cpp index 3a6721e5c9..2843204d78 100644 --- a/common/gal/opengl/opengl_compositor.cpp +++ b/common/gal/opengl/opengl_compositor.cpp @@ -35,7 +35,7 @@ using namespace KIGFX; OPENGL_COMPOSITOR::OPENGL_COMPOSITOR() : - m_initialized( false ), m_current( 0 ) + m_initialized( false ), m_current( 0 ), m_currentFbo( DIRECT_RENDERING ) { } @@ -52,9 +52,6 @@ void OPENGL_COMPOSITOR::Initialize() if( m_initialized ) return; - // Get the maximum number of buffers - glGetIntegerv( GL_MAX_COLOR_ATTACHMENTS, (GLint*) &m_maxBuffers ); - // We need framebuffer objects for drawing the screen contents // Generate framebuffer and a depth buffer glGenFramebuffersEXT( 1, &m_framebuffer ); @@ -68,15 +65,13 @@ void OPENGL_COMPOSITOR::Initialize() // Use here a size of 24 bits for the depth buffer, 8 bits for the stencil buffer // this is required later for anti-aliasing - glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL, m_width, m_height ); + glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, m_width, m_height ); glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER_EXT, m_depthBuffer ); - glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT, - GL_RENDERBUFFER_EXT, m_depthBuffer ); + GL_RENDERBUFFER_EXT, m_depthBuffer ); // Unbind the framebuffer, so by default all the rendering goes directly to the display glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, DIRECT_RENDERING ); - m_currentFbo = 0; + m_currentFbo = DIRECT_RENDERING; m_initialized = true; } @@ -96,9 +91,14 @@ unsigned int OPENGL_COMPOSITOR::CreateBuffer() { wxASSERT( m_initialized ); - if( usedBuffers() >= m_maxBuffers ) + unsigned int maxBuffers; + + // Get the maximum number of buffers + glGetIntegerv( GL_MAX_COLOR_ATTACHMENTS, (GLint*) &maxBuffers ); + + if( usedBuffers() >= maxBuffers ) { - DisplayError( NULL, wxT( "Cannot create more framebuffers. OpenGL rendering " + DisplayError( NULL, _( "Cannot create more framebuffers. OpenGL rendering " "backend requires at least 3 framebuffers. You may try to update/change " "your graphic drivers." ) ); return 0; // Unfortunately we have no more free buffers left @@ -114,7 +114,7 @@ unsigned int OPENGL_COMPOSITOR::CreateBuffer() // Set texture parameters glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); @@ -122,7 +122,8 @@ unsigned int OPENGL_COMPOSITOR::CreateBuffer() // Bind the texture to the specific attachment point, clear and rebind the screen glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_framebuffer ); m_currentFbo = m_framebuffer; - glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, attachmentPoint, GL_TEXTURE_2D, textureTarget, 0 ); + glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, attachmentPoint, + GL_TEXTURE_2D, textureTarget, 0 ); // Check the status, exit if the framebuffer can't be created GLenum status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT ); @@ -132,38 +133,38 @@ unsigned int OPENGL_COMPOSITOR::CreateBuffer() switch( status ) { case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: - DisplayError( NULL, wxT( "Cannot create the framebuffer." ) ); + DisplayError( NULL, _( "Cannot create the framebuffer." ) ); break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: - DisplayError( NULL, wxT( "The framebuffer attachment points are incomplete." ) ); + DisplayError( NULL, _( "The framebuffer attachment points are incomplete." ) ); break; case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: - DisplayError( NULL, wxT( "The framebuffer does not have at least " - "one image attached to it." ) ); + DisplayError( NULL, _( "The framebuffer does not have at least " + "one image attached to it." ) ); break; case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: - DisplayError( NULL, wxT( "The framebuffer read buffer is incomplete." ) ); + DisplayError( NULL, _( "The framebuffer read buffer is incomplete." ) ); break; case GL_FRAMEBUFFER_UNSUPPORTED_EXT: - DisplayError( NULL, wxT( "The combination of internal formats of the attached images " - "violates an implementation-dependent set of restrictions." ) ); + DisplayError( NULL, _( "The combination of internal formats of the attached images " + "violates an implementation-dependent set of restrictions." ) ); break; case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT: - DisplayError( NULL, wxT( "GL_RENDERBUFFER_SAMPLES is not the same " - "for all attached renderbuffers" ) ); + DisplayError( NULL, _( "GL_RENDERBUFFER_SAMPLES is not the same " + "for all attached renderbuffers" ) ); break; case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT: - DisplayError( NULL, wxT( "Framebuffer incomplete layer targets errors." ) ); + DisplayError( NULL, _( "Framebuffer incomplete layer targets errors." ) ); break; default: - DisplayError( NULL, wxT( "Cannot create the framebuffer." ) ); + DisplayError( NULL, _( "Cannot create the framebuffer." ) ); break; } @@ -192,7 +193,6 @@ void OPENGL_COMPOSITOR::SetBuffer( unsigned int aBufferHandle ) // Change the rendering destination to the selected attachment point if( aBufferHandle == DIRECT_RENDERING ) { - glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, DIRECT_RENDERING ); m_currentFbo = DIRECT_RENDERING; } else if( m_currentFbo != m_framebuffer ) @@ -221,12 +221,7 @@ void OPENGL_COMPOSITOR::ClearBuffer() void OPENGL_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle ) { wxASSERT( m_initialized ); - - if( aBufferHandle == 0 || aBufferHandle > usedBuffers() ) - { - DisplayError( NULL, wxT( "Wrong framebuffer handle" ) ); - return; - } + wxASSERT( aBufferHandle != 0 && aBufferHandle <= usedBuffers() ); // Switch to the main framebuffer and blit the scene glBindFramebufferEXT( GL_FRAMEBUFFER, DIRECT_RENDERING ); @@ -274,8 +269,8 @@ void OPENGL_COMPOSITOR::clean() { wxASSERT( m_initialized ); - glDeleteFramebuffersEXT( 1, &m_framebuffer ); - glDeleteRenderbuffersEXT( 1, &m_depthBuffer ); + glBindFramebufferEXT( GL_FRAMEBUFFER, DIRECT_RENDERING ); + m_currentFbo = DIRECT_RENDERING; OPENGL_BUFFERS::const_iterator it; @@ -286,8 +281,8 @@ void OPENGL_COMPOSITOR::clean() m_buffers.clear(); + glDeleteFramebuffersEXT( 1, &m_framebuffer ); + glDeleteRenderbuffersEXT( 1, &m_depthBuffer ); + m_initialized = false; } - - -GLuint OPENGL_COMPOSITOR::m_currentFbo = DIRECT_RENDERING; diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index 568772f96a..f7b7842a04 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -45,6 +45,8 @@ void InitTesselatorCallbacks( GLUtesselator* aTesselator ); const int glAttributes[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_DEPTH_SIZE, 16, 0 }; +wxGLContext* OPENGL_GAL::glContext = NULL; + OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, wxEvtHandler* aPaintListener, const wxString& aName ) : wxGLCanvas( aParent, wxID_ANY, (int*) glAttributes, wxDefaultPosition, wxDefaultSize, @@ -54,7 +56,9 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, overlayManager( false ) { // Create the OpenGL-Context - glContext = new wxGLContext( this ); + if( glContext == NULL ) + glContext = new wxGLContext( this ); + parentWindow = aParent; mouseListener = aMouseListener; paintListener = aPaintListener; @@ -113,8 +117,6 @@ OPENGL_GAL::~OPENGL_GAL() gluDeleteTess( tesselator ); ClearCache(); - - delete glContext; } @@ -122,23 +124,22 @@ void OPENGL_GAL::BeginDrawing() { SetCurrent( *glContext ); - clientDC = new wxClientDC( this ); + clientDC = new wxPaintDC( this ); // Initialize GLEW, FBOs & VBOs if( !isGlewInitialized ) initGlew(); + // Set up the view port + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glViewport( 0, 0, (GLsizei) screenSize.x, (GLsizei) screenSize.y ); + + // Create the screen transformation + glOrtho( 0, (GLint) screenSize.x, 0, (GLsizei) screenSize.y, -depthRange.x, -depthRange.y ); + if( !isFramebufferInitialized ) { - // Set up the view port - glMatrixMode( GL_PROJECTION ); - glLoadIdentity(); - glViewport( 0, 0, (GLsizei) screenSize.x, (GLsizei) screenSize.y ); - - // Create the screen transformation - glOrtho( 0, (GLint) screenSize.x, 0, (GLsizei) screenSize.y, - -depthRange.x, -depthRange.y ); - // Prepare rendering target buffers compositor.Initialize(); mainBuffer = compositor.CreateBuffer(); @@ -967,7 +968,7 @@ void OPENGL_GAL::initGlew() exit( 1 ); } - // Vertex buffer have to be supported + // Vertex buffer has to be supported if( !GLEW_ARB_vertex_buffer_object ) { DisplayError( parentWindow, wxT( "Vertex buffer objects are not supported!" ) ); diff --git a/common/gal/opengl/vertex_container.cpp b/common/gal/opengl/vertex_container.cpp index 82658e11ae..fa41ecb808 100644 --- a/common/gal/opengl/vertex_container.cpp +++ b/common/gal/opengl/vertex_container.cpp @@ -31,7 +31,8 @@ #include #include #include -#include +#include +#include using namespace KIGFX; @@ -45,9 +46,11 @@ VERTEX_CONTAINER* VERTEX_CONTAINER::MakeContainer( bool aCached ) VERTEX_CONTAINER::VERTEX_CONTAINER( unsigned int aSize ) : - m_freeSpace( aSize ), m_currentSize( aSize ), m_initialSize( aSize ), m_failed( false ) + m_freeSpace( aSize ), m_currentSize( aSize ), m_initialSize( aSize ), + m_failed( false ), m_dirty( true ) { m_vertices = static_cast( malloc( aSize * sizeof( VERTEX ) ) ); + memset( m_vertices, 0x00, aSize * sizeof( VERTEX ) ); } diff --git a/common/view/view.cpp b/common/view/view.cpp index 44d808e4ed..d4b20e9b42 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -1027,7 +1027,7 @@ struct VIEW::extentsVisitor { bool operator()( VIEW_ITEM* aItem ) { - if(first) + if( first ) extents = aItem->ViewBBox(); else extents.Merge ( aItem->ViewBBox() ); diff --git a/include/gal/opengl/opengl_compositor.h b/include/gal/opengl/opengl_compositor.h index 642a7f7bbc..c06add7d2e 100644 --- a/include/gal/opengl/opengl_compositor.h +++ b/include/gal/opengl/opengl_compositor.h @@ -80,18 +80,17 @@ protected: GLuint attachmentPoint; ///< Point to which an image from texture is attached } OPENGL_BUFFER; - bool m_initialized; ///< Initialization status flag - unsigned int m_current; ///< Currently used buffer handle - GLuint m_framebuffer; ///< Main FBO handle - GLuint m_depthBuffer; ///< Depth buffer handle - unsigned int m_maxBuffers; ///< Maximal amount of buffers + bool m_initialized; ///< Initialization status flag + unsigned int m_current; ///< Currently used buffer handle + GLuint m_framebuffer; ///< Main FBO handle + GLuint m_depthBuffer; ///< Depth buffer handle typedef std::deque OPENGL_BUFFERS; /// Stores information about initialized buffers - OPENGL_BUFFERS m_buffers; + OPENGL_BUFFERS m_buffers; /// Store the currently used FBO name in case there was more than one compositor used - static GLuint m_currentFbo; + GLuint m_currentFbo; /** * Function clean() @@ -100,7 +99,7 @@ protected: void clean(); /// Returns number of used buffers - unsigned int usedBuffers() + inline unsigned int usedBuffers() { return m_buffers.size(); } diff --git a/include/gal/opengl/opengl_gal.h b/include/gal/opengl/opengl_gal.h index 10c4fea54d..417cdd389e 100644 --- a/include/gal/opengl/opengl_gal.h +++ b/include/gal/opengl/opengl_gal.h @@ -37,22 +37,12 @@ #include #include -#include #include -#include -#include -#include -#include -#include #include #include #include -#include -#include -#include - #ifndef CALLBACK #define CALLBACK #endif @@ -262,8 +252,8 @@ private: static const int CIRCLE_POINTS = 64; ///< The number of points for circle approximation static const int CURVE_POINTS = 32; ///< The number of points for curve approximation - wxClientDC* clientDC; ///< Drawing context - wxGLContext* glContext; ///< OpenGL context of wxWidgets + wxPaintDC* clientDC; ///< Drawing context + static wxGLContext* glContext; ///< OpenGL context of wxWidgets wxWindow* parentWindow; ///< Parent window wxEvtHandler* mouseListener; wxEvtHandler* paintListener; diff --git a/include/gal/opengl/vertex_container.h b/include/gal/opengl/vertex_container.h index 50c8d7fec1..807731bb37 100644 --- a/include/gal/opengl/vertex_container.h +++ b/include/gal/opengl/vertex_container.h @@ -163,7 +163,7 @@ protected: * returns size of the reserved memory space. * @return Size of the reserved memory space (expressed as a number of vertices). */ - unsigned int reservedSpace() + inline unsigned int reservedSpace() { return m_currentSize - m_freeSpace; } From 2d44b7e3c2b20b35d529b685cf6849a322a79b2d Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:22:43 +0200 Subject: [PATCH 013/123] Reduced number of switched events, allowing to use VIEW_CONTROLS, even if there is no extra event dispatcher. --- common/draw_panel_gal.cpp | 86 +++++++++++++++++++++------------ common/tool/tool_dispatcher.cpp | 2 - include/class_draw_panel_gal.h | 1 + 3 files changed, 55 insertions(+), 34 deletions(-) diff --git a/common/draw_panel_gal.cpp b/common/draw_panel_gal.cpp index e960accb9b..4bf7835371 100644 --- a/common/draw_panel_gal.cpp +++ b/common/draw_panel_gal.cpp @@ -73,6 +73,20 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin Connect( wxEVT_SIZE, wxSizeEventHandler( EDA_DRAW_PANEL_GAL::onSize ), NULL, this ); Connect( wxEVT_ENTER_WINDOW, wxEventHandler( EDA_DRAW_PANEL_GAL::onEnter ), NULL, this ); + const wxEventType events[] = + { + wxEVT_LEFT_UP, wxEVT_LEFT_DOWN, wxEVT_LEFT_DCLICK, + wxEVT_RIGHT_UP, wxEVT_RIGHT_DOWN, wxEVT_RIGHT_DCLICK, + wxEVT_MIDDLE_UP, wxEVT_MIDDLE_DOWN, wxEVT_MIDDLE_DCLICK, + wxEVT_MOTION, wxEVT_MOUSEWHEEL, wxEVT_CHAR, KIGFX::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE + }; + + BOOST_FOREACH( wxEventType eventType, events ) + { + Connect( eventType, wxEventHandler( EDA_DRAW_PANEL_GAL::onEvent ), + NULL, m_eventDispatcher ); + } + // Set up timer that prevents too frequent redraw commands m_refreshTimer.SetOwner( this ); m_pendingRefresh = false; @@ -171,46 +185,43 @@ void EDA_DRAW_PANEL_GAL::SetEventDispatcher( TOOL_DISPATCHER* aEventDispatcher ) { m_eventDispatcher = aEventDispatcher; - const wxEventType events[] = - { - wxEVT_LEFT_UP, wxEVT_LEFT_DOWN, wxEVT_LEFT_DCLICK, - wxEVT_RIGHT_UP, wxEVT_RIGHT_DOWN, wxEVT_RIGHT_DCLICK, - wxEVT_MIDDLE_UP, wxEVT_MIDDLE_DOWN, wxEVT_MIDDLE_DCLICK, - wxEVT_MOTION, wxEVT_MOUSEWHEEL, wxEVT_CHAR, KIGFX::WX_VIEW_CONTROLS::EVT_REFRESH_MOUSE - }; - - const wxEventType commands[] = - { #if wxCHECK_VERSION( 3, 0, 0 ) - wxEVT_TOOL -#else - wxEVT_COMMAND_MENU_SELECTED, wxEVT_COMMAND_TOOL_CLICKED -#endif - }; - if( m_eventDispatcher ) { - BOOST_FOREACH( wxEventType eventType, events ) - Connect( eventType, wxEventHandler( TOOL_DISPATCHER::DispatchWxEvent ), - NULL, m_eventDispatcher ); - - BOOST_FOREACH( wxEventType eventType, commands ) - m_parent->Connect( eventType, - wxCommandEventHandler( TOOL_DISPATCHER::DispatchWxCommand ), - NULL, m_eventDispatcher ); + m_parent->Connect( wxEVT_TOOL, + wxCommandEventHandler( TOOL_DISPATCHER::DispatchWxCommand ), + NULL, m_eventDispatcher ); } else { // While loops are used to be sure, that we are removing all event handlers - BOOST_FOREACH( wxEventType eventType, events ) - while( Disconnect( eventType, wxEventHandler( TOOL_DISPATCHER::DispatchWxEvent ), - NULL, m_eventDispatcher ) ); - - BOOST_FOREACH( wxEventType eventType, commands ) - while( m_parent->Disconnect( eventType, - wxCommandEventHandler( TOOL_DISPATCHER::DispatchWxCommand ), - NULL, m_eventDispatcher ) ); + while( m_parent->Disconnect( wxEVT_TOOL, + wxCommandEventHandler( TOOL_DISPATCHER::DispatchWxCommand ), + NULL, m_eventDispatcher ) ); } +#else + if( m_eventDispatcher ) + { + m_parent->Connect( wxEVT_COMMAND_MENU_SELECTED, + wxCommandEventHandler( TOOL_DISPATCHER::DispatchWxCommand ), + NULL, m_eventDispatcher ); + + m_parent->Connect( wxEVT_COMMAND_TOOL_CLICKED, + wxCommandEventHandler( TOOL_DISPATCHER::DispatchWxCommand ), + NULL, m_eventDispatcher ); + } + else + { + // While loops are used to be sure, that we are removing all event handlers + while( m_parent->Disconnect( wxEVT_COMMAND_MENU_SELECTED, + wxCommandEventHandler( TOOL_DISPATCHER::DispatchWxCommand ), + NULL, m_eventDispatcher ) ); + + while( m_parent->Disconnect( wxEVT_COMMAND_TOOL_CLICKED, + wxCommandEventHandler( TOOL_DISPATCHER::DispatchWxCommand ), + NULL, m_eventDispatcher ) ); + } +#endif } @@ -292,6 +303,17 @@ void EDA_DRAW_PANEL_GAL::SwitchBackend( GalType aGalType ) } +void EDA_DRAW_PANEL_GAL::onEvent( wxEvent& aEvent ) +{ + if( !m_eventDispatcher ) + aEvent.Skip(); + else + m_eventDispatcher->DispatchWxEvent( aEvent ); + + Refresh(); +} + + void EDA_DRAW_PANEL_GAL::onEnter( wxEvent& aEvent ) { // Getting focus is necessary in order to receive key events properly diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp index 7a3320460b..89c09a16ec 100644 --- a/common/tool/tool_dispatcher.cpp +++ b/common/tool/tool_dispatcher.cpp @@ -281,8 +281,6 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) if( evt ) m_toolMgr->ProcessEvent( *evt ); - static_cast( m_toolMgr->GetEditFrame() )->GetGalCanvas()->Refresh(); - // pass the event to the GUI, it might still be interested in it aEvent.Skip(); } diff --git a/include/class_draw_panel_gal.h b/include/class_draw_panel_gal.h index 66793adf04..6d9dae1bba 100644 --- a/include/class_draw_panel_gal.h +++ b/include/class_draw_panel_gal.h @@ -147,6 +147,7 @@ public: protected: void onPaint( wxPaintEvent& WXUNUSED( aEvent ) ); void onSize( wxSizeEvent& aEvent ); + void onEvent( wxEvent& aEvent ); void onEnter( wxEvent& aEvent ); void onRefreshTimer( wxTimerEvent& aEvent ); From 47ce871043d27356128fa1bae5971f695ec72298 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:22:43 +0200 Subject: [PATCH 014/123] FOOTPRINT_VIEWER_FRAME handles events from toolbar buttons and hot keys. --- pcbnew/modview_frame.cpp | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp index 13134fe54f..0a50ed6eb9 100644 --- a/pcbnew/modview_frame.cpp +++ b/pcbnew/modview_frame.cpp @@ -55,6 +55,11 @@ #include #include +#include +#include +#include "tools/pcbnew_control.h" +#include "tools/common_actions.h" + #include @@ -144,14 +149,6 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent m_footprintList = new wxListBox( this, ID_MODVIEW_FOOTPRINT_LIST, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_HSCROLL ); - // Create GAL canvas - EDA_DRAW_FRAME* drawFrame = static_cast( aParent ); - PCB_DRAW_PANEL_GAL* drawPanel = new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), m_FrameSize, - drawFrame->GetGalCanvas()->GetBackend() ); - SetGalCanvas( drawPanel ); - - SetBoard( new BOARD() ); - // Ensure all layers and items are visible: GetBoard()->SetVisibleAlls(); SetScreen( new PCB_SCREEN( GetPageSizeIU() ) ); @@ -169,6 +166,23 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent ReCreateLibraryList(); UpdateTitle(); + EDA_DRAW_FRAME* drawFrame = static_cast( aParent ); + + // Create GAL canvas + PCB_DRAW_PANEL_GAL* drawPanel = new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), m_FrameSize, + drawFrame->GetGalCanvas()->GetBackend() ); + SetGalCanvas( drawPanel ); + + // Create the manager and dispatcher & route draw panel events to the dispatcher + m_toolManager = new TOOL_MANAGER; + m_toolManager->SetEnvironment( GetBoard(), drawPanel->GetView(), + drawPanel->GetViewControls(), this ); + m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager ); + drawPanel->SetEventDispatcher( m_toolDispatcher ); + + m_toolManager->RegisterTool( new PCBNEW_CONTROL ); + m_toolManager->ResetTools( TOOL_BASE::RUN ); + // If a footprint was previously loaded, reload it if( getCurNickname().size() && getCurFootprintName().size() ) { @@ -277,6 +291,10 @@ const wxChar* FOOTPRINT_VIEWER_FRAME::GetFootprintViewerFrameName() void FOOTPRINT_VIEWER_FRAME::OnCloseWindow( wxCloseEvent& Event ) { DBG(printf( "%s:\n", __func__ );) + + if( IsGalCanvasActive() ) + GetGalCanvas()->StopDrawing(); + if( IsModal() ) { // Only dismiss a modal frame once, so that the return values set by From 3f173e4c5c531ec9c30e9c336aa5c16c79d05501 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:22:43 +0200 Subject: [PATCH 015/123] GAL view in pad properties dialog - initial version. --- common/view/view.cpp | 5 +- include/view/view.h | 5 +- pcbnew/dialogs/dialog_pad_properties.cpp | 50 +++++++++-- pcbnew/dialogs/dialog_pad_properties_base.cpp | 3 + pcbnew/dialogs/dialog_pad_properties_base.fbp | 85 +++++++++++++++++++ pcbnew/dialogs/dialog_pad_properties_base.h | 2 + 6 files changed, 141 insertions(+), 9 deletions(-) diff --git a/common/view/view.cpp b/common/view/view.cpp index d4b20e9b42..4fb2f7c75e 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -272,9 +272,12 @@ BOX2D VIEW::GetViewport() const } -void VIEW::SetViewport( const BOX2D& aViewport, bool aKeepAspect ) +void VIEW::SetViewport( const BOX2D& aViewport ) { VECTOR2D ssize = ToWorld( m_gal->GetScreenPixelSize(), false ); + + wxASSERT( ssize.x > 0 && ssize.y > 0 ); + VECTOR2D centre = aViewport.Centre(); VECTOR2D vsize = aViewport.GetSize(); double zoom = 1.0 / std::max( fabs( vsize.x / ssize.x ), fabs( vsize.y / ssize.y ) ); diff --git a/include/view/view.h b/include/view/view.h index 1857664af9..529f3c63ce 100644 --- a/include/view/view.h +++ b/include/view/view.h @@ -159,9 +159,8 @@ public: * Function SetViewport() * Sets the visible area of the VIEW. * @param aViewport: desired visible area, in world space coordinates. - * @param aKeepProportions: when true, the X/Y size proportions are kept. */ - void SetViewport( const BOX2D& aViewport, bool aKeepProportions = true ); + void SetViewport( const BOX2D& aViewport ); /** * Function GetViewport() @@ -201,7 +200,7 @@ public: * Function GetScale() * @return Current scalefactor of this VIEW */ - double GetScale() const + double GetScale() const { return m_scale; } diff --git a/pcbnew/dialogs/dialog_pad_properties.cpp b/pcbnew/dialogs/dialog_pad_properties.cpp index b962b670c0..de92b283a4 100644 --- a/pcbnew/dialogs/dialog_pad_properties.cpp +++ b/pcbnew/dialogs/dialog_pad_properties.cpp @@ -117,6 +117,8 @@ private: bool padValuesOK(); ///< test if all values are acceptable for the pad + void redraw(); + /** * Function setPadLayersList * updates the CheckBox states in pad layers list, @@ -174,6 +176,21 @@ DIALOG_PAD_PROPERTIES::DIALOG_PAD_PROPERTIES( PCB_BASE_FRAME* aParent, D_PAD* aP else // We are editing a "master" pad, i.e. a pad used to create new pads m_dummyPad->Copy( m_padMaster ); + if( m_parent->IsGalCanvasActive() ) + { + m_panelShowPadGal->UseColorScheme( m_board->GetColorsSettings() ); + m_panelShowPadGal->SwitchBackend( m_parent->GetGalCanvas()->GetBackend() ); + m_panelShowPad->Hide(); + m_panelShowPadGal->Show(); + m_panelShowPadGal->GetView()->Add( m_dummyPad ); + m_panelShowPadGal->StartDrawing(); + } + else + { + m_panelShowPad->Show(); + m_panelShowPadGal->Hide(); + } + initValues(); m_sdbSizer1OK->SetDefault(); @@ -537,7 +554,7 @@ void DIALOG_PAD_PROPERTIES::OnPadShapeSelection( wxCommandEvent& event ) } transferDataToPad( m_dummyPad ); - m_panelShowPad->Refresh(); + redraw(); } @@ -566,7 +583,7 @@ void DIALOG_PAD_PROPERTIES::OnDrillShapeSelected( wxCommandEvent& event ) } transferDataToPad( m_dummyPad ); - m_panelShowPad->Refresh(); + redraw(); } @@ -599,7 +616,7 @@ void DIALOG_PAD_PROPERTIES::PadOrientEvent( wxCommandEvent& event ) m_PadOrientCtrl->SetValue( msg ); transferDataToPad( m_dummyPad ); - m_panelShowPad->Refresh(); + redraw(); } @@ -667,7 +684,7 @@ void DIALOG_PAD_PROPERTIES::setPadLayersList( LSET layer_mask ) void DIALOG_PAD_PROPERTIES::OnSetLayers( wxCommandEvent& event ) { transferDataToPad( m_dummyPad ); - m_panelShowPad->Refresh(); + redraw(); } @@ -758,6 +775,29 @@ bool DIALOG_PAD_PROPERTIES::padValuesOK() } +void DIALOG_PAD_PROPERTIES::redraw() +{ + if( m_parent->IsGalCanvasActive() ) + { + m_dummyPad->ViewUpdate(); + + BOX2I bbox = m_dummyPad->ViewBBox(); + + // Autozoom + m_panelShowPadGal->GetView()->SetViewport( BOX2D( bbox.GetOrigin(), bbox.GetSize() ) ); + + // Add a margin + m_panelShowPadGal->GetView()->SetScale( m_panelShowPadGal->GetView()->GetScale() * 0.7 ); + + m_panelShowPadGal->Refresh(); + } + else + { + m_panelShowPad->Refresh(); + } +} + + void DIALOG_PAD_PROPERTIES::PadPropertiesAccept( wxCommandEvent& event ) { if( !padValuesOK() ) @@ -1132,7 +1172,7 @@ void DIALOG_PAD_PROPERTIES::OnValuesChanged( wxCommandEvent& event ) if( m_canUpdate ) { transferDataToPad( m_dummyPad ); - m_panelShowPad->Refresh(); + redraw(); } } diff --git a/pcbnew/dialogs/dialog_pad_properties_base.cpp b/pcbnew/dialogs/dialog_pad_properties_base.cpp index 6da97464e5..c7a62c1d54 100644 --- a/pcbnew/dialogs/dialog_pad_properties_base.cpp +++ b/pcbnew/dialogs/dialog_pad_properties_base.cpp @@ -536,6 +536,9 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind bSizerDisplayPad->Add( m_panelShowPad, 4, wxRIGHT|wxTOP|wxEXPAND, 5 ); + m_panelShowPadGal = new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), wxDefaultSize, EDA_DRAW_PANEL_GAL::GAL_TYPE_CAIRO ); + bSizerDisplayPad->Add( m_panelShowPadGal, 4, wxEXPAND|wxRIGHT|wxTOP, 5 ); + bSizerUpper->Add( bSizerDisplayPad, 1, wxEXPAND|wxTOP|wxBOTTOM, 5 ); diff --git a/pcbnew/dialogs/dialog_pad_properties_base.fbp b/pcbnew/dialogs/dialog_pad_properties_base.fbp index cb8df4557b..8696b831e5 100644 --- a/pcbnew/dialogs/dialog_pad_properties_base.fbp +++ b/pcbnew/dialogs/dialog_pad_properties_base.fbp @@ -8310,6 +8310,91 @@ + + 5 + wxEXPAND|wxRIGHT|wxTOP + 4 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + PCB_DRAW_PANEL_GAL + 1 + m_panelShowPadGal = new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), wxDefaultSize, EDA_DRAW_PANEL_GAL::GAL_TYPE_CAIRO ); + + 1 + PCB_DRAW_PANEL_GAL* m_panelShowPadGal; + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + #include <pcb_draw_panel_gal.h> + + 0 + + + 0 + + 1 + m_panelShowPadGal + 1 + + + protected + 1 + + Resizable + + 1 + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pcbnew/dialogs/dialog_pad_properties_base.h b/pcbnew/dialogs/dialog_pad_properties_base.h index 8a6ffd636d..1170f7bf20 100644 --- a/pcbnew/dialogs/dialog_pad_properties_base.h +++ b/pcbnew/dialogs/dialog_pad_properties_base.h @@ -30,6 +30,7 @@ class DIALOG_SHIM; #include #include #include +#include #include #include @@ -143,6 +144,7 @@ class DIALOG_PAD_PROPERTIES_BASE : public DIALOG_SHIM wxStaticText* m_ThermalGapUnits; wxStaticText* m_staticTextWarning; wxPanel* m_panelShowPad; + PCB_DRAW_PANEL_GAL* m_panelShowPadGal; wxStaticText* m_staticTextWarningPadFlipped; wxStdDialogButtonSizer* m_sdbSizer1; wxButton* m_sdbSizer1OK; From 677240cd2a93674b17beefcd337331ff75751d98 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:22:43 +0200 Subject: [PATCH 016/123] bugfix: pads edited with properties dialog were not refreshed. bugfix: changing track width/via size using the dropdown menu when custom size was enabled did not change anything. --- pcbnew/tools/edit_tool.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index db08a607a5..675d95dc39 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -270,6 +270,7 @@ int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) updateRatsnest( true ); getModel()->GetRatsnest()->Recalculate(); + item->ViewUpdate(); m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate ); } From 64e1e419c88e2166dc3df3e19fdd502a1fcafd7c Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:22:43 +0200 Subject: [PATCH 017/123] Next/previous footprint toolbar buttons are handled in the Module Viewer using GAL canvas. --- pcbnew/modview_frame.cpp | 33 ++++++++++++++++++++------------- pcbnew/modview_frame.h | 5 +++-- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp index 0a50ed6eb9..cd0622fd12 100644 --- a/pcbnew/modview_frame.cpp +++ b/pcbnew/modview_frame.cpp @@ -356,6 +356,15 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateLibraryList() } +void FOOTPRINT_VIEWER_FRAME::UseGalCanvas( bool aEnable ) +{ + EDA_DRAW_FRAME::UseGalCanvas( aEnable ); + + if( aEnable ) + GetGalCanvas()->StartDrawing(); +} + + void FOOTPRINT_VIEWER_FRAME::ReCreateFootprintList() { m_footprintList->Clear(); @@ -455,15 +464,7 @@ void FOOTPRINT_VIEWER_FRAME::ClickOnFootprintList( wxCommandEvent& event ) UpdateTitle(); if( IsGalCanvasActive() ) - { - static_cast( GetGalCanvas() )->DisplayBoard( m_Pcb ); - - // Autozoom - m_Pcb->ComputeBoundingBox( false ); - EDA_RECT boardBbox = m_Pcb->GetBoundingBox(); - GetGalCanvas()->GetView()->SetViewport( BOX2D( boardBbox.GetOrigin(), - boardBbox.GetSize() ) ); - } + redrawGal(); Zoom_Automatique( false ); m_canvas->Refresh(); @@ -846,8 +847,12 @@ void FOOTPRINT_VIEWER_FRAME::SelectAndViewFootprint( int aMode ) GetBoard()->Add( footprint, ADD_APPEND ); Update3D_Frame(); + + if( IsGalCanvasActive() ) + redrawGal(); } + UpdateTitle(); Zoom_Automatique( false ); m_canvas->Refresh(); @@ -873,10 +878,12 @@ void FOOTPRINT_VIEWER_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg ) } -void FOOTPRINT_VIEWER_FRAME::UseGalCanvas( bool aEnable ) +void FOOTPRINT_VIEWER_FRAME::redrawGal() { - EDA_DRAW_FRAME::UseGalCanvas( aEnable ); + static_cast( GetGalCanvas() )->DisplayBoard( m_Pcb ); - if( aEnable ) - GetGalCanvas()->StartDrawing(); + // Autozoom + m_Pcb->ComputeBoundingBox( false ); + EDA_RECT boardBbox = m_Pcb->GetBoundingBox(); + GetGalCanvas()->GetView()->SetViewport( BOX2D( boardBbox.GetOrigin(), boardBbox.GetSize() ) ); } diff --git a/pcbnew/modview_frame.h b/pcbnew/modview_frame.h index 0301cfd52f..4dd1210979 100644 --- a/pcbnew/modview_frame.h +++ b/pcbnew/modview_frame.h @@ -69,6 +69,8 @@ public: */ void ReCreateLibraryList(); + ///> @copydoc EDA_DRAW_FRAME::UseGalCanvas() + virtual void UseGalCanvas( bool aEnable ); private: @@ -170,8 +172,7 @@ private: void SaveCopyInUndoList( BOARD_ITEM*, UNDO_REDO_T, const wxPoint& ) {} void SaveCopyInUndoList( const PICKED_ITEMS_LIST&, UNDO_REDO_T, const wxPoint &) {} - ///> @copydoc EDA_DRAW_FRAME::UseGalCanvas() - virtual void UseGalCanvas( bool aEnable ); + void redrawGal(); DECLARE_EVENT_TABLE() }; From ac7345453819f62de0452d1cd384e9b2de415ee5 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:22:43 +0200 Subject: [PATCH 018/123] Grid offset is recomputed only when settings are changed. --- common/gal/graphics_abstraction_layer.cpp | 3 --- include/gal/graphics_abstraction_layer.h | 6 ++++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/common/gal/graphics_abstraction_layer.cpp b/common/gal/graphics_abstraction_layer.cpp index 821df4969f..00e976b19a 100644 --- a/common/gal/graphics_abstraction_layer.cpp +++ b/common/gal/graphics_abstraction_layer.cpp @@ -134,9 +134,6 @@ void GAL::DrawGrid() // Draw the grid // For the drawing the start points, end points and increments have // to be calculated in world coordinates - gridOffset = VECTOR2D( (long) gridOrigin.x % (long) gridSize.x, - (long) gridOrigin.y % (long) gridSize.y ); - VECTOR2D worldStartPoint = screenWorldMatrix * VECTOR2D( 0.0, 0.0 ); VECTOR2D worldEndPoint = screenWorldMatrix * VECTOR2D( screenSize ); diff --git a/include/gal/graphics_abstraction_layer.h b/include/gal/graphics_abstraction_layer.h index 24f207f355..f607e96975 100644 --- a/include/gal/graphics_abstraction_layer.h +++ b/include/gal/graphics_abstraction_layer.h @@ -631,6 +631,9 @@ public: inline void SetGridOrigin( const VECTOR2D& aGridOrigin ) { gridOrigin = aGridOrigin; + + gridOffset = VECTOR2D( (long) gridOrigin.x % (long) gridSize.x, + (long) gridOrigin.y % (long) gridSize.y ); } /** @@ -661,6 +664,9 @@ public: inline void SetGridSize( const VECTOR2D& aGridSize ) { gridSize = aGridSize; + + gridOffset = VECTOR2D( (long) gridOrigin.x % (long) gridSize.x, + (long) gridOrigin.y % (long) gridSize.y ); } /** From 936fc7658169f9426ea62a781c94f88e476cfc19 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:22:43 +0200 Subject: [PATCH 019/123] Code formatting and cleaning. --- common/view/view.cpp | 37 +++++++++++++++++++------------------ pcbnew/tools/pcb_tools.cpp | 1 - 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/common/view/view.cpp b/common/view/view.cpp index 4fb2f7c75e..981c8b0d31 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -1019,33 +1019,34 @@ void VIEW::UpdateItems() m_needsUpdate.clear(); } -struct VIEW::extentsVisitor { - BOX2I extents; - bool first; - extentsVisitor() - { - first = true; - } +struct VIEW::extentsVisitor +{ + BOX2I extents; + bool first; + + extentsVisitor() + { + first = true; + } + + bool operator()( VIEW_ITEM* aItem ) + { + if( first ) + extents = aItem->ViewBBox(); + else + extents.Merge ( aItem->ViewBBox() ); + return false; + } +}; - bool operator()( VIEW_ITEM* aItem ) - { - if( first ) - extents = aItem->ViewBBox(); - else - extents.Merge ( aItem->ViewBBox() ); - return false; - } - }; const BOX2I VIEW::CalculateExtents() { - extentsVisitor v; BOX2I fullScene; fullScene.SetMaximum(); - BOOST_FOREACH( VIEW_LAYER* l, m_orderedLayers ) { l->items->Query( fullScene, v ); diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index 83fda666db..ee8af05595 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -29,7 +29,6 @@ #include #include -//#include #include "selection_tool.h" #include "edit_tool.h" From 748f7386751ae9576362c79bbe8072a24c6501b0 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:22:43 +0200 Subject: [PATCH 020/123] Initial version of the GAL-based Module Editor. --- pcbnew/loadcmp.cpp | 10 +++++++++ pcbnew/modedit.cpp | 13 +++++++++++ pcbnew/module_editor_frame.h | 3 +++ pcbnew/moduleframe.cpp | 42 ++++++++++++++++++++++++++++++++++++ pcbnew/tools/edit_tool.cpp | 1 + 5 files changed, 69 insertions(+) diff --git a/pcbnew/loadcmp.cpp b/pcbnew/loadcmp.cpp index 02c0601e10..748b47917f 100644 --- a/pcbnew/loadcmp.cpp +++ b/pcbnew/loadcmp.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -117,6 +118,15 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule ) GetScreen()->ClrModify(); Zoom_Automatique( false ); + if( IsGalCanvasActive() ) + { + static_cast( GetGalCanvas() )->DisplayBoard( GetBoard() ); + + m_Pcb->ComputeBoundingBox( false ); + EDA_RECT boardBbox = m_Pcb->GetBoundingBox(); + GetGalCanvas()->GetView()->SetViewport( BOX2D( boardBbox.GetOrigin(), boardBbox.GetSize() ) ); + } + return true; } diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp index ed81bc7989..c3bae138a9 100644 --- a/pcbnew/modedit.cpp +++ b/pcbnew/modedit.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -914,3 +915,15 @@ EDA_COLOR_T FOOTPRINT_EDIT_FRAME::GetGridColor() const return g_ColorsSettings.GetItemColor( GRID_VISIBLE ); } + +void FOOTPRINT_EDIT_FRAME::UseGalCanvas( bool aEnable ) +{ + EDA_DRAW_FRAME::UseGalCanvas( aEnable ); + + if( aEnable ) + { + SetBoard( m_Pcb ); + + GetGalCanvas()->StartDrawing(); + } +} diff --git a/pcbnew/module_editor_frame.h b/pcbnew/module_editor_frame.h index 1e10a01b09..665349aad9 100644 --- a/pcbnew/module_editor_frame.h +++ b/pcbnew/module_editor_frame.h @@ -399,6 +399,9 @@ public: virtual EDA_COLOR_T GetGridColor() const; + ///> @copydoc EDA_DRAW_FRAME::UseGalCanvas() + virtual void UseGalCanvas( bool aEnable ); + DECLARE_EVENT_TABLE() protected: diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index d844321bdc..9cf223a256 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -52,6 +53,15 @@ #include #include +#include +#include +#include "tools/selection_tool.h" +#include "tools/edit_tool.h" +#include "tools/drawing_tool.h" +#include "tools/point_editor.h" +#include "tools/pcbnew_control.h" +#include "tools/common_actions.h" + BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME ) EVT_MENU_RANGE( ID_POPUP_PCB_ITEM_SELECTION_START, ID_POPUP_PCB_ITEM_SELECTION_END, @@ -167,6 +177,12 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : // Show a title (frame title + footprint name): updateTitle(); + // Create GAL canvas + EDA_DRAW_FRAME* drawFrame = static_cast( aParent ); + PCB_DRAW_PANEL_GAL* drawPanel = new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), m_FrameSize, + drawFrame->GetGalCanvas()->GetBackend() ); + SetGalCanvas( drawPanel ); + SetBoard( new BOARD() ); // restore the last footprint from the project, if any @@ -224,11 +240,37 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : m_auimgr.AddPane( m_canvas, wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() ); + m_auimgr.AddPane( (wxWindow*) GetGalCanvas(), + wxAuiPaneInfo().Name( wxT( "DrawFrameGal" ) ).CentrePane().Hide() ); m_auimgr.AddPane( m_messagePanel, wxAuiPaneInfo( mesg_pane ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(10) ); m_auimgr.Update(); + + if( drawFrame->IsGalCanvasActive() ) + { + drawPanel->DisplayBoard( GetBoard() ); + + // Create the manager and dispatcher & route draw panel events to the dispatcher + m_toolManager = new TOOL_MANAGER; + m_toolManager->SetEnvironment( GetBoard(), drawPanel->GetView(), + drawPanel->GetViewControls(), this ); + m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager ); + drawPanel->SetEventDispatcher( m_toolDispatcher ); + + m_toolManager->RegisterTool( new SELECTION_TOOL ); + m_toolManager->RegisterTool( new EDIT_TOOL ); + m_toolManager->RegisterTool( new DRAWING_TOOL ); + m_toolManager->RegisterTool( new POINT_EDITOR ); + m_toolManager->RegisterTool( new PCBNEW_CONTROL ); + m_toolManager->ResetTools( TOOL_BASE::RUN ); + + // Run the selection tool, it is supposed to be always active + m_toolManager->InvokeTool( "pcbnew.InteractiveSelection" ); + + UseGalCanvas( true ); + } } diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 675d95dc39..d2199f8a5d 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -545,6 +545,7 @@ void EDIT_TOOL::processChanges( const PICKED_ITEMS_LIST* aList ) switch( operation ) { case UR_CHANGED: + case UR_MODEDIT: updItem->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); break; From 27ca6c97cbcc10032b5f4a9e5912669bb22411f4 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:24:56 +0200 Subject: [PATCH 021/123] Moved layers visibility synchronization to PCB_DRAW_PANEL_GAL::SyncLayersVisibility(). --- pcbnew/pcb_draw_panel_gal.cpp | 25 +++++++++++++++++++++++++ pcbnew/pcb_draw_panel_gal.h | 7 +++++++ pcbnew/pcbframe.cpp | 24 +----------------------- 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/pcbnew/pcb_draw_panel_gal.cpp b/pcbnew/pcb_draw_panel_gal.cpp index 2c60634453..92293aaf24 100644 --- a/pcbnew/pcb_draw_panel_gal.cpp +++ b/pcbnew/pcb_draw_panel_gal.cpp @@ -321,3 +321,28 @@ void PCB_DRAW_PANEL_GAL::SetTopLayer( LAYER_ID aLayer ) m_view->UpdateAllLayersOrder(); } + + +void PCB_DRAW_PANEL_GAL::SyncLayersVisibility( const BOARD* aBoard ) +{ + // Load layer & elements visibility settings + for( LAYER_NUM i = 0; i < NB_LAYERS; ++i ) + { + m_view->SetLayerVisible( i, aBoard->IsLayerVisible( i ) ); + + // Synchronize netname layers as well + if( IsCopperLayer( i ) ) + m_view->SetLayerVisible( GetNetnameLayer( i ), aBoard->IsLayerVisible( i ) ); + } + + for( LAYER_NUM i = 0; i < END_PCB_VISIBLE_LIST; ++i ) + { + m_view->SetLayerVisible( ITEM_GAL_LAYER( i ), aBoard->IsElementVisible( i ) ); + } + + // Enable some layers that are GAL specific + m_view->SetLayerVisible( ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), true ); + m_view->SetLayerVisible( ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), true ); + m_view->SetLayerVisible( ITEM_GAL_LAYER( WORKSHEET ), true ); + m_view->SetLayerVisible( ITEM_GAL_LAYER( GP_OVERLAY ), true ); +} diff --git a/pcbnew/pcb_draw_panel_gal.h b/pcbnew/pcb_draw_panel_gal.h index fa32cde04a..26ac94f968 100644 --- a/pcbnew/pcb_draw_panel_gal.h +++ b/pcbnew/pcb_draw_panel_gal.h @@ -70,6 +70,13 @@ public: ///> @copydoc EDA_DRAW_PANEL_GAL::SetTopLayer() virtual void SetTopLayer( LAYER_ID aLayer ); + /** + * Function SyncLayersVisibility + * Updates "visibility" property of each layer of a given BOARD. + * @param aBoard contains layers visibility settings to be applied. + */ + void SyncLayersVisibility( const BOARD* aBoard ); + protected: ///> Currently used worksheet KIGFX::WORKSHEET_VIEWITEM* m_worksheet; diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 66f939663d..fdf24ad63f 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -813,29 +813,7 @@ void PCB_EDIT_FRAME::syncRenderStates() void PCB_EDIT_FRAME::syncLayerVisibilities() { m_Layers->SyncLayerVisibilities(); - - KIGFX::VIEW* view = GetGalCanvas()->GetView(); - - // Load layer & elements visibility settings - for( LAYER_NUM i = 0; i < LAYER_ID_COUNT; ++i ) - { - view->SetLayerVisible( i, m_Pcb->IsLayerVisible( LAYER_ID( i ) ) ); - - // Synchronize netname layers as well - if( IsCopperLayer( i ) ) - view->SetLayerVisible( GetNetnameLayer( i ), m_Pcb->IsLayerVisible( LAYER_ID( i ) ) ); - } - - for( LAYER_NUM i = 0; i < END_PCB_VISIBLE_LIST; ++i ) - { - view->SetLayerVisible( ITEM_GAL_LAYER( i ), m_Pcb->IsElementVisible( i ) ); - } - - // Enable some layers that are GAL specific - view->SetLayerVisible( ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), true ); - view->SetLayerVisible( ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), true ); - view->SetLayerVisible( ITEM_GAL_LAYER( WORKSHEET ), true ); - view->SetLayerVisible( ITEM_GAL_LAYER( GP_OVERLAY ), true ); + static_cast( GetGalCanvas() )->SyncLayersVisibility( m_Pcb ); } From d93ccff5344562cfda426f22a7ece2a1d6b7b470 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:50:27 +0200 Subject: [PATCH 022/123] {Set,Get}ActiveLayer moved from PCB_EDIT_FRAME to PCB_BASE_FRAME. --- include/wxBasePcbFrame.h | 18 ++++++++++++++++++ include/wxPcbStruct.h | 11 +---------- pcbnew/class_pcb_layer_widget.cpp | 2 +- pcbnew/module_editor_frame.h | 1 - pcbnew/pcb_draw_panel_gal.cpp | 6 +++--- pcbnew/pcbframe.cpp | 7 +++---- pcbnew/pcbnew_config.cpp | 2 +- pcbnew/tools/pcbnew_control.cpp | 4 ++-- 8 files changed, 29 insertions(+), 22 deletions(-) diff --git a/include/wxBasePcbFrame.h b/include/wxBasePcbFrame.h index e5ab27d1c0..ebc694a0f6 100644 --- a/include/wxBasePcbFrame.h +++ b/include/wxBasePcbFrame.h @@ -613,6 +613,24 @@ public: virtual void SwitchLayer( wxDC* DC, LAYER_ID layer ); + /** + * Function SetActiveLayer + * will change the currently active layer to \a aLayer. + */ + virtual void SetActiveLayer( LAYER_ID aLayer ) + { + ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer = aLayer; + } + + /** + * Function GetActiveLayer + * returns the active layer + */ + virtual LAYER_ID GetActiveLayer() const + { + return ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer; + } + void LoadSettings( wxConfigBase* aCfg ); // override virtual void SaveSettings( wxConfigBase* aCfg ); // override virtual diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 4620fc2767..33f2e0e6bb 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -536,16 +536,7 @@ public: * will change the currently active layer to \a aLayer and also * update the PCB_LAYER_WIDGET. */ - void SetActiveLayer( LAYER_ID aLayer, bool doLayerWidgetUpdate = true ); - - /** - * Function GetActiveLayer - * returns the active layer - */ - LAYER_ID GetActiveLayer() const - { - return ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer; - } + virtual void SetActiveLayer( LAYER_ID aLayer ); /** * Function IsElementVisible diff --git a/pcbnew/class_pcb_layer_widget.cpp b/pcbnew/class_pcb_layer_widget.cpp index b0e5910a76..172df49f64 100644 --- a/pcbnew/class_pcb_layer_widget.cpp +++ b/pcbnew/class_pcb_layer_widget.cpp @@ -373,7 +373,7 @@ bool PCB_LAYER_WIDGET::OnLayerSelect( int aLayer ) { // the layer change from the PCB_LAYER_WIDGET can be denied by returning // false from this function. - myframe->SetActiveLayer( ToLAYER_ID( aLayer ), false ); + myframe->SetActiveLayer( ToLAYER_ID( aLayer ) ); if( m_alwaysShowActiveCopperLayer ) OnLayerSelected(); diff --git a/pcbnew/module_editor_frame.h b/pcbnew/module_editor_frame.h index 665349aad9..c733e922e0 100644 --- a/pcbnew/module_editor_frame.h +++ b/pcbnew/module_editor_frame.h @@ -217,7 +217,6 @@ public: BOARD_ITEM* ModeditLocateAndDisplay( int aHotKeyCode = 0 ); /* Undo and redo functions */ -public: /** * Function SaveCopyInUndoList. diff --git a/pcbnew/pcb_draw_panel_gal.cpp b/pcbnew/pcb_draw_panel_gal.cpp index 92293aaf24..12965f3e03 100644 --- a/pcbnew/pcb_draw_panel_gal.cpp +++ b/pcbnew/pcb_draw_panel_gal.cpp @@ -326,13 +326,13 @@ void PCB_DRAW_PANEL_GAL::SetTopLayer( LAYER_ID aLayer ) void PCB_DRAW_PANEL_GAL::SyncLayersVisibility( const BOARD* aBoard ) { // Load layer & elements visibility settings - for( LAYER_NUM i = 0; i < NB_LAYERS; ++i ) + for( LAYER_NUM i = 0; i < LAYER_ID_COUNT; ++i ) { - m_view->SetLayerVisible( i, aBoard->IsLayerVisible( i ) ); + m_view->SetLayerVisible( i, aBoard->IsLayerVisible( LAYER_ID( i ) ) ); // Synchronize netname layers as well if( IsCopperLayer( i ) ) - m_view->SetLayerVisible( GetNetnameLayer( i ), aBoard->IsLayerVisible( i ) ); + m_view->SetLayerVisible( GetNetnameLayer( i ), aBoard->IsLayerVisible( LAYER_ID( i ) ) ); } for( LAYER_NUM i = 0; i < END_PCB_VISIBLE_LIST; ++i ) diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index fdf24ad63f..c07f28a8c4 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -783,14 +783,13 @@ bool PCB_EDIT_FRAME::IsMicroViaAcceptable() } -void PCB_EDIT_FRAME::SetActiveLayer( LAYER_ID aLayer, bool doLayerWidgetUpdate ) +void PCB_EDIT_FRAME::SetActiveLayer( LAYER_ID aLayer ) { - ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer = aLayer; + PCB_BASE_FRAME::SetActiveLayer( aLayer ); GetGalCanvas()->SetHighContrastLayer( aLayer ); - if( doLayerWidgetUpdate ) - syncLayerWidgetLayer(); + syncLayerWidgetLayer(); if( IsGalCanvasActive() ) GetGalCanvas()->Refresh(); diff --git a/pcbnew/pcbnew_config.cpp b/pcbnew/pcbnew_config.cpp index d8eda36868..963f9c4ba2 100644 --- a/pcbnew/pcbnew_config.cpp +++ b/pcbnew/pcbnew_config.cpp @@ -99,7 +99,7 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event ) if( !GetBoard()->GetEnabledLayers()[ cur_layer ] ) cur_layer = F_Cu; - SetActiveLayer( cur_layer, true ); + SetActiveLayer( cur_layer ); OnModify(); ReCreateLayerBox(); diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index 49d2629206..17b5b021aa 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -289,7 +289,7 @@ int PCBNEW_CONTROL::LayerInner6( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::LayerBottom( TOOL_EVENT& aEvent ) { - getEditFrame()->SetActiveLayer( B_Cu, true ); + getEditFrame()->SwitchLayer( NULL, B_Cu ); getEditFrame()->GetGalCanvas()->SetFocus(); setTransitions(); @@ -311,7 +311,7 @@ int PCBNEW_CONTROL::LayerNext( TOOL_EVENT& aEvent ) if( getModel()->GetCopperLayerCount() < 2 ) // Single layer layer = B_Cu; else if( layer >= getModel()->GetCopperLayerCount() - 2 ) - layer = B_Cu; + layer = F_Cu; else ++layer; From 597338ba5ff18c9488f08271fb2d7871265e3628 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:59:23 +0200 Subject: [PATCH 023/123] PCB_LAYER_WIDGET became able to cooperate with PCB_BASE_FRAME. --- include/wxPcbStruct.h | 1 + pcbnew/class_pcb_layer_widget.cpp | 5 ++--- pcbnew/class_pcb_layer_widget.h | 6 ++++-- pcbnew/layer_widget.cpp | 6 ++++++ pcbnew/layer_widget.h | 1 + pcbnew/pcbframe.cpp | 8 ++++++++ 6 files changed, 22 insertions(+), 5 deletions(-) diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 33f2e0e6bb..98d95c465d 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -252,6 +252,7 @@ public: void OnUpdateAutoPlaceModulesMode( wxUpdateUIEvent& aEvent ); void OnUpdateAutoPlaceTracksMode( wxUpdateUIEvent& aEvent ); void OnUpdateMuWaveToolbar( wxUpdateUIEvent& aEvent ); + void OnLayerColorChange( wxCommandEvent& aEvent ); /** * Function RecordMacros. diff --git a/pcbnew/class_pcb_layer_widget.cpp b/pcbnew/class_pcb_layer_widget.cpp index 172df49f64..04954b1248 100644 --- a/pcbnew/class_pcb_layer_widget.cpp +++ b/pcbnew/class_pcb_layer_widget.cpp @@ -81,7 +81,7 @@ const LAYER_WIDGET::ROW PCB_LAYER_WIDGET::s_render_rows[] = { }; -PCB_LAYER_WIDGET::PCB_LAYER_WIDGET( PCB_EDIT_FRAME* aParent, wxWindow* aFocusOwner, int aPointSize ) : +PCB_LAYER_WIDGET::PCB_LAYER_WIDGET( PCB_BASE_FRAME* aParent, wxWindow* aFocusOwner, int aPointSize ) : LAYER_WIDGET( aParent, aFocusOwner, aPointSize ), myframe( aParent ) { @@ -213,7 +213,7 @@ void PCB_LAYER_WIDGET::SetLayersManagerTabsText() void PCB_LAYER_WIDGET::ReFillRender() { - BOARD* board = myframe->GetBoard(); + BOARD* board = myframe->GetBoard(); ClearRenderRows(); // Add "Render" tab rows to LAYER_WIDGET, after setting color and checkbox state. @@ -356,7 +356,6 @@ void PCB_LAYER_WIDGET::ReFill() void PCB_LAYER_WIDGET::OnLayerColorChange( int aLayer, EDA_COLOR_T aColor ) { myframe->GetBoard()->SetLayerColor( ToLAYER_ID( aLayer ), aColor ); - myframe->ReCreateLayerBox( false ); if( myframe->IsGalCanvasActive() ) { diff --git a/pcbnew/class_pcb_layer_widget.h b/pcbnew/class_pcb_layer_widget.h index 4f7d715367..211e603aa4 100644 --- a/pcbnew/class_pcb_layer_widget.h +++ b/pcbnew/class_pcb_layer_widget.h @@ -31,6 +31,8 @@ #ifndef CLASS_PCB_LAYER_WIDGET_H_ #define CLASS_PCB_LAYER_WIDGET_H_ +#include + /** * Class PCB_LAYER_WIDGET * is here to implement the abtract functions of LAYER_WIDGET so they @@ -49,7 +51,7 @@ public: * effectively sets the overal size of the widget via the row height and bitmap * button sizes. */ - PCB_LAYER_WIDGET( PCB_EDIT_FRAME* aParent, wxWindow* aFocusOwner, int aPointSize = 10 ); + PCB_LAYER_WIDGET( PCB_BASE_FRAME* aParent, wxWindow* aFocusOwner, int aPointSize = 10 ); void ReFill(); @@ -108,7 +110,7 @@ protected: bool m_alwaysShowActiveCopperLayer; // If true: Only shows the current active layer // even if it is changed - PCB_EDIT_FRAME* myframe; + PCB_BASE_FRAME* myframe; // popup menu ids. #define ID_SHOW_ALL_COPPERS wxID_HIGHEST diff --git a/pcbnew/layer_widget.cpp b/pcbnew/layer_widget.cpp index fda117b8e4..df23c188e3 100644 --- a/pcbnew/layer_widget.cpp +++ b/pcbnew/layer_widget.cpp @@ -44,6 +44,8 @@ #define BUTT_SIZE_Y 18 #define BUTT_VOID 4 +const wxEventType LAYER_WIDGET::EVT_LAYER_COLOR_CHANGE = wxNewEventType(); + /* XPM * This bitmap is used for not selected layers */ @@ -294,6 +296,10 @@ void LAYER_WIDGET::OnMiddleDownLayerColor( wxMouseEvent& event ) // tell the client code. OnLayerColorChange( layer, newColor ); + + // notify others + wxCommandEvent event( EVT_LAYER_COLOR_CHANGE ); + wxPostEvent( this, event ); } passOnFocus(); diff --git a/pcbnew/layer_widget.h b/pcbnew/layer_widget.h index 347038919c..cfb6bc384f 100644 --- a/pcbnew/layer_widget.h +++ b/pcbnew/layer_widget.h @@ -98,6 +98,7 @@ public: } }; + static const wxEventType EVT_LAYER_COLOR_CHANGE; protected: diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index c07f28a8c4..6bb044b1b7 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -294,6 +294,8 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME ) PCB_EDIT_FRAME::OnUpdateZoneDisplayStyle ) EVT_UPDATE_UI_RANGE( ID_PCB_MUWAVE_START_CMD, ID_PCB_MUWAVE_END_CMD, PCB_EDIT_FRAME::OnUpdateMuWaveToolbar ) + + EVT_COMMAND( wxID_ANY, LAYER_WIDGET::EVT_LAYER_COLOR_CHANGE, PCB_EDIT_FRAME::OnLayerColorChange ) END_EVENT_TABLE() @@ -1007,6 +1009,12 @@ void PCB_EDIT_FRAME::OnSelectAutoPlaceMode( wxCommandEvent& aEvent ) } +void PCB_EDIT_FRAME::OnLayerColorChange( wxCommandEvent& aEvent ) +{ + ReCreateLayerBox(); +} + + void PCB_EDIT_FRAME::ToPlotter( wxCommandEvent& event ) { DIALOG_PLOT dlg( this ); From d46d241b5e5b389d3368dd055e24c457605dfe39 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:59:23 +0200 Subject: [PATCH 024/123] Added layer widget to the module editor. --- pcbnew/loadcmp.cpp | 1 + pcbnew/modedit.cpp | 11 +++++++++++ pcbnew/module_editor_frame.h | 4 ++++ pcbnew/moduleframe.cpp | 28 ++++++++++++++++++++++++---- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/pcbnew/loadcmp.cpp b/pcbnew/loadcmp.cpp index 748b47917f..47a4728e92 100644 --- a/pcbnew/loadcmp.cpp +++ b/pcbnew/loadcmp.cpp @@ -56,6 +56,7 @@ #include #include #include +#include static void DisplayCmpDoc( wxString& Name ); diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp index c3bae138a9..8d643b4a67 100644 --- a/pcbnew/modedit.cpp +++ b/pcbnew/modedit.cpp @@ -916,6 +916,17 @@ EDA_COLOR_T FOOTPRINT_EDIT_FRAME::GetGridColor() const } +void FOOTPRINT_EDIT_FRAME::SetActiveLayer( LAYER_NUM aLayer ) +{ + PCB_BASE_FRAME::SetActiveLayer( aLayer ); + + GetGalCanvas()->SetHighContrastLayer( aLayer ); + + if( IsGalCanvasActive() ) + GetGalCanvas()->Refresh(); +} + + void FOOTPRINT_EDIT_FRAME::UseGalCanvas( bool aEnable ) { EDA_DRAW_FRAME::UseGalCanvas( aEnable ); diff --git a/pcbnew/module_editor_frame.h b/pcbnew/module_editor_frame.h index c733e922e0..ef9687a6a3 100644 --- a/pcbnew/module_editor_frame.h +++ b/pcbnew/module_editor_frame.h @@ -398,6 +398,9 @@ public: virtual EDA_COLOR_T GetGridColor() const; + ///> @copydoc PCB_BASE_FRAME::SetActiveLayer() + void SetActiveLayer( LAYER_NUM aLayer ); + ///> @copydoc EDA_DRAW_FRAME::UseGalCanvas() virtual void UseGalCanvas( bool aEnable ); @@ -408,6 +411,7 @@ protected: /// protected so only friend PCB::IFACE::CreateWindow() can act as sole factory. FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ); + PCB_LAYER_WIDGET* m_Layers; /** * Function GetComponentFromUndoList diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index 9cf223a256..b1253fc870 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -191,6 +192,9 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : // Ensure all layers and items are visible: GetBoard()->SetVisibleAlls(); + wxFont font = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ); + m_Layers = new PCB_LAYER_WIDGET( this, GetCanvas(), font.GetPointSize() ); + SetScreen( new PCB_SCREEN( GetPageSettings().GetSizeIU() ) ); GetScreen()->SetCurItem( NULL ); @@ -224,6 +228,14 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : EDA_PANEINFO mesg_pane; mesg_pane.MessageToolbarPane(); + // Create a wxAuiPaneInfo for the Layers Manager, not derived from the template. + // LAYER_WIDGET is floatable, but initially docked at far right + EDA_PANEINFO lyrs; + lyrs.LayersToolbarPane(); + lyrs.MinSize( m_Layers->GetBestSize() ); // updated in ReFillLayerWidget + lyrs.BestSize( m_Layers->GetBestSize() ); + lyrs.Caption( _( "Visibles" ) ); + m_auimgr.AddPane( m_mainToolBar, wxAuiPaneInfo( horiz ).Name( wxT( "m_mainToolBar" ) ).Top(). Row( 0 ) ); @@ -234,6 +246,11 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : m_auimgr.AddPane( m_drawToolBar, wxAuiPaneInfo( vert ).Name( wxT( "m_VToolBar" ) ).Right().Layer(1) ); + // Add the layer manager ( most right side of pcbframe ) + m_auimgr.AddPane( m_Layers, lyrs.Name( wxT( "m_LayersManagerToolBar" ) ).Right().Layer( 2 ) ); + // Layers manager is visible and served only in GAL canvas mode. + m_auimgr.GetPane( wxT( "m_LayersManagerToolBar" ) ).Show( drawFrame->IsGalCanvasActive() ); + // The left vertical toolbar (fast acces to display options) m_auimgr.AddPane( m_optionsToolBar, wxAuiPaneInfo( vert ).Name( wxT( "m_optionsToolBar" ) ). Left().Layer(1) ); @@ -246,12 +263,8 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : m_auimgr.AddPane( m_messagePanel, wxAuiPaneInfo( mesg_pane ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(10) ); - m_auimgr.Update(); - if( drawFrame->IsGalCanvasActive() ) { - drawPanel->DisplayBoard( GetBoard() ); - // Create the manager and dispatcher & route draw panel events to the dispatcher m_toolManager = new TOOL_MANAGER; m_toolManager->SetEnvironment( GetBoard(), drawPanel->GetView(), @@ -271,6 +284,11 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : UseGalCanvas( true ); } + + m_Layers->ReFill(); + m_Layers->ReFillRender(); + + m_auimgr.Update(); } @@ -278,6 +296,8 @@ FOOTPRINT_EDIT_FRAME::~FOOTPRINT_EDIT_FRAME() { // save the footprint in the PROJECT retainLastFootprint(); + + delete m_Layers; } From e4ec886a6cbe45f5d1bc8ebd3c530efddc9c9ab7 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:59:24 +0200 Subject: [PATCH 025/123] Added an alternative way to reach tools in the Tool Framework. --- common/tool/tool_manager.cpp | 10 +++++++--- include/tool/tool_manager.h | 27 +++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index abfd66b566..8f052d57fa 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -109,7 +109,7 @@ TOOL_MANAGER::TOOL_MANAGER() : TOOL_MANAGER::~TOOL_MANAGER() { - std::map::iterator it, it_end; + boost::unordered_map::iterator it, it_end; for( it = m_toolState.begin(), it_end = m_toolState.end(); it != it_end; ++it ) { @@ -129,6 +129,8 @@ void TOOL_MANAGER::RegisterTool( TOOL_BASE* aTool ) wxT( "Adding two tools with the same name may result in unexpected behaviour.") ); wxASSERT_MSG( m_toolIdIndex.find( aTool->GetId() ) == m_toolIdIndex.end(), wxT( "Adding two tools with the same ID may result in unexpected behaviour.") ); + wxASSERT_MSG( m_toolTypes.find( typeid( *aTool ).name() ) == m_toolTypes.end(), + wxT( "Adding two tools of the same type may result in unexpected behaviour.") ); TOOL_STATE* st = new TOOL_STATE; @@ -141,6 +143,7 @@ void TOOL_MANAGER::RegisterTool( TOOL_BASE* aTool ) m_toolState[aTool] = st; m_toolNameIndex[aTool->GetName()] = st; m_toolIdIndex[aTool->GetId()] = st; + m_toolTypes[typeid( *aTool ).name()] = st->theTool; aTool->m_toolMgr = this; @@ -155,6 +158,7 @@ void TOOL_MANAGER::RegisterTool( TOOL_BASE* aTool ) m_toolState.erase( aTool ); m_toolNameIndex.erase( aTool->GetName() ); m_toolIdIndex.erase( aTool->GetId() ); + m_toolTypes.erase( typeid( *aTool ).name() ); delete st; delete aTool; @@ -272,7 +276,7 @@ bool TOOL_MANAGER::runTool( TOOL_BASE* aTool ) TOOL_BASE* TOOL_MANAGER::FindTool( int aId ) const { - std::map::const_iterator it = m_toolIdIndex.find( aId ); + boost::unordered_map::const_iterator it = m_toolIdIndex.find( aId ); if( it != m_toolIdIndex.end() ) return it->second->theTool; @@ -283,7 +287,7 @@ TOOL_BASE* TOOL_MANAGER::FindTool( int aId ) const TOOL_BASE* TOOL_MANAGER::FindTool( const std::string& aName ) const { - std::map::const_iterator it = m_toolNameIndex.find( aName ); + boost::unordered_map::const_iterator it = m_toolNameIndex.find( aName ); if( it != m_toolNameIndex.end() ) return it->second->theTool; diff --git a/include/tool/tool_manager.h b/include/tool/tool_manager.h index c8861c7ff1..62f7e42e8a 100644 --- a/include/tool/tool_manager.h +++ b/include/tool/tool_manager.h @@ -26,8 +26,9 @@ #ifndef __TOOL_MANAGER_H #define __TOOL_MANAGER_H -#include #include +#include +#include #include @@ -135,6 +136,21 @@ public: */ TOOL_BASE* FindTool( const std::string& aName ) const; + /* + * Function GetTool() + * Returns the tool of given type or NULL if there is no such tool registered. + */ + template + T* GetTool() + { + boost::unordered_map::iterator tool = m_toolTypes.find( typeid( T ).name() ); + + if( tool != m_toolTypes.end() ) + return static_cast( tool->second ); + + return NULL; + } + /** * Function ResetTools() * Resets all tools (i.e. calls their Reset() method). @@ -344,13 +360,16 @@ private: bool isActive( TOOL_BASE* aTool ); /// Index of registered tools current states, associated by tools' objects. - std::map m_toolState; + boost::unordered_map m_toolState; /// Index of the registered tools current states, associated by tools' names. - std::map m_toolNameIndex; + boost::unordered_map m_toolNameIndex; + + /// Index of the registered tools to easily lookup by their type. + boost::unordered_map m_toolTypes; /// Index of the registered tools current states, associated by tools' ID numbers. - std::map m_toolIdIndex; + boost::unordered_map m_toolIdIndex; /// Stack of the active tools std::deque m_activeTools; From e290fff05241d4a9730e1287434a8c545f432859 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:59:24 +0200 Subject: [PATCH 026/123] Removed TOOL_ACTIONs: selectionSingle, selectionClear. SELECTION_TOOL methods are called directly instead. --- pcbnew/router/router_tool.cpp | 3 +- pcbnew/tools/common_actions.cpp | 5 - pcbnew/tools/common_actions.h | 6 -- pcbnew/tools/drawing_tool.cpp | 15 +-- pcbnew/tools/edit_tool.cpp | 16 ++-- pcbnew/tools/selection_tool.cpp | 162 +++++++++++++++----------------- pcbnew/tools/selection_tool.h | 38 ++++---- 7 files changed, 114 insertions(+), 131 deletions(-) diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 7416c14c17..09951064d9 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -40,6 +40,7 @@ #include #include +#include #include @@ -636,7 +637,7 @@ int ROUTER_TOOL::Main( TOOL_EVENT& aEvent ) BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings(); // Deselect all items - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->GetTool()->ClearSelection(); getEditFrame()->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Interactive Router" ) ); diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 285d662aed..73b67e462b 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -31,11 +31,6 @@ TOOL_ACTION COMMON_ACTIONS::selectionActivate( "pcbnew.InteractiveSelection", AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere -TOOL_ACTION COMMON_ACTIONS::selectionSingle( "pcbnew.InteractiveSelection.Single", - AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere - -TOOL_ACTION COMMON_ACTIONS::selectionClear( "pcbnew.InteractiveSelection.Clear", - AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere // Edit tool actions TOOL_ACTION COMMON_ACTIONS::editActivate( "pcbnew.InteractiveEdit", diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 428115bb6e..5ddb660dbb 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -37,12 +37,6 @@ public: /// Activation of the selection tool static TOOL_ACTION selectionActivate; - /// Select a single item under the cursor position - static TOOL_ACTION selectionSingle; - - /// Clears the current selection - static TOOL_ACTION selectionClear; - // Edit Tool /// Activation of the edit tool static TOOL_ACTION editActivate; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index d9d0147266..050681ca2f 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -38,6 +38,7 @@ #include #include #include +#include "selection_tool.h" #include #include @@ -102,7 +103,7 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->GetTool()->ClearSelection(); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); @@ -288,7 +289,7 @@ int DRAWING_TOOL::PlaceText( TOOL_EVENT& aEvent ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->GetTool()->ClearSelection(); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); m_controls->SetAutoPan( true ); @@ -394,7 +395,7 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->GetTool()->ClearSelection(); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); @@ -590,7 +591,7 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) m_view->Add( &preview ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->GetTool()->ClearSelection(); m_controls->SetSnapping( true ); m_controls->SetAutoPan( true ); @@ -665,7 +666,7 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->GetTool()->ClearSelection(); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); m_controls->SetAutoPan( true ); @@ -776,7 +777,7 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->GetTool()->ClearSelection(); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); @@ -952,7 +953,7 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->GetTool()->ClearSelection(); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index d2199f8a5d..85588472de 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -48,7 +48,7 @@ EDIT_TOOL::EDIT_TOOL() : bool EDIT_TOOL::Init() { // Find the selection tool, so they can cooperate - m_selectionTool = static_cast( m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ) ); + m_selectionTool = m_toolMgr->GetTool(); if( !m_selectionTool ) { @@ -198,7 +198,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) } if( unselect ) - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_selectionTool->ClearSelection(); RN_DATA* ratsnest = getModel()->GetRatsnest(); ratsnest->ClearSimple(); @@ -252,7 +252,7 @@ int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) std::vector& undoList = editFrame->GetScreen()->m_UndoList.m_CommandsList; // Some of properties dialogs alter pointers, so we should deselect them - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_selectionTool->ClearSelection(); STATUS_FLAGS flags = item->GetFlags(); item->ClearFlags(); @@ -279,7 +279,7 @@ int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) } if( unselect ) - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_selectionTool->ClearSelection(); setTransitions(); @@ -332,7 +332,7 @@ int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) getModel()->GetRatsnest()->Recalculate(); if( unselect ) - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_selectionTool->ClearSelection(); m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate ); setTransitions(); @@ -386,7 +386,7 @@ int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) getModel()->GetRatsnest()->Recalculate(); if( unselect ) - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_selectionTool->ClearSelection(); m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate ); setTransitions(); @@ -411,7 +411,7 @@ int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) PCB_EDIT_FRAME* editFrame = getEditFrame(); // As we are about to remove items, they have to be removed from the selection first - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_selectionTool->ClearSelection(); // Save them for( unsigned int i = 0; i < selectedItems.GetCount(); ++i ) @@ -529,7 +529,7 @@ wxPoint EDIT_TOOL::getModificationPoint( const SELECTION_TOOL::SELECTION& aSelec bool EDIT_TOOL::makeSelection( const SELECTION_TOOL::SELECTION& aSelection ) { if( aSelection.Empty() ) // Try to find an item that could be modified - m_toolMgr->RunAction( COMMON_ACTIONS::selectionSingle ); + m_selectionTool->SelectSingle( getView()->ToWorld( getViewControls()->GetMousePosition() ) ); return !aSelection.Empty(); } diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 34f8c5b6f9..285cbded07 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -77,7 +77,7 @@ void SELECTION_TOOL::Reset( RESET_REASON aReason ) m_selection.clear(); else // Restore previous properties of selected items and remove them from containers - clearSelection(); + ClearSelection(); // Reinsert the VIEW_GROUP, in case it was removed from the VIEW getView()->Remove( m_selection.group ); @@ -97,16 +97,9 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) // become the new selection (discarding previously selected items) m_additive = evt->Modifier( MD_SHIFT ); - if( evt->IsAction( &COMMON_ACTIONS::selectionSingle ) ) + if( evt->IsCancel() || evt->Action() == TA_UNDO_REDO ) { - // GetMousePosition() is used, as it is independent of snapping settings - selectSingle( getView()->ToWorld( getViewControls()->GetMousePosition() ) ); - } - - else if( evt->IsCancel() || evt->Action() == TA_UNDO_REDO || - evt->IsAction( &COMMON_ACTIONS::selectionClear ) ) - { - clearSelection(); + ClearSelection(); } // single click? Select single object @@ -119,9 +112,9 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) else { if( !m_additive ) - clearSelection(); + ClearSelection(); - selectSingle( evt->Position() ); + SelectSingle( evt->Position() ); } } @@ -129,7 +122,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) else if( evt->IsClick( BUT_RIGHT ) ) { if( m_selection.Empty() ) - selectSingle( evt->Position() ); + SelectSingle( evt->Position() ); if( !m_selection.Empty() ) SetContextMenu( &m_menu, CMENU_NOW ); @@ -139,7 +132,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) else if( evt->IsDblClick( BUT_LEFT ) ) { if( m_selection.Empty() ) - selectSingle( evt->Position() ); + SelectSingle( evt->Position() ); m_toolMgr->RunAction( COMMON_ACTIONS::properties ); } @@ -154,7 +147,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) else if( m_selection.Empty() ) { // There is nothing selected, so try to select something - if( !selectSingle( getView()->ToWorld( getViewControls()->GetMousePosition() ), false ) ) + if( !SelectSingle( getView()->ToWorld( getViewControls()->GetMousePosition() ), false ) ) { // If nothings has been selected or user wants to select more // draw the selection box @@ -177,7 +170,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) else { // No -> clear the selection list - clearSelection(); + ClearSelection(); } } } @@ -190,58 +183,21 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) } -void SELECTION_TOOL::AddMenuItem( const TOOL_ACTION& aAction ) +bool SELECTION_TOOL::SelectSingle( const VECTOR2I& aWhere, bool aAllowDisambiguation ) { - assert( aAction.GetId() > 0 ); // Check if the action was registered before in ACTION_MANAGER - - m_menu.Add( aAction ); -} - - -void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem ) -{ - if( aItem->IsSelected() ) - { - deselect( aItem ); - - // Inform other potentially interested tools - TOOL_EVENT deselectEvent( DeselectedEvent ); - m_toolMgr->ProcessEvent( deselectEvent ); - } - else - { - if( !m_additive ) - clearSelection(); - - // Prevent selection of invisible or inactive items - if( selectable( aItem ) ) - { - select( aItem ); - - // Inform other potentially interested tools - TOOL_EVENT selectEvent( SelectedEvent ); - m_toolMgr->ProcessEvent( selectEvent ); - } - } -} - - -bool SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere, bool aAllowDisambiguation ) -{ - BOARD* pcb = getModel(); BOARD_ITEM* item; GENERAL_COLLECTORS_GUIDE guide = getEditFrame()->GetCollectorsGuide(); GENERAL_COLLECTOR collector; const KICAD_T types[] = { PCB_TRACE_T, PCB_VIA_T, PCB_LINE_T, EOT }; // preferred types - collector.Collect( pcb, GENERAL_COLLECTOR::AllBoardItems, + collector.Collect( getModel(), GENERAL_COLLECTOR::AllBoardItems, wxPoint( aWhere.x, aWhere.y ), guide ); switch( collector.GetCount() ) { case 0: if( !m_additive ) - clearSelection(); + ClearSelection(); return false; @@ -293,6 +249,70 @@ bool SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere, bool aAllowDisambigua } +void SELECTION_TOOL::ClearSelection() +{ + if( m_selection.Empty() ) + return; + + KIGFX::VIEW_GROUP::const_iter it, it_end; + + // Restore the initial properties + for( it = m_selection.group->Begin(), it_end = m_selection.group->End(); it != it_end; ++it ) + { + BOARD_ITEM* item = static_cast( *it ); + + item->ViewSetVisible( true ); + item->ClearSelected(); + } + m_selection.clear(); + + getEditFrame()->SetCurItem( NULL ); + + // Do not show the context menu when there is nothing selected + SetContextMenu( &m_menu, CMENU_OFF ); + + // Inform other potentially interested tools + TOOL_EVENT clearEvent( ClearedEvent ); + m_toolMgr->ProcessEvent( clearEvent ); +} + + +void SELECTION_TOOL::AddMenuItem( const TOOL_ACTION& aAction ) +{ + assert( aAction.GetId() > 0 ); // Check if the action was registered before in ACTION_MANAGER + + m_menu.Add( aAction ); +} + + +void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem ) +{ + if( aItem->IsSelected() ) + { + deselect( aItem ); + + // Inform other potentially interested tools + TOOL_EVENT deselectEvent( DeselectedEvent ); + m_toolMgr->ProcessEvent( deselectEvent ); + } + else + { + if( !m_additive ) + ClearSelection(); + + // Prevent selection of invisible or inactive items + if( selectable( aItem ) ) + { + select( aItem ); + + // Inform other potentially interested tools + TOOL_EVENT selectEvent( SelectedEvent ); + m_toolMgr->ProcessEvent( selectEvent ); + } + } +} + + bool SELECTION_TOOL::selectMultiple() { bool cancelled = false; // Was the tool cancelled while it was running? @@ -313,7 +333,7 @@ bool SELECTION_TOOL::selectMultiple() if( evt->IsDrag( BUT_LEFT ) ) { if( !m_additive ) - clearSelection(); + ClearSelection(); // Start drawing a selection box m_selArea->SetOrigin( evt->DragOrigin() ); @@ -368,34 +388,6 @@ bool SELECTION_TOOL::selectMultiple() } -void SELECTION_TOOL::clearSelection() -{ - if( m_selection.Empty() ) - return; - - KIGFX::VIEW_GROUP::const_iter it, it_end; - - // Restore the initial properties - for( it = m_selection.group->Begin(), it_end = m_selection.group->End(); it != it_end; ++it ) - { - BOARD_ITEM* item = static_cast( *it ); - - item->ViewSetVisible( true ); - item->ClearSelected(); - } - m_selection.clear(); - - getEditFrame()->SetCurItem( NULL ); - - // Do not show the context menu when there is nothing selected - SetContextMenu( &m_menu, CMENU_OFF ); - - // Inform other potentially interested tools - TOOL_EVENT clearEvent( ClearedEvent ); - m_toolMgr->ProcessEvent( clearEvent ); -} - - BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector ) { BOARD_ITEM* current = NULL; diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index 9fe3d32b53..2f8a58fcf1 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -113,6 +113,24 @@ public: return m_selection; } + /** + * Function SelectSingle() + * Selects an item pointed by the parameter aWhere. If there is more than one item at that + * place, there is a menu displayed that allows to choose the item. + * + * @param aWhere is the place where the item should be selected. + * @param aAllowDisambiguation decides what to do in case of disambiguation. If true, then + * a menu is shown, otherise function finishes without selecting anything. + * @return True if an item was selected, false otherwise. + */ + bool SelectSingle( const VECTOR2I& aWhere, bool aAllowDisambiguation = true ); + + /** + * Function ClearSelection() + * Clears the current selection. + */ + void ClearSelection(); + /** * Function AddMenuItem() * @@ -131,32 +149,14 @@ public: const TOOL_EVENT ClearedEvent; private: - /** - * Function selectSingle() - * Selects an item pointed by the parameter aWhere. If there is more than one item at that - * place, there is a menu displayed that allows to choose the item. - * - * @param aWhere is the place where the item should be selected. - * @param aAllowDisambiguation decides what to do in case of disambiguation. If true, then - * a menu is shown, otherise function finishes without selecting anything. - * @return True if an item was selected, false otherwise. - */ - bool selectSingle( const VECTOR2I& aWhere, bool aAllowDisambiguation = true ); - /** * Function selectMultiple() * Handles drawing a selection box that allows to select many items at the same time. * - * @return true if the function was cancelled (ie. CancelEvent was received). + * @return true if the function was cancelled (i.e. CancelEvent was received). */ bool selectMultiple(); - /** - * Function ClearSelection() - * Clears the current selection. - */ - void clearSelection(); - /** * Function disambiguationMenu() * Handles the menu that allows to select one of many items in case there is more than one From 520038c750a00e32ae441f02e1aee6450cbb4692 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:59:24 +0200 Subject: [PATCH 027/123] Minor changes. --- include/tool/coroutine.h | 2 +- pcbnew/module_editor_frame.h | 4 ++-- pcbnew/tools/edit_tool.cpp | 10 +++------- pcbnew/tools/selection_tool.cpp | 1 - 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/include/tool/coroutine.h b/include/tool/coroutine.h index 9d502ff5c4..9daab59cb2 100644 --- a/include/tool/coroutine.h +++ b/include/tool/coroutine.h @@ -115,7 +115,7 @@ public: } /** - * * Function SetEntry() + * Function SetEntry() * * Defines the entry point for the coroutine, if not set in the constructor. */ diff --git a/pcbnew/module_editor_frame.h b/pcbnew/module_editor_frame.h index ef9687a6a3..295cce8670 100644 --- a/pcbnew/module_editor_frame.h +++ b/pcbnew/module_editor_frame.h @@ -419,7 +419,7 @@ protected: * - Place the current edited library component in Redo list * - Get old version of the current edited library component */ - void GetComponentFromUndoList( wxCommandEvent& event ); + void GetComponentFromUndoList( wxCommandEvent& aEvent ); /** * Function GetComponentFromRedoList @@ -427,7 +427,7 @@ protected: * - Place the current edited library component in undo list * - Get old version of the current edited library component */ - void GetComponentFromRedoList( wxCommandEvent& event ); + void GetComponentFromRedoList( wxCommandEvent& aEvent ); /** * Function UpdateTitle diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 85588472de..cc7e770e37 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -219,9 +219,6 @@ int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); PCB_EDIT_FRAME* editFrame = getEditFrame(); - // Shall the selection be cleared at the end? - bool unselect = selection.Empty(); - if( !makeSelection( selection ) ) { setTransitions(); @@ -238,9 +235,11 @@ int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) // Check if user wants to edit pad or module properties if( item->Type() == PCB_MODULE_T ) { + VECTOR2D cursor = getViewControls()->GetCursorPosition(); + for( D_PAD* pad = static_cast( item )->Pads(); pad; pad = pad->Next() ) { - if( pad->ViewBBox().Contains( getViewControls()->GetCursorPosition() ) ) + if( pad->ViewBBox().Contains( cursor ) ) { // Turns out that user wants to edit a pad properties item = pad; @@ -278,9 +277,6 @@ int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) item->SetFlags( flags ); } - if( unselect ) - m_selectionTool->ClearSelection(); - setTransitions(); return 0; diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 285cbded07..0953e7f517 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -24,7 +24,6 @@ */ #include -#include #include #include From d0615e8fec80c298f09961508a474bc28636aba9 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:59:24 +0200 Subject: [PATCH 028/123] Move() method updates local coordinates in EDGE_MODULE, D_PAD and TEXTE_MODULE classes. --- pcbnew/class_edge_mod.cpp | 19 +++++++++++++++++++ pcbnew/class_edge_mod.h | 11 +++++++++++ pcbnew/class_pad.cpp | 32 ++++++++++++++++++++++++++++++++ pcbnew/class_pad.h | 9 ++++++++- pcbnew/class_text_mod.cpp | 5 ++--- pcbnew/class_text_mod.h | 7 ++++--- 6 files changed, 76 insertions(+), 7 deletions(-) diff --git a/pcbnew/class_edge_mod.cpp b/pcbnew/class_edge_mod.cpp index 2d1ba56e57..5791563007 100644 --- a/pcbnew/class_edge_mod.cpp +++ b/pcbnew/class_edge_mod.cpp @@ -90,6 +90,25 @@ void EDGE_MODULE::Copy( EDGE_MODULE* source ) } +void EDGE_MODULE::SetLocalCoord() +{ + MODULE* module = (MODULE*) m_Parent; + + if( module == NULL ) + { + m_Start0 = m_Start; + m_End0 = m_End; + return; + } + + m_Start0 = m_Start - module->GetPosition(); + m_End0 = m_End - module->GetPosition(); + double angle = module->GetOrientation(); + RotatePoint( &m_Start0.x, &m_Start0.y, -angle ); + RotatePoint( &m_End0.x, &m_End0.y, -angle ); +} + + void EDGE_MODULE::SetDrawCoord() { MODULE* module = (MODULE*) m_Parent; diff --git a/pcbnew/class_edge_mod.h b/pcbnew/class_edge_mod.h index 7b8d5b09c8..e7b945a9af 100644 --- a/pcbnew/class_edge_mod.h +++ b/pcbnew/class_edge_mod.h @@ -61,12 +61,23 @@ public: void Copy( EDGE_MODULE* source ); // copy structure + void Move( const wxPoint& aMoveVector ) + { + m_Start += aMoveVector; + m_End += aMoveVector; + SetLocalCoord(); + } + void SetStart0( const wxPoint& aPoint ) { m_Start0 = aPoint; } const wxPoint& GetStart0() const { return m_Start0; } void SetEnd0( const wxPoint& aPoint ) { m_End0 = aPoint; } const wxPoint& GetEnd0() const { return m_End0; } + ///> Set relative coordinates. + void SetLocalCoord(); + + ///> Set absolute coordinates. void SetDrawCoord(); /* drawing functions */ diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index a65bd54784..246a766c9d 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -228,6 +228,38 @@ const EDA_RECT D_PAD::GetBoundingBox() const } +void D_PAD::SetDrawCoord() +{ + MODULE* module = (MODULE*) m_Parent; + + m_Pos = m_Pos0; + + if( module == NULL ) + return; + + double angle = module->GetOrientation(); + + RotatePoint( &m_Pos.x, &m_Pos.y, angle ); + m_Pos += module->GetPosition(); +} + + +void D_PAD::SetLocalCoord() +{ + MODULE* module = (MODULE*) m_Parent; + + if( module == NULL ) + { + m_Pos0 = m_Pos; + return; + } + + m_Pos0 = m_Pos - module->GetPosition(); + double angle = module->GetOrientation(); + RotatePoint( &m_Pos0.x, &m_Pos0.y, -angle ); +} + + void D_PAD::SetAttribute( PAD_ATTR_T aAttribute ) { m_Attribute = aAttribute; diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index 1687989462..53666d9e4c 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -153,7 +153,7 @@ public: * Function GetOrientation * returns the rotation angle of the pad in tenths of degrees, but soon degrees. */ - double GetOrientation() const { return m_Orient; } + double GetOrientation() const { return m_Orient; } void SetDrillShape( PAD_DRILL_SHAPE_T aDrillShape ) { m_drillShape = aDrillShape; } @@ -381,6 +381,12 @@ public: // Virtual function: const EDA_RECT GetBoundingBox() const; + ///> Set absolute coordinates. + void SetDrawCoord(); + + ///> Set relative coordinates. + void SetLocalCoord(); + /** * Function Compare * compares two pads and return 0 if they are equal. @@ -391,6 +397,7 @@ public: void Move( const wxPoint& aMoveVector ) { m_Pos += aMoveVector; + SetLocalCoord(); } diff --git a/pcbnew/class_text_mod.cpp b/pcbnew/class_text_mod.cpp index 5eda7cba6e..48b43b161b 100644 --- a/pcbnew/class_text_mod.cpp +++ b/pcbnew/class_text_mod.cpp @@ -129,7 +129,7 @@ int TEXTE_MODULE::GetLength() const return m_Text.Len(); } -// Update draw coordinates + void TEXTE_MODULE::SetDrawCoord() { MODULE* module = (MODULE*) m_Parent; @@ -146,8 +146,6 @@ void TEXTE_MODULE::SetDrawCoord() } -// Update "local" coordinates (coordinates relatives to the footprint -// anchor point) void TEXTE_MODULE::SetLocalCoord() { MODULE* module = (MODULE*) m_Parent; @@ -163,6 +161,7 @@ void TEXTE_MODULE::SetLocalCoord() RotatePoint( &m_Pos0.x, &m_Pos0.y, -angle ); } + bool TEXTE_MODULE::HitTest( const wxPoint& aPosition ) const { wxPoint rel_pos; diff --git a/pcbnew/class_text_mod.h b/pcbnew/class_text_mod.h index e9595a307f..fff9f20547 100644 --- a/pcbnew/class_text_mod.h +++ b/pcbnew/class_text_mod.h @@ -71,7 +71,6 @@ public: return aItem && PCB_MODULE_TEXT_T == aItem->Type(); } - virtual const wxPoint& GetPosition() const { return m_Pos; @@ -117,9 +116,11 @@ public: // Virtual function const EDA_RECT GetBoundingBox() const; - void SetDrawCoord(); // Set absolute coordinates. + ///> Set absolute coordinates. + void SetDrawCoord(); - void SetLocalCoord(); // Set relative coordinates. + ///> Set relative coordinates. + void SetLocalCoord(); /* drawing functions */ void Draw( EDA_DRAW_PANEL* panel, From caf2f12dee7364675b0e8f050949210f046e4d71 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 11:59:24 +0200 Subject: [PATCH 029/123] Unconditionally initialize the Tool Framework in FOOTPRINT_EDIT_FRAME. --- pcbnew/moduleframe.cpp | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index b1253fc870..49f24e749d 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -263,27 +263,24 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : m_auimgr.AddPane( m_messagePanel, wxAuiPaneInfo( mesg_pane ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(10) ); - if( drawFrame->IsGalCanvasActive() ) - { - // Create the manager and dispatcher & route draw panel events to the dispatcher - m_toolManager = new TOOL_MANAGER; - m_toolManager->SetEnvironment( GetBoard(), drawPanel->GetView(), - drawPanel->GetViewControls(), this ); - m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager ); - drawPanel->SetEventDispatcher( m_toolDispatcher ); + // Create the manager and dispatcher & route draw panel events to the dispatcher + m_toolManager = new TOOL_MANAGER; + m_toolManager->SetEnvironment( GetBoard(), drawPanel->GetView(), + drawPanel->GetViewControls(), this ); + m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager ); + drawPanel->SetEventDispatcher( m_toolDispatcher ); - m_toolManager->RegisterTool( new SELECTION_TOOL ); - m_toolManager->RegisterTool( new EDIT_TOOL ); - m_toolManager->RegisterTool( new DRAWING_TOOL ); - m_toolManager->RegisterTool( new POINT_EDITOR ); - m_toolManager->RegisterTool( new PCBNEW_CONTROL ); - m_toolManager->ResetTools( TOOL_BASE::RUN ); + m_toolManager->RegisterTool( new SELECTION_TOOL ); + m_toolManager->RegisterTool( new EDIT_TOOL ); + m_toolManager->RegisterTool( new DRAWING_TOOL ); + m_toolManager->RegisterTool( new POINT_EDITOR ); + m_toolManager->RegisterTool( new PCBNEW_CONTROL ); + m_toolManager->ResetTools( TOOL_BASE::RUN ); - // Run the selection tool, it is supposed to be always active - m_toolManager->InvokeTool( "pcbnew.InteractiveSelection" ); + // Run the selection tool, it is supposed to be always active + m_toolManager->InvokeTool( "pcbnew.InteractiveSelection" ); - UseGalCanvas( true ); - } + UseGalCanvas( drawFrame->IsGalCanvasActive() ); m_Layers->ReFill(); m_Layers->ReFillRender(); From 32171720f0284e693d910ed8961e5c4551e83852 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 12:10:27 +0200 Subject: [PATCH 030/123] SELECTION_TOOL got a new mode to edit MODULEs. --- pcbnew/modedit.cpp | 2 +- pcbnew/module_editor_frame.h | 2 +- pcbnew/moduleframe.cpp | 1 + pcbnew/tools/selection_tool.cpp | 18 ++++++++++++------ pcbnew/tools/selection_tool.h | 14 ++++++++++++++ 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp index 8d643b4a67..1d3283a276 100644 --- a/pcbnew/modedit.cpp +++ b/pcbnew/modedit.cpp @@ -916,7 +916,7 @@ EDA_COLOR_T FOOTPRINT_EDIT_FRAME::GetGridColor() const } -void FOOTPRINT_EDIT_FRAME::SetActiveLayer( LAYER_NUM aLayer ) +void FOOTPRINT_EDIT_FRAME::SetActiveLayer( LAYER_ID aLayer ) { PCB_BASE_FRAME::SetActiveLayer( aLayer ); diff --git a/pcbnew/module_editor_frame.h b/pcbnew/module_editor_frame.h index 295cce8670..f7e0dd4c2a 100644 --- a/pcbnew/module_editor_frame.h +++ b/pcbnew/module_editor_frame.h @@ -399,7 +399,7 @@ public: virtual EDA_COLOR_T GetGridColor() const; ///> @copydoc PCB_BASE_FRAME::SetActiveLayer() - void SetActiveLayer( LAYER_NUM aLayer ); + void SetActiveLayer( LAYER_ID aLayer ); ///> @copydoc EDA_DRAW_FRAME::UseGalCanvas() virtual void UseGalCanvas( bool aEnable ); diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index 49f24e749d..1649b24b74 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -271,6 +271,7 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : drawPanel->SetEventDispatcher( m_toolDispatcher ); m_toolManager->RegisterTool( new SELECTION_TOOL ); + m_toolManager->GetTool()->EditModules( true ); m_toolManager->RegisterTool( new EDIT_TOOL ); m_toolManager->RegisterTool( new DRAWING_TOOL ); m_toolManager->RegisterTool( new POINT_EDITOR ); diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 0953e7f517..591bfb9e3e 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -54,7 +54,7 @@ SELECTION_TOOL::SELECTION_TOOL() : SelectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.selected" ), DeselectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.deselected" ), ClearedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.cleared" ), - m_additive( false ), m_multiple( false ) + m_additive( false ), m_multiple( false ), m_editModules( false ) { m_selArea = new SELECTION_AREA; m_selection.group = new KIGFX::VIEW_GROUP; @@ -189,8 +189,12 @@ bool SELECTION_TOOL::SelectSingle( const VECTOR2I& aWhere, bool aAllowDisambigua GENERAL_COLLECTOR collector; const KICAD_T types[] = { PCB_TRACE_T, PCB_VIA_T, PCB_LINE_T, EOT }; // preferred types - collector.Collect( getModel(), GENERAL_COLLECTOR::AllBoardItems, - wxPoint( aWhere.x, aWhere.y ), guide ); + if( m_editModules ) + collector.Collect( getModel(), GENERAL_COLLECTOR::ModulesAndTheirItems, + wxPoint( aWhere.x, aWhere.y ), guide ); + else + collector.Collect( getModel(), GENERAL_COLLECTOR::AllBoardItems, + wxPoint( aWhere.x, aWhere.y ), guide ); switch( collector.GetCount() ) { @@ -532,23 +536,25 @@ bool SELECTION_TOOL::selectable( const BOARD_ITEM* aItem ) const case PCB_MODULE_T: if( aItem->IsOnLayer( F_Cu ) && board->IsElementVisible( MOD_FR_VISIBLE ) ) - return true; + return !m_editModules; if( aItem->IsOnLayer( B_Cu ) && board->IsElementVisible( MOD_BK_VISIBLE ) ) - return true; + return !m_editModules; return false; break; case PCB_MODULE_TEXT_T: - if( m_multiple ) + if( m_multiple && !m_editModules ) return false; break; // These are not selectable case PCB_MODULE_EDGE_T: case PCB_PAD_T: + return m_editModules; + case NOT_USED: case TYPE_NOT_INIT: return false; diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index 2f8a58fcf1..642b2ee358 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -139,6 +139,17 @@ public: */ void AddMenuItem( const TOOL_ACTION& aAction ); + /** + * Function EditModules() + * Toggles edit module mode. When enabled, one may select parts of modules individually + * (graphics, pads, etc.), so they can be modified. + * @param aEnabled decides if the mode should be enabled. + */ + void EditModules( bool aEnabled ) + { + m_editModules = aEnabled; + } + ///> Event sent after an item is selected. const TOOL_EVENT SelectedEvent; @@ -260,6 +271,9 @@ private: /// Right click popup menu CONTEXT_MENU m_menu; + + /// Edit module mode flag + bool m_editModules; }; #endif From f7e3b1b0cb25566e7396584dbc6e972bf351ff74 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 12:10:27 +0200 Subject: [PATCH 031/123] FOOTPRINT_EDIT_FRAME undo buffer handles operations done with GAL editor. --- pcbnew/modedit_undo_redo.cpp | 58 +++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/pcbnew/modedit_undo_redo.cpp b/pcbnew/modedit_undo_redo.cpp index 613f4d8d2b..4e057c3e3c 100644 --- a/pcbnew/modedit_undo_redo.cpp +++ b/pcbnew/modedit_undo_redo.cpp @@ -2,8 +2,11 @@ /* library editor: undo and redo functions */ /********************************************/ +#include #include #include +#include +#include #include #include @@ -50,31 +53,52 @@ void FOOTPRINT_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsLi UNDO_REDO_T aTypeCommand, const wxPoint& aTransformPoint ) { - // Currently unused in modedit, because the module itself is saved for each change - wxMessageBox( wxT( "SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList..) not yet in use" ) ); + assert( aItemsList.GetPickedItem( 0 )->GetParent()->Type() == PCB_MODULE_T ); + MODULE* owner = static_cast( aItemsList.GetPickedItem( 0 )->GetParent() ); + +#ifndef NDEBUG + // All items should have the same parent (MODULE) to make undo/redo entry valid + for( unsigned int i = 0; i < aItemsList.GetCount(); ++i ) + assert( aItemsList.GetPickedItem( i )->GetParent() == owner ); +#endif /* not NDEBUG */ + + SaveCopyInUndoList( owner, aTypeCommand, aTransformPoint ); } -void FOOTPRINT_EDIT_FRAME::GetComponentFromRedoList( wxCommandEvent& event ) +void FOOTPRINT_EDIT_FRAME::GetComponentFromRedoList( wxCommandEvent& aEvent ) { if( GetScreen()->GetRedoCommandCount() <= 0 ) return; + // Inform tools that undo command was issued + TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL ); + m_toolManager->ProcessEvent( event ); + // Save current module state in undo list PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST(); - MODULE * module = GetBoard()->m_Modules.PopFront(); - ITEM_PICKER wrapper( module, UR_MODEDIT ); + MODULE* module = GetBoard()->m_Modules.PopFront(); + ITEM_PICKER wrapper( module, UR_MODEDIT ); + KIGFX::VIEW* view = GetGalCanvas()->GetView(); lastcmd->PushItem( wrapper ); GetScreen()->PushCommandToUndoList( lastcmd ); + view->Remove( module ); + module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) ); + // Retrieve last module state from undo list lastcmd = GetScreen()->PopCommandFromRedoList(); wrapper = lastcmd->PopItem(); - module = (MODULE *)wrapper.GetItem(); + module = (MODULE*) wrapper.GetItem(); delete lastcmd; if( module ) + { GetBoard()->Add( module ); + GetGalCanvas()->GetView()->Add( module ); + module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) ); + module->ViewUpdate(); + } SetCurItem( NULL ); @@ -83,27 +107,39 @@ void FOOTPRINT_EDIT_FRAME::GetComponentFromRedoList( wxCommandEvent& event ) } -void FOOTPRINT_EDIT_FRAME::GetComponentFromUndoList( wxCommandEvent& event ) +void FOOTPRINT_EDIT_FRAME::GetComponentFromUndoList( wxCommandEvent& aEvent ) { if( GetScreen()->GetUndoCommandCount() <= 0 ) return; + // Inform tools that undo command was issued + TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL ); + m_toolManager->ProcessEvent( event ); + // Save current module state in redo list PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST(); - MODULE * module = GetBoard()->m_Modules.PopFront(); - ITEM_PICKER wrapper( module, UR_MODEDIT ); + MODULE* module = GetBoard()->m_Modules.PopFront(); + ITEM_PICKER wrapper( module, UR_MODEDIT ); + KIGFX::VIEW* view = GetGalCanvas()->GetView(); lastcmd->PushItem( wrapper ); GetScreen()->PushCommandToRedoList( lastcmd ); + view->Remove( module ); + module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) ); + // Retrieve last module state from undo list lastcmd = GetScreen()->PopCommandFromUndoList(); wrapper = lastcmd->PopItem(); - module = (MODULE *)wrapper.GetItem(); + module = (MODULE*) wrapper.GetItem(); delete lastcmd; if( module ) + { GetBoard()->Add( module, ADD_APPEND ); - + view->Add( module ); + module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) ); + module->ViewUpdate(); + } SetCurItem( NULL ); From 63b69d94be7aeda171b1319b8414ed6bb33746fd Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 12:10:28 +0200 Subject: [PATCH 032/123] Code formatting. --- include/core/typeinfo.h | 11 +++++------ pcbnew/module_editor_frame.h | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/include/core/typeinfo.h b/include/core/typeinfo.h index d995b14fcb..dbb066f4a8 100644 --- a/include/core/typeinfo.h +++ b/include/core/typeinfo.h @@ -148,15 +148,15 @@ struct remove_pointer * @return true, if aObject type equals T. */ template -bool IsA(const I *aObject) +bool IsA( const I* aObject ) { - return aObject && remove_pointer::type::ClassOf(aObject); + return aObject && remove_pointer::type::ClassOf( aObject ); } template -bool IsA(const I& aObject) +bool IsA( const I& aObject ) { - return remove_pointer::type::ClassOf(&aObject); + return remove_pointer::type::ClassOf( &aObject ); } /** @@ -168,7 +168,7 @@ bool IsA(const I& aObject) * @return down-casted object or NULL if type doesn't match Casted. */ template -Casted dyn_cast(From aObject) +Casted dyn_cast( From aObject ) { if( remove_pointer::type::ClassOf ( aObject ) ) return static_cast( aObject ); @@ -177,4 +177,3 @@ Casted dyn_cast(From aObject) } #endif // __KICAD_TYPEINFO_H - diff --git a/pcbnew/module_editor_frame.h b/pcbnew/module_editor_frame.h index f7e0dd4c2a..7a3f513afc 100644 --- a/pcbnew/module_editor_frame.h +++ b/pcbnew/module_editor_frame.h @@ -161,7 +161,7 @@ public: * and prepare, if needed the refresh of the 3D frame showing the footprint * do not forget to call the basic OnModify function to update auxiliary info */ - virtual void OnModify( ); + virtual void OnModify(); /** * Function ToPrinter From 6e34910b75ebdb021669422f40693848ac3c3682 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 13:50:27 +0200 Subject: [PATCH 033/123] Moved some layout editor specific tool actions to another class (PCB_EDITOR_CONTROL). --- pcbnew/CMakeLists.txt | 1 + pcbnew/tools/pcb_editor_control.cpp | 144 +++++++++++++++++++++++++++ pcbnew/tools/pcb_editor_control.h | 62 ++++++++++++ pcbnew/tools/pcb_tools.cpp | 2 + pcbnew/tools/pcbnew_control.cpp | 145 ++++++---------------------- pcbnew/tools/pcbnew_control.h | 4 +- 6 files changed, 238 insertions(+), 120 deletions(-) create mode 100644 pcbnew/tools/pcb_editor_control.cpp create mode 100644 pcbnew/tools/pcb_editor_control.h diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index f8253fb31f..3bb9580e90 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -262,6 +262,7 @@ set( PCBNEW_CLASS_SRCS tools/drawing_tool.cpp tools/edit_tool.cpp tools/pcbnew_control.cpp + tools/pcb_editor_control.cpp tools/pcb_tools.cpp tools/common_actions.cpp ) diff --git a/pcbnew/tools/pcb_editor_control.cpp b/pcbnew/tools/pcb_editor_control.cpp new file mode 100644 index 0000000000..a1b46c8a46 --- /dev/null +++ b/pcbnew/tools/pcb_editor_control.cpp @@ -0,0 +1,144 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 CERN + * @author Maciej Suminski + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "pcb_editor_control.h" +#include "common_actions.h" + +#include +#include +#include + +PCB_EDITOR_CONTROL::PCB_EDITOR_CONTROL() : + TOOL_INTERACTIVE( "pcbnew.EditorControl" ) +{ +} + + +void PCB_EDITOR_CONTROL::Reset( RESET_REASON aReason ) +{ + m_frame = getEditFrame(); +} + + +bool PCB_EDITOR_CONTROL::Init() +{ + setTransitions(); + + return true; +} + + +// Track & via size control +int PCB_EDITOR_CONTROL::TrackWidthInc( TOOL_EVENT& aEvent ) +{ + BOARD* board = getModel(); + int widthIndex = board->GetDesignSettings().GetTrackWidthIndex() + 1; + + if( widthIndex >= (int) board->GetDesignSettings().m_TrackWidthList.size() ) + widthIndex = board->GetDesignSettings().m_TrackWidthList.size() - 1; + + board->GetDesignSettings().SetTrackWidthIndex( widthIndex ); + board->GetDesignSettings().UseCustomTrackViaSize( false ); + + wxUpdateUIEvent dummy; + m_frame->OnUpdateSelectTrackWidth( dummy ); + setTransitions(); + + m_toolMgr->RunAction( COMMON_ACTIONS::trackViaSizeChanged ); + + return 0; +} + + +int PCB_EDITOR_CONTROL::TrackWidthDec( TOOL_EVENT& aEvent ) +{ + BOARD* board = getModel(); + int widthIndex = board->GetDesignSettings().GetTrackWidthIndex() - 1; + + if( widthIndex < 0 ) + widthIndex = 0; + + board->GetDesignSettings().SetTrackWidthIndex( widthIndex ); + board->GetDesignSettings().UseCustomTrackViaSize( false ); + + wxUpdateUIEvent dummy; + m_frame->OnUpdateSelectTrackWidth( dummy ); + setTransitions(); + + m_toolMgr->RunAction( COMMON_ACTIONS::trackViaSizeChanged ); + + return 0; +} + + +int PCB_EDITOR_CONTROL::ViaSizeInc( TOOL_EVENT& aEvent ) +{ + BOARD* board = getModel(); + int sizeIndex = board->GetDesignSettings().GetViaSizeIndex() + 1; + + if( sizeIndex >= (int) board->GetDesignSettings().m_ViasDimensionsList.size() ) + sizeIndex = board->GetDesignSettings().m_ViasDimensionsList.size() - 1; + + board->GetDesignSettings().SetViaSizeIndex( sizeIndex ); + board->GetDesignSettings().UseCustomTrackViaSize( false ); + + wxUpdateUIEvent dummy; + m_frame->OnUpdateSelectViaSize( dummy ); + setTransitions(); + + m_toolMgr->RunAction( COMMON_ACTIONS::trackViaSizeChanged ); + + return 0; +} + + +int PCB_EDITOR_CONTROL::ViaSizeDec( TOOL_EVENT& aEvent ) +{ + BOARD* board = getModel(); + int sizeIndex = board->GetDesignSettings().GetViaSizeIndex() - 1; + + if( sizeIndex < 0 ) + sizeIndex = 0; + + board->GetDesignSettings().SetViaSizeIndex( sizeIndex ); + board->GetDesignSettings().UseCustomTrackViaSize( false ); + + wxUpdateUIEvent dummy; + m_frame->OnUpdateSelectViaSize( dummy ); + setTransitions(); + + m_toolMgr->RunAction( COMMON_ACTIONS::trackViaSizeChanged ); + + return 0; +} + + +void PCB_EDITOR_CONTROL::setTransitions() +{ + // Track & via size control + Go( &PCB_EDITOR_CONTROL::TrackWidthInc, COMMON_ACTIONS::trackWidthInc.MakeEvent() ); + Go( &PCB_EDITOR_CONTROL::TrackWidthDec, COMMON_ACTIONS::trackWidthDec.MakeEvent() ); + Go( &PCB_EDITOR_CONTROL::ViaSizeInc, COMMON_ACTIONS::viaSizeInc.MakeEvent() ); + Go( &PCB_EDITOR_CONTROL::ViaSizeDec, COMMON_ACTIONS::viaSizeDec.MakeEvent() ); +} diff --git a/pcbnew/tools/pcb_editor_control.h b/pcbnew/tools/pcb_editor_control.h new file mode 100644 index 0000000000..50b9a6c691 --- /dev/null +++ b/pcbnew/tools/pcb_editor_control.h @@ -0,0 +1,62 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 CERN + * @author Maciej Suminski + * + * 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 PCB_EDITOR_CONTROL_H +#define PCB_EDITOR_CONTROL_H + +#include + +class PCB_EDIT_FRAME; + +/** + * Class PCBNEW_CONTROL + * + * Handles hot keys that are not accepted by any other tool. + */ +class PCB_EDITOR_CONTROL : public TOOL_INTERACTIVE +{ +public: + PCB_EDITOR_CONTROL(); + + /// @copydoc TOOL_INTERACTIVE::Reset() + void Reset( RESET_REASON aReason ); + + /// @copydoc TOOL_INTERACTIVE::Init() + bool Init(); + + // Track & via size control + int TrackWidthInc( TOOL_EVENT& aEvent ); + int TrackWidthDec( TOOL_EVENT& aEvent ); + int ViaSizeInc( TOOL_EVENT& aEvent ); + int ViaSizeDec( TOOL_EVENT& aEvent ); + +private: + ///> Sets up handlers for various events. + void setTransitions(); + + ///> Pointerto the currently used edit frame. + PCB_EDIT_FRAME* m_frame; +}; + +#endif diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index ee8af05595..6ba1a787e8 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -35,6 +35,7 @@ #include "drawing_tool.h" #include "point_editor.h" #include "pcbnew_control.h" +#include "pcb_editor_control.h" #include "common_actions.h" #include @@ -53,6 +54,7 @@ void PCB_EDIT_FRAME::setupTools() m_toolManager->RegisterTool( new DRAWING_TOOL ); m_toolManager->RegisterTool( new POINT_EDITOR ); m_toolManager->RegisterTool( new PCBNEW_CONTROL ); + m_toolManager->RegisterTool( new PCB_EDITOR_CONTROL ); m_toolManager->ResetTools( TOOL_BASE::RUN ); // Run the selection tool, it is supposed to be always active diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index 17b5b021aa..1702cfe64b 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -46,7 +46,7 @@ PCBNEW_CONTROL::PCBNEW_CONTROL() : void PCBNEW_CONTROL::Reset( RESET_REASON aReason ) { - m_frame = getEditFrame(); + m_frame = getEditFrame(); } @@ -149,7 +149,7 @@ int PCBNEW_CONTROL::TrackDisplayMode( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::PadDisplayMode( TOOL_EVENT& aEvent ) { wxCommandEvent dummy; - getEditFrame()->OnTogglePadDrawMode( dummy ); + m_frame->OnTogglePadDrawMode( dummy ); setTransitions(); return 0; @@ -219,8 +219,8 @@ int PCBNEW_CONTROL::HighContrastDec( TOOL_EVENT& aEvent ) // Layer control int PCBNEW_CONTROL::LayerTop( TOOL_EVENT& aEvent ) { - getEditFrame()->SwitchLayer( NULL, F_Cu ); - getEditFrame()->GetGalCanvas()->SetFocus(); + m_frame->SwitchLayer( NULL, F_Cu ); + m_frame->GetGalCanvas()->SetFocus(); setTransitions(); return 0; @@ -229,8 +229,8 @@ int PCBNEW_CONTROL::LayerTop( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::LayerInner1( TOOL_EVENT& aEvent ) { - getEditFrame()->SwitchLayer( NULL, In1_Cu ); - getEditFrame()->GetGalCanvas()->SetFocus(); + m_frame->SwitchLayer( NULL, In1_Cu ); + m_frame->GetGalCanvas()->SetFocus(); setTransitions(); return 0; @@ -239,8 +239,8 @@ int PCBNEW_CONTROL::LayerInner1( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::LayerInner2( TOOL_EVENT& aEvent ) { - getEditFrame()->SwitchLayer( NULL, In2_Cu ); - getEditFrame()->GetGalCanvas()->SetFocus(); + m_frame->SwitchLayer( NULL, In2_Cu ); + m_frame->GetGalCanvas()->SetFocus(); setTransitions(); return 0; @@ -249,8 +249,8 @@ int PCBNEW_CONTROL::LayerInner2( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::LayerInner3( TOOL_EVENT& aEvent ) { - getEditFrame()->SwitchLayer( NULL, In3_Cu ); - getEditFrame()->GetGalCanvas()->SetFocus(); + m_frame->SwitchLayer( NULL, In3_Cu ); + m_frame->GetGalCanvas()->SetFocus(); setTransitions(); return 0; @@ -259,8 +259,8 @@ int PCBNEW_CONTROL::LayerInner3( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::LayerInner4( TOOL_EVENT& aEvent ) { - getEditFrame()->SwitchLayer( NULL, In4_Cu ); - getEditFrame()->GetGalCanvas()->SetFocus(); + m_frame->SwitchLayer( NULL, In4_Cu ); + m_frame->GetGalCanvas()->SetFocus(); setTransitions(); return 0; @@ -269,8 +269,8 @@ int PCBNEW_CONTROL::LayerInner4( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::LayerInner5( TOOL_EVENT& aEvent ) { - getEditFrame()->SwitchLayer( NULL, In5_Cu ); - getEditFrame()->GetGalCanvas()->SetFocus(); + m_frame->SwitchLayer( NULL, In5_Cu ); + m_frame->GetGalCanvas()->SetFocus(); setTransitions(); return 0; @@ -279,8 +279,8 @@ int PCBNEW_CONTROL::LayerInner5( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::LayerInner6( TOOL_EVENT& aEvent ) { - getEditFrame()->SwitchLayer( NULL, In6_Cu ); - getEditFrame()->GetGalCanvas()->SetFocus(); + m_frame->SwitchLayer( NULL, In6_Cu ); + m_frame->GetGalCanvas()->SetFocus(); setTransitions(); return 0; @@ -289,8 +289,8 @@ int PCBNEW_CONTROL::LayerInner6( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::LayerBottom( TOOL_EVENT& aEvent ) { - getEditFrame()->SwitchLayer( NULL, B_Cu ); - getEditFrame()->GetGalCanvas()->SetFocus(); + m_frame->SetActiveLayer( B_Cu ); + m_frame->GetGalCanvas()->SetFocus(); setTransitions(); return 0; @@ -299,8 +299,8 @@ int PCBNEW_CONTROL::LayerBottom( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::LayerNext( TOOL_EVENT& aEvent ) { - PCB_EDIT_FRAME* editFrame = getEditFrame(); - LAYER_NUM layer = editFrame->GetActiveLayer(); + PCB_BASE_FRAME* editFrame = m_frame; + LAYER_NUM layer = editFrame->GetActiveLayer(); if( layer < F_Cu || layer >= B_Cu ) { @@ -325,8 +325,8 @@ int PCBNEW_CONTROL::LayerNext( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::LayerPrev( TOOL_EVENT& aEvent ) { - PCB_EDIT_FRAME* editFrame = getEditFrame(); - LAYER_NUM layer = editFrame->GetActiveLayer(); + PCB_BASE_FRAME* editFrame = m_frame; + LAYER_NUM layer = editFrame->GetActiveLayer(); if( layer <= F_Cu || layer > B_Cu ) { @@ -399,7 +399,7 @@ int PCBNEW_CONTROL::LayerAlphaDec( TOOL_EVENT& aEvent ) // Grid control int PCBNEW_CONTROL::GridFast1( TOOL_EVENT& aEvent ) { - getEditFrame()->SetFastGrid1(); + m_frame->SetFastGrid1(); setTransitions(); return 0; @@ -408,7 +408,7 @@ int PCBNEW_CONTROL::GridFast1( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::GridFast2( TOOL_EVENT& aEvent ) { - getEditFrame()->SetFastGrid2(); + m_frame->SetFastGrid2(); setTransitions(); return 0; @@ -417,7 +417,7 @@ int PCBNEW_CONTROL::GridFast2( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::GridNext( TOOL_EVENT& aEvent ) { - getEditFrame()->SetNextGrid(); + m_frame->SetNextGrid(); setTransitions(); return 0; @@ -426,7 +426,7 @@ int PCBNEW_CONTROL::GridNext( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::GridPrev( TOOL_EVENT& aEvent ) { - getEditFrame()->SetPrevGrid(); + m_frame->SetPrevGrid(); setTransitions(); return 0; @@ -436,7 +436,7 @@ int PCBNEW_CONTROL::GridPrev( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::GridSetOrigin( TOOL_EVENT& aEvent ) { Activate(); - getEditFrame()->SetToolID( ID_PCB_PLACE_GRID_COORD_BUTT, wxCURSOR_PENCIL, + m_frame->SetToolID( ID_PCB_PLACE_GRID_COORD_BUTT, wxCURSOR_PENCIL, _( "Adjust grid origin" ) ); KIGFX::VIEW_CONTROLS* controls = getViewControls(); @@ -466,91 +466,6 @@ int PCBNEW_CONTROL::GridSetOrigin( TOOL_EVENT& aEvent ) } -// Track & via size control -int PCBNEW_CONTROL::TrackWidthInc( TOOL_EVENT& aEvent ) -{ - BOARD* board = getModel(); - int widthIndex = board->GetDesignSettings().GetTrackWidthIndex() + 1; - - if( widthIndex >= (int) board->GetDesignSettings().m_TrackWidthList.size() ) - widthIndex = board->GetDesignSettings().m_TrackWidthList.size() - 1; - - board->GetDesignSettings().SetTrackWidthIndex( widthIndex ); - board->GetDesignSettings().UseCustomTrackViaSize( false ); - - wxUpdateUIEvent dummy; - getEditFrame()->OnUpdateSelectTrackWidth( dummy ); - setTransitions(); - - m_toolMgr->RunAction( COMMON_ACTIONS::trackViaSizeChanged ); - - return 0; -} - - -int PCBNEW_CONTROL::TrackWidthDec( TOOL_EVENT& aEvent ) -{ - BOARD* board = getModel(); - int widthIndex = board->GetDesignSettings().GetTrackWidthIndex() - 1; - - if( widthIndex < 0 ) - widthIndex = 0; - - board->GetDesignSettings().SetTrackWidthIndex( widthIndex ); - board->GetDesignSettings().UseCustomTrackViaSize( false ); - - wxUpdateUIEvent dummy; - getEditFrame()->OnUpdateSelectTrackWidth( dummy ); - setTransitions(); - - m_toolMgr->RunAction( COMMON_ACTIONS::trackViaSizeChanged ); - - return 0; -} - - -int PCBNEW_CONTROL::ViaSizeInc( TOOL_EVENT& aEvent ) -{ - BOARD* board = getModel(); - int sizeIndex = board->GetDesignSettings().GetViaSizeIndex() + 1; - - if( sizeIndex >= (int) board->GetDesignSettings().m_ViasDimensionsList.size() ) - sizeIndex = board->GetDesignSettings().m_ViasDimensionsList.size() - 1; - - board->GetDesignSettings().SetViaSizeIndex( sizeIndex ); - board->GetDesignSettings().UseCustomTrackViaSize( false ); - - wxUpdateUIEvent dummy; - getEditFrame()->OnUpdateSelectViaSize( dummy ); - setTransitions(); - - m_toolMgr->RunAction( COMMON_ACTIONS::trackViaSizeChanged ); - - return 0; -} - - -int PCBNEW_CONTROL::ViaSizeDec( TOOL_EVENT& aEvent ) -{ - BOARD* board = getModel(); - int sizeIndex = board->GetDesignSettings().GetViaSizeIndex() - 1; - - if( sizeIndex < 0 ) - sizeIndex = 0; - - board->GetDesignSettings().SetViaSizeIndex( sizeIndex ); - board->GetDesignSettings().UseCustomTrackViaSize( false ); - - wxUpdateUIEvent dummy; - getEditFrame()->OnUpdateSelectViaSize( dummy ); - setTransitions(); - - m_toolMgr->RunAction( COMMON_ACTIONS::trackViaSizeChanged ); - - return 0; -} - - // Miscellaneous int PCBNEW_CONTROL::ResetCoords( TOOL_EVENT& aEvent ) { @@ -630,12 +545,6 @@ void PCBNEW_CONTROL::setTransitions() Go( &PCBNEW_CONTROL::GridPrev, COMMON_ACTIONS::gridPrev.MakeEvent() ); Go( &PCBNEW_CONTROL::GridSetOrigin, COMMON_ACTIONS::gridSetOrigin.MakeEvent() ); - // Track & via size control - Go( &PCBNEW_CONTROL::TrackWidthInc, COMMON_ACTIONS::trackWidthInc.MakeEvent() ); - Go( &PCBNEW_CONTROL::TrackWidthDec, COMMON_ACTIONS::trackWidthDec.MakeEvent() ); - Go( &PCBNEW_CONTROL::ViaSizeInc, COMMON_ACTIONS::viaSizeInc.MakeEvent() ); - Go( &PCBNEW_CONTROL::ViaSizeDec, COMMON_ACTIONS::viaSizeDec.MakeEvent() ); - // Miscellaneous Go( &PCBNEW_CONTROL::ResetCoords, COMMON_ACTIONS::resetCoords.MakeEvent() ); Go( &PCBNEW_CONTROL::SwitchUnits, COMMON_ACTIONS::switchUnits.MakeEvent() ); diff --git a/pcbnew/tools/pcbnew_control.h b/pcbnew/tools/pcbnew_control.h index e4920484db..c5bd7e8841 100644 --- a/pcbnew/tools/pcbnew_control.h +++ b/pcbnew/tools/pcbnew_control.h @@ -27,7 +27,7 @@ #include -class PCB_EDIT_FRAME; +class PCB_BASE_FRAME; /** * Class PCBNEW_CONTROL @@ -97,7 +97,7 @@ private: void setTransitions(); ///> Pointerto the currently used edit frame. - PCB_EDIT_FRAME* m_frame; + PCB_BASE_FRAME* m_frame; }; #endif From 98c35ceab471ad1716a19458113da2833123b1c4 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 13:50:27 +0200 Subject: [PATCH 034/123] Created a common interface for edit frames. --- include/wxPcbStruct.h | 12 +++--- pcbnew/board_undo_redo.cpp | 4 +- pcbnew/modedit_onclick.cpp | 74 ++++++++++++++++++----------------- pcbnew/modedit_undo_redo.cpp | 4 +- pcbnew/module_editor_frame.h | 38 ++++++++++-------- pcbnew/moduleframe.cpp | 10 ++--- pcbnew/pcb_base_edit_frame.h | 69 ++++++++++++++++++++++++++++++++ pcbnew/pcbframe.cpp | 6 +-- pcbnew/tools/edit_tool.cpp | 2 +- pcbnew/tools/point_editor.cpp | 2 +- 10 files changed, 149 insertions(+), 72 deletions(-) create mode 100644 pcbnew/pcb_base_edit_frame.h diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 98d95c465d..6caca78ea1 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -30,7 +30,7 @@ #define WXPCB_STRUCT_H_ -#include +#include #include #include #include @@ -73,7 +73,7 @@ namespace PCB { struct IFACE; } // KIFACE_I is in pcbnew.cpp * * See also class PCB_BASE_FRAME(): Basic class for Pcbnew and GerbView. */ -class PCB_EDIT_FRAME : public PCB_BASE_FRAME +class PCB_EDIT_FRAME : public PCB_BASE_EDIT_FRAME { friend class PCB::IFACE; friend class PCB_LAYER_WIDGET; @@ -659,22 +659,22 @@ public: bool aRebuildRatsnet = true ); /** - * Function GetBoardFromRedoList + * Function RestoreCopyFromRedoList * Redo the last edition: * - Save the current board in Undo list * - Get an old version of the board from Redo list * @return none */ - void GetBoardFromRedoList( wxCommandEvent& aEvent ); + void RestoreCopyFromRedoList( wxCommandEvent& aEvent ); /** - * Function GetBoardFromUndoList + * Function RestoreCopyFromUndoList * Undo the last edition: * - Save the current board in Redo list * - Get an old version of the board from Undo list * @return none */ - void GetBoardFromUndoList( wxCommandEvent& aEvent ); + void RestoreCopyFromUndoList( wxCommandEvent& aEvent ); /* Block operations: */ diff --git a/pcbnew/board_undo_redo.cpp b/pcbnew/board_undo_redo.cpp index 56b5ca63d2..6bef956fc1 100644 --- a/pcbnew/board_undo_redo.cpp +++ b/pcbnew/board_undo_redo.cpp @@ -630,7 +630,7 @@ void PCB_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed } -void PCB_EDIT_FRAME::GetBoardFromUndoList( wxCommandEvent& aEvent ) +void PCB_EDIT_FRAME::RestoreCopyFromUndoList( wxCommandEvent& aEvent ) { if( GetScreen()->GetUndoCommandCount() <= 0 ) return; @@ -653,7 +653,7 @@ void PCB_EDIT_FRAME::GetBoardFromUndoList( wxCommandEvent& aEvent ) } -void PCB_EDIT_FRAME::GetBoardFromRedoList( wxCommandEvent& aEvent ) +void PCB_EDIT_FRAME::RestoreCopyFromRedoList( wxCommandEvent& aEvent ) { if( GetScreen()->GetRedoCommandCount() == 0 ) return; diff --git a/pcbnew/modedit_onclick.cpp b/pcbnew/modedit_onclick.cpp index 5fa0abb448..b6f4437e53 100644 --- a/pcbnew/modedit_onclick.cpp +++ b/pcbnew/modedit_onclick.cpp @@ -418,41 +418,7 @@ void FOOTPRINT_EDIT_FRAME::OnLeftDClick( wxDC* DC, const wxPoint& MousePos ) // Item found SetCurItem( item ); - - switch( item->Type() ) - { - case PCB_PAD_T: - InstallPadOptionsFrame( (D_PAD*) item ); - m_canvas->MoveCursorToCrossHair(); - break; - - case PCB_MODULE_T: - { - DIALOG_MODULE_MODULE_EDITOR dialog( this, (MODULE*) item ); - int ret = dialog.ShowModal(); - GetScreen()->GetCurItem()->ClearFlags(); - m_canvas->MoveCursorToCrossHair(); - - if( ret > 0 ) - m_canvas->Refresh(); - } - break; - - case PCB_MODULE_TEXT_T: - InstallTextModOptionsFrame( (TEXTE_MODULE*) item, DC ); - m_canvas->MoveCursorToCrossHair(); - break; - - case PCB_MODULE_EDGE_T : - m_canvas->MoveCursorToCrossHair(); - InstallFootprintBodyItemPropertiesDlg( (EDGE_MODULE*) item ); - m_canvas->Refresh(); - break; - - default: - break; - } - + OnEditItemRequest( DC, item ); break; // end case 0 case ID_PCB_ADD_LINE_BUTT: @@ -471,3 +437,41 @@ void FOOTPRINT_EDIT_FRAME::OnLeftDClick( wxDC* DC, const wxPoint& MousePos ) break; } } + + +void FOOTPRINT_EDIT_FRAME::OnEditItemRequest( wxDC* aDC, BOARD_ITEM* aItem ) +{ + switch( aItem->Type() ) + { + case PCB_PAD_T: + InstallPadOptionsFrame( (D_PAD*) aItem ); + m_canvas->MoveCursorToCrossHair(); + break; + + case PCB_MODULE_T: + { + DIALOG_MODULE_MODULE_EDITOR dialog( this, (MODULE*) aItem ); + int ret = dialog.ShowModal(); + GetScreen()->GetCurItem()->ClearFlags(); + m_canvas->MoveCursorToCrossHair(); + + if( ret > 0 ) + m_canvas->Refresh(); + } + break; + + case PCB_MODULE_TEXT_T: + InstallTextModOptionsFrame( (TEXTE_MODULE*) aItem, aDC ); + m_canvas->MoveCursorToCrossHair(); + break; + + case PCB_MODULE_EDGE_T : + m_canvas->MoveCursorToCrossHair(); + InstallFootprintBodyItemPropertiesDlg( (EDGE_MODULE*) aItem ); + m_canvas->Refresh(); + break; + + default: + break; + } +} diff --git a/pcbnew/modedit_undo_redo.cpp b/pcbnew/modedit_undo_redo.cpp index 4e057c3e3c..2b61e1e78e 100644 --- a/pcbnew/modedit_undo_redo.cpp +++ b/pcbnew/modedit_undo_redo.cpp @@ -66,7 +66,7 @@ void FOOTPRINT_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsLi } -void FOOTPRINT_EDIT_FRAME::GetComponentFromRedoList( wxCommandEvent& aEvent ) +void FOOTPRINT_EDIT_FRAME::RestoreCopyFromRedoList( wxCommandEvent& aEvent ) { if( GetScreen()->GetRedoCommandCount() <= 0 ) return; @@ -107,7 +107,7 @@ void FOOTPRINT_EDIT_FRAME::GetComponentFromRedoList( wxCommandEvent& aEvent ) } -void FOOTPRINT_EDIT_FRAME::GetComponentFromUndoList( wxCommandEvent& aEvent ) +void FOOTPRINT_EDIT_FRAME::RestoreCopyFromUndoList( wxCommandEvent& aEvent ) { if( GetScreen()->GetUndoCommandCount() <= 0 ) return; diff --git a/pcbnew/module_editor_frame.h b/pcbnew/module_editor_frame.h index 7a3f513afc..e72ea402bd 100644 --- a/pcbnew/module_editor_frame.h +++ b/pcbnew/module_editor_frame.h @@ -30,6 +30,7 @@ #define MODULE_EDITOR_FRAME_H_ #include +#include #include @@ -38,7 +39,7 @@ class FP_LIB_TABLE; namespace PCB { struct IFACE; } // A KIFACE_I coded in pcbnew.c -class FOOTPRINT_EDIT_FRAME : public PCB_BASE_FRAME +class FOOTPRINT_EDIT_FRAME : public PCB_BASE_EDIT_FRAME { friend struct PCB::IFACE; @@ -148,6 +149,9 @@ public: void OnUpdateReplaceModuleInBoard( wxUpdateUIEvent& aEvent ); void OnUpdateSelectCurrentLib( wxUpdateUIEvent& aEvent ); + ///> @copydoc PCB_BASE_EDIT_FRAME::OnEditItemRequest() + void OnEditItemRequest( wxDC* aDC, BOARD_ITEM* aItem ); + /** * Function LoadModuleFromBoard * called from the main toolbar to load a footprint from board mainly to edit it. @@ -244,6 +248,22 @@ public: UNDO_REDO_T aTypeCommand, const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ); + /** + * Function RestoreCopyFromUndoList + * performs an undo operation on the last edition: + * - Place the current edited library component in Redo list + * - Get old version of the current edited library component + */ + void RestoreCopyFromUndoList( wxCommandEvent& aEvent ); + + /** + * Function RestoreCopyFromRedoList + * performs a redo operation on the the last edition: + * - Place the current edited library component in undo list + * - Get old version of the current edited library component + */ + void RestoreCopyFromRedoList( wxCommandEvent& aEvent ); + /// Return the current library nickname. const wxString GetCurrentLib() const; @@ -413,22 +433,6 @@ protected: PCB_LAYER_WIDGET* m_Layers; - /** - * Function GetComponentFromUndoList - * performs an undo operation on the last edition: - * - Place the current edited library component in Redo list - * - Get old version of the current edited library component - */ - void GetComponentFromUndoList( wxCommandEvent& aEvent ); - - /** - * Function GetComponentFromRedoList - * performs a redo operation on the the last edition: - * - Place the current edited library component in undo list - * - Get old version of the current edited library component - */ - void GetComponentFromRedoList( wxCommandEvent& aEvent ); - /** * Function UpdateTitle * updates window title according to getLibNickName(). diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index 1649b24b74..cdd06bf229 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -99,8 +99,8 @@ BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME ) EVT_TOOL( ID_MODEDIT_INSERT_MODULE_IN_BOARD, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( ID_MODEDIT_UPDATE_MODULE_IN_BOARD, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( ID_MODEDIT_EDIT_MODULE_PROPERTIES, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) - EVT_TOOL( wxID_UNDO, FOOTPRINT_EDIT_FRAME::GetComponentFromUndoList ) - EVT_TOOL( wxID_REDO, FOOTPRINT_EDIT_FRAME::GetComponentFromRedoList ) + EVT_TOOL( wxID_UNDO, FOOTPRINT_EDIT_FRAME::RestoreCopyFromUndoList ) + EVT_TOOL( wxID_REDO, FOOTPRINT_EDIT_FRAME::RestoreCopyFromRedoList ) // Vertical tool bar button click event handler. EVT_TOOL( ID_NO_TOOL_SELECTED, FOOTPRINT_EDIT_FRAME::OnVerticalToolbar ) @@ -160,9 +160,9 @@ END_EVENT_TABLE() #define FOOTPRINT_EDIT_FRAME_NAME wxT( "ModEditFrame" ) FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : - PCB_BASE_FRAME( aKiway, aParent, FRAME_PCB_MODULE_EDITOR, wxEmptyString, - wxDefaultPosition, wxDefaultSize, - KICAD_DEFAULT_DRAWFRAME_STYLE, GetFootprintEditorFrameName() ) + PCB_BASE_EDIT_FRAME( aKiway, aParent, FRAME_PCB_MODULE_EDITOR, wxEmptyString, + wxDefaultPosition, wxDefaultSize, + KICAD_DEFAULT_DRAWFRAME_STYLE, GetFootprintEditorFrameName() ) { m_FrameName = GetFootprintEditorFrameName(); m_showBorderAndTitleBlock = false; // true to show the frame references diff --git a/pcbnew/pcb_base_edit_frame.h b/pcbnew/pcb_base_edit_frame.h new file mode 100644 index 0000000000..f1c66e160f --- /dev/null +++ b/pcbnew/pcb_base_edit_frame.h @@ -0,0 +1,69 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 CERN + * @author Maciej Suminski + * + * 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 BASE_EDIT_FRAME_H +#define BASE_EDIT_FRAME_H + +#include + +/** + * Common, abstract interface for edit frames. + */ +class PCB_BASE_EDIT_FRAME : public PCB_BASE_FRAME +{ +public: + PCB_BASE_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType, + const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, + long aStyle, const wxString& aFrameName ) : + PCB_BASE_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName ) + {} + + virtual ~PCB_BASE_EDIT_FRAME() {}; + + /** + * Function OnEditItemRequest + * Install the corresponding dialog editor for the given item + * @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; + + /** + * Function RestoreCopyFromRedoList + * Redo the last edition: + * - Save the current data in Undo list + * - Get an old version of the data from Redo list + */ + virtual void RestoreCopyFromRedoList( wxCommandEvent& aEvent ) = 0; + + /** + * Function RestoreCopyFromUndoList + * Undo the last edition: + * - Save the current board in Redo list + * - Get an old version of the data from Undo list + */ + virtual void RestoreCopyFromUndoList( wxCommandEvent& aEvent ) = 0; +}; + +#endif diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 6bb044b1b7..f744584e6c 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -187,8 +187,8 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME ) EVT_TOOL( wxID_CUT, PCB_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( wxID_COPY, PCB_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( wxID_PASTE, PCB_EDIT_FRAME::Process_Special_Functions ) - EVT_TOOL( wxID_UNDO, PCB_EDIT_FRAME::GetBoardFromUndoList ) - EVT_TOOL( wxID_REDO, PCB_EDIT_FRAME::GetBoardFromRedoList ) + EVT_TOOL( wxID_UNDO, PCB_EDIT_FRAME::RestoreCopyFromUndoList ) + EVT_TOOL( wxID_REDO, PCB_EDIT_FRAME::RestoreCopyFromRedoList ) EVT_TOOL( wxID_PRINT, PCB_EDIT_FRAME::ToPrinter ) EVT_TOOL( ID_GEN_PLOT_SVG, PCB_EDIT_FRAME::SVG_Print ) EVT_TOOL( ID_GEN_PLOT, PCB_EDIT_FRAME::Process_Special_Functions ) @@ -304,7 +304,7 @@ END_EVENT_TABLE() #define PCB_EDIT_FRAME_NAME wxT( "PcbFrame" ) PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : - PCB_BASE_FRAME( aKiway, aParent, FRAME_PCB, wxT( "Pcbnew" ), wxDefaultPosition, + PCB_BASE_EDIT_FRAME( aKiway, aParent, FRAME_PCB, wxT( "Pcbnew" ), wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, PCB_EDIT_FRAME_NAME ) { m_FrameName = PCB_EDIT_FRAME_NAME; diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index cc7e770e37..496bc92d8f 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -189,7 +189,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) { // Modifications have to be rollbacked, so restore the previous state of items wxCommandEvent dummy; - editFrame->GetBoardFromUndoList( dummy ); + editFrame->RestoreCopyFromUndoList( dummy ); } else { diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index eab541add2..22bde0c384 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -309,7 +309,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) if( modified ) // Restore the last change { wxCommandEvent dummy; - editFrame->GetBoardFromUndoList( dummy ); + editFrame->RestoreCopyFromUndoList( dummy ); updatePoints(); modified = false; From d41e93ef14e3e933d49252112b86495f07a05dee Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 13:50:27 +0200 Subject: [PATCH 035/123] Adapted tools to PCB_BASE{_EDIT}_FRAME. --- pcbnew/tools/common_actions.cpp | 11 ++- pcbnew/tools/common_actions.h | 3 +- pcbnew/tools/drawing_tool.cpp | 120 ++++++++++++++++++++++++++++++-- pcbnew/tools/drawing_tool.h | 17 +++-- pcbnew/tools/edit_tool.cpp | 12 ++-- pcbnew/tools/point_editor.cpp | 10 +-- pcbnew/tools/selection_tool.cpp | 16 +++-- pcbnew/tools/selection_tool.h | 4 ++ 8 files changed, 160 insertions(+), 33 deletions(-) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 73b67e462b..d96f42d3ee 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -67,7 +67,11 @@ TOOL_ACTION COMMON_ACTIONS::drawArc( "pcbnew.InteractiveDrawing.arc", AS_GLOBAL, 0, "Draw an arc", "Draw an arc" ); -TOOL_ACTION COMMON_ACTIONS::placeText( "pcbnew.InteractiveDrawing.text", +TOOL_ACTION COMMON_ACTIONS::placeTextModule( "pcbnew.InteractiveDrawing.textPcb", + AS_GLOBAL, 0, + "Add a text", "Add a text" ); + +TOOL_ACTION COMMON_ACTIONS::placeTextPcb( "pcbnew.InteractiveDrawing.textModule", AS_GLOBAL, 0, "Add a text", "Add a text" ); @@ -284,7 +288,10 @@ std::string COMMON_ACTIONS::TranslateLegacyId( int aId ) return COMMON_ACTIONS::drawArc.GetName(); case ID_PCB_ADD_TEXT_BUTT: - return COMMON_ACTIONS::placeText.GetName(); + return COMMON_ACTIONS::placeTextPcb.GetName(); + + case ID_MODEDIT_TEXT_TOOL: + return COMMON_ACTIONS::placeTextModule.GetName(); case ID_PCB_DIMENSION_BUTT: return COMMON_ACTIONS::drawDimension.GetName(); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 5ddb660dbb..986489da63 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -64,7 +64,8 @@ public: static TOOL_ACTION drawArc; /// Activation of the drawing tool (text) - static TOOL_ACTION placeText; + static TOOL_ACTION placeTextPcb; + static TOOL_ACTION placeTextModule; /// Activation of the drawing tool (dimension) static TOOL_ACTION drawDimension; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 050681ca2f..c33bd7a3fa 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -65,7 +65,7 @@ void DRAWING_TOOL::Reset( RESET_REASON aReason ) m_view = getView(); m_controls = getViewControls(); m_board = getModel(); - m_frame = getEditFrame(); + m_frame = getEditFrame(); setTransitions(); } @@ -281,7 +281,112 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) } -int DRAWING_TOOL::PlaceText( TOOL_EVENT& aEvent ) +int DRAWING_TOOL::PlaceTextModule( TOOL_EVENT& aEvent ) +{ + TEXTE_MODULE* text = NULL; + + // Add a VIEW_GROUP that serves as a preview for the new item + KIGFX::VIEW_GROUP preview( m_view ); + m_view->Add( &preview ); + + m_toolMgr->GetTool()->ClearSelection(); + m_controls->ShowCursor( true ); + m_controls->SetSnapping( true ); + m_controls->SetAutoPan( true ); + + Activate(); + m_frame->SetToolID( ID_PCB_ADD_TEXT_BUTT, wxCURSOR_PENCIL, _( "Add text" ) ); + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + VECTOR2I cursorPos = m_controls->GetCursorPosition(); + + if( evt->IsCancel() ) + { + if( text ) + { + // Delete the old text and have another try + m_board->Delete( text ); // it was already added by CreateTextPcb() + text = NULL; + + preview.Clear(); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + m_controls->ShowCursor( true ); + } + else + break; + } + + else if( text && evt->Category() == TC_COMMAND ) + { + if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) + { + text->Rotate( text->GetPosition(), 900.0 /*m_frame->GetRotationAngle()*/ ); // FIXME + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) + { + text->Flip( text->GetPosition() ); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + + else if( evt->IsClick( BUT_LEFT ) ) + { + if( !text ) + { + // Init the new item attributes + text = m_frame->CreateTextModule( m_frame->GetBoard()->m_Modules, NULL ); + + if( text == NULL ) + continue; + + m_controls->ShowCursor( false ); + preview.Add( text ); + } + else + { + assert( text->GetText().Length() > 0 ); + assert( text->GetSize().x > 0 && text->GetSize().y > 0 ); + + text->ClearFlags(); + m_view->Add( text ); + // m_board->Add( text ); // it is already added by CreateTextePcb() + text->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( text, UR_NEW ); + + preview.Remove( text ); + m_controls->ShowCursor( true ); + + text = NULL; + } + } + + else if( text && evt->IsMotion() ) + { + text->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) ); + + // Show a preview of the item + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + + m_controls->ShowCursor( false ); + m_controls->SetSnapping( false ); + m_controls->SetAutoPan( false ); + m_view->Remove( &preview ); + + setTransitions(); + m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); + + return 0; +} + + +int DRAWING_TOOL::PlaceTextPcb( TOOL_EVENT& aEvent ) { TEXTE_PCB* text = NULL; @@ -322,7 +427,7 @@ int DRAWING_TOOL::PlaceText( TOOL_EVENT& aEvent ) { if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) { - text->Rotate( text->GetPosition(), m_frame->GetRotationAngle() ); + text->Rotate( text->GetPosition(), /*m_frame->GetRotationAngle()*/ 900.0 ); // FIXME preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) @@ -337,7 +442,7 @@ int DRAWING_TOOL::PlaceText( TOOL_EVENT& aEvent ) if( !text ) { // Init the new item attributes - text = m_frame->CreateTextePcb( NULL ); + text = static_cast( m_frame )->CreateTextePcb( NULL ); if( text == NULL ) continue; @@ -698,7 +803,7 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) { if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) { - module->Rotate( module->GetPosition(), m_frame->GetRotationAngle() ); + module->Rotate( module->GetPosition(), /*m_frame->GetRotationAngle()*/ 900.0 ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) @@ -1029,7 +1134,7 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) m_view->Add( zone ); if( !aKeepout ) - m_frame->Fill_Zone( zone ); + static_cast( m_frame )->Fill_Zone( zone ); zone->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); @@ -1179,7 +1284,8 @@ void DRAWING_TOOL::setTransitions() Go( &DRAWING_TOOL::DrawDimension, COMMON_ACTIONS::drawDimension.MakeEvent() ); Go( &DRAWING_TOOL::DrawZone, COMMON_ACTIONS::drawZone.MakeEvent() ); Go( &DRAWING_TOOL::DrawKeepout, COMMON_ACTIONS::drawKeepout.MakeEvent() ); - Go( &DRAWING_TOOL::PlaceText, COMMON_ACTIONS::placeText.MakeEvent() ); + Go( &DRAWING_TOOL::PlaceTextPcb, COMMON_ACTIONS::placeTextPcb.MakeEvent() ); + Go( &DRAWING_TOOL::PlaceTextModule, COMMON_ACTIONS::placeTextModule.MakeEvent() ); Go( &DRAWING_TOOL::PlaceTarget, COMMON_ACTIONS::placeTarget.MakeEvent() ); Go( &DRAWING_TOOL::PlaceModule, COMMON_ACTIONS::placeModule.MakeEvent() ); } diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index e05a3a59ce..99427a77be 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -33,7 +33,7 @@ namespace KIGFX class VIEW_CONTROLS; } class BOARD; -class PCB_EDIT_FRAME; +class PCB_BASE_FRAME; class DRAWSEGMENT; /** @@ -76,11 +76,18 @@ public: int DrawArc( TOOL_EVENT& aEvent ); /** - * Function DrawText() + * Function PlaceTextModule() * Displays a dialog that allows to input text and its settings and then lets the user decide - * where to place the text. + * where to place the text in module editor. */ - int PlaceText( TOOL_EVENT& aEvent ); + int PlaceTextModule( TOOL_EVENT& aEvent ); + + /** + * Function PlaceTextPcb() + * Displays a dialog that allows to input text and its settings and then lets the user decide + * where to place the text in board editor. + */ + int PlaceTextPcb( TOOL_EVENT& aEvent ); /** * Function DrawDimension() @@ -143,7 +150,7 @@ private: KIGFX::VIEW* m_view; KIGFX::VIEW_CONTROLS* m_controls; BOARD* m_board; - PCB_EDIT_FRAME* m_frame; + PCB_BASE_FRAME* m_frame; // How does line width change after one -/+ key press. static const int WIDTH_STEP = 100000; diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 496bc92d8f..4d33c1ec07 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -93,7 +93,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) m_updateFlag = KIGFX::VIEW_ITEM::GEOMETRY; KIGFX::VIEW_CONTROLS* controls = getViewControls(); - PCB_EDIT_FRAME* editFrame = getEditFrame(); + PCB_BASE_EDIT_FRAME* editFrame = getEditFrame(); controls->ShowCursor( true ); controls->SetSnapping( true ); controls->SetAutoPan( true ); @@ -217,7 +217,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) { const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); - PCB_EDIT_FRAME* editFrame = getEditFrame(); + PCB_BASE_EDIT_FRAME* editFrame = getEditFrame(); if( !makeSelection( selection ) ) { @@ -286,7 +286,7 @@ int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) { const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); - PCB_EDIT_FRAME* editFrame = getEditFrame(); + PCB_BASE_FRAME* editFrame = getEditFrame(); // Shall the selection be cleared at the end? bool unselect = selection.Empty(); @@ -310,7 +310,7 @@ int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) { BOARD_ITEM* item = selection.Item( i ); - item->Rotate( rotatePoint, editFrame->GetRotationAngle() ); + item->Rotate( rotatePoint, 900.0 /*m_frame->GetRotationAngle()*/ ); if( !m_dragging ) item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); @@ -340,7 +340,7 @@ int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) { const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); - PCB_EDIT_FRAME* editFrame = getEditFrame(); + PCB_BASE_FRAME* editFrame = getEditFrame(); // Shall the selection be cleared at the end? bool unselect = selection.Empty(); @@ -404,7 +404,7 @@ int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) // Get a copy of the selected items set PICKED_ITEMS_LIST selectedItems = selection.items; - PCB_EDIT_FRAME* editFrame = getEditFrame(); + PCB_BASE_FRAME* editFrame = getEditFrame(); // As we are about to remove items, they have to be removed from the selection first m_selectionTool->ClearSelection(); diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 22bde0c384..fa9ae8b029 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -209,7 +209,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) KIGFX::VIEW_CONTROLS* controls = getViewControls(); KIGFX::VIEW* view = getView(); - PCB_EDIT_FRAME* editFrame = getEditFrame(); + PCB_BASE_EDIT_FRAME* editFrame = getEditFrame(); EDA_ITEM* item = selection.items.GetPickedItem( 0 ); m_editPoints = EDIT_POINTS_FACTORY::Make( item, getView()->GetGAL() ); @@ -661,8 +661,8 @@ void POINT_EDITOR::breakOutline( const VECTOR2I& aBreakPoint ) if( item->Type() == PCB_ZONE_AREA_T ) { - getEditFrame()->OnModify(); - getEditFrame()->SaveCopyInUndoList( selection.items, UR_CHANGED ); + getEditFrame()->OnModify(); + getEditFrame()->SaveCopyInUndoList( selection.items, UR_CHANGED ); ZONE_CONTAINER* zone = static_cast( item ); CPolyLine* outline = zone->Outline(); @@ -702,8 +702,8 @@ void POINT_EDITOR::breakOutline( const VECTOR2I& aBreakPoint ) else if( item->Type() == PCB_LINE_T ) { - getEditFrame()->OnModify(); - getEditFrame()->SaveCopyInUndoList( selection.items, UR_CHANGED ); + getEditFrame()->OnModify(); + getEditFrame()->SaveCopyInUndoList( selection.items, UR_CHANGED ); DRAWSEGMENT* segment = static_cast( item ); diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 591bfb9e3e..08fb358094 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -78,6 +78,8 @@ void SELECTION_TOOL::Reset( RESET_REASON aReason ) // Restore previous properties of selected items and remove them from containers ClearSelection(); + m_frame = getEditFrame(); + // Reinsert the VIEW_GROUP, in case it was removed from the VIEW getView()->Remove( m_selection.group ); getView()->Add( m_selection.group ); @@ -185,7 +187,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) bool SELECTION_TOOL::SelectSingle( const VECTOR2I& aWhere, bool aAllowDisambiguation ) { BOARD_ITEM* item; - GENERAL_COLLECTORS_GUIDE guide = getEditFrame()->GetCollectorsGuide(); + GENERAL_COLLECTORS_GUIDE guide = m_frame->GetCollectorsGuide(); GENERAL_COLLECTOR collector; const KICAD_T types[] = { PCB_TRACE_T, PCB_VIA_T, PCB_LINE_T, EOT }; // preferred types @@ -269,7 +271,7 @@ void SELECTION_TOOL::ClearSelection() } m_selection.clear(); - getEditFrame()->SetCurItem( NULL ); + m_frame->SetCurItem( NULL ); // Do not show the context menu when there is nothing selected SetContextMenu( &m_menu, CMENU_OFF ); @@ -370,7 +372,7 @@ bool SELECTION_TOOL::selectMultiple() } // Do not display information about selected item,as there is more than one - getEditFrame()->SetCurItem( NULL ); + m_frame->SetCurItem( NULL ); if( !m_selection.Empty() ) { @@ -586,7 +588,7 @@ void SELECTION_TOOL::select( BOARD_ITEM* aItem ) if( m_selection.Size() == 1 ) { // Set as the current item, so the information about selection is displayed - getEditFrame()->SetCurItem( aItem, true ); + m_frame->SetCurItem( aItem, true ); // Now the context menu should be enabled SetContextMenu( &m_menu, CMENU_BUTTON ); @@ -594,7 +596,7 @@ void SELECTION_TOOL::select( BOARD_ITEM* aItem ) 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 - getEditFrame()->SetCurItem( NULL, true ); + m_frame->SetCurItem( NULL, true ); } } @@ -619,7 +621,7 @@ void SELECTION_TOOL::deselect( BOARD_ITEM* aItem ) if( m_selection.Empty() ) { SetContextMenu( &m_menu, CMENU_OFF ); - getEditFrame()->SetCurItem( NULL ); + m_frame->SetCurItem( NULL ); } // Inform other potentially interested tools @@ -671,7 +673,7 @@ bool SELECTION_TOOL::selectionContains( const VECTOR2I& aPoint ) const void SELECTION_TOOL::highlightNet( const VECTOR2I& aPoint ) { KIGFX::RENDER_SETTINGS* render = getView()->GetPainter()->GetSettings(); - GENERAL_COLLECTORS_GUIDE guide = getEditFrame()->GetCollectorsGuide(); + GENERAL_COLLECTORS_GUIDE guide = m_frame->GetCollectorsGuide(); GENERAL_COLLECTOR collector; int net = -1; diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index 642b2ee358..fffd1ec27f 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -31,6 +31,7 @@ #include #include +class PCB_BASE_FRAME; class SELECTION_AREA; class BOARD_ITEM; class GENERAL_COLLECTOR; @@ -257,6 +258,9 @@ private: */ BOARD_ITEM* prefer( GENERAL_COLLECTOR& aCollector, const KICAD_T aTypes[] ) const; + /// Pointer to the parent frame. + PCB_BASE_FRAME* m_frame; + /// Visual representation of selection box SELECTION_AREA* m_selArea; From 43275ef943fcf9077f71b243b44ffeae4cc00796 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 13:50:27 +0200 Subject: [PATCH 036/123] Restored support for custom angle rotation. --- include/wxPcbStruct.h | 6 ------ pcbnew/CMakeLists.txt | 1 + pcbnew/pcb_base_edit_frame.cpp | 33 +++++++++++++++++++++++++++++++++ pcbnew/pcb_base_edit_frame.h | 10 +++++++++- pcbnew/pcbframe.cpp | 10 ---------- pcbnew/tools/edit_tool.cpp | 4 ++-- 6 files changed, 45 insertions(+), 19 deletions(-) create mode 100644 pcbnew/pcb_base_edit_frame.cpp diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 6caca78ea1..fa7d78323e 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -87,9 +87,6 @@ class PCB_EDIT_FRAME : public PCB_BASE_EDIT_FRAME /// The auxiliary right vertical tool bar used to access the microwave tools. wxAuiToolBar* m_microWaveToolBar; - /// User defined rotation angle (in tenths of a degree). - int m_rotationAngle; - /** * Function loadFootprints * loads the footprints for each #COMPONENT in \a aNetlist from the list of libraries. @@ -315,9 +312,6 @@ public: */ virtual void SetGridColor(EDA_COLOR_T aColor); - int GetRotationAngle() const { return m_rotationAngle; } - void SetRotationAngle( int aRotationAngle ); - // Configurations: void Process_Config( wxCommandEvent& event ); diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 3bb9580e90..2884741b8a 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -160,6 +160,7 @@ set( PCBNEW_CLASS_SRCS tool_modview.cpp modview_frame.cpp pcbframe.cpp + pcb_base_edit_frame.cpp attribut.cpp board_items_to_polygon_shape_transform.cpp board_undo_redo.cpp diff --git a/pcbnew/pcb_base_edit_frame.cpp b/pcbnew/pcb_base_edit_frame.cpp new file mode 100644 index 0000000000..e4aa24108b --- /dev/null +++ b/pcbnew/pcb_base_edit_frame.cpp @@ -0,0 +1,33 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 CERN + * @author Maciej Suminski + * + * 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 + +void PCB_BASE_EDIT_FRAME::SetRotationAngle( int aRotationAngle ) +{ + wxCHECK2_MSG( aRotationAngle > 0 && aRotationAngle <= 900, aRotationAngle = 900, + wxT( "Invalid rotation angle, defaulting to 90." ) ); + + m_rotationAngle = aRotationAngle; +} diff --git a/pcbnew/pcb_base_edit_frame.h b/pcbnew/pcb_base_edit_frame.h index f1c66e160f..3d867874d6 100644 --- a/pcbnew/pcb_base_edit_frame.h +++ b/pcbnew/pcb_base_edit_frame.h @@ -36,7 +36,8 @@ public: PCB_BASE_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, long aStyle, const wxString& aFrameName ) : - PCB_BASE_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName ) + PCB_BASE_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName ), + m_rotationAngle( 900 ) {} virtual ~PCB_BASE_EDIT_FRAME() {}; @@ -64,6 +65,13 @@ public: * - Get an old version of the data from Undo list */ virtual void RestoreCopyFromUndoList( wxCommandEvent& aEvent ) = 0; + + int GetRotationAngle() const { return m_rotationAngle; } + void SetRotationAngle( int aRotationAngle ); + +protected: + /// User defined rotation angle (in tenths of a degree). + int m_rotationAngle; }; #endif diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index f744584e6c..45267d2e0a 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -1021,13 +1021,3 @@ void PCB_EDIT_FRAME::ToPlotter( wxCommandEvent& event ) dlg.ShowModal(); } - - -void PCB_EDIT_FRAME::SetRotationAngle( int aRotationAngle ) -{ - wxCHECK2_MSG( aRotationAngle > 0 && aRotationAngle <= 900, aRotationAngle = 900, - wxT( "Invalid rotation angle, defaulting to 90." ) ); - - m_rotationAngle = aRotationAngle; -} - diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 4d33c1ec07..5fa5359fe5 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -286,7 +286,7 @@ int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) { const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); - PCB_BASE_FRAME* editFrame = getEditFrame(); + PCB_BASE_EDIT_FRAME* editFrame = getEditFrame(); // Shall the selection be cleared at the end? bool unselect = selection.Empty(); @@ -310,7 +310,7 @@ int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) { BOARD_ITEM* item = selection.Item( i ); - item->Rotate( rotatePoint, 900.0 /*m_frame->GetRotationAngle()*/ ); + item->Rotate( rotatePoint, editFrame->GetRotationAngle() ); if( !m_dragging ) item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); From 946ffb2ad96de1397945ec9e9d702c3a5d4c619c Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 13:50:27 +0200 Subject: [PATCH 037/123] Restored std::map in TOOL_MANAGER. --- common/tool/tool_manager.cpp | 6 +++--- include/tool/tool_manager.h | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index 8f052d57fa..4aa62d2e99 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -109,7 +109,7 @@ TOOL_MANAGER::TOOL_MANAGER() : TOOL_MANAGER::~TOOL_MANAGER() { - boost::unordered_map::iterator it, it_end; + std::map::iterator it, it_end; for( it = m_toolState.begin(), it_end = m_toolState.end(); it != it_end; ++it ) { @@ -276,7 +276,7 @@ bool TOOL_MANAGER::runTool( TOOL_BASE* aTool ) TOOL_BASE* TOOL_MANAGER::FindTool( int aId ) const { - boost::unordered_map::const_iterator it = m_toolIdIndex.find( aId ); + std::map::const_iterator it = m_toolIdIndex.find( aId ); if( it != m_toolIdIndex.end() ) return it->second->theTool; @@ -287,7 +287,7 @@ TOOL_BASE* TOOL_MANAGER::FindTool( int aId ) const TOOL_BASE* TOOL_MANAGER::FindTool( const std::string& aName ) const { - boost::unordered_map::const_iterator it = m_toolNameIndex.find( aName ); + std::map::const_iterator it = m_toolNameIndex.find( aName ); if( it != m_toolNameIndex.end() ) return it->second->theTool; diff --git a/include/tool/tool_manager.h b/include/tool/tool_manager.h index 62f7e42e8a..6969483664 100644 --- a/include/tool/tool_manager.h +++ b/include/tool/tool_manager.h @@ -28,7 +28,7 @@ #include #include -#include +#include #include @@ -143,7 +143,7 @@ public: template T* GetTool() { - boost::unordered_map::iterator tool = m_toolTypes.find( typeid( T ).name() ); + std::map::iterator tool = m_toolTypes.find( typeid( T ).name() ); if( tool != m_toolTypes.end() ) return static_cast( tool->second ); @@ -360,16 +360,16 @@ private: bool isActive( TOOL_BASE* aTool ); /// Index of registered tools current states, associated by tools' objects. - boost::unordered_map m_toolState; + std::map m_toolState; /// Index of the registered tools current states, associated by tools' names. - boost::unordered_map m_toolNameIndex; + std::map m_toolNameIndex; /// Index of the registered tools to easily lookup by their type. - boost::unordered_map m_toolTypes; + std::map m_toolTypes; /// Index of the registered tools current states, associated by tools' ID numbers. - boost::unordered_map m_toolIdIndex; + std::map m_toolIdIndex; /// Stack of the active tools std::deque m_activeTools; From 3587f47cca04d1d1dabd9a24f4a9dc1a7390a691 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 13:50:27 +0200 Subject: [PATCH 038/123] Minor fixes to the Tool Framework. --- common/tool/tool_manager.cpp | 2 -- include/tool/coroutine.h | 22 +++++++++++++++------- include/tool/tool_event.h | 4 ---- include/tool/tool_manager.h | 3 --- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index 4aa62d2e99..4ce84ca2ba 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -470,8 +470,6 @@ void TOOL_MANAGER::finishTool( TOOL_STATE* aState ) bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent ) { -// wxLogDebug( "event: %s", aEvent.Format().c_str() ); - // Early dispatch of events destined for the TOOL_MANAGER if( !dispatchStandardEvents( aEvent ) ) return false; diff --git a/include/tool/coroutine.h b/include/tool/coroutine.h index 9daab59cb2..3385dece7d 100644 --- a/include/tool/coroutine.h +++ b/include/tool/coroutine.h @@ -56,11 +56,10 @@ template class COROUTINE { public: - COROUTINE() + COROUTINE() : + m_saved( NULL ), m_self( NULL ), m_stack( NULL ), m_stackSize( c_defaultStackSize ), + m_running( false ) { - m_stackSize = c_defaultStackSize; - m_stack = NULL; - m_saved = NULL; } /** @@ -69,7 +68,8 @@ public: */ template COROUTINE( T* object, ReturnType(T::* ptr)( ArgType ) ) : - m_func( object, ptr ), m_saved( NULL ), m_stack( NULL ), m_stackSize( c_defaultStackSize ) + m_func( object, ptr ), m_self( NULL ), m_saved( NULL ), m_stack( NULL ), + m_stackSize( c_defaultStackSize ), m_running( false ) { } @@ -78,8 +78,10 @@ public: * Creates a coroutine from a delegate object */ COROUTINE( DELEGATE aEntry ) : - m_func( aEntry ), m_saved( NULL ), m_stack( NULL ), m_stackSize( c_defaultStackSize ) - {}; + m_func( aEntry ), m_saved( NULL ), m_self( NULL ), m_stack( NULL ), + m_stackSize( c_defaultStackSize ), m_running( false ) + { + } ~COROUTINE() { @@ -138,6 +140,12 @@ public: // align to 16 bytes void* sp = (void*) ( ( ( (ptrdiff_t) m_stack ) + m_stackSize - 0xf ) & ( ~0x0f ) ); + // correct the stack size + m_stackSize -= ( (size_t) m_stack + m_stackSize - (size_t) sp ); + + assert( m_self == NULL ); + assert( m_saved == NULL ); + m_args = &aArgs; m_self = boost::context::make_fcontext( sp, m_stackSize, callerStub ); m_saved = new boost::context::fcontext_t(); diff --git a/include/tool/tool_event.h b/include/tool/tool_event.h index bdfe8a8a10..49f8fe55f1 100644 --- a/include/tool/tool_event.h +++ b/include/tool/tool_event.h @@ -318,9 +318,6 @@ public: if( m_commandId && aEvent.m_commandId ) return *m_commandId == *aEvent.m_commandId; - - // Command-type event has to contain either id or string - assert( false ); } return true; @@ -496,7 +493,6 @@ inline const TOOL_EVENT_LIST operator||( const TOOL_EVENT& aEventA, const TOOL_E return l; } - inline const TOOL_EVENT_LIST operator||( const TOOL_EVENT& aEvent, const TOOL_EVENT_LIST& aEventList ) { diff --git a/include/tool/tool_manager.h b/include/tool/tool_manager.h index 6969483664..54ec87bf57 100644 --- a/include/tool/tool_manager.h +++ b/include/tool/tool_manager.h @@ -384,9 +384,6 @@ private: /// Flag saying if the currently processed event should be passed to other tools. bool m_passEvent; - - /// Pointer to the tool on the top of the active tools stack. - TOOL_STATE* m_currentTool; }; #endif From d63dd3fa70fd4fc4fc823b88d745deb94c265639 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 13:50:27 +0200 Subject: [PATCH 039/123] Implemented stacking for TOOL_STATEs. --- common/tool/tool_manager.cpp | 153 +++++++++++++++++++++++++---------- 1 file changed, 111 insertions(+), 42 deletions(-) diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index 4ce84ca2ba..1147304d5b 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -25,6 +25,8 @@ #include #include +#include +#include #include #include @@ -51,6 +53,32 @@ using boost::optional; /// Struct describing the current execution state of a TOOL struct TOOL_MANAGER::TOOL_STATE { + TOOL_STATE( TOOL_BASE* aTool ) : + theTool( aTool ) + { + clear(); + } + + TOOL_STATE( const TOOL_STATE& aState ) + { + theTool = aState.theTool; + idle = aState.idle; + pendingWait = aState.pendingWait; + pendingContextMenu = aState.pendingContextMenu; + contextMenu = aState.contextMenu; + contextMenuTrigger = aState.contextMenuTrigger; + cofunc = aState.cofunc; + wakeupEvent = aState.wakeupEvent; + waitEvents = aState.waitEvents; + transitions = aState.transitions; + // do not copy stateStack + } + + ~TOOL_STATE() + { + assert( stateStack.empty() ); + } + /// The tool itself TOOL_BASE* theTool; @@ -83,6 +111,21 @@ struct TOOL_MANAGER::TOOL_STATE /// upon the event reception std::vector transitions; + void operator=( const TOOL_STATE& aState ) + { + theTool = aState.theTool; + idle = aState.idle; + pendingWait = aState.pendingWait; + pendingContextMenu = aState.pendingContextMenu; + contextMenu = aState.contextMenu; + contextMenuTrigger = aState.contextMenuTrigger; + cofunc = aState.cofunc; + wakeupEvent = aState.wakeupEvent; + waitEvents = aState.waitEvents; + transitions = aState.transitions; + // do not copy stateStack + } + bool operator==( const TOOL_MANAGER::TOOL_STATE& aRhs ) const { return aRhs.theTool == this->theTool; @@ -92,6 +135,48 @@ struct TOOL_MANAGER::TOOL_STATE { return aRhs.theTool != this->theTool; } + + void Push() + { + stateStack.push( *this ); + + clear(); + } + + bool Pop() + { + delete cofunc; + + if( !stateStack.empty() ) + { + *this = stateStack.top(); + stateStack.pop(); + + return true; + } + else + { + cofunc = NULL; + + return false; + } + } + +private: + ///> Stack preserving previous states of a TOOL. + std::stack stateStack; + + ///> Restores the initial state. + void clear() + { + idle = true; + pendingWait = false; + pendingContextMenu = false; + cofunc = NULL; + contextMenu = NULL; + contextMenuTrigger = CMENU_OFF; + transitions.clear(); + } }; @@ -118,7 +203,6 @@ TOOL_MANAGER::~TOOL_MANAGER() delete it->first; // delete the tool itself } - m_toolState.clear(); delete m_actionMgr; } @@ -132,13 +216,7 @@ void TOOL_MANAGER::RegisterTool( TOOL_BASE* aTool ) wxASSERT_MSG( m_toolTypes.find( typeid( *aTool ).name() ) == m_toolTypes.end(), wxT( "Adding two tools of the same type may result in unexpected behaviour.") ); - TOOL_STATE* st = new TOOL_STATE; - - st->theTool = aTool; - st->pendingWait = false; - st->pendingContextMenu = false; - st->cofunc = NULL; - st->contextMenuTrigger = CMENU_OFF; + TOOL_STATE* st = new TOOL_STATE( aTool ); m_toolState[aTool] = st; m_toolNameIndex[aTool->GetName()] = st; @@ -379,35 +457,31 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent ) BOOST_FOREACH( TOOL_STATE* st, m_toolState | boost::adaptors::map_values ) { - // the tool scheduled next state(s) by calling Go() - if( !st->pendingWait ) + // no state handler in progress - check if there are any transitions (defined by + // Go() method that match the event. + if( !st->pendingWait && !st->transitions.empty() ) { - // no state handler in progress - check if there are any transitions (defined by - // Go() method that match the event. - if( st->transitions.size() ) + BOOST_FOREACH( TRANSITION& tr, st->transitions ) { - BOOST_FOREACH( TRANSITION& tr, st->transitions ) + if( tr.first.Matches( aEvent ) ) { - if( tr.first.Matches( aEvent ) ) - { - // as the state changes, the transition table has to be set up again - st->transitions.clear(); + // no tool context allocated yet? Create one. + if( st->cofunc ) + st->Push(); - // no tool context allocated yet? Create one. - if( !st->cofunc ) - st->cofunc = new COROUTINE( tr.second ); - else - st->cofunc->SetEntry( tr.second ); + // as the state changes, the transition table has to be set up again + st->transitions.clear(); - // got match? Run the handler. - st->cofunc->Call( aEvent ); + st->cofunc = new COROUTINE( tr.second ); - if( !st->cofunc->Running() ) - finishTool( st ); // The couroutine has finished immediately? + // got match? Run the handler. + st->cofunc->Call( aEvent ); - // there is no point in further checking, as transitions got cleared - break; - } + if( !st->cofunc->Running() ) + finishTool( st ); // The couroutine has finished immediately? + + // there is no point in further checking, as transitions got cleared + break; } } } @@ -451,20 +525,15 @@ bool TOOL_MANAGER::dispatchActivation( TOOL_EVENT& aEvent ) void TOOL_MANAGER::finishTool( TOOL_STATE* aState ) { - std::deque::iterator it, itEnd; - - // Find the tool and deactivate it - for( it = m_activeTools.begin(), itEnd = m_activeTools.end(); it != itEnd; ++it ) + if( !aState->Pop() ) // if there are no other contexts saved on the stack { - if( aState == m_toolIdIndex[*it] ) - { - m_activeTools.erase( it ); - break; - } - } + // find the tool and deactivate it + std::deque::iterator tool = std::find( m_activeTools.begin(), m_activeTools.end(), + aState->theTool->GetId() ); - delete aState->cofunc; - aState->cofunc = NULL; + if( tool != m_activeTools.end() ) + m_activeTools.erase( tool ); + } } From 4933fb3f2cb655b761910da1a019bf3252f7ef52 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 13:50:27 +0200 Subject: [PATCH 040/123] Restored invocation of SELECTION_TOOL commands with TOOL_ACTIONs. --- pcbnew/router/router_tool.cpp | 3 +- pcbnew/tools/common_actions.cpp | 9 +- pcbnew/tools/common_actions.h | 6 + pcbnew/tools/drawing_tool.cpp | 17 ++- pcbnew/tools/edit_tool.cpp | 14 +-- pcbnew/tools/selection_tool.cpp | 196 +++++++++++++++++++------------- pcbnew/tools/selection_tool.h | 47 ++++---- 7 files changed, 171 insertions(+), 121 deletions(-) diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 09951064d9..7416c14c17 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -40,7 +40,6 @@ #include #include -#include #include @@ -637,7 +636,7 @@ int ROUTER_TOOL::Main( TOOL_EVENT& aEvent ) BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings(); // Deselect all items - m_toolMgr->GetTool()->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); getEditFrame()->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Interactive Router" ) ); diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index d96f42d3ee..23d66b4249 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -31,17 +31,22 @@ TOOL_ACTION COMMON_ACTIONS::selectionActivate( "pcbnew.InteractiveSelection", AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere +TOOL_ACTION COMMON_ACTIONS::selectionSingle( "pcbnew.InteractiveSelection.Single", + AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere + +TOOL_ACTION COMMON_ACTIONS::selectionClear( "pcbnew.InteractiveSelection.Clear", + AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere // Edit tool actions TOOL_ACTION COMMON_ACTIONS::editActivate( "pcbnew.InteractiveEdit", AS_GLOBAL, 'M', "Move", "Moves the selected item(s)" ); -TOOL_ACTION COMMON_ACTIONS::rotate( "pcbnew.rotate", +TOOL_ACTION COMMON_ACTIONS::rotate( "pcbnew.InteractiveEdit.rotate", AS_GLOBAL, 'R', "Rotate", "Rotates selected item(s)" ); -TOOL_ACTION COMMON_ACTIONS::flip( "pcbnew.flip", +TOOL_ACTION COMMON_ACTIONS::flip( "pcbnew.InteractiveEdit.flip", AS_GLOBAL, 'F', "Flip", "Flips selected item(s)" ); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 986489da63..800a085f2a 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -37,6 +37,12 @@ public: /// Activation of the selection tool static TOOL_ACTION selectionActivate; + /// Select a single item under the cursor position + static TOOL_ACTION selectionSingle; + + /// Clears the current selection + static TOOL_ACTION selectionClear; + // Edit Tool /// Activation of the edit tool static TOOL_ACTION editActivate; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index c33bd7a3fa..9d3cf63670 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -38,7 +38,6 @@ #include #include #include -#include "selection_tool.h" #include #include @@ -103,7 +102,7 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->GetTool()->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); @@ -289,7 +288,7 @@ int DRAWING_TOOL::PlaceTextModule( TOOL_EVENT& aEvent ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->GetTool()->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); m_controls->SetAutoPan( true ); @@ -394,7 +393,7 @@ int DRAWING_TOOL::PlaceTextPcb( TOOL_EVENT& aEvent ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->GetTool()->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); m_controls->SetAutoPan( true ); @@ -500,7 +499,7 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->GetTool()->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); @@ -696,7 +695,7 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) m_view->Add( &preview ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - m_toolMgr->GetTool()->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->SetSnapping( true ); m_controls->SetAutoPan( true ); @@ -771,7 +770,7 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->GetTool()->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); m_controls->SetAutoPan( true ); @@ -882,7 +881,7 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->GetTool()->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); @@ -1058,7 +1057,7 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->GetTool()->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 5fa5359fe5..1db8267981 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -48,7 +48,7 @@ EDIT_TOOL::EDIT_TOOL() : bool EDIT_TOOL::Init() { // Find the selection tool, so they can cooperate - m_selectionTool = m_toolMgr->GetTool(); + m_selectionTool = static_cast( m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ) ); if( !m_selectionTool ) { @@ -198,7 +198,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) } if( unselect ) - m_selectionTool->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); RN_DATA* ratsnest = getModel()->GetRatsnest(); ratsnest->ClearSimple(); @@ -251,7 +251,7 @@ int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) std::vector& undoList = editFrame->GetScreen()->m_UndoList.m_CommandsList; // Some of properties dialogs alter pointers, so we should deselect them - m_selectionTool->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); STATUS_FLAGS flags = item->GetFlags(); item->ClearFlags(); @@ -328,7 +328,7 @@ int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) getModel()->GetRatsnest()->Recalculate(); if( unselect ) - m_selectionTool->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate ); setTransitions(); @@ -382,7 +382,7 @@ int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) getModel()->GetRatsnest()->Recalculate(); if( unselect ) - m_selectionTool->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate ); setTransitions(); @@ -407,7 +407,7 @@ int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) PCB_BASE_FRAME* editFrame = getEditFrame(); // As we are about to remove items, they have to be removed from the selection first - m_selectionTool->ClearSelection(); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); // Save them for( unsigned int i = 0; i < selectedItems.GetCount(); ++i ) @@ -525,7 +525,7 @@ wxPoint EDIT_TOOL::getModificationPoint( const SELECTION_TOOL::SELECTION& aSelec bool EDIT_TOOL::makeSelection( const SELECTION_TOOL::SELECTION& aSelection ) { if( aSelection.Empty() ) // Try to find an item that could be modified - m_selectionTool->SelectSingle( getView()->ToWorld( getViewControls()->GetMousePosition() ) ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionSingle ); return !aSelection.Empty(); } diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 08fb358094..ef6d9d0446 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -76,7 +76,7 @@ void SELECTION_TOOL::Reset( RESET_REASON aReason ) m_selection.clear(); else // Restore previous properties of selected items and remove them from containers - ClearSelection(); + clearSelection(); m_frame = getEditFrame(); @@ -84,8 +84,7 @@ void SELECTION_TOOL::Reset( RESET_REASON aReason ) getView()->Remove( m_selection.group ); getView()->Add( m_selection.group ); - // The tool launches upon reception of action event ("pcbnew.InteractiveSelection") - Go( &SELECTION_TOOL::Main, COMMON_ACTIONS::selectionActivate.MakeEvent() ); + setTransitions(); } @@ -98,13 +97,8 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) // become the new selection (discarding previously selected items) m_additive = evt->Modifier( MD_SHIFT ); - if( evt->IsCancel() || evt->Action() == TA_UNDO_REDO ) - { - ClearSelection(); - } - // single click? Select single object - else if( evt->IsClick( BUT_LEFT ) ) + if( evt->IsClick( BUT_LEFT ) ) { if( evt->Modifier( MD_CTRL ) ) { @@ -113,9 +107,9 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) else { if( !m_additive ) - ClearSelection(); + clearSelection(); - SelectSingle( evt->Position() ); + selectSingle( evt->Position() ); } } @@ -123,7 +117,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) else if( evt->IsClick( BUT_RIGHT ) ) { if( m_selection.Empty() ) - SelectSingle( evt->Position() ); + selectSingle( evt->Position() ); if( !m_selection.Empty() ) SetContextMenu( &m_menu, CMENU_NOW ); @@ -133,7 +127,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) else if( evt->IsDblClick( BUT_LEFT ) ) { if( m_selection.Empty() ) - SelectSingle( evt->Position() ); + selectSingle( evt->Position() ); m_toolMgr->RunAction( COMMON_ACTIONS::properties ); } @@ -148,7 +142,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) else if( m_selection.Empty() ) { // There is nothing selected, so try to select something - if( !SelectSingle( getView()->ToWorld( getViewControls()->GetMousePosition() ), false ) ) + if( !selectSingle( getView()->ToWorld( getViewControls()->GetMousePosition() ), false ) ) { // If nothings has been selected or user wants to select more // draw the selection box @@ -171,10 +165,22 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) else { // No -> clear the selection list - ClearSelection(); + clearSelection(); } } } + + else if( evt->IsAction( &COMMON_ACTIONS::selectionSingle ) ) + { + // GetMousePosition() is used, as it is independent of snapping settings + selectSingle( getView()->ToWorld( getViewControls()->GetMousePosition() ) ); + } + + else if( evt->IsCancel() || evt->Action() == TA_UNDO_REDO || + evt->IsAction( &COMMON_ACTIONS::selectionClear ) ) + { + clearSelection(); + } } // This tool is supposed to be active forever @@ -184,7 +190,43 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) } -bool SELECTION_TOOL::SelectSingle( const VECTOR2I& aWhere, bool aAllowDisambiguation ) +void SELECTION_TOOL::AddMenuItem( const TOOL_ACTION& aAction ) +{ + assert( aAction.GetId() > 0 ); // Check if the action was registered before in ACTION_MANAGER + + m_menu.Add( aAction ); +} + + +void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem ) +{ + if( aItem->IsSelected() ) + { + deselect( aItem ); + + // Inform other potentially interested tools + TOOL_EVENT deselectEvent( DeselectedEvent ); + m_toolMgr->ProcessEvent( deselectEvent ); + } + else + { + if( !m_additive ) + clearSelection(); + + // Prevent selection of invisible or inactive items + if( selectable( aItem ) ) + { + select( aItem ); + + // Inform other potentially interested tools + TOOL_EVENT selectEvent( SelectedEvent ); + m_toolMgr->ProcessEvent( selectEvent ); + } + } +} + + +bool SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere, bool aAllowDisambiguation ) { BOARD_ITEM* item; GENERAL_COLLECTORS_GUIDE guide = m_frame->GetCollectorsGuide(); @@ -202,7 +244,7 @@ bool SELECTION_TOOL::SelectSingle( const VECTOR2I& aWhere, bool aAllowDisambigua { case 0: if( !m_additive ) - ClearSelection(); + clearSelection(); return false; @@ -254,70 +296,6 @@ bool SELECTION_TOOL::SelectSingle( const VECTOR2I& aWhere, bool aAllowDisambigua } -void SELECTION_TOOL::ClearSelection() -{ - if( m_selection.Empty() ) - return; - - KIGFX::VIEW_GROUP::const_iter it, it_end; - - // Restore the initial properties - for( it = m_selection.group->Begin(), it_end = m_selection.group->End(); it != it_end; ++it ) - { - BOARD_ITEM* item = static_cast( *it ); - - item->ViewSetVisible( true ); - item->ClearSelected(); - } - m_selection.clear(); - - m_frame->SetCurItem( NULL ); - - // Do not show the context menu when there is nothing selected - SetContextMenu( &m_menu, CMENU_OFF ); - - // Inform other potentially interested tools - TOOL_EVENT clearEvent( ClearedEvent ); - m_toolMgr->ProcessEvent( clearEvent ); -} - - -void SELECTION_TOOL::AddMenuItem( const TOOL_ACTION& aAction ) -{ - assert( aAction.GetId() > 0 ); // Check if the action was registered before in ACTION_MANAGER - - m_menu.Add( aAction ); -} - - -void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem ) -{ - if( aItem->IsSelected() ) - { - deselect( aItem ); - - // Inform other potentially interested tools - TOOL_EVENT deselectEvent( DeselectedEvent ); - m_toolMgr->ProcessEvent( deselectEvent ); - } - else - { - if( !m_additive ) - ClearSelection(); - - // Prevent selection of invisible or inactive items - if( selectable( aItem ) ) - { - select( aItem ); - - // Inform other potentially interested tools - TOOL_EVENT selectEvent( SelectedEvent ); - m_toolMgr->ProcessEvent( selectEvent ); - } - } -} - - bool SELECTION_TOOL::selectMultiple() { bool cancelled = false; // Was the tool cancelled while it was running? @@ -338,7 +316,7 @@ bool SELECTION_TOOL::selectMultiple() if( evt->IsDrag( BUT_LEFT ) ) { if( !m_additive ) - ClearSelection(); + clearSelection(); // Start drawing a selection box m_selArea->SetOrigin( evt->DragOrigin() ); @@ -393,6 +371,60 @@ bool SELECTION_TOOL::selectMultiple() } +void SELECTION_TOOL::setTransitions() +{ + Go( &SELECTION_TOOL::Main, COMMON_ACTIONS::selectionActivate.MakeEvent() ); + Go( &SELECTION_TOOL::SingleSelection, COMMON_ACTIONS::selectionSingle.MakeEvent() ); + Go( &SELECTION_TOOL::ClearSelection, COMMON_ACTIONS::selectionClear.MakeEvent() ); +} + + +int SELECTION_TOOL::SingleSelection( TOOL_EVENT& aEvent ) +{ + selectSingle( getView()->ToWorld( getViewControls()->GetMousePosition() ) ); + setTransitions(); + + return 0; +} + +int SELECTION_TOOL::ClearSelection( TOOL_EVENT& aEvent ) +{ + clearSelection(); + setTransitions(); + + return 0; +} + +void SELECTION_TOOL::clearSelection() +{ + if( m_selection.Empty() ) + return; + + KIGFX::VIEW_GROUP::const_iter it, it_end; + + // Restore the initial properties + for( it = m_selection.group->Begin(), it_end = m_selection.group->End(); it != it_end; ++it ) + { + BOARD_ITEM* item = static_cast( *it ); + + item->ViewSetVisible( true ); + item->ClearSelected(); + } + m_selection.clear(); + + getEditFrame()->SetCurItem( NULL ); + + // Do not show the context menu when there is nothing selected + SetContextMenu( &m_menu, CMENU_OFF ); + + // Inform other potentially interested tools + TOOL_EVENT clearEvent( ClearedEvent ); + m_toolMgr->ProcessEvent( clearEvent ); + + return; +} + + BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector ) { BOARD_ITEM* current = NULL; diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index fffd1ec27f..6f5e06606d 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -48,7 +48,7 @@ class VIEW_GROUP; * - pick single objects (click LMB) * - add objects to existing selection (Shift+LMB) * - draw selection box (drag LMB) - * - handles MODULEs properly (ie. selects either MODULE or its PADs, TEXTs, etc.) + * - handles MODULEs properly (i.e. selects either MODULE or its PADs, TEXTs, etc.) * - takes into account high-contrast & layer visibility settings * - invokes InteractiveEdit tool when user starts to drag selected items */ @@ -114,24 +114,6 @@ public: return m_selection; } - /** - * Function SelectSingle() - * Selects an item pointed by the parameter aWhere. If there is more than one item at that - * place, there is a menu displayed that allows to choose the item. - * - * @param aWhere is the place where the item should be selected. - * @param aAllowDisambiguation decides what to do in case of disambiguation. If true, then - * a menu is shown, otherise function finishes without selecting anything. - * @return True if an item was selected, false otherwise. - */ - bool SelectSingle( const VECTOR2I& aWhere, bool aAllowDisambiguation = true ); - - /** - * Function ClearSelection() - * Clears the current selection. - */ - void ClearSelection(); - /** * Function AddMenuItem() * @@ -160,7 +142,25 @@ public: ///> Event sent after selection is cleared. const TOOL_EVENT ClearedEvent; + ///> Select single item event handler. + int SingleSelection( TOOL_EVENT& aEvent ); + + ///> Clear current selection event handler. + int ClearSelection( TOOL_EVENT& aEvent ); + private: + /** + * Function selectSingle() + * Selects an item pointed by the parameter aWhere. If there is more than one item at that + * place, there is a menu displayed that allows to choose the item. + * + * @param aWhere is the place where the item should be selected. + * @param aAllowDisambiguation decides what to do in case of disambiguation. If true, then + * a menu is shown, otherise function finishes without selecting anything. + * @return True if an item was selected, false otherwise. + */ + bool selectSingle( const VECTOR2I& aWhere, bool aAllowDisambiguation = true ); + /** * Function selectMultiple() * Handles drawing a selection box that allows to select many items at the same time. @@ -169,6 +169,15 @@ private: */ bool selectMultiple(); + ///> Sets up handlers for various events. + void setTransitions(); + + /** + * Function ClearSelection() + * Clears the current selection. + */ + void clearSelection(); + /** * Function disambiguationMenu() * Handles the menu that allows to select one of many items in case there is more than one From acdf9dd65cceda6c473b5bbcd53fdd11c3fd80c5 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 13:50:27 +0200 Subject: [PATCH 041/123] Added required resets for tools. --- pcbnew/loadcmp.cpp | 2 ++ pcbnew/modedit.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/pcbnew/loadcmp.cpp b/pcbnew/loadcmp.cpp index 47a4728e92..21113267a2 100644 --- a/pcbnew/loadcmp.cpp +++ b/pcbnew/loadcmp.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -126,6 +127,7 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule ) m_Pcb->ComputeBoundingBox( false ); EDA_RECT boardBbox = m_Pcb->GetBoundingBox(); GetGalCanvas()->GetView()->SetViewport( BOX2D( boardBbox.GetOrigin(), boardBbox.GetSize() ) ); + m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD ); } return true; diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp index 1d3283a276..ba76b1e0de 100644 --- a/pcbnew/modedit.cpp +++ b/pcbnew/modedit.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -935,6 +936,7 @@ void FOOTPRINT_EDIT_FRAME::UseGalCanvas( bool aEnable ) { SetBoard( m_Pcb ); + m_toolManager->ResetTools( TOOL_BASE::GAL_SWITCH ); GetGalCanvas()->StartDrawing(); } } From b020162d790b64526f61fb31f854ef395e6313fe Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 13:50:27 +0200 Subject: [PATCH 042/123] Rotate support for pads. --- pcbnew/class_pad.cpp | 7 +++++++ pcbnew/class_pad.h | 1 + 2 files changed, 8 insertions(+) diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index 246a766c9d..ef2be10951 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -829,6 +829,13 @@ int D_PAD::Compare( const D_PAD* padref, const D_PAD* padcmp ) } +void D_PAD::Rotate( const wxPoint& aRotCentre, double aAngle ) +{ + RotatePoint( &m_Pos, aRotCentre, aAngle ); + m_Orient += aAngle; +} + + wxString D_PAD::ShowPadShape() const { switch( GetShape() ) diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index 53666d9e4c..7fc41f8dcd 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -400,6 +400,7 @@ public: SetLocalCoord(); } + void Rotate( const wxPoint& aRotCentre, double aAngle ); wxString GetSelectMenuText() const; From 7a5d144d9d7a5195ee4f721c36af4c3cedbc97a6 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 13:50:27 +0200 Subject: [PATCH 043/123] SELECTION_TOOL in edit module mode does not try to select MODULEs. --- pcbnew/collectors.cpp | 11 ++++++++++- pcbnew/collectors.h | 8 +++++++- pcbnew/controle.cpp | 4 ++-- pcbnew/tools/selection_tool.cpp | 2 +- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/pcbnew/collectors.cpp b/pcbnew/collectors.cpp index a2e1d845f8..cb99353899 100644 --- a/pcbnew/collectors.cpp +++ b/pcbnew/collectors.cpp @@ -86,7 +86,7 @@ const KICAD_T GENERAL_COLLECTOR::AllButZones[] = { }; -const KICAD_T GENERAL_COLLECTOR::ModuleItems[] = { +const KICAD_T GENERAL_COLLECTOR::Modules[] = { PCB_MODULE_T, EOT }; @@ -118,12 +118,21 @@ const KICAD_T GENERAL_COLLECTOR::ModulesAndTheirItems[] = { }; +const KICAD_T GENERAL_COLLECTOR::ModuleItems[] = { + PCB_MODULE_TEXT_T, + PCB_MODULE_EDGE_T, + PCB_PAD_T, + EOT +}; + + const KICAD_T GENERAL_COLLECTOR::Tracks[] = { PCB_TRACE_T, PCB_VIA_T, EOT }; + const KICAD_T GENERAL_COLLECTOR::Zones[] = { PCB_ZONE_AREA_T, EOT diff --git a/pcbnew/collectors.h b/pcbnew/collectors.h index 267ec20034..4d2520c06d 100644 --- a/pcbnew/collectors.h +++ b/pcbnew/collectors.h @@ -262,7 +262,7 @@ public: /** * A scan list for only MODULEs */ - static const KICAD_T ModuleItems[]; + static const KICAD_T Modules[]; /** @@ -282,6 +282,12 @@ public: static const KICAD_T ModulesAndTheirItems[]; + /** + * A scan list for primary module items. + */ + static const KICAD_T ModuleItems[]; + + /** * A scan list for only TRACKS */ diff --git a/pcbnew/controle.cpp b/pcbnew/controle.cpp index c5f1d00f9f..911a473dda 100644 --- a/pcbnew/controle.cpp +++ b/pcbnew/controle.cpp @@ -119,7 +119,7 @@ BOARD_ITEM* PCB_BASE_FRAME::PcbGeneralLocateAndDisplay( int aHotKeyCode ) else if( GetToolId() == ID_NO_TOOL_SELECTED ) { if( m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_MODULE ) ) - scanList = GENERAL_COLLECTOR::ModuleItems; + scanList = GENERAL_COLLECTOR::Modules; else scanList = (DisplayOpt.DisplayZonesMode == 0) ? GENERAL_COLLECTOR::AllBoardItems : @@ -138,7 +138,7 @@ BOARD_ITEM* PCB_BASE_FRAME::PcbGeneralLocateAndDisplay( int aHotKeyCode ) break; case ID_PCB_MODULE_BUTT: - scanList = GENERAL_COLLECTOR::ModuleItems; + scanList = GENERAL_COLLECTOR::Modules; break; case ID_PCB_ZONES_BUTT: diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index ef6d9d0446..ac9f1aa51c 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -234,7 +234,7 @@ bool SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere, bool aAllowDisambigua const KICAD_T types[] = { PCB_TRACE_T, PCB_VIA_T, PCB_LINE_T, EOT }; // preferred types if( m_editModules ) - collector.Collect( getModel(), GENERAL_COLLECTOR::ModulesAndTheirItems, + collector.Collect( getModel(), GENERAL_COLLECTOR::ModuleItems, wxPoint( aWhere.x, aWhere.y ), guide ); else collector.Collect( getModel(), GENERAL_COLLECTOR::AllBoardItems, From d4ae51d0241dceb32860b778c320c904af1986ac Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 13:50:27 +0200 Subject: [PATCH 044/123] Module editor loads the last edited footprint in GAL mode. --- pcbnew/loadcmp.cpp | 10 +--------- pcbnew/modedit.cpp | 3 +-- pcbnew/module_editor_frame.h | 3 +++ pcbnew/moduleframe.cpp | 26 ++++++++++++++++++++++++++ 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/pcbnew/loadcmp.cpp b/pcbnew/loadcmp.cpp index 21113267a2..a794f3f685 100644 --- a/pcbnew/loadcmp.cpp +++ b/pcbnew/loadcmp.cpp @@ -49,7 +49,6 @@ #include #include #include -#include #include #include @@ -121,14 +120,7 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule ) Zoom_Automatique( false ); if( IsGalCanvasActive() ) - { - static_cast( GetGalCanvas() )->DisplayBoard( GetBoard() ); - - m_Pcb->ComputeBoundingBox( false ); - EDA_RECT boardBbox = m_Pcb->GetBoundingBox(); - GetGalCanvas()->GetView()->SetViewport( BOX2D( boardBbox.GetOrigin(), boardBbox.GetSize() ) ); - m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD ); - } + updateView(); return true; } diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp index ba76b1e0de..d51e1550a5 100644 --- a/pcbnew/modedit.cpp +++ b/pcbnew/modedit.cpp @@ -935,8 +935,7 @@ void FOOTPRINT_EDIT_FRAME::UseGalCanvas( bool aEnable ) if( aEnable ) { SetBoard( m_Pcb ); - - m_toolManager->ResetTools( TOOL_BASE::GAL_SWITCH ); + updateView(); GetGalCanvas()->StartDrawing(); } } diff --git a/pcbnew/module_editor_frame.h b/pcbnew/module_editor_frame.h index e72ea402bd..9a3f0379a2 100644 --- a/pcbnew/module_editor_frame.h +++ b/pcbnew/module_editor_frame.h @@ -439,6 +439,9 @@ protected: */ void updateTitle(); + /// Reloads displayed items and sets view. + void updateView(); + /// The libPath is not publicly visible, grab it from the FP_LIB_TABLE if we must. const wxString getLibPath(); diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index cdd06bf229..451f5a9130 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -680,3 +680,29 @@ void FOOTPRINT_EDIT_FRAME::updateTitle() SetTitle( title ); } + + +void FOOTPRINT_EDIT_FRAME::updateView() +{ + static_cast( GetGalCanvas() )->DisplayBoard( GetBoard() ); + + m_Pcb->ComputeBoundingBox( false ); + EDA_RECT boardBbox = m_Pcb->GetBoundingBox(); + BOX2D bbox; + + if( boardBbox.GetSize().x > 0 && boardBbox.GetSize().y > 0 ) + { + bbox.SetOrigin( VECTOR2D( boardBbox.GetOrigin() ) ); + bbox.SetSize( VECTOR2D( boardBbox.GetSize() ) ); + } + else + { + // Default empty view + bbox.SetOrigin( VECTOR2D( -1000, -1000 ) ); + bbox.SetSize( VECTOR2D( 2000, 2000 ) ); + } + + GetGalCanvas()->GetView()->SetViewport( bbox ); + + m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD ); +} From cc7d97319ac44681fc0f1e785442f61cece3db24 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 13:50:27 +0200 Subject: [PATCH 045/123] Module editor: modules are shown in GAL mode when loaded from file/library. --- pcbnew/librairi.cpp | 1 + pcbnew/modedit.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/pcbnew/librairi.cpp b/pcbnew/librairi.cpp index 556726d826..b793856792 100644 --- a/pcbnew/librairi.cpp +++ b/pcbnew/librairi.cpp @@ -274,6 +274,7 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module() PlaceModule( module, NULL ); GetBoard()->m_Status_Pcb = 0; GetBoard()->BuildListOfNets(); + updateView(); return module; } diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp index d51e1550a5..c813011dd6 100644 --- a/pcbnew/modedit.cpp +++ b/pcbnew/modedit.cpp @@ -541,6 +541,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) m_Draw3DFrame->NewDisplay(); GetScreen()->ClrModify(); + updateView(); break; From 6b61ea547f27717034083c98613bcab71390923e Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 13:50:27 +0200 Subject: [PATCH 046/123] Corrected names of common tool actions. --- pcbnew/tools/common_actions.cpp | 76 +++++++++++++++++---------------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 23d66b4249..cd41f0e96c 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -37,6 +37,7 @@ TOOL_ACTION COMMON_ACTIONS::selectionSingle( "pcbnew.InteractiveSelection.Single TOOL_ACTION COMMON_ACTIONS::selectionClear( "pcbnew.InteractiveSelection.Clear", AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere + // Edit tool actions TOOL_ACTION COMMON_ACTIONS::editActivate( "pcbnew.InteractiveEdit", AS_GLOBAL, 'M', @@ -109,160 +110,161 @@ TOOL_ACTION COMMON_ACTIONS::pointEditorUpdate( "pcbnew.PointEditor.update", // View Controls -TOOL_ACTION COMMON_ACTIONS::zoomIn( "pcbnew.zoomIn", +TOOL_ACTION COMMON_ACTIONS::zoomIn( "pcbnew.Control.zoomIn", AS_GLOBAL, WXK_F1, "", "" ); -TOOL_ACTION COMMON_ACTIONS::zoomOut( "pcbnew.zoomOut", +TOOL_ACTION COMMON_ACTIONS::zoomOut( "pcbnew.Control.zoomOut", AS_GLOBAL, WXK_F2, "", "" ); -TOOL_ACTION COMMON_ACTIONS::zoomInCenter( "pcbnew.zoomInCenter", +TOOL_ACTION COMMON_ACTIONS::zoomInCenter( "pcbnew.Control.zoomInCenter", AS_GLOBAL, 0, "", "" ); -TOOL_ACTION COMMON_ACTIONS::zoomOutCenter( "pcbnew.zoomOutCenter", +TOOL_ACTION COMMON_ACTIONS::zoomOutCenter( "pcbnew.Control.zoomOutCenter", AS_GLOBAL, 0, "", "" ); -TOOL_ACTION COMMON_ACTIONS::zoomCenter( "pcbnew.zoomCenter", +TOOL_ACTION COMMON_ACTIONS::zoomCenter( "pcbnew.Control.zoomCenter", AS_GLOBAL, WXK_F4, "", "" ); -TOOL_ACTION COMMON_ACTIONS::zoomFitScreen( "pcbnew.zoomFitScreen", +TOOL_ACTION COMMON_ACTIONS::zoomFitScreen( "pcbnew.Control.zoomFitScreen", AS_GLOBAL, WXK_HOME, "", "" ); // Display modes -TOOL_ACTION COMMON_ACTIONS::trackDisplayMode( "pcbnew.trackDisplayMode", +TOOL_ACTION COMMON_ACTIONS::trackDisplayMode( "pcbnew.Control.trackDisplayMode", AS_GLOBAL, 'K', "", "" ); -TOOL_ACTION COMMON_ACTIONS::padDisplayMode( "pcbnew.padDisplayMode", +TOOL_ACTION COMMON_ACTIONS::padDisplayMode( "pcbnew.Control.padDisplayMode", AS_GLOBAL, 'J', // TODO temporarily, find a better hot key "", "" ); -TOOL_ACTION COMMON_ACTIONS::viaDisplayMode( "pcbnew.viaDisplayMode", +TOOL_ACTION COMMON_ACTIONS::viaDisplayMode( "pcbnew.Control.viaDisplayMode", AS_GLOBAL, 'L', // TODO temporarily, find a better hot key "", "" ); -TOOL_ACTION COMMON_ACTIONS::highContrastMode( "pcbnew.highContrastMode", +TOOL_ACTION COMMON_ACTIONS::highContrastMode( "pcbnew.Control.highContrastMode", AS_GLOBAL, 'H', "", "" ); -TOOL_ACTION COMMON_ACTIONS::highContrastInc( "pcbnew.highContrastInc", +TOOL_ACTION COMMON_ACTIONS::highContrastInc( "pcbnew.Control.highContrastInc", AS_GLOBAL, '>', "", "" ); -TOOL_ACTION COMMON_ACTIONS::highContrastDec( "pcbnew.highContrastDec", +TOOL_ACTION COMMON_ACTIONS::highContrastDec( "pcbnew.Control.highContrastDec", AS_GLOBAL, '<', "", "" ); // Layer control -TOOL_ACTION COMMON_ACTIONS::layerTop( "pcbnew.layerTop", +TOOL_ACTION COMMON_ACTIONS::layerTop( "pcbnew.Control.layerTop", AS_GLOBAL, WXK_PAGEUP, "", "" ); -TOOL_ACTION COMMON_ACTIONS::layerInner1( "pcbnew.layerInner1", +TOOL_ACTION COMMON_ACTIONS::layerInner1( "pcbnew.Control.layerInner1", AS_GLOBAL, WXK_F5, "", "" ); -TOOL_ACTION COMMON_ACTIONS::layerInner2( "pcbnew.layerInner2", +TOOL_ACTION COMMON_ACTIONS::layerInner2( "pcbnew.Control.layerInner2", AS_GLOBAL, WXK_F6, "", "" ); -TOOL_ACTION COMMON_ACTIONS::layerInner3( "pcbnew.layerInner3", +TOOL_ACTION COMMON_ACTIONS::layerInner3( "pcbnew.Control.layerInner3", AS_GLOBAL, WXK_F7, "", "" ); -TOOL_ACTION COMMON_ACTIONS::layerInner4( "pcbnew.layerInner4", +TOOL_ACTION COMMON_ACTIONS::layerInner4( "pcbnew.Control.layerInner4", AS_GLOBAL, WXK_F8, "", "" ); -TOOL_ACTION COMMON_ACTIONS::layerInner5( "pcbnew.layerInner5", +TOOL_ACTION COMMON_ACTIONS::layerInner5( "pcbnew.Control.layerInner5", AS_GLOBAL, WXK_F9, "", "" ); -TOOL_ACTION COMMON_ACTIONS::layerInner6( "pcbnew.layerInner6", +TOOL_ACTION COMMON_ACTIONS::layerInner6( "pcbnew.Control.layerInner6", AS_GLOBAL, WXK_F10, "", "" ); -TOOL_ACTION COMMON_ACTIONS::layerBottom( "pcbnew.layerBottom", +TOOL_ACTION COMMON_ACTIONS::layerBottom( "pcbnew.Control.layerBottom", AS_GLOBAL, WXK_PAGEDOWN, "", "" ); -TOOL_ACTION COMMON_ACTIONS::layerNext( "pcbnew.layerNext", +TOOL_ACTION COMMON_ACTIONS::layerNext( "pcbnew.Control.layerNext", AS_GLOBAL, '=', "", "" ); -TOOL_ACTION COMMON_ACTIONS::layerPrev( "pcbnew.layerPrev", +TOOL_ACTION COMMON_ACTIONS::layerPrev( "pcbnew.Control.layerPrev", AS_GLOBAL, '-', "", "" ); -TOOL_ACTION COMMON_ACTIONS::layerAlphaInc( "pcbnew.layerAlphaInc", +TOOL_ACTION COMMON_ACTIONS::layerAlphaInc( "pcbnew.Control.layerAlphaInc", AS_GLOBAL, '}', "", "" ); -TOOL_ACTION COMMON_ACTIONS::layerAlphaDec( "pcbnew.layerAlphaDec", +TOOL_ACTION COMMON_ACTIONS::layerAlphaDec( "pcbnew.Control.layerAlphaDec", AS_GLOBAL, '{', "", "" ); // Grid control -TOOL_ACTION COMMON_ACTIONS::gridFast1( "pcbnew.gridFast1", +TOOL_ACTION COMMON_ACTIONS::gridFast1( "pcbnew.Control.gridFast1", AS_GLOBAL, MD_ALT + int( '1' ), "", "" ); -TOOL_ACTION COMMON_ACTIONS::gridFast2( "pcbnew.gridFast2", +TOOL_ACTION COMMON_ACTIONS::gridFast2( "pcbnew.Control.gridFast2", AS_GLOBAL, MD_ALT + int( '2' ), "", "" ); -TOOL_ACTION COMMON_ACTIONS::gridNext( "pcbnew.gridNext", +TOOL_ACTION COMMON_ACTIONS::gridNext( "pcbnew.Control.gridNext", AS_GLOBAL, '`', "", "" ); -TOOL_ACTION COMMON_ACTIONS::gridPrev( "pcbnew.gridPrev", +TOOL_ACTION COMMON_ACTIONS::gridPrev( "pcbnew.Control.gridPrev", AS_GLOBAL, MD_CTRL + int( '`' ), "", "" ); -TOOL_ACTION COMMON_ACTIONS::gridSetOrigin( "pcbnew.gridSetOrigin", +TOOL_ACTION COMMON_ACTIONS::gridSetOrigin( "pcbnew.Control.gridSetOrigin", AS_GLOBAL, 0, "", "" ); // Track & via size control -TOOL_ACTION COMMON_ACTIONS::trackWidthInc( "pcbnew.trackWidthInc", +TOOL_ACTION COMMON_ACTIONS::trackWidthInc( "pcbnew.EditorControl.trackWidthInc", AS_GLOBAL, '[', "", "" ); -TOOL_ACTION COMMON_ACTIONS::trackWidthDec( "pcbnew.trackWidthDec", +TOOL_ACTION COMMON_ACTIONS::trackWidthDec( "pcbnew.EditorControl.trackWidthDec", AS_GLOBAL, ']', "", "" ); -TOOL_ACTION COMMON_ACTIONS::viaSizeInc( "pcbnew.viaSizeInc", +TOOL_ACTION COMMON_ACTIONS::viaSizeInc( "pcbnew.EditorControl.viaSizeInc", AS_GLOBAL, '\'', "", "" ); -TOOL_ACTION COMMON_ACTIONS::viaSizeDec( "pcbnew.viaSizeDec", +TOOL_ACTION COMMON_ACTIONS::viaSizeDec( "pcbnew.EditorControl.viaSizeDec", AS_GLOBAL, '\\', "", "" ); -TOOL_ACTION COMMON_ACTIONS::trackViaSizeChanged( "pcbnew.trackViaSizeChanged", +TOOL_ACTION COMMON_ACTIONS::trackViaSizeChanged( "pcbnew.EditorControl.trackViaSizeChanged", AS_GLOBAL, 0, "", "" ); + // Miscellaneous -TOOL_ACTION COMMON_ACTIONS::resetCoords( "pcbnew.resetCoords", +TOOL_ACTION COMMON_ACTIONS::resetCoords( "pcbnew.Control.resetCoords", AS_GLOBAL, ' ', "", "" ); -TOOL_ACTION COMMON_ACTIONS::switchUnits( "pcbnew.switchUnits", +TOOL_ACTION COMMON_ACTIONS::switchUnits( "pcbnew.Control.switchUnits", AS_GLOBAL, MD_CTRL + int( 'U' ), "", "" ); -TOOL_ACTION COMMON_ACTIONS::showHelp( "pcbnew.showHelp", +TOOL_ACTION COMMON_ACTIONS::showHelp( "pcbnew.Control.showHelp", AS_GLOBAL, '?', "", "" ); From 6859bf83010e2f210e215c88dbe187e35bdfa469 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 13:50:27 +0200 Subject: [PATCH 047/123] Introduced a new type of action: TA_ACTIVATE to distinguish events activating tools from common tool actions. --- common/CMakeLists.txt | 1 + common/tool/tool_action.cpp | 47 ++++++++++++++++++++++++++++++++++++ common/tool/tool_event.cpp | 1 + common/tool/tool_manager.cpp | 19 ++++++++------- include/tool/tool_action.h | 18 ++++++++++---- include/tool/tool_event.h | 5 +++- 6 files changed, 76 insertions(+), 15 deletions(-) create mode 100644 common/tool/tool_action.cpp diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 88db67da3b..c9caece966 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -228,6 +228,7 @@ set( COMMON_SRCS math/math_util.cpp + tool/tool_action.cpp tool/tool_base.cpp tool/tool_manager.cpp tool/tool_dispatcher.cpp diff --git a/common/tool/tool_action.cpp b/common/tool/tool_action.cpp new file mode 100644 index 0000000000..4d1fd9d658 --- /dev/null +++ b/common/tool/tool_action.cpp @@ -0,0 +1,47 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2013 CERN + * @author Maciej Suminski + * + * 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 + +std::string TOOL_ACTION::GetToolName() const +{ + int dotCount = std::count( m_name.begin(), m_name.end(), '.' ); + + switch( dotCount ) + { + case 0: + assert( false ); // Invalid action name format + return ""; + + case 1: + return m_name; + + case 2: + return m_name.substr( 0, m_name.rfind( '.' ) ); + + default: + assert( false ); // TODO not implemented + return ""; + } +} diff --git a/common/tool/tool_event.cpp b/common/tool/tool_event.cpp index 50739ba419..68518a2d50 100644 --- a/common/tool/tool_event.cpp +++ b/common/tool/tool_event.cpp @@ -92,6 +92,7 @@ const std::string TOOL_EVENT::Format() const { TA_CONTEXT_MENU_CHOICE, "context-menu-choice" }, { TA_UNDO_REDO, "undo-redo" }, { TA_ACTION, "action" }, + { TA_ACTIVATE, "activate" }, { 0, "" } }; diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index 1147304d5b..6bbc0cd51e 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -294,7 +294,7 @@ bool TOOL_MANAGER::invokeTool( TOOL_BASE* aTool ) { wxASSERT( aTool != NULL ); - TOOL_EVENT evt( TC_COMMAND, TA_ACTION, aTool->GetName() ); + TOOL_EVENT evt( TC_COMMAND, TA_ACTIVATE, aTool->GetName() ); ProcessEvent( evt ); return true; @@ -497,8 +497,11 @@ bool TOOL_MANAGER::dispatchStandardEvents( TOOL_EVENT& aEvent ) if( m_actionMgr->RunHotKey( aEvent.Modifier() | aEvent.KeyCode() ) ) return false; // hotkey event was handled so it does not go any further } - else if( aEvent.Category() == TC_COMMAND ) // it may be a tool activation event + else if( aEvent.Action() == TA_ACTIVATE ) { + // Check if the tool name conforms to the the used tool name format + assert( std::count( aEvent.m_commandStr->begin(), aEvent.m_commandStr->end(), '.' ) == 1 ); + dispatchActivation( aEvent ); // do not return false, as the event has to go on to the destined tool } @@ -509,14 +512,12 @@ bool TOOL_MANAGER::dispatchStandardEvents( TOOL_EVENT& aEvent ) bool TOOL_MANAGER::dispatchActivation( TOOL_EVENT& aEvent ) { - // Look for the tool that has the same name as parameter in the processed command TOOL_EVENT - BOOST_FOREACH( TOOL_STATE* st, m_toolState | boost::adaptors::map_values ) + std::map::iterator tool = m_toolNameIndex.find( *aEvent.m_commandStr ); + + if( tool != m_toolNameIndex.end() ) { - if( st->theTool->GetName() == aEvent.m_commandStr ) - { - runTool( st->theTool ); - return true; - } + runTool( tool->second->theTool ); + return true; } return false; diff --git a/include/tool/tool_action.h b/include/tool/tool_action.h index 152cf52928..c9d3510bc1 100644 --- a/include/tool/tool_action.h +++ b/include/tool/tool_action.h @@ -132,7 +132,6 @@ public: * Checks if the action has a hot key assigned. * * @return True if there is a hot key assigned, false otherwise. - * */ bool HasHotKey() const { @@ -141,14 +140,17 @@ public: /** * Function MakeEvent() - * Returns the event associated with the action (ie. the event that will be sent after + * Returns the event associated with the action (i.e. the event that will be sent after * activating the action). * * @return The event associated with the action. */ TOOL_EVENT MakeEvent() const { - return TOOL_EVENT( TC_COMMAND, TA_ACTION, m_name, m_scope ); + if( IsActivation() ) + return TOOL_EVENT( TC_COMMAND, TA_ACTIVATE, m_name, m_scope ); + else + return TOOL_EVENT( TC_COMMAND, TA_ACTION, m_name, m_scope ); } const std::string& GetMenuItem() const @@ -181,9 +183,15 @@ public: * stripped of the last part (e.g. for "pcbnew.InteractiveDrawing.drawCircle" it is * "pcbnew.InteractiveDrawing"). */ - std::string GetToolName() const + std::string GetToolName() const; + + /** + * Returns true if the action is intended to activate a tool. + */ + bool IsActivation() const { - return m_name.substr( 0, m_name.rfind( '.' ) ); + // Tool activation events are of format appName.toolName + return std::count( m_name.begin(), m_name.end(), '.' ) == 1; } private: diff --git a/include/tool/tool_event.h b/include/tool/tool_event.h index 49f8fe55f1..854e4d3b38 100644 --- a/include/tool/tool_event.h +++ b/include/tool/tool_event.h @@ -91,9 +91,12 @@ enum TOOL_ACTIONS // This event is sent *before* undo/redo command is performed. TA_UNDO_REDO = 0x10000, - // Tool action (allows to control tools) + // Tool action (allows to control tools). TA_ACTION = 0x20000, + // Tool activation event. + TA_ACTIVATE = 0x40000, + TA_ANY = 0xffffffff }; From 3ce4e4d35647284ab4acf9088e67e957b21fcc6c Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 13:50:27 +0200 Subject: [PATCH 048/123] Improved way of translating wxEvent commands to TOOL_ACTIONs. --- common/tool/tool_dispatcher.cpp | 23 +---- pcbnew/edit.cpp | 164 ++++++++++++++------------------ pcbnew/tools/common_actions.cpp | 37 ++++--- pcbnew/tools/common_actions.h | 5 +- 4 files changed, 99 insertions(+), 130 deletions(-) diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp index 89c09a16ec..cd416f7c50 100644 --- a/common/tool/tool_dispatcher.cpp +++ b/common/tool/tool_dispatcher.cpp @@ -288,27 +288,10 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) void TOOL_DISPATCHER::DispatchWxCommand( wxCommandEvent& aEvent ) { - boost::optional evt; - - switch( aEvent.GetId() ) - { - case ID_ZOOM_IN: // toolbar button "Zoom In" - evt = COMMON_ACTIONS::zoomInCenter.MakeEvent(); - break; - - case ID_ZOOM_OUT: // toolbar button "Zoom In" - evt = COMMON_ACTIONS::zoomOutCenter.MakeEvent(); - break; - - case ID_ZOOM_PAGE: // toolbar button "Fit on Screen" - evt = COMMON_ACTIONS::zoomFitScreen.MakeEvent(); - break; - - default: - aEvent.Skip(); - break; - } + boost::optional evt = COMMON_ACTIONS::TranslateLegacyId( aEvent.GetId() ); if( evt ) m_toolMgr->ProcessEvent( *evt ); + else + aEvent.Skip(); } diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index eb6bb85843..efb92a7064 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -1385,125 +1385,99 @@ void PCB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent ) if( GetToolId() == id ) return; - if( IsGalCanvasActive() ) + INSTALL_UNBUFFERED_DC( dc, m_canvas ); + + // Stop the current command and deselect the current tool. + m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() ); + + switch( id ) { - std::string actionName = COMMON_ACTIONS::TranslateLegacyId( id ); + case ID_NO_TOOL_SELECTED: + SetToolID( id, m_canvas->GetDefaultCursor(), wxEmptyString ); + break; - if( !actionName.empty() || id == ID_NO_TOOL_SELECTED ) + case ID_TRACK_BUTT: + if( g_Drc_On ) + SetToolID( id, wxCURSOR_PENCIL, _( "Add tracks" ) ); + else + SetToolID( id, wxCURSOR_QUESTION_ARROW, _( "Add tracks" ) ); + + if( (GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 ) { - const int MAX_TRIALS = 10; - int trials = 0; - - // Cancel the current tool - // TODO while sending a lot of cancel events works for sure, it is not the most - // elegant way to cancel a tool, this should be probably done another way - while( m_toolManager->GetCurrentTool()->GetName() != "pcbnew.InteractiveSelection" && - trials++ < MAX_TRIALS ) - { - TOOL_EVENT cancel( TC_ANY, TA_CANCEL_TOOL ); - m_toolManager->ProcessEvent( cancel ); - } - - if( !actionName.empty() ) - m_toolManager->RunAction( actionName ); + Compile_Ratsnest( &dc, true ); } - } - else - { - INSTALL_UNBUFFERED_DC( dc, m_canvas ); - // Stop the current command and deselect the current tool. - m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() ); + break; - switch( id ) - { - case ID_NO_TOOL_SELECTED: - SetToolID( id, m_canvas->GetDefaultCursor(), wxEmptyString ); - break; + case ID_PCB_MODULE_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Add module" ) ); + break; - case ID_TRACK_BUTT: - if( g_Drc_On ) - SetToolID( id, wxCURSOR_PENCIL, _( "Add tracks" ) ); - else - SetToolID( id, wxCURSOR_QUESTION_ARROW, _( "Add tracks" ) ); + case ID_PCB_ZONES_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Add zones" ) ); - if( (GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 ) - { - Compile_Ratsnest( &dc, true ); - } + if( DisplayOpt.DisplayZonesMode != 0 ) + DisplayInfoMessage( this, _( "Warning: zone display is OFF!!!" ) ); - break; + if( !GetBoard()->IsHighLightNetON() && (GetBoard()->GetHighLightNetCode() > 0 ) ) + HighLight( &dc ); - case ID_PCB_MODULE_BUTT: - SetToolID( id, wxCURSOR_PENCIL, _( "Add module" ) ); - break; + break; - case ID_PCB_ZONES_BUTT: - SetToolID( id, wxCURSOR_PENCIL, _( "Add zones" ) ); + case ID_PCB_KEEPOUT_AREA_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Add keepout" ) ); + break; - if( DisplayOpt.DisplayZonesMode != 0 ) - DisplayInfoMessage( this, _( "Warning: zone display is OFF!!!" ) ); + case ID_PCB_MIRE_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Add layer alignment target" ) ); + break; - if( !GetBoard()->IsHighLightNetON() && (GetBoard()->GetHighLightNetCode() > 0 ) ) - HighLight( &dc ); + case ID_PCB_PLACE_OFFSET_COORD_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Adjust zero" ) ); + break; - break; + case ID_PCB_PLACE_GRID_COORD_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Adjust grid origin" ) ); + break; - case ID_PCB_KEEPOUT_AREA_BUTT: - SetToolID( id, wxCURSOR_PENCIL, _( "Add keepout" ) ); - break; + case ID_PCB_ADD_LINE_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Add graphic line" ) ); + break; - case ID_PCB_MIRE_BUTT: - SetToolID( id, wxCURSOR_PENCIL, _( "Add layer alignment target" ) ); - break; + case ID_PCB_ARC_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Add graphic arc" ) ); + break; - case ID_PCB_PLACE_OFFSET_COORD_BUTT: - SetToolID( id, wxCURSOR_PENCIL, _( "Adjust zero" ) ); - break; + case ID_PCB_CIRCLE_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Add graphic circle" ) ); + break; - case ID_PCB_PLACE_GRID_COORD_BUTT: - SetToolID( id, wxCURSOR_PENCIL, _( "Adjust grid origin" ) ); - break; + case ID_PCB_ADD_TEXT_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Add text" ) ); + break; - case ID_PCB_ADD_LINE_BUTT: - SetToolID( id, wxCURSOR_PENCIL, _( "Add graphic line" ) ); - break; + case ID_COMPONENT_BUTT: + SetToolID( id, wxCURSOR_HAND, _( "Add module" ) ); + break; - case ID_PCB_ARC_BUTT: - SetToolID( id, wxCURSOR_PENCIL, _( "Add graphic arc" ) ); - break; + case ID_PCB_DIMENSION_BUTT: + SetToolID( id, wxCURSOR_PENCIL, _( "Add dimension" ) ); + break; - case ID_PCB_CIRCLE_BUTT: - SetToolID( id, wxCURSOR_PENCIL, _( "Add graphic circle" ) ); - break; + case ID_PCB_DELETE_ITEM_BUTT: + SetToolID( id, wxCURSOR_BULLSEYE, _( "Delete item" ) ); + break; - case ID_PCB_ADD_TEXT_BUTT: - SetToolID( id, wxCURSOR_PENCIL, _( "Add text" ) ); - break; + case ID_PCB_HIGHLIGHT_BUTT: + SetToolID( id, wxCURSOR_HAND, _( "Highlight net" ) ); + break; - case ID_COMPONENT_BUTT: - SetToolID( id, wxCURSOR_HAND, _( "Add module" ) ); - break; + case ID_PCB_SHOW_1_RATSNEST_BUTT: + SetToolID( id, wxCURSOR_HAND, _( "Select rats nest" ) ); - case ID_PCB_DIMENSION_BUTT: - SetToolID( id, wxCURSOR_PENCIL, _( "Add dimension" ) ); - break; + if( ( GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK ) == 0 ) + Compile_Ratsnest( &dc, true ); - case ID_PCB_DELETE_ITEM_BUTT: - SetToolID( id, wxCURSOR_BULLSEYE, _( "Delete item" ) ); - break; - - case ID_PCB_HIGHLIGHT_BUTT: - SetToolID( id, wxCURSOR_HAND, _( "Highlight net" ) ); - break; - - case ID_PCB_SHOW_1_RATSNEST_BUTT: - SetToolID( id, wxCURSOR_HAND, _( "Select rats nest" ) ); - - if( ( GetBoard()->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK ) == 0 ) - Compile_Ratsnest( &dc, true ); - - break; - } + break; } } diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index cd41f0e96c..856fcf81f6 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -269,46 +269,55 @@ TOOL_ACTION COMMON_ACTIONS::showHelp( "pcbnew.Control.showHelp", "", "" ); -std::string COMMON_ACTIONS::TranslateLegacyId( int aId ) +boost::optional COMMON_ACTIONS::TranslateLegacyId( int aId ) { switch( aId ) { case ID_PCB_MODULE_BUTT: - return COMMON_ACTIONS::placeModule.GetName(); + return COMMON_ACTIONS::placeModule.MakeEvent(); case ID_TRACK_BUTT: - return COMMON_ACTIONS::routerActivate.GetName(); + return COMMON_ACTIONS::routerActivate.MakeEvent(); case ID_PCB_ZONES_BUTT: - return COMMON_ACTIONS::drawZone.GetName(); + return COMMON_ACTIONS::drawZone.MakeEvent(); case ID_PCB_KEEPOUT_AREA_BUTT: - return COMMON_ACTIONS::drawKeepout.GetName(); + return COMMON_ACTIONS::drawKeepout.MakeEvent(); case ID_PCB_ADD_LINE_BUTT: - return COMMON_ACTIONS::drawLine.GetName(); + return COMMON_ACTIONS::drawLine.MakeEvent(); case ID_PCB_CIRCLE_BUTT: - return COMMON_ACTIONS::drawCircle.GetName(); + return COMMON_ACTIONS::drawCircle.MakeEvent(); case ID_PCB_ARC_BUTT: - return COMMON_ACTIONS::drawArc.GetName(); + return COMMON_ACTIONS::drawArc.MakeEvent(); case ID_PCB_ADD_TEXT_BUTT: - return COMMON_ACTIONS::placeTextPcb.GetName(); + return COMMON_ACTIONS::placeTextPcb.MakeEvent(); case ID_MODEDIT_TEXT_TOOL: - return COMMON_ACTIONS::placeTextModule.GetName(); + return COMMON_ACTIONS::placeTextModule.MakeEvent(); case ID_PCB_DIMENSION_BUTT: - return COMMON_ACTIONS::drawDimension.GetName(); + return COMMON_ACTIONS::drawDimension.MakeEvent(); case ID_PCB_MIRE_BUTT: - return COMMON_ACTIONS::placeTarget.GetName(); + return COMMON_ACTIONS::placeTarget.MakeEvent(); case ID_PCB_PLACE_GRID_COORD_BUTT: - return COMMON_ACTIONS::gridSetOrigin.GetName(); + return COMMON_ACTIONS::gridSetOrigin.MakeEvent(); + + case ID_ZOOM_IN: // toolbar button "Zoom In" + return COMMON_ACTIONS::zoomInCenter.MakeEvent(); + + case ID_ZOOM_OUT: // toolbar button "Zoom In" + return COMMON_ACTIONS::zoomOutCenter.MakeEvent(); + + case ID_ZOOM_PAGE: // toolbar button "Fit on Screen" + return COMMON_ACTIONS::zoomFitScreen.MakeEvent(); } - return ""; + return boost::optional(); } diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 800a085f2a..ec98e65abd 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -23,6 +23,9 @@ */ #include +#include + +class TOOL_EVENT; /** * Class COMMON_ACTIONS @@ -153,5 +156,5 @@ public: * @return std::string is name of the corresponding TOOL_ACTION. It may be empty, if there is * no corresponding TOOL_ACTION. */ - static std::string TranslateLegacyId( int aId ); + static boost::optional TranslateLegacyId( int aId ); }; From 06361eb2c1a2cb99a6f45017ed6043216d5511ae Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 13:50:27 +0200 Subject: [PATCH 049/123] Added AF_ACTIVATE flag for TOOL_ACTIONs. Reworked the way of processing events in TOOL_MANAGER class. Added GetCommandStr() for TOOL_EVENT class. --- common/tool/tool_manager.cpp | 72 ++++++++++++++++----------------- include/tool/tool_action.h | 13 +++--- include/tool/tool_event.h | 19 ++++++++- include/tool/tool_manager.h | 10 +++++ pcbnew/router/router_tool.cpp | 14 +++---- pcbnew/tools/common_actions.cpp | 38 ++++++++--------- pcbnew/tools/drawing_tool.cpp | 37 +++++++++++++---- 7 files changed, 126 insertions(+), 77 deletions(-) diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index 6bbc0cd51e..0f4e3f22e2 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -495,15 +495,7 @@ bool TOOL_MANAGER::dispatchStandardEvents( TOOL_EVENT& aEvent ) { // Check if there is a hotkey associated if( m_actionMgr->RunHotKey( aEvent.Modifier() | aEvent.KeyCode() ) ) - return false; // hotkey event was handled so it does not go any further - } - else if( aEvent.Action() == TA_ACTIVATE ) - { - // Check if the tool name conforms to the the used tool name format - assert( std::count( aEvent.m_commandStr->begin(), aEvent.m_commandStr->end(), '.' ) == 1 ); - - dispatchActivation( aEvent ); - // do not return false, as the event has to go on to the destined tool + return false; // hotkey event was handled so it does not go any further } return true; @@ -512,41 +504,23 @@ bool TOOL_MANAGER::dispatchStandardEvents( TOOL_EVENT& aEvent ) bool TOOL_MANAGER::dispatchActivation( TOOL_EVENT& aEvent ) { - std::map::iterator tool = m_toolNameIndex.find( *aEvent.m_commandStr ); - - if( tool != m_toolNameIndex.end() ) + if( aEvent.IsActivate() ) { - runTool( tool->second->theTool ); - return true; + std::map::iterator tool = m_toolNameIndex.find( *aEvent.m_commandStr ); + + if( tool != m_toolNameIndex.end() ) + { + runTool( tool->second->theTool ); + return true; + } } return false; } -void TOOL_MANAGER::finishTool( TOOL_STATE* aState ) +void TOOL_MANAGER::dispatchContextMenu( TOOL_EVENT& aEvent ) { - if( !aState->Pop() ) // if there are no other contexts saved on the stack - { - // find the tool and deactivate it - std::deque::iterator tool = std::find( m_activeTools.begin(), m_activeTools.end(), - aState->theTool->GetId() ); - - if( tool != m_activeTools.end() ) - m_activeTools.erase( tool ); - } -} - - -bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent ) -{ - // Early dispatch of events destined for the TOOL_MANAGER - if( !dispatchStandardEvents( aEvent ) ) - return false; - - dispatchInternal( aEvent ); - - // popup menu handling BOOST_FOREACH( TOOL_ID toolId, m_activeTools ) { TOOL_STATE* st = m_toolIdIndex[toolId]; @@ -577,6 +551,32 @@ bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent ) break; } } +} + + +void TOOL_MANAGER::finishTool( TOOL_STATE* aState ) +{ + if( !aState->Pop() ) // if there are no other contexts saved on the stack + { + // find the tool and deactivate it + std::deque::iterator tool = std::find( m_activeTools.begin(), m_activeTools.end(), + aState->theTool->GetId() ); + + if( tool != m_activeTools.end() ) + m_activeTools.erase( tool ); + } +} + + +bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent ) +{ + // Early dispatch of events destined for the TOOL_MANAGER + if( !dispatchStandardEvents( aEvent ) ) + return false; + + dispatchInternal( aEvent ); + dispatchActivation( aEvent ); + dispatchContextMenu( aEvent ); if( m_view->IsDirty() ) { diff --git a/include/tool/tool_action.h b/include/tool/tool_action.h index c9d3510bc1..e215efba83 100644 --- a/include/tool/tool_action.h +++ b/include/tool/tool_action.h @@ -29,7 +29,6 @@ #include #include -#include #include /** @@ -47,10 +46,10 @@ class TOOL_ACTION public: TOOL_ACTION( const std::string& aName, TOOL_ACTION_SCOPE aScope = AS_CONTEXT, int aDefaultHotKey = 0, const std::string& aMenuItem = std::string( "" ), - const std::string& aMenuDesc = std::string( "" ) ) : + const std::string& aMenuDesc = std::string( "" ), TOOL_ACTION_FLAGS aFlags = AF_NONE ) : m_name( aName ), m_scope( aScope ), m_defaultHotKey( aDefaultHotKey ), m_currentHotKey( aDefaultHotKey ), m_menuItem( aMenuItem ), - m_menuDescription( aMenuDesc ), m_id( -1 ) + m_menuDescription( aMenuDesc ), m_id( -1 ), m_flags( aFlags ) { TOOL_MANAGER::GetActionList().push_back( this ); } @@ -190,8 +189,7 @@ public: */ bool IsActivation() const { - // Tool activation events are of format appName.toolName - return std::count( m_name.begin(), m_name.end(), '.' ) == 1; + return m_flags & AF_ACTIVATE; } private: @@ -200,7 +198,7 @@ private: /// Name of the action (convention is: app.[tool.]action.name) std::string m_name; - /// Scope of the action (ie. the event that is issued after activation). + /// Scope of the action (i.e. the event that is issued after activation). TOOL_ACTION_SCOPE m_scope; /// Default hot key that activates the action. @@ -221,6 +219,9 @@ private: /// Unique ID for fast matching. Assigned by ACTION_MANAGER. int m_id; + /// Action flags + TOOL_ACTION_FLAGS m_flags; + /// Origin of the action // const TOOL_BASE* m_origin; diff --git a/include/tool/tool_event.h b/include/tool/tool_event.h index 854e4d3b38..fd6eaa2c72 100644 --- a/include/tool/tool_event.h +++ b/include/tool/tool_event.h @@ -126,6 +126,13 @@ enum TOOL_ACTION_SCOPE AS_GLOBAL ///> Global action (toolbar/main menu event, global shortcut) }; +/// Flags for tool actions +enum TOOL_ACTION_FLAGS +{ + AF_NONE = 0, + AF_ACTIVATE = 1 ///> Action activates a tool +}; + /// Defines when a context menu is opened. enum CONTEXT_MENU_TRIGGER { @@ -268,6 +275,11 @@ public: return m_actions == TA_CANCEL_TOOL; } + bool IsActivate() const + { + return m_actions == TA_ACTIVATE; + } + ///> Returns information about key modifiers state (Ctrl, Alt, etc.) int Modifier( int aMask = MD_MODIFIER_MASK ) const { @@ -334,11 +346,16 @@ public: */ bool IsAction( const TOOL_ACTION* aAction ) const; - boost::optional GetCommandId() + boost::optional GetCommandId() const { return m_commandId; } + boost::optional GetCommandStr() const + { + return m_commandStr; + } + private: friend class TOOL_MANAGER; diff --git a/include/tool/tool_manager.h b/include/tool/tool_manager.h index 54ec87bf57..fdc17480d6 100644 --- a/include/tool/tool_manager.h +++ b/include/tool/tool_manager.h @@ -274,6 +274,10 @@ private: struct TOOL_STATE; typedef std::pair TRANSITION; + /** + * Function dispatchInternal + * Passes an event at first to the active tools, then to all others. + */ void dispatchInternal( TOOL_EVENT& aEvent ); /** @@ -292,6 +296,12 @@ private: */ bool dispatchActivation( TOOL_EVENT& aEvent ); + /** + * Function dispatchContextMenu() + * Handles context menu related events. + */ + void dispatchContextMenu( TOOL_EVENT& aEvent ); + /** * Function invokeTool() * Invokes a tool by sending a proper event (in contrary to runTool, which makes the tool run diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 7416c14c17..f961722180 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -480,8 +480,7 @@ void ROUTER_TOOL::updateEndItem( TOOL_EVENT& aEvent ) VECTOR2I p = getView()->ToWorld( ctls->GetMousePosition() ); VECTOR2I cp = ctls->GetCursorPosition(); int layer; - - bool snapEnabled = !aEvent.Modifier(MD_SHIFT); + bool snapEnabled = !aEvent.Modifier( MD_SHIFT ); m_router->EnableSnapping ( snapEnabled ); @@ -554,7 +553,7 @@ void ROUTER_TOOL::performRouting() while( OPT_TOOL_EVENT evt = Wait() ) { - if( evt->IsCancel() ) + if( evt->IsCancel() || evt->IsActivate() ) break; else if( evt->Action() == TA_UNDO_REDO ) { @@ -663,7 +662,7 @@ int ROUTER_TOOL::Main( TOOL_EVENT& aEvent ) m_needsSync = false; } - if( evt->IsCancel() ) + if( evt->IsCancel() || evt->IsActivate() ) break; // Finish else if( evt->Action() == TA_UNDO_REDO ) m_needsSync = true; @@ -677,10 +676,11 @@ int ROUTER_TOOL::Main( TOOL_EVENT& aEvent ) performDragging(); else performRouting(); - } else if ( evt->IsAction( &ACT_Drag ) ) + } + else if ( evt->IsAction( &ACT_Drag ) ) performDragging(); - handleCommonEvents(*evt); + handleCommonEvents( *evt ); } // Restore the default settings @@ -715,7 +715,7 @@ void ROUTER_TOOL::performDragging() while( OPT_TOOL_EVENT evt = Wait() ) { - if( evt->IsCancel() ) + if( evt->IsCancel() || evt->IsActivate() ) break; else if( evt->Action() == TA_UNDO_REDO ) { diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 856fcf81f6..5f0fdf5d3c 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -29,7 +29,7 @@ // Selection tool actions TOOL_ACTION COMMON_ACTIONS::selectionActivate( "pcbnew.InteractiveSelection", - AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere + AS_GLOBAL, 0, "", "", AF_ACTIVATE ); // No description, it is not supposed to be shown anywhere TOOL_ACTION COMMON_ACTIONS::selectionSingle( "pcbnew.InteractiveSelection.Single", AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere @@ -41,7 +41,7 @@ TOOL_ACTION COMMON_ACTIONS::selectionClear( "pcbnew.InteractiveSelection.Clear", // Edit tool actions TOOL_ACTION COMMON_ACTIONS::editActivate( "pcbnew.InteractiveEdit", AS_GLOBAL, 'M', - "Move", "Moves the selected item(s)" ); + "Move", "Moves the selected item(s)", AF_ACTIVATE ); TOOL_ACTION COMMON_ACTIONS::rotate( "pcbnew.InteractiveEdit.rotate", AS_GLOBAL, 'R', @@ -63,50 +63,43 @@ TOOL_ACTION COMMON_ACTIONS::properties( "pcbnew.InteractiveEdit.properties", // Drawing tool actions TOOL_ACTION COMMON_ACTIONS::drawLine( "pcbnew.InteractiveDrawing.line", AS_GLOBAL, 0, - "Draw a line", "Draw a line" ); + "Draw a line", "Draw a line", AF_ACTIVATE ); TOOL_ACTION COMMON_ACTIONS::drawCircle( "pcbnew.InteractiveDrawing.circle", AS_GLOBAL, 0, - "Draw a circle", "Draw a circle" ); + "Draw a circle", "Draw a circle", AF_ACTIVATE ); TOOL_ACTION COMMON_ACTIONS::drawArc( "pcbnew.InteractiveDrawing.arc", AS_GLOBAL, 0, - "Draw an arc", "Draw an arc" ); + "Draw an arc", "Draw an arc", AF_ACTIVATE ); TOOL_ACTION COMMON_ACTIONS::placeTextModule( "pcbnew.InteractiveDrawing.textPcb", AS_GLOBAL, 0, - "Add a text", "Add a text" ); + "Add a text", "Add a text", AF_ACTIVATE ); TOOL_ACTION COMMON_ACTIONS::placeTextPcb( "pcbnew.InteractiveDrawing.textModule", AS_GLOBAL, 0, - "Add a text", "Add a text" ); + "Add a text", "Add a text", AF_ACTIVATE ); TOOL_ACTION COMMON_ACTIONS::drawDimension( "pcbnew.InteractiveDrawing.dimension", AS_GLOBAL, 0, - "Add a dimension", "Add a dimension" ); + "Add a dimension", "Add a dimension", AF_ACTIVATE ); TOOL_ACTION COMMON_ACTIONS::drawZone( "pcbnew.InteractiveDrawing.zone", AS_GLOBAL, 0, - "Add a filled zone", "Add a filled zone" ); + "Add a filled zone", "Add a filled zone", AF_ACTIVATE ); TOOL_ACTION COMMON_ACTIONS::drawKeepout( "pcbnew.InteractiveDrawing.keepout", AS_GLOBAL, 0, - "Add a keepout area", "Add a keepout area" ); + "Add a keepout area", "Add a keepout area", AF_ACTIVATE ); TOOL_ACTION COMMON_ACTIONS::placeTarget( "pcbnew.InteractiveDrawing.placeTarget", AS_GLOBAL, 0, - "Add layer alignment target", "Add layer alignment target" ); + "Add layer alignment target", "Add layer alignment target", AF_ACTIVATE ); TOOL_ACTION COMMON_ACTIONS::placeModule( "pcbnew.InteractiveDrawing.placeModule", AS_GLOBAL, 'O', - "Add modules", "Add modules" ); - -TOOL_ACTION COMMON_ACTIONS::routerActivate( "pcbnew.InteractiveRouter", - AS_GLOBAL, 'X', - "Run push & shove router", "Run push & shove router" ); - -TOOL_ACTION COMMON_ACTIONS::pointEditorUpdate( "pcbnew.PointEditor.update", - AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere + "Add modules", "Add modules", AF_ACTIVATE ); // View Controls @@ -268,6 +261,13 @@ TOOL_ACTION COMMON_ACTIONS::showHelp( "pcbnew.Control.showHelp", AS_GLOBAL, '?', "", "" ); +TOOL_ACTION COMMON_ACTIONS::routerActivate( "pcbnew.InteractiveRouter", + AS_GLOBAL, 'X', + "Run push & shove router", "Run push & shove router", AF_ACTIVATE ); + +TOOL_ACTION COMMON_ACTIONS::pointEditorUpdate( "pcbnew.PointEditor.update", + AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere + boost::optional COMMON_ACTIONS::TranslateLegacyId( int aId ) { diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 9d3cf63670..37fc7b0698 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -123,7 +123,7 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) { cursorPos = m_controls->GetCursorPosition(); - if( evt->IsCancel() ) + if( evt->IsCancel() || evt->IsActivate() ) { if( step != SET_ORIGIN ) // start from the beginning { @@ -135,6 +135,9 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) } else break; + + if( evt->IsActivate() ) // now finish unconditionally + break; } else if( evt->IsKeyPressed() && step != SET_ORIGIN ) @@ -301,7 +304,7 @@ int DRAWING_TOOL::PlaceTextModule( TOOL_EVENT& aEvent ) { VECTOR2I cursorPos = m_controls->GetCursorPosition(); - if( evt->IsCancel() ) + if( evt->IsCancel() || evt->IsActivate() ) { if( text ) { @@ -315,6 +318,9 @@ int DRAWING_TOOL::PlaceTextModule( TOOL_EVENT& aEvent ) } else break; + + if( evt->IsActivate() ) // now finish unconditionally + break; } else if( text && evt->Category() == TC_COMMAND ) @@ -406,7 +412,7 @@ int DRAWING_TOOL::PlaceTextPcb( TOOL_EVENT& aEvent ) { VECTOR2I cursorPos = m_controls->GetCursorPosition(); - if( evt->IsCancel() ) + if( evt->IsCancel() || evt->IsActivate() ) { if( text ) { @@ -420,6 +426,9 @@ int DRAWING_TOOL::PlaceTextPcb( TOOL_EVENT& aEvent ) } else break; + + if( evt->IsActivate() ) // now finish unconditionally + break; } else if( text && evt->Category() == TC_COMMAND ) @@ -520,7 +529,7 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) { VECTOR2I cursorPos = m_controls->GetCursorPosition(); - if( evt->IsCancel() ) + if( evt->IsCancel() || evt->IsActivate() ) { if( step != SET_ORIGIN ) // start from the beginning { @@ -532,6 +541,9 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) } else break; + + if( evt->IsActivate() ) // now finish unconditionally + break; } else if( evt->IsKeyPressed() && step != SET_ORIGIN ) @@ -707,7 +719,7 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) { cursorPos = m_controls->GetCursorPosition(); - if( evt->IsCancel() ) + if( evt->IsCancel() || evt->IsActivate() ) break; else if( evt->IsKeyPressed() ) @@ -783,7 +795,7 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) { VECTOR2I cursorPos = m_controls->GetCursorPosition(); - if( evt->IsCancel() ) + if( evt->IsCancel() || evt->IsActivate() ) { if( module ) { @@ -796,6 +808,9 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) } else break; + + if( evt->IsActivate() ) // now finish unconditionally + break; } else if( module && evt->Category() == TC_COMMAND ) @@ -915,7 +930,7 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) updatePreview = true; } - if( evt->IsCancel() ) + if( evt->IsCancel() || evt->IsActivate() ) { if( !graphic ) break; @@ -927,6 +942,9 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) graphic = NULL; m_controls->SetAutoPan( false ); + + if( evt->IsActivate() ) // now finish unconditionally + break; } else if( graphic && evt->IsKeyPressed() ) @@ -1093,7 +1111,7 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) updatePreview = true; } - if( evt->IsCancel() ) + if( evt->IsCancel() || evt->IsActivate() ) { if( numPoints > 0 ) // cancel the current zone { @@ -1114,6 +1132,9 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) } else // there is no zone currently drawn - just stop the tool break; + + if( evt->IsActivate() ) // now finish unconditionally + break; } else if( evt->IsClick( BUT_LEFT ) ) From ada02bce9781943598205b8c03d04c462be3bd73 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 13:50:27 +0200 Subject: [PATCH 050/123] Added a handler for not implemented toolbar buttons functionality in GAL. --- pcbnew/tools/common_actions.cpp | 15 +++++++++++++++ pcbnew/tools/common_actions.h | 1 + pcbnew/tools/pcbnew_control.cpp | 10 ++++++++++ pcbnew/tools/pcbnew_control.h | 1 + 4 files changed, 27 insertions(+) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 5f0fdf5d3c..343f1813f3 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -261,6 +261,10 @@ TOOL_ACTION COMMON_ACTIONS::showHelp( "pcbnew.Control.showHelp", AS_GLOBAL, '?', "", "" ); +TOOL_ACTION COMMON_ACTIONS::toBeDone( "pcbnew.Control.toBeDone", + AS_GLOBAL, 0, // dialog saying it is not implemented yet + "", "" ); // so users are aware of that + TOOL_ACTION COMMON_ACTIONS::routerActivate( "pcbnew.InteractiveRouter", AS_GLOBAL, 'X', "Run push & shove router", "Run push & shove router", AF_ACTIVATE ); @@ -317,6 +321,17 @@ boost::optional COMMON_ACTIONS::TranslateLegacyId( int aId ) case ID_ZOOM_PAGE: // toolbar button "Fit on Screen" return COMMON_ACTIONS::zoomFitScreen.MakeEvent(); + + case ID_PCB_DELETE_ITEM_BUTT: + case ID_PCB_HIGHLIGHT_BUTT: + case ID_PCB_SHOW_1_RATSNEST_BUTT: + case ID_PCB_PLACE_OFFSET_COORD_BUTT: + case ID_TB_OPTIONS_SHOW_MODULE_RATSNEST: + case ID_TB_OPTIONS_SELECT_CURSOR: + case ID_TB_OPTIONS_SHOW_EXTRA_VERTICAL_TOOLBAR_MICROWAVE: + case ID_MENU_PCB_SHOW_HIDE_MUWAVE_TOOLBAR: + case ID_MICROWAVE_V_TOOLBAR: + return COMMON_ACTIONS::toBeDone.MakeEvent(); } return boost::optional(); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index ec98e65abd..9eec3ce112 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -148,6 +148,7 @@ public: static TOOL_ACTION resetCoords; static TOOL_ACTION switchUnits; static TOOL_ACTION showHelp; + static TOOL_ACTION toBeDone; /** * Function TranslateLegacyId() diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index 1702cfe64b..89b356c38c 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -506,6 +506,15 @@ int PCBNEW_CONTROL::ShowHelp( TOOL_EVENT& aEvent ) } +int PCBNEW_CONTROL::ToBeDone( TOOL_EVENT& aEvent ) +{ + DisplayInfoMessage( m_frame, _( "Not implemented yet." ) ); + setTransitions(); + + return 0; +} + + void PCBNEW_CONTROL::setTransitions() { // View controls @@ -549,4 +558,5 @@ void PCBNEW_CONTROL::setTransitions() Go( &PCBNEW_CONTROL::ResetCoords, COMMON_ACTIONS::resetCoords.MakeEvent() ); Go( &PCBNEW_CONTROL::SwitchUnits, COMMON_ACTIONS::switchUnits.MakeEvent() ); Go( &PCBNEW_CONTROL::ShowHelp, COMMON_ACTIONS::showHelp.MakeEvent() ); + Go( &PCBNEW_CONTROL::ToBeDone, COMMON_ACTIONS::toBeDone.MakeEvent() ); } diff --git a/pcbnew/tools/pcbnew_control.h b/pcbnew/tools/pcbnew_control.h index c5bd7e8841..62c7a9c7cd 100644 --- a/pcbnew/tools/pcbnew_control.h +++ b/pcbnew/tools/pcbnew_control.h @@ -91,6 +91,7 @@ public: int ResetCoords( TOOL_EVENT& aEvent ); int SwitchUnits( TOOL_EVENT& aEvent ); int ShowHelp( TOOL_EVENT& aEvent ); + int ToBeDone( TOOL_EVENT& aEvent ); private: ///> Sets up handlers for various events. From 2c19954d192643f49b9323ae30b094902b0ac7ef Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 13:50:27 +0200 Subject: [PATCH 051/123] Updated POINT_EDITOR to handle module edges. --- pcbnew/tools/point_editor.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index fa9ae8b029..64ad775a06 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -36,7 +36,7 @@ #include "point_editor.h" #include -#include +#include #include #include #include @@ -77,6 +77,7 @@ public: switch( aItem->Type() ) { case PCB_LINE_T: + case PCB_MODULE_EDGE_T: { const DRAWSEGMENT* segment = static_cast( aItem ); @@ -354,6 +355,7 @@ void POINT_EDITOR::updateItem() const switch( item->Type() ) { case PCB_LINE_T: + case PCB_MODULE_EDGE_T: { DRAWSEGMENT* segment = static_cast( item ); switch( segment->GetShape() ) @@ -428,6 +430,10 @@ void POINT_EDITOR::updateItem() const break; } + // Update relative coordinates for module edges + if( EDGE_MODULE* edge = dyn_cast( item ) ) + edge->SetLocalCoord(); + break; } @@ -521,6 +527,7 @@ void POINT_EDITOR::updatePoints() const switch( item->Type() ) { case PCB_LINE_T: + case PCB_MODULE_EDGE_T: { const DRAWSEGMENT* segment = static_cast( item ); { @@ -610,6 +617,7 @@ EDIT_POINT POINT_EDITOR::get45DegConstrainer() const switch( item->Type() ) { case PCB_LINE_T: + case PCB_MODULE_EDGE_T: { const DRAWSEGMENT* segment = static_cast( item ); { @@ -700,7 +708,7 @@ void POINT_EDITOR::breakOutline( const VECTOR2I& aBreakPoint ) outline->InsertCorner( nearestIdx, nearestPoint.x, nearestPoint.y ); } - else if( item->Type() == PCB_LINE_T ) + else if( item->Type() == PCB_LINE_T || item->Type() == PCB_MODULE_EDGE_T ) { getEditFrame()->OnModify(); getEditFrame()->SaveCopyInUndoList( selection.items, UR_CHANGED ); From 51d2061edf61c11b99a6c143f5454cf6750902bf Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 14:01:06 +0200 Subject: [PATCH 052/123] Refactored drawing tools: lines, circles and arcs. --- pcbnew/tools/drawing_tool.cpp | 500 ++++++++++++++++------------------ pcbnew/tools/drawing_tool.h | 14 +- 2 files changed, 254 insertions(+), 260 deletions(-) diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 37fc7b0698..71a8b2501f 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -74,7 +74,17 @@ int DRAWING_TOOL::DrawLine( TOOL_EVENT& aEvent ) { m_frame->SetToolID( ID_PCB_ADD_LINE_BUTT, wxCURSOR_PENCIL, _( "Add graphic line" ) ); - return drawSegment( S_SEGMENT, true ); + DRAWSEGMENT* line = new DRAWSEGMENT; + + while( drawSegment( S_SEGMENT, line ) ) + { + line = new DRAWSEGMENT; + } + + setTransitions(); + m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); + + return 0; } @@ -82,200 +92,31 @@ int DRAWING_TOOL::DrawCircle( TOOL_EVENT& aEvent ) { m_frame->SetToolID( ID_PCB_CIRCLE_BUTT, wxCURSOR_PENCIL, _( "Add graphic circle" ) ); - return drawSegment( S_CIRCLE, false ); + DRAWSEGMENT* circle = new DRAWSEGMENT; + + while( drawSegment( S_CIRCLE, circle ) ) + { + circle = new DRAWSEGMENT; + } + + setTransitions(); + m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); + + return 0; } int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) { - bool clockwise = true; // drawing direction of the arc - double startAngle = 0.0f; // angle of the first arc line - VECTOR2I cursorPos = m_controls->GetCursorPosition(); - - DRAWSEGMENT* arc = NULL; - DRAWSEGMENT helperLine; - helperLine.SetShape( S_SEGMENT ); - helperLine.SetLayer( Dwgs_User ); - helperLine.SetWidth( 1 ); - - // Add a VIEW_GROUP that serves as a preview for the new item - KIGFX::VIEW_GROUP preview( m_view ); - m_view->Add( &preview ); - - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); - m_controls->ShowCursor( true ); - m_controls->SetSnapping( true ); - - Activate(); m_frame->SetToolID( ID_PCB_ARC_BUTT, wxCURSOR_PENCIL, _( "Add graphic arc" ) ); - enum ARC_STEPS + DRAWSEGMENT* arc = new DRAWSEGMENT; + + while( drawArc( arc ) ) { - SET_ORIGIN = 0, - SET_END, - SET_ANGLE, - FINISHED - }; - int step = SET_ORIGIN; - - // Main loop: keep receiving events - while( OPT_TOOL_EVENT evt = Wait() ) - { - cursorPos = m_controls->GetCursorPosition(); - - if( evt->IsCancel() || evt->IsActivate() ) - { - if( step != SET_ORIGIN ) // start from the beginning - { - preview.Clear(); - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - - delete arc; - step = SET_ORIGIN; - } - else - break; - - if( evt->IsActivate() ) // now finish unconditionally - break; - } - - else if( evt->IsKeyPressed() && step != SET_ORIGIN ) - { - int width = arc->GetWidth(); - - // Modify the new item width - if( evt->KeyCode() == '-' && width > WIDTH_STEP ) - arc->SetWidth( width - WIDTH_STEP ); - else if( evt->KeyCode() == '=' ) - arc->SetWidth( width + WIDTH_STEP ); - else if( evt->KeyCode() == '/' ) - { - if( clockwise ) - arc->SetAngle( arc->GetAngle() - 3600.0 ); - else - arc->SetAngle( arc->GetAngle() + 3600.0 ); - - clockwise = !clockwise; - } - - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - - else if( evt->IsClick( BUT_LEFT ) ) - { - switch( step ) - { - case SET_ORIGIN: - { - LAYER_ID layer = m_frame->GetScreen()->m_Active_Layer; - - if( IsCopperLayer( layer ) ) - { - DisplayInfoMessage( NULL, _( "Graphic not allowed on Copper layers" ) ); - --step; - } - else - { - // Init the new item attributes - arc = new DRAWSEGMENT( m_board ); - arc->SetShape( S_ARC ); - arc->SetAngle( 0.0 ); - arc->SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth ); - arc->SetCenter( wxPoint( cursorPos.x, cursorPos.y ) ); - arc->SetLayer( layer ); - - helperLine.SetStart( arc->GetCenter() ); - helperLine.SetEnd( arc->GetCenter() ); - - preview.Add( arc ); - preview.Add( &helperLine ); - - m_controls->SetAutoPan( true ); - } - } - break; - - case SET_END: - { - if( wxPoint( cursorPos.x, cursorPos.y ) != arc->GetCenter() ) - { - VECTOR2D startLine( arc->GetArcStart() - arc->GetCenter() ); - startAngle = startLine.Angle(); - arc->SetArcStart( wxPoint( cursorPos.x, cursorPos.y ) ); - } - else - --step; // one another chance to draw a proper arc - - } - break; - - case SET_ANGLE: - { - if( wxPoint( cursorPos.x, cursorPos.y ) != arc->GetArcStart() ) - { - assert( arc->GetAngle() != 0 ); - assert( arc->GetArcStart() != arc->GetArcEnd() ); - assert( arc->GetWidth() > 0 ); - - m_view->Add( arc ); - m_board->Add( arc ); - arc->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - - m_frame->OnModify(); - m_frame->SaveCopyInUndoList( arc, UR_NEW ); - - preview.Remove( arc ); - preview.Remove( &helperLine ); - } - else - --step; // one another chance to draw a proper arc - } - break; - } - - if( ++step == FINISHED ) - { - step = SET_ORIGIN; - m_controls->SetAutoPan( false ); - } - } - - else if( evt->IsMotion() ) - { - switch( step ) - { - case SET_END: - helperLine.SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); - arc->SetArcStart( wxPoint( cursorPos.x, cursorPos.y ) ); - break; - - case SET_ANGLE: - { - VECTOR2D endLine( wxPoint( cursorPos.x, cursorPos.y ) - arc->GetCenter() ); - double newAngle = RAD2DECIDEG( endLine.Angle() - startAngle ); - - // Adjust the new angle to (counter)clockwise setting - if( clockwise && newAngle < 0.0 ) - newAngle += 3600.0; - else if( !clockwise && newAngle > 0.0 ) - newAngle -= 3600.0; - - arc->SetAngle( newAngle ); - } - break; - } - - // Show a preview of the item - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } + arc = new DRAWSEGMENT; } - m_controls->ShowCursor( false ); - m_controls->SetSnapping( false ); - m_controls->SetAutoPan( false ); - m_view->Remove( &preview ); - setTransitions(); m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); @@ -884,12 +725,11 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) } -int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) +bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT* aGraphic ) { // Only two shapes are currently supported assert( aShape == S_SEGMENT || aShape == S_CIRCLE ); - DRAWSEGMENT* graphic = NULL; DRAWSEGMENT line45; // Add a VIEW_GROUP that serves as a preview for the new item @@ -903,7 +743,7 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) Activate(); bool direction45 = false; // 45 degrees only mode - int addedSegments = 0; + bool started = false; // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) @@ -912,19 +752,19 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) VECTOR2I cursorPos = m_controls->GetCursorPosition(); // Enable 45 degrees lines only mode by holding control - if( direction45 != evt->Modifier( MD_CTRL ) && graphic && aShape == S_SEGMENT ) + if( direction45 != evt->Modifier( MD_CTRL ) && started && aShape == S_SEGMENT ) { direction45 = evt->Modifier( MD_CTRL ); if( direction45 ) { preview.Add( &line45 ); - make45DegLine( graphic, &line45 ); + make45DegLine( aGraphic, &line45 ); } else { preview.Remove( &line45 ); - graphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + aGraphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); } updatePreview = true; @@ -932,37 +772,28 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) if( evt->IsCancel() || evt->IsActivate() ) { - if( !graphic ) - break; - preview.Clear(); updatePreview = true; - - delete graphic; - graphic = NULL; - - m_controls->SetAutoPan( false ); - - if( evt->IsActivate() ) // now finish unconditionally - break; + delete aGraphic; + break; } - else if( graphic && evt->IsKeyPressed() ) + else if( evt->IsKeyPressed() ) { - int width = graphic->GetWidth(); + int width = aGraphic->GetWidth(); // Modify the new item width - if( evt->KeyCode() == '-' && width > WIDTH_STEP ) - graphic->SetWidth( width - WIDTH_STEP ); + if( evt->KeyCode() == '-' && width > WIDTH_STEP ) // TODO change it to TOOL_ACTIONs + aGraphic->SetWidth( width - WIDTH_STEP ); else if( evt->KeyCode() == '=' ) - graphic->SetWidth( width + WIDTH_STEP ); + aGraphic->SetWidth( width + WIDTH_STEP ); updatePreview = true; } else if( evt->IsClick( BUT_LEFT ) ) { - if( !graphic ) + if( !started ) { LAYER_ID layer = m_frame->GetScreen()->m_Active_Layer; @@ -973,78 +804,56 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) else { // Init the new item attributes - graphic = new DRAWSEGMENT( m_board ); - graphic->SetShape( (STROKE_T) aShape ); - graphic->SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth ); - graphic->SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); - graphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); - graphic->SetLayer( layer ); + aGraphic->SetShape( (STROKE_T) aShape ); + aGraphic->SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth ); + aGraphic->SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); + aGraphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + aGraphic->SetLayer( layer ); if( aShape == S_SEGMENT ) { - line45 = *graphic; // used only for direction 45 mode with lines + line45 = *aGraphic; // used only for direction 45 mode with lines line45.SetLayer( layer ); } - preview.Add( graphic ); + preview.Add( aGraphic ); m_controls->SetAutoPan( true ); + + started = true; } } else { - if( graphic->GetEnd() != graphic->GetStart() ) + if( aGraphic->GetEnd() != aGraphic->GetStart() ) { - assert( graphic->GetLength() > 0 ); - assert( graphic->GetWidth() > 0 ); + assert( aGraphic->GetLength() > 0 ); + assert( aGraphic->GetWidth() > 0 ); - m_view->Add( graphic ); - m_board->Add( graphic ); - graphic->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + m_view->Add( aGraphic ); + m_board->Add( aGraphic ); + aGraphic->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); m_frame->OnModify(); - m_frame->SaveCopyInUndoList( graphic, UR_NEW ); - - preview.Remove( graphic ); - ++addedSegments; - - if( aContinous ) - { - graphic = new DRAWSEGMENT( *graphic ); - - // Start the new line in the same spot where the previous one has ended - graphic->SetStart( graphic->GetEnd() ); - - if( direction45 ) - graphic->SetEnd( line45.GetEnd() ); - - preview.Add( graphic ); - } - else // start a new graphic - { - addedSegments = 0; - m_controls->SetAutoPan( false ); - graphic = NULL; - } + m_frame->SaveCopyInUndoList( aGraphic, UR_NEW ); } - else if( addedSegments > 0 ) // User has clicked twice in the same spot + else // User has clicked twice in the same spot { // a clear sign that the current drawing is finished - preview.Clear(); // but only if at least one graphic was created - // otherwise - force user to draw more or cancel - delete graphic; - graphic = NULL; - - m_controls->SetAutoPan( false ); + delete aGraphic; // but only if at least one graphic was created + started = false; // otherwise - force user to draw more or cancel } + + preview.Clear(); + break; } } - else if( graphic && evt->IsMotion() ) + else if( evt->IsMotion() ) { // 45 degree lines if( direction45 && aShape == S_SEGMENT ) - make45DegLine( graphic, &line45 ); + make45DegLine( aGraphic, &line45 ); else - graphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + aGraphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); updatePreview = true; } @@ -1058,10 +867,185 @@ int DRAWING_TOOL::drawSegment( int aShape, bool aContinous ) m_controls->SetAutoPan( false ); m_view->Remove( &preview ); - setTransitions(); - m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); + return started; +} - return 0; + +bool DRAWING_TOOL::drawArc( DRAWSEGMENT* aGraphic ) +{ + bool clockwise = true; // drawing direction of the arc + double startAngle = 0.0f; // angle of the first arc line + VECTOR2I cursorPos = m_controls->GetCursorPosition(); + + DRAWSEGMENT helperLine; + helperLine.SetShape( S_SEGMENT ); + helperLine.SetLayer( Dwgs_User ); + helperLine.SetWidth( 1 ); + + // Add a VIEW_GROUP that serves as a preview for the new item + KIGFX::VIEW_GROUP preview( m_view ); + m_view->Add( &preview ); + + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_controls->ShowCursor( true ); + m_controls->SetSnapping( true ); + + Activate(); + + enum ARC_STEPS + { + SET_ORIGIN = 0, + SET_END, + SET_ANGLE, + FINISHED + }; + int step = SET_ORIGIN; + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + cursorPos = m_controls->GetCursorPosition(); + + if( evt->IsCancel() || evt->IsActivate() ) + { + preview.Clear(); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + delete aGraphic; + break; + } + + else if( evt->IsKeyPressed() && step != SET_ORIGIN ) + { + int width = aGraphic->GetWidth(); + + // Modify the new item width + if( evt->KeyCode() == '-' && width > WIDTH_STEP ) // TODO convert to tool actions + aGraphic->SetWidth( width - WIDTH_STEP ); + else if( evt->KeyCode() == '=' ) + aGraphic->SetWidth( width + WIDTH_STEP ); + else if( evt->KeyCode() == '/' ) + { + if( clockwise ) + aGraphic->SetAngle( aGraphic->GetAngle() - 3600.0 ); + else + aGraphic->SetAngle( aGraphic->GetAngle() + 3600.0 ); + + clockwise = !clockwise; + } + + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + + else if( evt->IsClick( BUT_LEFT ) ) + { + switch( step ) + { + case SET_ORIGIN: + { + LAYER_ID layer = m_frame->GetScreen()->m_Active_Layer; + + if( IsCopperLayer( layer ) ) + { + DisplayInfoMessage( NULL, _( "Graphic not allowed on Copper layers" ) ); + --step; + } + else + { + // Init the new item attributes + aGraphic->SetShape( S_ARC ); + aGraphic->SetAngle( 0.0 ); + aGraphic->SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth ); + aGraphic->SetCenter( wxPoint( cursorPos.x, cursorPos.y ) ); + aGraphic->SetLayer( layer ); + + helperLine.SetStart( aGraphic->GetCenter() ); + helperLine.SetEnd( aGraphic->GetCenter() ); + + preview.Add( aGraphic ); + preview.Add( &helperLine ); + + m_controls->SetAutoPan( true ); + } + } + break; + + case SET_END: + { + if( wxPoint( cursorPos.x, cursorPos.y ) != aGraphic->GetCenter() ) + { + VECTOR2D startLine( aGraphic->GetArcStart() - aGraphic->GetCenter() ); + startAngle = startLine.Angle(); + aGraphic->SetArcStart( wxPoint( cursorPos.x, cursorPos.y ) ); + } + else + --step; // one another chance to draw a proper arc + } + break; + + case SET_ANGLE: + { + if( wxPoint( cursorPos.x, cursorPos.y ) != aGraphic->GetArcStart() ) + { + assert( aGraphic->GetAngle() != 0 ); + assert( aGraphic->GetArcStart() != aGraphic->GetArcEnd() ); + assert( aGraphic->GetWidth() > 0 ); + + m_view->Add( aGraphic ); + m_board->Add( aGraphic ); + aGraphic->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( aGraphic, UR_NEW ); + + preview.Remove( aGraphic ); + preview.Remove( &helperLine ); + } + else + --step; // one another chance to draw a proper arc + } + break; + } + + if( ++step == FINISHED ) + break; + } + + else if( evt->IsMotion() ) + { + switch( step ) + { + case SET_END: + helperLine.SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + aGraphic->SetArcStart( wxPoint( cursorPos.x, cursorPos.y ) ); + break; + + case SET_ANGLE: + { + VECTOR2D endLine( wxPoint( cursorPos.x, cursorPos.y ) - aGraphic->GetCenter() ); + double newAngle = RAD2DECIDEG( endLine.Angle() - startAngle ); + + // Adjust the new angle to (counter)clockwise setting + if( clockwise && newAngle < 0.0 ) + newAngle += 3600.0; + else if( !clockwise && newAngle > 0.0 ) + newAngle -= 3600.0; + + aGraphic->SetAngle( newAngle ); + } + break; + } + + // Show a preview of the item + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + + m_controls->ShowCursor( false ); + m_controls->SetSnapping( false ); + m_controls->SetAutoPan( false ); + m_view->Remove( &preview ); + + return ( step > SET_ORIGIN ); } diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index 99427a77be..57e865bfd7 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -130,8 +130,18 @@ public: private: ///> Starts drawing a selected shape (i.e. DRAWSEGMENT). ///> @param aShape is the type of created shape (@see STROKE_T). - ///> @param aContinous decides if there is only one or multiple shapes to draw. - int drawSegment( int aShape, bool aContinous ); + ///> @param aGraphic is an object that is going to be used by the tool for drawing. It has to + ///> be already created. The tool deletes the object if it is not added to a BOARD. + ///> @return False if the tool was cancelled before the origin was set or origin and end are + ///> the same point. + bool drawSegment( int aShape, DRAWSEGMENT* aGraphic ); + + ///> Starts drawing an arc. + ///> @param aGraphic is an object that is going to be used by the tool for drawing. It has to + ///> be already created. The tool deletes the object if it is not added to a BOARD. + ///> @return False if the tool was cancelled before the origin was set or origin and end are + ///> the same point. + bool drawArc( DRAWSEGMENT* aGraphic ); ///> Draws a polygon, that is added as a zone or a keepout area. ///> @param aKeepout decides if the drawn polygon is a zone or a keepout area. From e5158c7635550dc15135e40f085eddf7f5b59109 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 14:01:06 +0200 Subject: [PATCH 053/123] Created a header file for DialogEditModuleText class. --- pcbnew/dialogs/dialog_edit_module_text.cpp | 24 +--------- pcbnew/dialogs/dialog_edit_module_text.h | 53 ++++++++++++++++++++++ 2 files changed, 54 insertions(+), 23 deletions(-) create mode 100644 pcbnew/dialogs/dialog_edit_module_text.h diff --git a/pcbnew/dialogs/dialog_edit_module_text.cpp b/pcbnew/dialogs/dialog_edit_module_text.cpp index 928ca8541c..05ec826763 100644 --- a/pcbnew/dialogs/dialog_edit_module_text.cpp +++ b/pcbnew/dialogs/dialog_edit_module_text.cpp @@ -44,34 +44,12 @@ #include #include -#include +#include extern wxPoint MoveVector; // Move vector for move edge, imported from edtxtmod.cpp -/*************** **************/ -/* class DialogEditModuleText */ -/*************** **************/ -class DialogEditModuleText : public DialogEditModuleText_base -{ -private: - PCB_BASE_FRAME* m_parent; - wxDC* m_dc; - MODULE* m_module; - TEXTE_MODULE* m_currentText; - -public: - DialogEditModuleText( PCB_BASE_FRAME* aParent, TEXTE_MODULE* aTextMod, wxDC* aDC ); - ~DialogEditModuleText() {}; - -private: - void initDlg( ); - void OnOkClick( wxCommandEvent& event ); - void OnCancelClick( wxCommandEvent& event ); -}; - - void PCB_BASE_FRAME::InstallTextModOptionsFrame( TEXTE_MODULE* TextMod, wxDC* DC ) { m_canvas->SetIgnoreMouseEvents( true ); diff --git a/pcbnew/dialogs/dialog_edit_module_text.h b/pcbnew/dialogs/dialog_edit_module_text.h new file mode 100644 index 0000000000..674481b891 --- /dev/null +++ b/pcbnew/dialogs/dialog_edit_module_text.h @@ -0,0 +1,53 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2013 Jean-Pierre Charras + * Copyright (C) 2013 Dick Hollenbeck, dick@softplc.com + * Copyright (C) 2008-2013 Wayne Stambaugh + * Copyright (C) 1992-2013 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 + */ + +#ifndef DIALOG_EDIT_MODULE_TEXT_H +#define DIALOG_EDIT_MODULE_TEXT_H + +#include + +/*************** **************/ +/* class DialogEditModuleText */ +/*************** **************/ +class DialogEditModuleText : public DialogEditModuleText_base +{ +private: + PCB_BASE_FRAME* m_parent; + wxDC* m_dc; + MODULE* m_module; + TEXTE_MODULE* m_currentText; + +public: + DialogEditModuleText( PCB_BASE_FRAME* aParent, TEXTE_MODULE* aTextMod, wxDC* aDC ); + ~DialogEditModuleText() {}; + +private: + void initDlg( ); + void OnOkClick( wxCommandEvent& event ); + void OnCancelClick( wxCommandEvent& event ); +}; + +#endif /* DIALOG_EDIT_MODULE_TEXT_H */ From 803c05992c88cd7a150c483cd5052702cdf60be7 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 14:01:06 +0200 Subject: [PATCH 054/123] Fixed DRAWING_TOOL::PlaceTextModule() method. --- pcbnew/tools/drawing_tool.cpp | 59 +++++++++++++++++++++-------------- pcbnew/tools/drawing_tool.h | 4 +-- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 71a8b2501f..3fe19576b9 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -64,7 +65,7 @@ void DRAWING_TOOL::Reset( RESET_REASON aReason ) m_view = getView(); m_controls = getViewControls(); m_board = getModel(); - m_frame = getEditFrame(); + m_frame = getEditFrame(); setTransitions(); } @@ -126,7 +127,9 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) int DRAWING_TOOL::PlaceTextModule( TOOL_EVENT& aEvent ) { - TEXTE_MODULE* text = NULL; + TEXTE_MODULE* text = new TEXTE_MODULE( NULL ); + const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings(); + MODULE* module = m_frame->GetBoard()->m_Modules; // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( m_view ); @@ -139,6 +142,7 @@ int DRAWING_TOOL::PlaceTextModule( TOOL_EVENT& aEvent ) Activate(); m_frame->SetToolID( ID_PCB_ADD_TEXT_BUTT, wxCURSOR_PENCIL, _( "Add text" ) ); + bool placing = false; // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) @@ -147,28 +151,26 @@ int DRAWING_TOOL::PlaceTextModule( TOOL_EVENT& aEvent ) if( evt->IsCancel() || evt->IsActivate() ) { - if( text ) - { - // Delete the old text and have another try - m_board->Delete( text ); // it was already added by CreateTextPcb() - text = NULL; + preview.Clear(); + preview.ViewUpdate(); + m_controls->ShowCursor( true ); - preview.Clear(); - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - m_controls->ShowCursor( true ); + if( !placing || evt->IsActivate() ) + { + delete text; + break; } else - break; - - if( evt->IsActivate() ) // now finish unconditionally - break; + { + placing = false; // start from the beginning + } } else if( text && evt->Category() == TC_COMMAND ) { if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) { - text->Rotate( text->GetPosition(), 900.0 /*m_frame->GetRotationAngle()*/ ); // FIXME + text->Rotate( text->GetPosition(), m_frame->GetRotationAngle() ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) @@ -180,15 +182,21 @@ int DRAWING_TOOL::PlaceTextModule( TOOL_EVENT& aEvent ) else if( evt->IsClick( BUT_LEFT ) ) { - if( !text ) + if( !placing ) { - // Init the new item attributes - text = m_frame->CreateTextModule( m_frame->GetBoard()->m_Modules, NULL ); + text->SetSize( dsnSettings.m_ModuleTextSize ); + text->SetThickness( dsnSettings.m_ModuleTextWidth ); + text->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) ); - if( text == NULL ) + DialogEditModuleText textDialog( m_frame, text, NULL ); + placing = textDialog.ShowModal() && ( text->GetText().Length() > 0 ); + + if( !placing ) continue; m_controls->ShowCursor( false ); + text->SetParent( module ); // it has to set after the settings dialog + // otherwise the dialog stores it in undo buffer preview.Add( text ); } else @@ -196,18 +204,23 @@ int DRAWING_TOOL::PlaceTextModule( TOOL_EVENT& aEvent ) assert( text->GetText().Length() > 0 ); assert( text->GetSize().x > 0 && text->GetSize().y > 0 ); + text->SetLocalCoord(); text->ClearFlags(); + + // Module has to be saved before any modification is made + m_frame->SaveCopyInUndoList( m_frame->GetBoard()->m_Modules, UR_MODEDIT ); + module->GraphicalItems().PushFront( text ); + m_view->Add( text ); - // m_board->Add( text ); // it is already added by CreateTextePcb() text->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); m_frame->OnModify(); - m_frame->SaveCopyInUndoList( text, UR_NEW ); preview.Remove( text ); m_controls->ShowCursor( true ); - text = NULL; + text = new TEXTE_MODULE( NULL ); + placing = false; } } @@ -276,7 +289,7 @@ int DRAWING_TOOL::PlaceTextPcb( TOOL_EVENT& aEvent ) { if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) { - text->Rotate( text->GetPosition(), /*m_frame->GetRotationAngle()*/ 900.0 ); // FIXME + text->Rotate( text->GetPosition(), m_frame->GetRotationAngle() ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index 57e865bfd7..1a38edbd62 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -33,7 +33,7 @@ namespace KIGFX class VIEW_CONTROLS; } class BOARD; -class PCB_BASE_FRAME; +class PCB_EDIT_FRAME; class DRAWSEGMENT; /** @@ -160,7 +160,7 @@ private: KIGFX::VIEW* m_view; KIGFX::VIEW_CONTROLS* m_controls; BOARD* m_board; - PCB_BASE_FRAME* m_frame; + PCB_EDIT_FRAME* m_frame; // How does line width change after one -/+ key press. static const int WIDTH_STEP = 100000; From d373ffa551dc06e8fe8dd953e58486a924d7417b Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 14:01:06 +0200 Subject: [PATCH 055/123] Added "edit modules" mode for DRAWING_TOOL. --- pcbnew/tools/common_actions.cpp | 10 +- pcbnew/tools/common_actions.h | 3 +- pcbnew/tools/drawing_tool.cpp | 478 ++++++++++++++++---------------- pcbnew/tools/drawing_tool.h | 41 ++- 4 files changed, 277 insertions(+), 255 deletions(-) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 343f1813f3..71c5b928f3 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -73,11 +73,7 @@ TOOL_ACTION COMMON_ACTIONS::drawArc( "pcbnew.InteractiveDrawing.arc", AS_GLOBAL, 0, "Draw an arc", "Draw an arc", AF_ACTIVATE ); -TOOL_ACTION COMMON_ACTIONS::placeTextModule( "pcbnew.InteractiveDrawing.textPcb", - AS_GLOBAL, 0, - "Add a text", "Add a text", AF_ACTIVATE ); - -TOOL_ACTION COMMON_ACTIONS::placeTextPcb( "pcbnew.InteractiveDrawing.textModule", +TOOL_ACTION COMMON_ACTIONS::placeText( "pcbnew.InteractiveDrawing.text", AS_GLOBAL, 0, "Add a text", "Add a text", AF_ACTIVATE ); @@ -299,10 +295,8 @@ boost::optional COMMON_ACTIONS::TranslateLegacyId( int aId ) return COMMON_ACTIONS::drawArc.MakeEvent(); case ID_PCB_ADD_TEXT_BUTT: - return COMMON_ACTIONS::placeTextPcb.MakeEvent(); - case ID_MODEDIT_TEXT_TOOL: - return COMMON_ACTIONS::placeTextModule.MakeEvent(); + return COMMON_ACTIONS::placeText.MakeEvent(); case ID_PCB_DIMENSION_BUTT: return COMMON_ACTIONS::drawDimension.MakeEvent(); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 9eec3ce112..0cd45e56c2 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -73,8 +73,7 @@ public: static TOOL_ACTION drawArc; /// Activation of the drawing tool (text) - static TOOL_ACTION placeTextPcb; - static TOOL_ACTION placeTextModule; + static TOOL_ACTION placeText; /// Activation of the drawing tool (dimension) static TOOL_ACTION drawDimension; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 3fe19576b9..e2fde67446 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -49,7 +49,7 @@ #include DRAWING_TOOL::DRAWING_TOOL() : - TOOL_INTERACTIVE( "pcbnew.InteractiveDrawing" ) + TOOL_INTERACTIVE( "pcbnew.InteractiveDrawing" ), m_editModules( false ) { } @@ -125,231 +125,12 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) } -int DRAWING_TOOL::PlaceTextModule( TOOL_EVENT& aEvent ) +int DRAWING_TOOL::PlaceText( TOOL_EVENT& aEvent ) { - TEXTE_MODULE* text = new TEXTE_MODULE( NULL ); - const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings(); - MODULE* module = m_frame->GetBoard()->m_Modules; - - // Add a VIEW_GROUP that serves as a preview for the new item - KIGFX::VIEW_GROUP preview( m_view ); - m_view->Add( &preview ); - - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); - m_controls->ShowCursor( true ); - m_controls->SetSnapping( true ); - m_controls->SetAutoPan( true ); - - Activate(); - m_frame->SetToolID( ID_PCB_ADD_TEXT_BUTT, wxCURSOR_PENCIL, _( "Add text" ) ); - bool placing = false; - - // Main loop: keep receiving events - while( OPT_TOOL_EVENT evt = Wait() ) - { - VECTOR2I cursorPos = m_controls->GetCursorPosition(); - - if( evt->IsCancel() || evt->IsActivate() ) - { - preview.Clear(); - preview.ViewUpdate(); - m_controls->ShowCursor( true ); - - if( !placing || evt->IsActivate() ) - { - delete text; - break; - } - else - { - placing = false; // start from the beginning - } - } - - else if( text && evt->Category() == TC_COMMAND ) - { - if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) - { - text->Rotate( text->GetPosition(), m_frame->GetRotationAngle() ); - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) - { - text->Flip( text->GetPosition() ); - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - } - - else if( evt->IsClick( BUT_LEFT ) ) - { - if( !placing ) - { - text->SetSize( dsnSettings.m_ModuleTextSize ); - text->SetThickness( dsnSettings.m_ModuleTextWidth ); - text->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) ); - - DialogEditModuleText textDialog( m_frame, text, NULL ); - placing = textDialog.ShowModal() && ( text->GetText().Length() > 0 ); - - if( !placing ) - continue; - - m_controls->ShowCursor( false ); - text->SetParent( module ); // it has to set after the settings dialog - // otherwise the dialog stores it in undo buffer - preview.Add( text ); - } - else - { - assert( text->GetText().Length() > 0 ); - assert( text->GetSize().x > 0 && text->GetSize().y > 0 ); - - text->SetLocalCoord(); - text->ClearFlags(); - - // Module has to be saved before any modification is made - m_frame->SaveCopyInUndoList( m_frame->GetBoard()->m_Modules, UR_MODEDIT ); - module->GraphicalItems().PushFront( text ); - - m_view->Add( text ); - text->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - - m_frame->OnModify(); - - preview.Remove( text ); - m_controls->ShowCursor( true ); - - text = new TEXTE_MODULE( NULL ); - placing = false; - } - } - - else if( text && evt->IsMotion() ) - { - text->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) ); - - // Show a preview of the item - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - } - - m_controls->ShowCursor( false ); - m_controls->SetSnapping( false ); - m_controls->SetAutoPan( false ); - m_view->Remove( &preview ); - - setTransitions(); - m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); - - return 0; -} - - -int DRAWING_TOOL::PlaceTextPcb( TOOL_EVENT& aEvent ) -{ - TEXTE_PCB* text = NULL; - - // Add a VIEW_GROUP that serves as a preview for the new item - KIGFX::VIEW_GROUP preview( m_view ); - m_view->Add( &preview ); - - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); - m_controls->ShowCursor( true ); - m_controls->SetSnapping( true ); - m_controls->SetAutoPan( true ); - - Activate(); - m_frame->SetToolID( ID_PCB_ADD_TEXT_BUTT, wxCURSOR_PENCIL, _( "Add text" ) ); - - // Main loop: keep receiving events - while( OPT_TOOL_EVENT evt = Wait() ) - { - VECTOR2I cursorPos = m_controls->GetCursorPosition(); - - if( evt->IsCancel() || evt->IsActivate() ) - { - if( text ) - { - // Delete the old text and have another try - m_board->Delete( text ); // it was already added by CreateTextPcb() - text = NULL; - - preview.Clear(); - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - m_controls->ShowCursor( true ); - } - else - break; - - if( evt->IsActivate() ) // now finish unconditionally - break; - } - - else if( text && evt->Category() == TC_COMMAND ) - { - if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) - { - text->Rotate( text->GetPosition(), m_frame->GetRotationAngle() ); - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) - { - text->Flip( text->GetPosition() ); - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - } - - else if( evt->IsClick( BUT_LEFT ) ) - { - if( !text ) - { - // Init the new item attributes - text = static_cast( m_frame )->CreateTextePcb( NULL ); - - if( text == NULL ) - continue; - - m_controls->ShowCursor( false ); - preview.Add( text ); - } - else - { - assert( text->GetText().Length() > 0 ); - assert( text->GetSize().x > 0 && text->GetSize().y > 0 ); - - text->ClearFlags(); - m_view->Add( text ); - // m_board->Add( text ); // it is already added by CreateTextePcb() - text->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - - m_frame->OnModify(); - m_frame->SaveCopyInUndoList( text, UR_NEW ); - - preview.Remove( text ); - m_controls->ShowCursor( true ); - - text = NULL; - } - } - - else if( text && evt->IsMotion() ) - { - text->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) ); - - // Show a preview of the item - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - } - - m_controls->ShowCursor( false ); - m_controls->SetSnapping( false ); - m_controls->SetAutoPan( false ); - m_view->Remove( &preview ); - - setTransitions(); - m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); - - return 0; + if( m_editModules ) + return placeTextModule(); + else + return placeTextPcb(); } @@ -1271,6 +1052,234 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) } +int DRAWING_TOOL::placeTextModule() +{ + TEXTE_MODULE* text = new TEXTE_MODULE( NULL ); + const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings(); + MODULE* module = m_frame->GetBoard()->m_Modules; + + // Add a VIEW_GROUP that serves as a preview for the new item + KIGFX::VIEW_GROUP preview( m_view ); + m_view->Add( &preview ); + + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_controls->ShowCursor( true ); + m_controls->SetSnapping( true ); + m_controls->SetAutoPan( true ); + + Activate(); + m_frame->SetToolID( ID_PCB_ADD_TEXT_BUTT, wxCURSOR_PENCIL, _( "Add text" ) ); + bool placing = false; + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + VECTOR2I cursorPos = m_controls->GetCursorPosition(); + + if( evt->IsCancel() || evt->IsActivate() ) + { + preview.Clear(); + preview.ViewUpdate(); + m_controls->ShowCursor( true ); + + if( !placing || evt->IsActivate() ) + { + delete text; + break; + } + else + { + placing = false; // start from the beginning + } + } + + else if( text && evt->Category() == TC_COMMAND ) + { + if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) + { + text->Rotate( text->GetPosition(), m_frame->GetRotationAngle() ); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) + { + text->Flip( text->GetPosition() ); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + + else if( evt->IsClick( BUT_LEFT ) ) + { + if( !placing ) + { + text->SetSize( dsnSettings.m_ModuleTextSize ); + text->SetThickness( dsnSettings.m_ModuleTextWidth ); + text->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) ); + + DialogEditModuleText textDialog( m_frame, text, NULL ); + placing = textDialog.ShowModal() && ( text->GetText().Length() > 0 ); + + if( !placing ) + continue; + + m_controls->ShowCursor( false ); + text->SetParent( module ); // it has to set after the settings dialog + // otherwise the dialog stores it in undo buffer + preview.Add( text ); + } + else + { + assert( text->GetText().Length() > 0 ); + assert( text->GetSize().x > 0 && text->GetSize().y > 0 ); + + text->SetLocalCoord(); + text->ClearFlags(); + + // Module has to be saved before any modification is made + m_frame->SaveCopyInUndoList( m_frame->GetBoard()->m_Modules, UR_MODEDIT ); + module->GraphicalItems().PushFront( text ); + + m_view->Add( text ); + text->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + + m_frame->OnModify(); + + preview.Remove( text ); + m_controls->ShowCursor( true ); + + text = new TEXTE_MODULE( NULL ); + placing = false; + } + } + + else if( text && evt->IsMotion() ) + { + text->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) ); + + // Show a preview of the item + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + + m_controls->ShowCursor( false ); + m_controls->SetSnapping( false ); + m_controls->SetAutoPan( false ); + m_view->Remove( &preview ); + + setTransitions(); + m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); + + return 0; +} + + +int DRAWING_TOOL::placeTextPcb() +{ + TEXTE_PCB* text = NULL; + + // Add a VIEW_GROUP that serves as a preview for the new item + KIGFX::VIEW_GROUP preview( m_view ); + m_view->Add( &preview ); + + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_controls->ShowCursor( true ); + m_controls->SetSnapping( true ); + m_controls->SetAutoPan( true ); + + Activate(); + m_frame->SetToolID( ID_PCB_ADD_TEXT_BUTT, wxCURSOR_PENCIL, _( "Add text" ) ); + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + VECTOR2I cursorPos = m_controls->GetCursorPosition(); + + if( evt->IsCancel() || evt->IsActivate() ) + { + if( text ) + { + // Delete the old text and have another try + m_board->Delete( text ); // it was already added by CreateTextPcb() + text = NULL; + + preview.Clear(); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + m_controls->ShowCursor( true ); + } + else + break; + + if( evt->IsActivate() ) // now finish unconditionally + break; + } + + else if( text && evt->Category() == TC_COMMAND ) + { + if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) + { + text->Rotate( text->GetPosition(), m_frame->GetRotationAngle() ); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) + { + text->Flip( text->GetPosition() ); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + + else if( evt->IsClick( BUT_LEFT ) ) + { + if( !text ) + { + // Init the new item attributes + text = static_cast( m_frame )->CreateTextePcb( NULL ); + + if( text == NULL ) + continue; + + m_controls->ShowCursor( false ); + preview.Add( text ); + } + else + { + assert( text->GetText().Length() > 0 ); + assert( text->GetSize().x > 0 && text->GetSize().y > 0 ); + + text->ClearFlags(); + m_view->Add( text ); + // m_board->Add( text ); // it is already added by CreateTextePcb() + text->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( text, UR_NEW ); + + preview.Remove( text ); + m_controls->ShowCursor( true ); + + text = NULL; + } + } + + else if( text && evt->IsMotion() ) + { + text->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) ); + + // Show a preview of the item + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + + m_controls->ShowCursor( false ); + m_controls->SetSnapping( false ); + m_controls->SetAutoPan( false ); + m_view->Remove( &preview ); + + setTransitions(); + m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); + + return 0; +} + + void DRAWING_TOOL::make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper ) const { VECTOR2I cursorPos = m_controls->GetCursorPosition(); @@ -1295,14 +1304,13 @@ void DRAWING_TOOL::make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper ) void DRAWING_TOOL::setTransitions() { - Go( &DRAWING_TOOL::DrawLine, COMMON_ACTIONS::drawLine.MakeEvent() ); - Go( &DRAWING_TOOL::DrawCircle, COMMON_ACTIONS::drawCircle.MakeEvent() ); - Go( &DRAWING_TOOL::DrawArc, COMMON_ACTIONS::drawArc.MakeEvent() ); - Go( &DRAWING_TOOL::DrawDimension, COMMON_ACTIONS::drawDimension.MakeEvent() ); - Go( &DRAWING_TOOL::DrawZone, COMMON_ACTIONS::drawZone.MakeEvent() ); - Go( &DRAWING_TOOL::DrawKeepout, COMMON_ACTIONS::drawKeepout.MakeEvent() ); - Go( &DRAWING_TOOL::PlaceTextPcb, COMMON_ACTIONS::placeTextPcb.MakeEvent() ); - Go( &DRAWING_TOOL::PlaceTextModule, COMMON_ACTIONS::placeTextModule.MakeEvent() ); - Go( &DRAWING_TOOL::PlaceTarget, COMMON_ACTIONS::placeTarget.MakeEvent() ); - Go( &DRAWING_TOOL::PlaceModule, COMMON_ACTIONS::placeModule.MakeEvent() ); + Go( &DRAWING_TOOL::DrawLine, COMMON_ACTIONS::drawLine.MakeEvent() ); + Go( &DRAWING_TOOL::DrawCircle, COMMON_ACTIONS::drawCircle.MakeEvent() ); + Go( &DRAWING_TOOL::DrawArc, COMMON_ACTIONS::drawArc.MakeEvent() ); + Go( &DRAWING_TOOL::DrawDimension, COMMON_ACTIONS::drawDimension.MakeEvent() ); + Go( &DRAWING_TOOL::DrawZone, COMMON_ACTIONS::drawZone.MakeEvent() ); + Go( &DRAWING_TOOL::DrawKeepout, COMMON_ACTIONS::drawKeepout.MakeEvent() ); + Go( &DRAWING_TOOL::PlaceText, COMMON_ACTIONS::placeText.MakeEvent() ); + Go( &DRAWING_TOOL::PlaceTarget, COMMON_ACTIONS::placeTarget.MakeEvent() ); + Go( &DRAWING_TOOL::PlaceModule, COMMON_ACTIONS::placeModule.MakeEvent() ); } diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index 1a38edbd62..1137bf2c4c 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -76,18 +76,11 @@ public: int DrawArc( TOOL_EVENT& aEvent ); /** - * Function PlaceTextModule() + * Function PlaceText() * Displays a dialog that allows to input text and its settings and then lets the user decide - * where to place the text in module editor. + * where to place the text in editor. */ - int PlaceTextModule( TOOL_EVENT& aEvent ); - - /** - * Function PlaceTextPcb() - * Displays a dialog that allows to input text and its settings and then lets the user decide - * where to place the text in board editor. - */ - int PlaceTextPcb( TOOL_EVENT& aEvent ); + int PlaceText( TOOL_EVENT& aEvent ); /** * Function DrawDimension() @@ -127,6 +120,17 @@ public: */ int PlaceModule( TOOL_EVENT& aEvent ); + /** + * Function EditModules() + * Toggles edit module mode. When enabled, one may select parts of modules individually + * (graphics, pads, etc.), so they can be modified. + * @param aEnabled decides if the mode should be enabled. + */ + void EditModules( bool aEnabled ) + { + m_editModules = aEnabled; + } + private: ///> Starts drawing a selected shape (i.e. DRAWSEGMENT). ///> @param aShape is the type of created shape (@see STROKE_T). @@ -147,6 +151,20 @@ private: ///> @param aKeepout decides if the drawn polygon is a zone or a keepout area. int drawZone( bool aKeepout ); + /** + * Function placeTextModule() + * Displays a dialog that allows to input text and its settings and then lets the user decide + * where to place the text in module . + */ + int placeTextModule(); + + /** + * Function placeTextPcb() + * Displays a dialog that allows to input text and its settings and then lets the user decide + * where to place the text in board editor. + */ + int placeTextPcb(); + ///> Forces a DRAWSEGMENT to be drawn at multiple of 45 degrees. The origin ///> stays the same, the end of the aSegment is modified according to the ///> current cursor position. @@ -162,6 +180,9 @@ private: BOARD* m_board; PCB_EDIT_FRAME* m_frame; + /// Edit module mode flag + bool m_editModules; + // How does line width change after one -/+ key press. static const int WIDTH_STEP = 100000; }; From bd22ab3df5f2d869b500262d4655a64757630f06 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 14:01:06 +0200 Subject: [PATCH 056/123] Adapted graphics tools to cooperate with module editor. --- pcbnew/moduleframe.cpp | 3 +- pcbnew/tools/common_actions.cpp | 7 ++ pcbnew/tools/drawing_tool.cpp | 121 +++++++++++++++++++++++++------- 3 files changed, 103 insertions(+), 28 deletions(-) diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index 451f5a9130..ed9ff6165e 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -271,11 +271,12 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : drawPanel->SetEventDispatcher( m_toolDispatcher ); m_toolManager->RegisterTool( new SELECTION_TOOL ); - m_toolManager->GetTool()->EditModules( true ); m_toolManager->RegisterTool( new EDIT_TOOL ); m_toolManager->RegisterTool( new DRAWING_TOOL ); m_toolManager->RegisterTool( new POINT_EDITOR ); m_toolManager->RegisterTool( new PCBNEW_CONTROL ); + m_toolManager->GetTool()->EditModules( true ); + m_toolManager->GetTool()->EditModules( true ); m_toolManager->ResetTools( TOOL_BASE::RUN ); // Run the selection tool, it is supposed to be always active diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 71c5b928f3..57edb54dc6 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -286,12 +286,15 @@ boost::optional COMMON_ACTIONS::TranslateLegacyId( int aId ) return COMMON_ACTIONS::drawKeepout.MakeEvent(); case ID_PCB_ADD_LINE_BUTT: + case ID_MODEDIT_LINE_TOOL: return COMMON_ACTIONS::drawLine.MakeEvent(); case ID_PCB_CIRCLE_BUTT: + case ID_MODEDIT_CIRCLE_TOOL: return COMMON_ACTIONS::drawCircle.MakeEvent(); case ID_PCB_ARC_BUTT: + case ID_MODEDIT_ARC_TOOL: return COMMON_ACTIONS::drawArc.MakeEvent(); case ID_PCB_ADD_TEXT_BUTT: @@ -305,6 +308,7 @@ boost::optional COMMON_ACTIONS::TranslateLegacyId( int aId ) return COMMON_ACTIONS::placeTarget.MakeEvent(); case ID_PCB_PLACE_GRID_COORD_BUTT: + case ID_MODEDIT_PLACE_GRID_COORD: return COMMON_ACTIONS::gridSetOrigin.MakeEvent(); case ID_ZOOM_IN: // toolbar button "Zoom In" @@ -325,6 +329,9 @@ boost::optional COMMON_ACTIONS::TranslateLegacyId( int aId ) case ID_TB_OPTIONS_SHOW_EXTRA_VERTICAL_TOOLBAR_MICROWAVE: case ID_MENU_PCB_SHOW_HIDE_MUWAVE_TOOLBAR: case ID_MICROWAVE_V_TOOLBAR: + case ID_MODEDIT_PAD_TOOL: + case ID_MODEDIT_DELETE_TOOL: + case ID_MODEDIT_ANCHOR_TOOL: return COMMON_ACTIONS::toBeDone.MakeEvent(); } diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index e2fde67446..37264569a5 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -41,7 +41,7 @@ #include #include -#include +#include #include #include #include @@ -73,13 +73,38 @@ void DRAWING_TOOL::Reset( RESET_REASON aReason ) int DRAWING_TOOL::DrawLine( TOOL_EVENT& aEvent ) { - m_frame->SetToolID( ID_PCB_ADD_LINE_BUTT, wxCURSOR_PENCIL, _( "Add graphic line" ) ); - - DRAWSEGMENT* line = new DRAWSEGMENT; - - while( drawSegment( S_SEGMENT, line ) ) + if( m_editModules ) { - line = new DRAWSEGMENT; + m_frame->SetToolID( ID_MODEDIT_LINE_TOOL, wxCURSOR_PENCIL, _( "Add graphic line" ) ); + + MODULE* module = m_frame->GetBoard()->m_Modules; + EDGE_MODULE* line = new EDGE_MODULE( module ); + + while( drawSegment( S_SEGMENT, line ) ) + { + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( module, UR_MODEDIT ); + line->SetLocalCoord(); + line->SetParent( module ); + module->GraphicalItems().PushFront( line ); + + line = new EDGE_MODULE( module ); + } + } + else + { + m_frame->SetToolID( ID_PCB_ADD_LINE_BUTT, wxCURSOR_PENCIL, _( "Add graphic line" ) ); + + DRAWSEGMENT* line = new DRAWSEGMENT; + + while( drawSegment( S_SEGMENT, line ) ) + { + m_board->Add( line ); + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( line, UR_NEW ); + + line = new DRAWSEGMENT; + } } setTransitions(); @@ -91,13 +116,38 @@ int DRAWING_TOOL::DrawLine( TOOL_EVENT& aEvent ) int DRAWING_TOOL::DrawCircle( TOOL_EVENT& aEvent ) { - m_frame->SetToolID( ID_PCB_CIRCLE_BUTT, wxCURSOR_PENCIL, _( "Add graphic circle" ) ); - - DRAWSEGMENT* circle = new DRAWSEGMENT; - - while( drawSegment( S_CIRCLE, circle ) ) + if( m_editModules ) { - circle = new DRAWSEGMENT; + m_frame->SetToolID( ID_MODEDIT_CIRCLE_TOOL, wxCURSOR_PENCIL, _( "Add graphic circle" ) ); + + MODULE* module = m_frame->GetBoard()->m_Modules; + EDGE_MODULE* circle = new EDGE_MODULE( module ); + + while( drawSegment( S_CIRCLE, circle ) ) + { + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( module, UR_MODEDIT ); + circle->SetLocalCoord(); + circle->SetParent( module ); + module->GraphicalItems().PushFront( circle ); + + circle = new EDGE_MODULE( module ); + } + } + else + { + m_frame->SetToolID( ID_PCB_CIRCLE_BUTT, wxCURSOR_PENCIL, _( "Add graphic circle" ) ); + + DRAWSEGMENT* circle = new DRAWSEGMENT; + + while( drawSegment( S_CIRCLE, circle ) ) + { + m_board->Add( circle ); + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( circle, UR_NEW ); + + circle = new DRAWSEGMENT; + } } setTransitions(); @@ -109,13 +159,38 @@ int DRAWING_TOOL::DrawCircle( TOOL_EVENT& aEvent ) int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) { - m_frame->SetToolID( ID_PCB_ARC_BUTT, wxCURSOR_PENCIL, _( "Add graphic arc" ) ); - - DRAWSEGMENT* arc = new DRAWSEGMENT; - - while( drawArc( arc ) ) + if( m_editModules ) { - arc = new DRAWSEGMENT; + m_frame->SetToolID( ID_MODEDIT_ARC_TOOL, wxCURSOR_PENCIL, _( "Add graphic arc" ) ); + + MODULE* module = m_frame->GetBoard()->m_Modules; + EDGE_MODULE* arc = new EDGE_MODULE( module ); + + while( drawArc( arc ) ) + { + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( module, UR_MODEDIT ); + arc->SetLocalCoord(); + arc->SetParent( module ); + module->GraphicalItems().PushFront( arc ); + + arc = new EDGE_MODULE( module ); + } + } + else + { + m_frame->SetToolID( ID_PCB_ARC_BUTT, wxCURSOR_PENCIL, _( "Add graphic arc" ) ); + + DRAWSEGMENT* arc = new DRAWSEGMENT; + + while( drawArc( arc ) ) + { + m_board->Add( arc ); + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( arc, UR_NEW ); + + arc = new DRAWSEGMENT; + } } setTransitions(); @@ -624,11 +699,7 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT* aGraphic ) assert( aGraphic->GetWidth() > 0 ); m_view->Add( aGraphic ); - m_board->Add( aGraphic ); aGraphic->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - - m_frame->OnModify(); - m_frame->SaveCopyInUndoList( aGraphic, UR_NEW ); } else // User has clicked twice in the same spot { // a clear sign that the current drawing is finished @@ -785,12 +856,8 @@ bool DRAWING_TOOL::drawArc( DRAWSEGMENT* aGraphic ) assert( aGraphic->GetWidth() > 0 ); m_view->Add( aGraphic ); - m_board->Add( aGraphic ); aGraphic->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - m_frame->OnModify(); - m_frame->SaveCopyInUndoList( aGraphic, UR_NEW ); - preview.Remove( aGraphic ); preview.Remove( &helperLine ); } From 17e082088b58c75156fb25cc252221b8dd441305 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 14:01:06 +0200 Subject: [PATCH 057/123] Fixed the legacy module editor. --- pcbnew/basepcbframe.cpp | 2 +- pcbnew/moduleframe.cpp | 26 ++++++++++++++------------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index fadf3e1774..3ff1a97f51 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -125,7 +125,7 @@ PCB_BASE_FRAME::~PCB_BASE_FRAME() { delete m_Collector; - delete m_Pcb; // is already NULL for FOOTPRINT_EDIT_FRAME + delete m_Pcb; delete GetGalCanvas(); } diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index ed9ff6165e..2fa40ac774 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -268,21 +268,23 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : m_toolManager->SetEnvironment( GetBoard(), drawPanel->GetView(), drawPanel->GetViewControls(), this ); m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager ); - drawPanel->SetEventDispatcher( m_toolDispatcher ); - m_toolManager->RegisterTool( new SELECTION_TOOL ); - m_toolManager->RegisterTool( new EDIT_TOOL ); - m_toolManager->RegisterTool( new DRAWING_TOOL ); - m_toolManager->RegisterTool( new POINT_EDITOR ); - m_toolManager->RegisterTool( new PCBNEW_CONTROL ); - m_toolManager->GetTool()->EditModules( true ); - m_toolManager->GetTool()->EditModules( true ); - m_toolManager->ResetTools( TOOL_BASE::RUN ); + if( drawFrame->IsGalCanvasActive() ) + { + drawPanel->SetEventDispatcher( m_toolDispatcher ); - // Run the selection tool, it is supposed to be always active - m_toolManager->InvokeTool( "pcbnew.InteractiveSelection" ); + m_toolManager->RegisterTool( new SELECTION_TOOL ); + m_toolManager->RegisterTool( new EDIT_TOOL ); + m_toolManager->RegisterTool( new DRAWING_TOOL ); + m_toolManager->RegisterTool( new POINT_EDITOR ); + m_toolManager->RegisterTool( new PCBNEW_CONTROL ); + m_toolManager->GetTool()->EditModules( true ); + m_toolManager->GetTool()->EditModules( true ); + m_toolManager->ResetTools( TOOL_BASE::RUN ); + m_toolManager->InvokeTool( "pcbnew.InteractiveSelection" ); - UseGalCanvas( drawFrame->IsGalCanvasActive() ); + UseGalCanvas( true ); + } m_Layers->ReFill(); m_Layers->ReFillRender(); From 0f3f219ed293d28e2716f24c3f012467b439b9d6 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 14:01:06 +0200 Subject: [PATCH 058/123] MInor fixes. --- pcbnew/class_pad.cpp | 3 +-- pcbnew/tools/drawing_tool.cpp | 12 ++++++------ pcbnew/tools/drawing_tool.h | 14 ++++++++------ 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index ef2be10951..bd20fd83af 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -255,8 +255,7 @@ void D_PAD::SetLocalCoord() } m_Pos0 = m_Pos - module->GetPosition(); - double angle = module->GetOrientation(); - RotatePoint( &m_Pos0.x, &m_Pos0.y, -angle ); + RotatePoint( &m_Pos0.x, &m_Pos0.y, -module->GetOrientation() ); } diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 37264569a5..e46ce6db27 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -77,7 +77,7 @@ int DRAWING_TOOL::DrawLine( TOOL_EVENT& aEvent ) { m_frame->SetToolID( ID_MODEDIT_LINE_TOOL, wxCURSOR_PENCIL, _( "Add graphic line" ) ); - MODULE* module = m_frame->GetBoard()->m_Modules; + MODULE* module = m_board->m_Modules; EDGE_MODULE* line = new EDGE_MODULE( module ); while( drawSegment( S_SEGMENT, line ) ) @@ -120,7 +120,7 @@ int DRAWING_TOOL::DrawCircle( TOOL_EVENT& aEvent ) { m_frame->SetToolID( ID_MODEDIT_CIRCLE_TOOL, wxCURSOR_PENCIL, _( "Add graphic circle" ) ); - MODULE* module = m_frame->GetBoard()->m_Modules; + MODULE* module = m_board->m_Modules; EDGE_MODULE* circle = new EDGE_MODULE( module ); while( drawSegment( S_CIRCLE, circle ) ) @@ -163,7 +163,7 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) { m_frame->SetToolID( ID_MODEDIT_ARC_TOOL, wxCURSOR_PENCIL, _( "Add graphic arc" ) ); - MODULE* module = m_frame->GetBoard()->m_Modules; + MODULE* module = m_board->m_Modules; EDGE_MODULE* arc = new EDGE_MODULE( module ); while( drawArc( arc ) ) @@ -527,7 +527,7 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) { if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) { - module->Rotate( module->GetPosition(), /*m_frame->GetRotationAngle()*/ 900.0 ); + module->Rotate( module->GetPosition(), m_frame->GetRotationAngle() ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) @@ -1123,7 +1123,7 @@ int DRAWING_TOOL::placeTextModule() { TEXTE_MODULE* text = new TEXTE_MODULE( NULL ); const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings(); - MODULE* module = m_frame->GetBoard()->m_Modules; + MODULE* module = m_board->m_Modules; // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( m_view ); @@ -1202,7 +1202,7 @@ int DRAWING_TOOL::placeTextModule() text->ClearFlags(); // Module has to be saved before any modification is made - m_frame->SaveCopyInUndoList( m_frame->GetBoard()->m_Modules, UR_MODEDIT ); + m_frame->SaveCopyInUndoList( module, UR_MODEDIT ); module->GraphicalItems().PushFront( text ); m_view->Add( text ); diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index 1137bf2c4c..32c15a8401 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -116,7 +116,7 @@ public: /** * Function PlaceModule() - * Displays a dialog to selected a module to be added and then allows user to set its position. + * Displays a dialog to select a module to be added and allows the user to set its position. */ int PlaceModule( TOOL_EVENT& aEvent ); @@ -165,11 +165,13 @@ private: */ int placeTextPcb(); - ///> Forces a DRAWSEGMENT to be drawn at multiple of 45 degrees. The origin - ///> stays the same, the end of the aSegment is modified according to the - ///> current cursor position. - ///> @param aSegment is the segment that is currently drawn. - ///> @param aHelper is a helper line that shows the next possible segment. + /** + * Function make45DegLine() + * Forces a DRAWSEGMENT to be drawn at multiple of 45 degrees. The origin stays the same, + * the end of the aSegment is modified according to the current cursor position. + * @param aSegment is the segment that is currently drawn. + * @param aHelper is a helper line that shows the next possible segment. + */ void make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper ) const; ///> Sets up handlers for various events. From cdeb700f70fd4da40ede8130c2ef331086844df1 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 14:01:06 +0200 Subject: [PATCH 059/123] Added pad placement tool for module editor (GAL). --- pcbnew/tools/common_actions.cpp | 7 +- pcbnew/tools/common_actions.h | 3 + pcbnew/tools/drawing_tool.cpp | 154 ++++++++++++++++++++++++++++++++ pcbnew/tools/drawing_tool.h | 12 +++ 4 files changed, 175 insertions(+), 1 deletion(-) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 57edb54dc6..45305cc83e 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -97,6 +97,9 @@ TOOL_ACTION COMMON_ACTIONS::placeModule( "pcbnew.InteractiveDrawing.placeModule" AS_GLOBAL, 'O', "Add modules", "Add modules", AF_ACTIVATE ); +TOOL_ACTION COMMON_ACTIONS::placePad( "pcbnew.InteractiveDrawing.placePad", + AS_GLOBAL, 0, + "Add pads", "Add pads", AF_ACTIVATE ); // View Controls TOOL_ACTION COMMON_ACTIONS::zoomIn( "pcbnew.Control.zoomIn", @@ -307,6 +310,9 @@ boost::optional COMMON_ACTIONS::TranslateLegacyId( int aId ) case ID_PCB_MIRE_BUTT: return COMMON_ACTIONS::placeTarget.MakeEvent(); + case ID_MODEDIT_PAD_TOOL: + return COMMON_ACTIONS::placePad.MakeEvent(); + case ID_PCB_PLACE_GRID_COORD_BUTT: case ID_MODEDIT_PLACE_GRID_COORD: return COMMON_ACTIONS::gridSetOrigin.MakeEvent(); @@ -329,7 +335,6 @@ boost::optional COMMON_ACTIONS::TranslateLegacyId( int aId ) case ID_TB_OPTIONS_SHOW_EXTRA_VERTICAL_TOOLBAR_MICROWAVE: case ID_MENU_PCB_SHOW_HIDE_MUWAVE_TOOLBAR: case ID_MICROWAVE_V_TOOLBAR: - case ID_MODEDIT_PAD_TOOL: case ID_MODEDIT_DELETE_TOOL: case ID_MODEDIT_ANCHOR_TOOL: return COMMON_ACTIONS::toBeDone.MakeEvent(); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 0cd45e56c2..9c812414df 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -90,6 +90,9 @@ public: /// Activation of the drawing tool (placing a MODULE) static TOOL_ACTION placeModule; + /// Activation of the drawing tool (placing a PAD) + static TOOL_ACTION placePad; + // Push and Shove Router Tool /// Activation of the Push and Shove router static TOOL_ACTION routerActivate; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index e46ce6db27..fff955bfca 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -23,6 +23,8 @@ */ #include +#include + #include "drawing_tool.h" #include "common_actions.h" @@ -594,6 +596,110 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) } +int DRAWING_TOOL::PlacePad( TOOL_EVENT& aEvent ) +{ + assert( m_editModules ); + + m_frame->SetToolID( ID_MODEDIT_PAD_TOOL, wxCURSOR_PENCIL, _( "Add pads" ) ); + + MODULE* module = m_board->m_Modules; + assert( module ); + + D_PAD* pad = new D_PAD( module ); + m_frame->Import_Pad_Settings( pad, false ); // use the global settings for pad + + VECTOR2I cursorPos = m_controls->GetCursorPosition(); + pad->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); + + // Add a VIEW_GROUP that serves as a preview for the new item + KIGFX::VIEW_GROUP preview( m_view ); + preview.Add( pad ); + m_view->Add( &preview ); + + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_controls->ShowCursor( true ); + m_controls->SetSnapping( true ); + + Activate(); + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + cursorPos = m_controls->GetCursorPosition(); + + if( evt->IsMotion() ) + { + pad->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); + preview.ViewUpdate(); + } + + else if( evt->Category() == TC_COMMAND ) + { + if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) + { + pad->Rotate( pad->GetPosition(), m_frame->GetRotationAngle() ); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) + { + pad->Flip( pad->GetPosition() ); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else if( evt->IsCancel() || evt->IsActivate() ) + { + preview.Clear(); + delete pad; + break; + } + } + + else if( evt->IsClick( BUT_LEFT ) ) + { + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( module, UR_MODEDIT ); + + m_board->m_Status_Pcb = 0; // I have no clue why, but it is done in the legacy view + module->SetLastEditTime(); + module->Pads().PushBack( pad ); + + pad->SetNetCode( NETINFO_LIST::UNCONNECTED ); + + // Set the relative pad position + // ( pad position for module orient, 0, and relative to the module position) + pad->SetLocalCoord(); + + /* NPTH pads take empty pad number (since they can't be connected), + * other pads get incremented from the last one edited */ + wxString padName; + + if( pad->GetAttribute() != PAD_HOLE_NOT_PLATED ) + padName = getNextPadName(); + + pad->SetPadName( padName ); + + // Handle the view aspect + preview.Remove( pad ); + m_view->Add( pad ); + + // Start placing next pad + pad = new D_PAD( module ); + m_frame->Import_Pad_Settings( pad, false ); + preview.Add( pad ); + } + } + + m_controls->ShowCursor( false ); + m_controls->SetSnapping( false ); + m_controls->SetAutoPan( false ); + m_view->Remove( &preview ); + + setTransitions(); + m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); + + return 0; +} + + bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT* aGraphic ) { // Only two shapes are currently supported @@ -1369,6 +1475,53 @@ void DRAWING_TOOL::make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper ) } +bool isNotDigit( char aChar ) +{ + return ( aChar < '0' || aChar > '9' ); +} + + +wxString DRAWING_TOOL::getNextPadName() const +{ + std::set usedNumbers; + + // Find the first, not used pad number + for( MODULE* module = m_board->m_Modules; module; module = module->Next() ) + { + for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) + { + wxString padName = pad->GetPadName(); + int padNumber = 0; + int base = 1; + + // Trim and extract the trailing numeric part + while( padName.Len() && padName.Last() >= '0' && padName.Last() <= '9' ) + { + padNumber += ( padName.Last() - '0' ) * base; + padName.RemoveLast(); + base *= 10; + } + + usedNumbers.insert( padNumber ); + } + } + + int candidate = *usedNumbers.begin(); + + // Look for a gap in pad numbering + for( std::set::iterator it = usedNumbers.begin(), + itEnd = usedNumbers.end(); it != itEnd; ++it ) + { + if( *it - candidate > 1 ) + break; + + candidate = *it; + } + + return wxString::Format( wxT( "%i" ), ++candidate ); +} + + void DRAWING_TOOL::setTransitions() { Go( &DRAWING_TOOL::DrawLine, COMMON_ACTIONS::drawLine.MakeEvent() ); @@ -1380,4 +1533,5 @@ void DRAWING_TOOL::setTransitions() Go( &DRAWING_TOOL::PlaceText, COMMON_ACTIONS::placeText.MakeEvent() ); Go( &DRAWING_TOOL::PlaceTarget, COMMON_ACTIONS::placeTarget.MakeEvent() ); Go( &DRAWING_TOOL::PlaceModule, COMMON_ACTIONS::placeModule.MakeEvent() ); + Go( &DRAWING_TOOL::PlacePad, COMMON_ACTIONS::placePad.MakeEvent() ); } diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index 32c15a8401..29b87560ea 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -120,6 +120,12 @@ public: */ int PlaceModule( TOOL_EVENT& aEvent ); + /** + * Function PlacePad() + * Places a pad in the module editor. + */ + int PlacePad( TOOL_EVENT& aEvent ); + /** * Function EditModules() * Toggles edit module mode. When enabled, one may select parts of modules individually @@ -174,6 +180,12 @@ private: */ void make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper ) const; + /** + * Function getNextPadName() + * Compute the 'next' pad number for autoincrement. + * */ + wxString getNextPadName() const; + ///> Sets up handlers for various events. void setTransitions(); From e5b868cf73bfcf6a5d7d87e64d79422ec6b940a0 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 14:01:06 +0200 Subject: [PATCH 060/123] Added support for pads, texts and graphics removal in module editor (GAL). --- pcbnew/moduleframe.cpp | 3 +++ pcbnew/tools/edit_tool.cpp | 35 ++++++++++++++++++++++++++++++++--- pcbnew/tools/edit_tool.h | 14 ++++++++++++++ 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index 2fa40ac774..53c4e89fc6 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -278,8 +278,11 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : m_toolManager->RegisterTool( new DRAWING_TOOL ); m_toolManager->RegisterTool( new POINT_EDITOR ); m_toolManager->RegisterTool( new PCBNEW_CONTROL ); + m_toolManager->GetTool()->EditModules( true ); + m_toolManager->GetTool()->EditModules( true ); m_toolManager->GetTool()->EditModules( true ); + m_toolManager->ResetTools( TOOL_BASE::RUN ); m_toolManager->InvokeTool( "pcbnew.InteractiveSelection" ); diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 1db8267981..e4667867c3 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -40,7 +40,7 @@ #include "edit_tool.h" EDIT_TOOL::EDIT_TOOL() : - TOOL_INTERACTIVE( "pcbnew.InteractiveEdit" ), m_selectionTool( NULL ) + TOOL_INTERACTIVE( "pcbnew.InteractiveEdit" ), m_selectionTool( NULL ), m_editModules( false ) { } @@ -448,11 +448,40 @@ void EDIT_TOOL::remove( BOARD_ITEM* aItem ) } break; - // These are not supposed to be removed - case PCB_PAD_T: + // Default removal procedure case PCB_MODULE_TEXT_T: + { + if( m_editModules ) + { + TEXTE_MODULE* text = static_cast( aItem ); + + switch( text->GetType() ) + { + case TEXTE_MODULE::TEXT_is_REFERENCE: + DisplayError( getEditFrame(), _( "Cannot delete REFERENCE!" ) ); + return; + + case TEXTE_MODULE::TEXT_is_VALUE: + DisplayError( getEditFrame(), _( "Cannot delete VALUE!" ) ); + return; + } + } + } + /* no break */ + + case PCB_PAD_T: case PCB_MODULE_EDGE_T: + if( m_editModules ) + { + MODULE* module = static_cast( aItem->GetParent() ); + module->SetLastEditTime(); + + board->m_Status_Pcb = 0; // it is done in the legacy view + aItem->DeleteStructure(); + } + return; + break; case PCB_LINE_T: // a segment not on copper layers case PCB_TEXT_T: // a text on a layer diff --git a/pcbnew/tools/edit_tool.h b/pcbnew/tools/edit_tool.h index 207e446493..068727ad4d 100644 --- a/pcbnew/tools/edit_tool.h +++ b/pcbnew/tools/edit_tool.h @@ -91,6 +91,17 @@ public: */ int Remove( TOOL_EVENT& aEvent ); + /** + * Function EditModules() + * Toggles edit module mode. When enabled, one may select parts of modules individually + * (graphics, pads, etc.), so they can be modified. + * @param aEnabled decides if the mode should be enabled. + */ + void EditModules( bool aEnabled ) + { + m_editModules = aEnabled; + } + private: ///> Selection tool used for obtaining selected items SELECTION_TOOL* m_selectionTool; @@ -105,6 +116,9 @@ private: ///> of edit reference point). VECTOR2I m_cursor; + /// Edit module mode flag + bool m_editModules; + ///> Removes and frees a single BOARD_ITEM. void remove( BOARD_ITEM* aItem ); From 0b4b0f7b0d9e85041489f1175e7e28d1d9ceb6cf Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 14:01:06 +0200 Subject: [PATCH 061/123] Added support for placing the footprint anchor. --- pcbnew/tools/common_actions.cpp | 9 ++++++- pcbnew/tools/common_actions.h | 3 +++ pcbnew/tools/drawing_tool.cpp | 47 +++++++++++++++++++++++++++++++++ pcbnew/tools/drawing_tool.h | 6 +++++ pcbnew/tools/pcbnew_control.cpp | 2 +- 5 files changed, 65 insertions(+), 2 deletions(-) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 45305cc83e..41fbea71e8 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -101,6 +101,11 @@ TOOL_ACTION COMMON_ACTIONS::placePad( "pcbnew.InteractiveDrawing.placePad", AS_GLOBAL, 0, "Add pads", "Add pads", AF_ACTIVATE ); +TOOL_ACTION COMMON_ACTIONS::setAnchor( "pcbnew.InteractiveDrawing.setAnchor", + AS_GLOBAL, 0, + "Place the footprint anchor", "Place the footprint anchor", + AF_ACTIVATE ); + // View Controls TOOL_ACTION COMMON_ACTIONS::zoomIn( "pcbnew.Control.zoomIn", AS_GLOBAL, WXK_F1, @@ -313,6 +318,9 @@ boost::optional COMMON_ACTIONS::TranslateLegacyId( int aId ) case ID_MODEDIT_PAD_TOOL: return COMMON_ACTIONS::placePad.MakeEvent(); + case ID_MODEDIT_ANCHOR_TOOL: + return COMMON_ACTIONS::setAnchor.MakeEvent(); + case ID_PCB_PLACE_GRID_COORD_BUTT: case ID_MODEDIT_PLACE_GRID_COORD: return COMMON_ACTIONS::gridSetOrigin.MakeEvent(); @@ -336,7 +344,6 @@ boost::optional COMMON_ACTIONS::TranslateLegacyId( int aId ) case ID_MENU_PCB_SHOW_HIDE_MUWAVE_TOOLBAR: case ID_MICROWAVE_V_TOOLBAR: case ID_MODEDIT_DELETE_TOOL: - case ID_MODEDIT_ANCHOR_TOOL: return COMMON_ACTIONS::toBeDone.MakeEvent(); } diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 9c812414df..f971116d6e 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -93,6 +93,9 @@ public: /// Activation of the drawing tool (placing a PAD) static TOOL_ACTION placePad; + /// Activation of the drawing tool (placing the footprint anchor) + static TOOL_ACTION setAnchor; + // Push and Shove Router Tool /// Activation of the Push and Shove router static TOOL_ACTION routerActivate; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index fff955bfca..d3da87ce44 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -700,6 +700,52 @@ int DRAWING_TOOL::PlacePad( TOOL_EVENT& aEvent ) } +int DRAWING_TOOL::SetAnchor( TOOL_EVENT& aEvent ) +{ + assert( m_editModules ); + + Activate(); + m_frame->SetToolID( ID_MODEDIT_ANCHOR_TOOL, wxCURSOR_PENCIL, + _( "Place the footprint anchor" ) ); + + KIGFX::VIEW_CONTROLS* controls = getViewControls(); + controls->ShowCursor( true ); + controls->SetSnapping( true ); + controls->SetAutoPan( true ); + + while( OPT_TOOL_EVENT evt = Wait() ) + { + if( evt->IsClick( BUT_LEFT ) ) + { + MODULE* module = m_board->m_Modules; + + m_frame->SaveCopyInUndoList( module, UR_MODEDIT ); + + // set the new relative internal local coordinates of footprint items + VECTOR2I cursorPos = controls->GetCursorPosition(); + wxPoint moveVector = module->GetPosition() - wxPoint( cursorPos.x, cursorPos.y ); + module->MoveAnchorPosition( moveVector ); + + // Usually, we do not need to change twice the anchor position, + // so deselect the active tool + break; + } + + else if( evt->IsCancel() || evt->IsActivate() ) + break; + } + + controls->SetAutoPan( false ); + controls->SetSnapping( false ); + controls->ShowCursor( false ); + + setTransitions(); + m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); + + return 0; +} + + bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT* aGraphic ) { // Only two shapes are currently supported @@ -1534,4 +1580,5 @@ void DRAWING_TOOL::setTransitions() Go( &DRAWING_TOOL::PlaceTarget, COMMON_ACTIONS::placeTarget.MakeEvent() ); Go( &DRAWING_TOOL::PlaceModule, COMMON_ACTIONS::placeModule.MakeEvent() ); Go( &DRAWING_TOOL::PlacePad, COMMON_ACTIONS::placePad.MakeEvent() ); + Go( &DRAWING_TOOL::SetAnchor, COMMON_ACTIONS::setAnchor.MakeEvent() ); } diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index 29b87560ea..293674a81f 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -126,6 +126,12 @@ public: */ int PlacePad( TOOL_EVENT& aEvent ); + /** + * Function SetAnchor() + * Places the footprint anchor (only in module editor). + */ + int SetAnchor( TOOL_EVENT& aEvent ); + /** * Function EditModules() * Toggles edit module mode. When enabled, one may select parts of modules individually diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index 89b356c38c..3a46cbacff 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -452,7 +452,7 @@ int PCBNEW_CONTROL::GridSetOrigin( TOOL_EVENT& aEvent ) getView()->MarkDirty(); } - else if( evt->IsCancel() ) + else if( evt->IsCancel() || evt->IsActivate() ) break; } From 098449d7dcd1b1f7512ee6e5867567b389ad1966 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 14:01:07 +0200 Subject: [PATCH 062/123] Routines for handling clipboard with TOOL_MANAGER. --- common/tool/tool_manager.cpp | 36 ++++++++++++++++++++++++++++++++++++ include/tool/tool_manager.h | 13 +++++++++++++ 2 files changed, 49 insertions(+) diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index 0f4e3f22e2..e225e05e2b 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -34,6 +34,7 @@ #include #include +#include #include @@ -598,6 +599,41 @@ void TOOL_MANAGER::ScheduleContextMenu( TOOL_BASE* aTool, CONTEXT_MENU* aMenu, } +bool TOOL_MANAGER::SaveClipboard( const std::string& aText ) +{ + if( wxTheClipboard->Open() ) + { + wxTheClipboard->SetData( new wxTextDataObject( aText ) ); + wxTheClipboard->Close(); + + return true; + } + + return false; +} + + +std::string TOOL_MANAGER::GetClipboard() const +{ + std::string result; + + if( wxTheClipboard->Open() ) + { + if( wxTheClipboard->IsSupported( wxDF_TEXT ) ) + { + wxTextDataObject data; + wxTheClipboard->GetData( data ); + + result = data.GetText().mb_str(); + } + + wxTheClipboard->Close(); + } + + return result; +} + + TOOL_ID TOOL_MANAGER::MakeToolId( const std::string& aToolName ) { static int currentId; diff --git a/include/tool/tool_manager.h b/include/tool/tool_manager.h index fdc17480d6..1935cf1b14 100644 --- a/include/tool/tool_manager.h +++ b/include/tool/tool_manager.h @@ -257,6 +257,19 @@ public: m_passEvent = true; } + /** + * Stores an information to the system clipboard. + * @param aText is the information to be stored. + * @return False if error occured. + */ + bool SaveClipboard( const std::string& aText ); + + /** + * Returns the information currently stored in the system clipboard. If data stored in the + * clipboard is in non-text format, empty string is returned. + */ + std::string GetClipboard() const; + /** * Returns list of TOOL_ACTIONs. TOOL_ACTIONs add themselves to the list upon their * creation. From d2c78c8bb710d93fc8835bec5d7774cf0a584d6c Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 14:22:29 +0200 Subject: [PATCH 063/123] Added MODULE::Add( BOARD_ITEM* )/Remove( BOARD_ITEM* )/Delete( BOARD_ITEM* ). Removed MODULE::AddPad(). --- pcbnew/class_module.cpp | 77 +++++++++++++++++++++++++++++++++----- pcbnew/class_module.h | 34 ++++++++++++----- pcbnew/gpcb_plugin.cpp | 4 +- pcbnew/pcb_parser.cpp | 2 +- pcbnew/tools/edit_tool.cpp | 3 ++ 5 files changed, 98 insertions(+), 22 deletions(-) diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index bc01aa1bcb..6080fa0d98 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -295,6 +295,72 @@ void MODULE::Copy( MODULE* aModule ) } +void MODULE::Add( BOARD_ITEM* aBoardItem, bool doAppend ) +{ + switch( aBoardItem->Type() ) + { + case PCB_MODULE_TEXT_T: + // Only common texts can be added this way. Reference and value are not hold in the DLIST. + assert( static_cast( aBoardItem )->GetType() == TEXTE_MODULE::TEXT_is_DIVERS ); + /* no break */ + + case PCB_MODULE_EDGE_T: + if( doAppend ) + m_Drawings.PushBack( static_cast( aBoardItem ) ); + else + m_Drawings.PushFront( static_cast( aBoardItem ) ); + break; + + case PCB_PAD_T: + if( doAppend ) + m_Pads.PushBack( static_cast( aBoardItem ) ); + else + m_Pads.PushFront( static_cast( aBoardItem ) ); + break; + + default: + { + wxString msg; + msg.Printf( wxT( "MODULE::Add() needs work: BOARD_ITEM type (%d) not handled" ), + aBoardItem->Type() ); + wxFAIL_MSG( msg ); + + return; + } + } + + aBoardItem->SetParent( this ); +} + + +BOARD_ITEM* MODULE::Remove( BOARD_ITEM* aBoardItem ) +{ + switch( aBoardItem->Type() ) + { + case PCB_MODULE_TEXT_T: + // Only common texts can be added this way. Reference and value are not hold in the DLIST. + assert( static_cast( aBoardItem )->GetType() == TEXTE_MODULE::TEXT_is_DIVERS ); + /* no break */ + + case PCB_MODULE_EDGE_T: + return m_Drawings.Remove( static_cast( aBoardItem ) ); + + case PCB_PAD_T: + return m_Pads.Remove( static_cast( aBoardItem ) ); + + default: + { + wxString msg; + msg.Printf( wxT( "MODULE::Remove() needs work: BOARD_ITEM type (%d) not handled" ), + aBoardItem->Type() ); + wxFAIL_MSG( msg ); + } + } + + return NULL; +} + + void MODULE::CopyNetlistSettings( MODULE* aModule ) { // Don't do anything foolish like trying to copy to yourself. @@ -636,13 +702,6 @@ void MODULE::Add3DModel( S3D_MASTER* a3DModel ) } -void MODULE::AddPad( D_PAD* aPad ) -{ - aPad->SetParent( this ); - m_Pads.PushBack( aPad ); -} - - // see class_module.h SEARCH_RESULT MODULE::Visit( INSPECTOR* inspector, const void* testData, const KICAD_T scanTypes[] ) @@ -738,10 +797,10 @@ EDA_ITEM* MODULE::Clone() const void MODULE::RunOnChildren( boost::function aFunction ) { - for( D_PAD* pad = m_Pads.GetFirst(); pad; pad = pad->Next() ) + for( D_PAD* pad = m_Pads; pad; pad = pad->Next() ) aFunction( static_cast( pad ) ); - for( BOARD_ITEM* drawing = m_Drawings.GetFirst(); drawing; drawing = drawing->Next() ) + for( BOARD_ITEM* drawing = m_Drawings; drawing; drawing = drawing->Next() ) aFunction( drawing ); aFunction( static_cast( m_Reference ) ); diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h index 8eac8a87d8..d1496f2425 100644 --- a/pcbnew/class_module.h +++ b/pcbnew/class_module.h @@ -91,9 +91,31 @@ public: * Function Add * adds the given item to this MODULE and takes ownership of its memory. * @param aBoardItem The item to add to this board. - * @param doInsert If true, then insert, else append - * void Add( BOARD_ITEM* aBoardItem, bool doInsert = true ); + * @param doAppend If true, then append, else insert. */ + void Add( BOARD_ITEM* aBoardItem, bool doAppend = true ); + + /** + * Function Delete + * removes the given single item from this MODULE and deletes its memory. + * @param aBoardItem The item to remove from this module and delete + */ + void Delete( BOARD_ITEM* aBoardItem ) + { + // developers should run DEBUG versions and fix such calls with NULL + wxASSERT( aBoardItem ); + + if( aBoardItem ) + delete Remove( aBoardItem ); + } + + /** + * Function Remove + * removes \a aBoardItem from this MODULE and returns it to caller without deleting it. + * @param aBoardItem The item to remove from this module. + * @return BOARD_ITEM* \a aBoardItem which was passed in. + */ + BOARD_ITEM* Remove( BOARD_ITEM* aBoardItem ); /** * Function CalculateBoundingBox @@ -436,14 +458,6 @@ public: */ void Add3DModel( S3D_MASTER* a3DModel ); - /** - * Function AddPad - * adds \a aPad to the end of the pad list. - * - * @param aPad A pointer to a #D_PAD to add to the list. - */ - void AddPad( D_PAD* aPad ); - SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData, const KICAD_T scanTypes[] ); diff --git a/pcbnew/gpcb_plugin.cpp b/pcbnew/gpcb_plugin.cpp index def86f32ff..c306aa8639 100644 --- a/pcbnew/gpcb_plugin.cpp +++ b/pcbnew/gpcb_plugin.cpp @@ -637,7 +637,7 @@ MODULE* GPCB_FPL_CACHE::parseMODULE( LINE_READER* aLineReader ) throw( IO_ERROR, pad->SetShape( PAD_OVAL ); } - module->AddPad( pad ); + module->Add( pad ); continue; } @@ -701,7 +701,7 @@ MODULE* GPCB_FPL_CACHE::parseMODULE( LINE_READER* aLineReader ) throw( IO_ERROR, if( pad->GetShape() == PAD_ROUND && pad->GetSize().x != pad->GetSize().y ) pad->SetShape( PAD_OVAL ); - module->AddPad( pad ); + module->Add( pad ); continue; } } diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index 475a844948..33783ea548 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -1856,7 +1856,7 @@ MODULE* PCB_PARSER::parseMODULE( wxArrayString* aInitialComments ) throw( IO_ERR RotatePoint( &pt, module->GetOrientation() ); pad->SetPosition( pt + module->GetPosition() ); - module->AddPad( pad ); + module->Add( pad ); } break; diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index e4667867c3..c1bbcc14a9 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -464,6 +464,9 @@ void EDIT_TOOL::remove( BOARD_ITEM* aItem ) case TEXTE_MODULE::TEXT_is_VALUE: DisplayError( getEditFrame(), _( "Cannot delete VALUE!" ) ); return; + + default: // suppress warnings + break; } } } From 73245e593050a3f073ff331f92e7e72d6d506211 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 14:22:29 +0200 Subject: [PATCH 064/123] Copy & paste for module editor (GAL). --- pcbnew/tools/common_actions.cpp | 8 ++ pcbnew/tools/common_actions.h | 6 ++ pcbnew/tools/edit_tool.cpp | 176 ++++++++++++++++++++++++++++++++ pcbnew/tools/edit_tool.h | 15 +++ 4 files changed, 205 insertions(+) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 41fbea71e8..fec32b59cf 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -59,6 +59,14 @@ TOOL_ACTION COMMON_ACTIONS::properties( "pcbnew.InteractiveEdit.properties", AS_GLOBAL, 'E', "Properties...", "Displays properties window" ); +TOOL_ACTION COMMON_ACTIONS::copyItems( "pcbnew.InteractiveEdit.copyItems", + AS_GLOBAL, MD_CTRL + int( 'C' ), + "Copy items", "Copy items", AF_ACTIVATE ); + +TOOL_ACTION COMMON_ACTIONS::pasteItems( "pcbnew.InteractiveEdit.pasteItems", + AS_GLOBAL, MD_CTRL + int( 'V' ), + "Paste items", "Paste items", AF_ACTIVATE ); + // Drawing tool actions TOOL_ACTION COMMON_ACTIONS::drawLine( "pcbnew.InteractiveDrawing.line", diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index f971116d6e..c61f6e811d 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -62,6 +62,12 @@ public: /// Deleting a BOARD_ITEM static TOOL_ACTION remove; + /// Copying pad to clipboard + static TOOL_ACTION copyItems; + + /// Pasting a pad from clipboard + static TOOL_ACTION pasteItems; + // Drawing Tool /// Activation of the drawing tool (line) static TOOL_ACTION drawLine; diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index c1bbcc14a9..782fe5f90d 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -24,12 +24,15 @@ #include #include +#include #include #include + #include #include #include #include +#include #include #include @@ -428,6 +431,177 @@ int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) } +int EDIT_TOOL::CopyItems( TOOL_EVENT& aEvent ) +{ + const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + PCB_IO io( CTL_FOR_CLIPBOARD ); + + if( !m_editModules || !makeSelection( selection ) ) + { + setTransitions(); + + return 0; + } + + // Create a temporary module that contains selected items to ease serialization + MODULE module( getModel() ); + + for( int i = 0; i < selection.Size(); ++i ) + { + BOARD_ITEM* clone = static_cast( selection.Item( i )->Clone() ); + + // Do not add reference/value - convert them to the common type + if( TEXTE_MODULE* text = dyn_cast( clone ) ) + text->SetType( TEXTE_MODULE::TEXT_is_DIVERS ); + + module.Add( clone ); + } + + io.Format( &module, 0 ); + std::string data = io.GetStringOutput( true ); + m_toolMgr->SaveClipboard( data ); + + setTransitions(); + + return 0; +} + + +int EDIT_TOOL::PasteItems( TOOL_EVENT& aEvent ) +{ + if( !m_editModules ) + { + setTransitions(); + + return 0; + } + + // Parse clipboard + PCB_IO io( CTL_FOR_CLIPBOARD ); + MODULE* currentModule = getModel()->m_Modules; + MODULE* pastedModule = NULL; + + try + { + BOARD_ITEM* item = io.Parse( m_toolMgr->GetClipboard() ); + assert( item->Type() == PCB_MODULE_T ); + pastedModule = dyn_cast( item ); + } + catch( ... ) + { + setTransitions(); + + return 0; + } + + // Placement tool part + KIGFX::VIEW* view = getView(); + KIGFX::VIEW_CONTROLS* controls = getViewControls(); + BOARD* board = getModel(); + PCB_EDIT_FRAME* frame = getEditFrame(); + VECTOR2I cursorPos = getViewControls()->GetCursorPosition(); + + // Add a VIEW_GROUP that serves as a preview for the new item + KIGFX::VIEW_GROUP preview( view ); + pastedModule->SetParent( board ); + pastedModule->RunOnChildren( boost::bind( &KIGFX::VIEW_GROUP::Add, boost::ref( preview ), _1 ) ); + preview.Add( pastedModule ); + view->Add( &preview ); + + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + controls->ShowCursor( true ); + controls->SetSnapping( true ); + + Activate(); + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + cursorPos = controls->GetCursorPosition(); + + if( evt->IsMotion() ) + { + pastedModule->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); + preview.ViewUpdate(); + } + + else if( evt->Category() == TC_COMMAND ) + { + if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) + { + pastedModule->Rotate( pastedModule->GetPosition(), frame->GetRotationAngle() ); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) + { + pastedModule->Flip( pastedModule->GetPosition() ); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else if( evt->IsCancel() || evt->IsActivate() ) + { + preview.Clear(); + break; + } + } + + else if( evt->IsClick( BUT_LEFT ) ) + { + frame->OnModify(); + frame->SaveCopyInUndoList( currentModule, UR_MODEDIT ); + + board->m_Status_Pcb = 0; // I have no clue why, but it is done in the legacy view + currentModule->SetLastEditTime(); + + // MODULE::RunOnChildren is infeasible here: we need to create copies of items, do not + // directly modify them + + for( D_PAD* pad = pastedModule->Pads(); pad; pad = pad->Next() ) + { + D_PAD* clone = static_cast( pad->Clone() ); + currentModule->Add( clone ); + clone->SetLocalCoord(); + view->Add( clone ); + } + + for( BOARD_ITEM* drawing = pastedModule->GraphicalItems(); + drawing; drawing = drawing->Next() ) + { + BOARD_ITEM* clone = static_cast( drawing->Clone() ); + + if( TEXTE_MODULE* text = dyn_cast( clone ) ) + { + // Do not add reference/value - convert them to the common type + text->SetType( TEXTE_MODULE::TEXT_is_DIVERS ); + currentModule->Add( clone ); + text->SetLocalCoord(); + } + else if( EDGE_MODULE* edge = dyn_cast( clone ) ) + { + currentModule->Add( clone ); + edge->SetLocalCoord(); + } + + view->Add( clone ); + } + + preview.Clear(); + + break; + } + } + + delete pastedModule; + controls->ShowCursor( false ); + controls->SetSnapping( false ); + controls->SetAutoPan( false ); + view->Remove( &preview ); + + setTransitions(); + + return 0; +} + + void EDIT_TOOL::remove( BOARD_ITEM* aItem ) { BOARD* board = getModel(); @@ -515,6 +689,8 @@ void EDIT_TOOL::setTransitions() Go( &EDIT_TOOL::Flip, COMMON_ACTIONS::flip.MakeEvent() ); Go( &EDIT_TOOL::Remove, COMMON_ACTIONS::remove.MakeEvent() ); Go( &EDIT_TOOL::Properties, COMMON_ACTIONS::properties.MakeEvent() ); + Go( &EDIT_TOOL::CopyItems, COMMON_ACTIONS::copyItems.MakeEvent() ); + Go( &EDIT_TOOL::PasteItems, COMMON_ACTIONS::pasteItems.MakeEvent() ); } diff --git a/pcbnew/tools/edit_tool.h b/pcbnew/tools/edit_tool.h index 068727ad4d..e68cd74894 100644 --- a/pcbnew/tools/edit_tool.h +++ b/pcbnew/tools/edit_tool.h @@ -91,8 +91,23 @@ public: */ int Remove( TOOL_EVENT& aEvent ); + /** + * Function CopyItems() + * + * Copies selected items to the clipboard. Works only in "edit modules" mode. + */ + int CopyItems( TOOL_EVENT& aEvent ); + + /** + * Function PastePad() + * + * Pastes items from the clipboard. Works only in "edit modules" mode. + */ + int PasteItems( TOOL_EVENT& aEvent ); + /** * Function EditModules() + * * Toggles edit module mode. When enabled, one may select parts of modules individually * (graphics, pads, etc.), so they can be modified. * @param aEnabled decides if the mode should be enabled. From bba31a43eb1b9a6ecb99c6c153fec63c7167cd1f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 14:23:13 +0200 Subject: [PATCH 065/123] wxWidgets 2.8 compatibility fix. --- common/tool/tool_manager.cpp | 13 ++++++++++++- pcbnew/class_board.cpp | 4 +++- pcbnew/ratsnest_data.cpp | 6 +++--- pcbnew/tools/edit_tool.cpp | 2 +- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index e225e05e2b..cb91124f31 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -137,6 +137,11 @@ struct TOOL_MANAGER::TOOL_STATE return aRhs.theTool != this->theTool; } + /** + * Function Push() + * Stores the current state of the tool on stack. Stacks are stored internally and are not + * shared between different TOOL_STATE objects. + */ void Push() { stateStack.push( *this ); @@ -144,6 +149,12 @@ struct TOOL_MANAGER::TOOL_STATE clear(); } + /** + * Function Pop() + * Restores state of the tool from stack. Stacks are stored internally and are not + * shared between different TOOL_STATE objects. + * @return True if state was restored, false if the stack was empty. + */ bool Pop() { delete cofunc; @@ -603,7 +614,7 @@ bool TOOL_MANAGER::SaveClipboard( const std::string& aText ) { if( wxTheClipboard->Open() ) { - wxTheClipboard->SetData( new wxTextDataObject( aText ) ); + wxTheClipboard->SetData( new wxTextDataObject( wxString( aText.c_str(), wxConvUTF8 ) ) ); wxTheClipboard->Close(); return true; diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index f1d304817c..6496692a47 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -688,10 +688,12 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl ) m_Status_Pcb = 0; break; + case PCB_MODULE_EDGE_T: + assert( false ); // TODO Orson: I am just checking if it is supposed to be here + case PCB_DIMENSION_T: case PCB_LINE_T: case PCB_TEXT_T: - case PCB_MODULE_EDGE_T: case PCB_TARGET_T: if( aControl & ADD_APPEND ) m_Drawings.PushBack( aBoardItem ); diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index 9271f00f42..3c069e1932 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -305,7 +305,7 @@ void RN_NET::clearNode( const RN_NODE_PTR& aNode ) // Remove all ratsnest edges for associated with the node newEnd = std::remove_if( m_rnEdges->begin(), m_rnEdges->end(), - boost::bind( isEdgeConnectingNode, _1, aNode ) ); + boost::bind( isEdgeConnectingNode, _1, boost::ref( aNode ) ) ); m_rnEdges->resize( std::distance( m_rnEdges->begin(), newEnd ) ); } @@ -629,7 +629,7 @@ std::list RN_NET::GetClosestNodes( const RN_NODE_PTR& aNode, int aN closest.push_back( node ); // Sort by the distance from aNode - closest.sort( boost::bind( sortDistance, aNode, _1, _2 ) ); + closest.sort( boost::bind( sortDistance, boost::ref( aNode ), _1, _2 ) ); // Remove the first node (==aNode), as it is surely located within the smallest distance closest.pop_front(); @@ -653,7 +653,7 @@ std::list RN_NET::GetClosestNodes( const RN_NODE_PTR& aNode, closest.push_back( node ); // Sort by the distance from aNode - closest.sort( boost::bind( sortDistance, aNode, _1, _2 ) ); + closest.sort( boost::bind( sortDistance, boost::ref( aNode ), _1, _2 ) ); // Remove the first node (==aNode), as it is surely located within the smallest distance closest.pop_front(); diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 782fe5f90d..5eb6620c7a 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -483,7 +483,7 @@ int EDIT_TOOL::PasteItems( TOOL_EVENT& aEvent ) try { - BOARD_ITEM* item = io.Parse( m_toolMgr->GetClipboard() ); + BOARD_ITEM* item = io.Parse( wxString( m_toolMgr->GetClipboard().c_str(), wxConvUTF8 ) ); assert( item->Type() == PCB_MODULE_T ); pastedModule = dyn_cast( item ); } From cfddb40d7914c49f8f5881b7e4978aa1e19d6900 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 14:23:13 +0200 Subject: [PATCH 066/123] Reference point is selected for copied items. Enabled autopanning for copy & paste operations (module editor/GAL). --- pcbnew/tools/edit_tool.cpp | 74 ++++++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 14 deletions(-) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 5eb6620c7a..6a0733cfcc 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -434,7 +434,6 @@ int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) int EDIT_TOOL::CopyItems( TOOL_EVENT& aEvent ) { const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); - PCB_IO io( CTL_FOR_CLIPBOARD ); if( !m_editModules || !makeSelection( selection ) ) { @@ -443,23 +442,67 @@ int EDIT_TOOL::CopyItems( TOOL_EVENT& aEvent ) return 0; } - // Create a temporary module that contains selected items to ease serialization - MODULE module( getModel() ); + Activate(); - for( int i = 0; i < selection.Size(); ++i ) + KIGFX::VIEW_CONTROLS* controls = getViewControls(); + controls->SetSnapping( true ); + controls->ShowCursor( true ); + controls->SetAutoPan( true ); + + PCB_BASE_FRAME* frame = getEditFrame(); + frame->DisplayToolMsg( _( "Select reference point" ) ); + + bool cancelled = false; + VECTOR2I cursorPos; + + while( OPT_TOOL_EVENT evt = Wait() ) { - BOARD_ITEM* clone = static_cast( selection.Item( i )->Clone() ); - - // Do not add reference/value - convert them to the common type - if( TEXTE_MODULE* text = dyn_cast( clone ) ) - text->SetType( TEXTE_MODULE::TEXT_is_DIVERS ); - - module.Add( clone ); + if( evt->IsMotion() ) + { + cursorPos = getViewControls()->GetCursorPosition(); + } + else if( evt->IsClick( BUT_LEFT ) ) + { + break; + } + else if( evt->IsCancel() || evt->IsActivate() ) + { + cancelled = true; + break; + } } - io.Format( &module, 0 ); - std::string data = io.GetStringOutput( true ); - m_toolMgr->SaveClipboard( data ); + if( !cancelled ) + { + PCB_IO io( CTL_FOR_CLIPBOARD ); + + // Create a temporary module that contains selected items to ease serialization + MODULE module( getModel() ); + + for( int i = 0; i < selection.Size(); ++i ) + { + BOARD_ITEM* clone = static_cast( selection.Item( i )->Clone() ); + + // Do not add reference/value - convert them to the common type + if( TEXTE_MODULE* text = dyn_cast( clone ) ) + text->SetType( TEXTE_MODULE::TEXT_is_DIVERS ); + + module.Add( clone ); + } + + // Set the new relative internal local coordinates of footprint items + wxPoint moveVector = module.GetPosition() - wxPoint( cursorPos.x, cursorPos.y ); + module.MoveAnchorPosition( moveVector ); + + io.Format( &module, 0 ); + std::string data = io.GetStringOutput( true ); + m_toolMgr->SaveClipboard( data ); + } + + frame->DisplayToolMsg( wxString::Format( _( "Copied %d items" ), selection.Size() ) ); + controls->SetSnapping( false ); + controls->ShowCursor( false ); + controls->SetAutoPan( false ); setTransitions(); @@ -504,6 +547,7 @@ int EDIT_TOOL::PasteItems( TOOL_EVENT& aEvent ) // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( view ); pastedModule->SetParent( board ); + pastedModule->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); pastedModule->RunOnChildren( boost::bind( &KIGFX::VIEW_GROUP::Add, boost::ref( preview ), _1 ) ); preview.Add( pastedModule ); view->Add( &preview ); @@ -511,6 +555,7 @@ int EDIT_TOOL::PasteItems( TOOL_EVENT& aEvent ) m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); controls->ShowCursor( true ); controls->SetSnapping( true ); + controls->SetAutoPan( true ); Activate(); @@ -558,6 +603,7 @@ int EDIT_TOOL::PasteItems( TOOL_EVENT& aEvent ) for( D_PAD* pad = pastedModule->Pads(); pad; pad = pad->Next() ) { D_PAD* clone = static_cast( pad->Clone() ); + currentModule->Add( clone ); clone->SetLocalCoord(); view->Add( clone ); From 327c8594c547c914c61edc65b2cc03f958ce902a Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 14:23:13 +0200 Subject: [PATCH 067/123] Pasted module texts are rotated in the right way. --- pcbnew/tools/edit_tool.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 6a0733cfcc..1eb1b37bee 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -618,12 +618,16 @@ int EDIT_TOOL::PasteItems( TOOL_EVENT& aEvent ) { // Do not add reference/value - convert them to the common type text->SetType( TEXTE_MODULE::TEXT_is_DIVERS ); - currentModule->Add( clone ); + currentModule->Add( text ); text->SetLocalCoord(); + + // Whyyyyyyyyyyyyyyyyyyyyyy?! All other items conform to rotation performed + // on its parent module, but texts are so independent.. + text->Rotate( text->GetPosition(), pastedModule->GetOrientation() ); } else if( EDGE_MODULE* edge = dyn_cast( clone ) ) { - currentModule->Add( clone ); + currentModule->Add( edge ); edge->SetLocalCoord(); } From 21b3eb98b6129805c2244dcfbae6b19620ccd669 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 14:23:13 +0200 Subject: [PATCH 068/123] Fixed wrong reference point for copied items in subsequent module editor invocations (GAL). --- pcbnew/loadcmp.cpp | 1 + pcbnew/tools/edit_tool.cpp | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/pcbnew/loadcmp.cpp b/pcbnew/loadcmp.cpp index a794f3f685..6d6f6395b7 100644 --- a/pcbnew/loadcmp.cpp +++ b/pcbnew/loadcmp.cpp @@ -107,6 +107,7 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule ) SetCrossHairPosition( wxPoint( 0, 0 ) ); PlaceModule( newModule, NULL ); + newModule->SetPosition( wxPoint( 0, 0 ) ); // cursor in GAL may not be initialized at the moment // Put it on FRONT layer, // because this is the default in ModEdit, and in libs diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 1eb1b37bee..6b833b2290 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -453,7 +453,7 @@ int EDIT_TOOL::CopyItems( TOOL_EVENT& aEvent ) frame->DisplayToolMsg( _( "Select reference point" ) ); bool cancelled = false; - VECTOR2I cursorPos; + VECTOR2I cursorPos = getViewControls()->GetCursorPosition(); while( OPT_TOOL_EVENT evt = Wait() ) { @@ -490,8 +490,10 @@ int EDIT_TOOL::CopyItems( TOOL_EVENT& aEvent ) module.Add( clone ); } - // Set the new relative internal local coordinates of footprint items - wxPoint moveVector = module.GetPosition() - wxPoint( cursorPos.x, cursorPos.y ); + // Set the new relative internal local coordinates of copied items + MODULE* editedModule = getModel()->m_Modules; + wxPoint moveVector = module.GetPosition() + editedModule->GetPosition() - + wxPoint( cursorPos.x, cursorPos.y ); module.MoveAnchorPosition( moveVector ); io.Format( &module, 0 ); @@ -499,7 +501,7 @@ int EDIT_TOOL::CopyItems( TOOL_EVENT& aEvent ) m_toolMgr->SaveClipboard( data ); } - frame->DisplayToolMsg( wxString::Format( _( "Copied %d items" ), selection.Size() ) ); + frame->DisplayToolMsg( wxString::Format( _( "Copied %d item(s)" ), selection.Size() ) ); controls->SetSnapping( false ); controls->ShowCursor( false ); controls->SetAutoPan( false ); From 3dd651cf221f52c40e022f0a0bde776b101d37c7 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 14:23:13 +0200 Subject: [PATCH 069/123] Initial version of the Placement Tool. --- pcbnew/CMakeLists.txt | 1 + pcbnew/moduleframe.cpp | 2 + pcbnew/tools/common_actions.cpp | 32 +++ pcbnew/tools/common_actions.h | 19 ++ pcbnew/tools/pcb_tools.cpp | 2 + pcbnew/tools/placement_tool.cpp | 356 ++++++++++++++++++++++++++++++++ pcbnew/tools/placement_tool.h | 73 +++++++ 7 files changed, 485 insertions(+) create mode 100644 pcbnew/tools/placement_tool.cpp create mode 100644 pcbnew/tools/placement_tool.h diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 2884741b8a..bab69a7b37 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -265,6 +265,7 @@ set( PCBNEW_CLASS_SRCS tools/pcbnew_control.cpp tools/pcb_editor_control.cpp tools/pcb_tools.cpp + tools/placement_tool.cpp tools/common_actions.cpp ) diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index 53c4e89fc6..603e4e0838 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -61,6 +61,7 @@ #include "tools/drawing_tool.h" #include "tools/point_editor.h" #include "tools/pcbnew_control.h" +#include "tools/placement_tool.h" #include "tools/common_actions.h" @@ -278,6 +279,7 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : m_toolManager->RegisterTool( new DRAWING_TOOL ); m_toolManager->RegisterTool( new POINT_EDITOR ); m_toolManager->RegisterTool( new PCBNEW_CONTROL ); + m_toolManager->RegisterTool( new PLACEMENT_TOOL ); m_toolManager->GetTool()->EditModules( true ); m_toolManager->GetTool()->EditModules( true ); diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index fec32b59cf..a1b6966a06 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -285,6 +285,38 @@ TOOL_ACTION COMMON_ACTIONS::pointEditorUpdate( "pcbnew.PointEditor.update", AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere +// Placement tool +TOOL_ACTION COMMON_ACTIONS::alignTop( "pcbnew.Place.alignTop", + AS_GLOBAL, 0, + "Align items to the top", + "Aligns selected items to the top edge" ); + +TOOL_ACTION COMMON_ACTIONS::alignBottom( "pcbnew.Place.alignBottom", + AS_GLOBAL, 0, + "Align items to the bottom", + "Aligns selected items to the bottom edge" ); + +TOOL_ACTION COMMON_ACTIONS::alignLeft( "pcbnew.Place.alignLeft", + AS_GLOBAL, 0, + "Align items to the left", + "Aligns selected items to the top left" ); + +TOOL_ACTION COMMON_ACTIONS::alignRight( "pcbnew.Place.alignRight", + AS_GLOBAL, 0, + "Align items to the right", + "Aligns selected items to the right edge" ); + +TOOL_ACTION COMMON_ACTIONS::distributeHorizontally( "pcbnew.Place.distributeHorizontally", + AS_GLOBAL, 0, + "Distribute horizontally", + "Distributes selected items along the horizontal axis" ); + +TOOL_ACTION COMMON_ACTIONS::distributeVertically( "pcbnew.Place.distributeVertically", + AS_GLOBAL, 0, + "Distribure vertically", + "Distributes selected items along the vertical axis" ); + + boost::optional COMMON_ACTIONS::TranslateLegacyId( int aId ) { switch( aId ) diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index c61f6e811d..2cd367c05d 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -110,6 +110,25 @@ public: /// Update edit points static TOOL_ACTION pointEditorUpdate; + // Placement tool + /// Align items to the top edge of selection bounding box + static TOOL_ACTION alignTop; + + /// Align items to the bottom edge of selection bounding box + static TOOL_ACTION alignBottom; + + /// Align items to the left edge of selection bounding box + static TOOL_ACTION alignLeft; + + /// Align items to the right edge of selection bounding box + static TOOL_ACTION alignRight; + + /// Distributes items evenly along the horizontal axis + static TOOL_ACTION distributeHorizontally; + + /// Distributes items evenly along the vertical axis + static TOOL_ACTION distributeVertically; + // View controls static TOOL_ACTION zoomIn; static TOOL_ACTION zoomOut; diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp index 6ba1a787e8..9e604a0b04 100644 --- a/pcbnew/tools/pcb_tools.cpp +++ b/pcbnew/tools/pcb_tools.cpp @@ -36,6 +36,7 @@ #include "point_editor.h" #include "pcbnew_control.h" #include "pcb_editor_control.h" +#include "placement_tool.h" #include "common_actions.h" #include @@ -55,6 +56,7 @@ void PCB_EDIT_FRAME::setupTools() m_toolManager->RegisterTool( new POINT_EDITOR ); m_toolManager->RegisterTool( new PCBNEW_CONTROL ); m_toolManager->RegisterTool( new PCB_EDITOR_CONTROL ); + m_toolManager->RegisterTool( new PLACEMENT_TOOL ); m_toolManager->ResetTools( TOOL_BASE::RUN ); // Run the selection tool, it is supposed to be always active diff --git a/pcbnew/tools/placement_tool.cpp b/pcbnew/tools/placement_tool.cpp new file mode 100644 index 0000000000..05ac2522ba --- /dev/null +++ b/pcbnew/tools/placement_tool.cpp @@ -0,0 +1,356 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 CERN + * @author Maciej Suminski + * + * 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 "placement_tool.h" +#include "common_actions.h" +#include "selection_tool.h" + +#include +#include +#include + +#include +#include + +PLACEMENT_TOOL::PLACEMENT_TOOL() : + TOOL_INTERACTIVE( "pcbnew.Placement" ) +{ +} + +PLACEMENT_TOOL::~PLACEMENT_TOOL() +{ +} + + +bool PLACEMENT_TOOL::Init() +{ + // Find the selection tool, so they can cooperate + m_selectionTool = static_cast( m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ) ); + + if( !m_selectionTool ) + { + DisplayError( NULL, wxT( "pcbnew.InteractiveSelection tool is not available" ) ); + return false; + } + + // TODO create a context menu and add it to the selection tool + + setTransitions(); + + return true; +} + + +int PLACEMENT_TOOL::AlignTop( TOOL_EVENT& aEvent ) +{ + const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + + if( selection.Size() > 1 ) + { + PCB_BASE_FRAME* editFrame = getEditFrame(); + RN_DATA* ratsnest = getModel()->GetRatsnest(); + + editFrame->OnModify(); + editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED ); + + // Compute the highest point of selection - it will be the edge of alignment + int top = selection.Item( 0 )->GetBoundingBox().GetY(); + + for( int i = 1; i < selection.Size(); ++i ) + { + int currentTop = selection.Item( i )->GetBoundingBox().GetY(); + + if( top > currentTop ) // Y decreases when going up + top = currentTop; + } + + // Move the selected items + for( int i = 0; i < selection.Size(); ++i ) + { + BOARD_ITEM* item = selection.Item( i ); + int difference = top - item->GetBoundingBox().GetY(); + + item->Move( wxPoint( 0, difference ) ); + item->ViewUpdate(); + ratsnest->Update( item ); + } + + getModel()->GetRatsnest()->Recalculate(); + } + + setTransitions(); + + return 0; +} + + +int PLACEMENT_TOOL::AlignBottom( TOOL_EVENT& aEvent ) +{ + const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + + if( selection.Size() > 1 ) + { + PCB_BASE_FRAME* editFrame = getEditFrame(); + RN_DATA* ratsnest = getModel()->GetRatsnest(); + + editFrame->OnModify(); + editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED ); + + // Compute the lowest point of selection - it will be the edge of alignment + int bottom = selection.Item( 0 )->GetBoundingBox().GetBottom(); + + for( int i = 1; i < selection.Size(); ++i ) + { + int currentBottom = selection.Item( i )->GetBoundingBox().GetBottom(); + + if( bottom < currentBottom ) // Y increases when going down + bottom = currentBottom; + } + + // Move the selected items + for( int i = 0; i < selection.Size(); ++i ) + { + BOARD_ITEM* item = selection.Item( i ); + int difference = bottom - item->GetBoundingBox().GetBottom(); + + item->Move( wxPoint( 0, difference ) ); + item->ViewUpdate(); + ratsnest->Update( item ); + } + + getModel()->GetRatsnest()->Recalculate(); + } + + setTransitions(); + + return 0; +} + + +int PLACEMENT_TOOL::AlignLeft( TOOL_EVENT& aEvent ) +{ + const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + + if( selection.Size() > 1 ) + { + PCB_BASE_FRAME* editFrame = getEditFrame(); + RN_DATA* ratsnest = getModel()->GetRatsnest(); + + editFrame->OnModify(); + editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED ); + + // Compute the leftmost point of selection - it will be the edge of alignment + int left = selection.Item( 0 )->GetBoundingBox().GetX(); + + for( int i = 1; i < selection.Size(); ++i ) + { + int currentLeft = selection.Item( i )->GetBoundingBox().GetX(); + + if( left > currentLeft ) // X decreases when going left + left = currentLeft; + } + + // Move the selected items + for( int i = 0; i < selection.Size(); ++i ) + { + BOARD_ITEM* item = selection.Item( i ); + int difference = left - item->GetBoundingBox().GetX(); + + item->Move( wxPoint( difference, 0 ) ); + item->ViewUpdate(); + ratsnest->Update( item ); + } + + getModel()->GetRatsnest()->Recalculate(); + } + + setTransitions(); + + return 0; +} + + +int PLACEMENT_TOOL::AlignRight( TOOL_EVENT& aEvent ) +{ + const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + + if( selection.Size() > 1 ) + { + PCB_BASE_FRAME* editFrame = getEditFrame(); + RN_DATA* ratsnest = getModel()->GetRatsnest(); + + editFrame->OnModify(); + editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED ); + + // Compute the rightmost point of selection - it will be the edge of alignment + int right = selection.Item( 0 )->GetBoundingBox().GetRight(); + + for( int i = 1; i < selection.Size(); ++i ) + { + int currentRight = selection.Item( i )->GetBoundingBox().GetRight(); + + if( right < currentRight ) // X increases when going right + right = currentRight; + } + + // Move the selected items + for( int i = 0; i < selection.Size(); ++i ) + { + BOARD_ITEM* item = selection.Item( i ); + int difference = right - item->GetBoundingBox().GetRight(); + + item->Move( wxPoint( difference, 0 ) ); + item->ViewUpdate(); + ratsnest->Update( item ); + } + + getModel()->GetRatsnest()->Recalculate(); + } + + setTransitions(); + + return 0; +} + + +static bool compareX( const BOARD_ITEM* aA, const BOARD_ITEM* aB ) +{ + return aA->GetBoundingBox().Centre().x < aB->GetBoundingBox().Centre().x; +} + + +static bool compareY( const BOARD_ITEM* aA, const BOARD_ITEM* aB ) +{ + return aA->GetBoundingBox().Centre().y < aB->GetBoundingBox().Centre().y; +} + + +int PLACEMENT_TOOL::DistributeHorizontally( TOOL_EVENT& aEvent ) +{ + const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + + if( selection.Size() > 1 ) + { + PCB_BASE_FRAME* editFrame = getEditFrame(); + RN_DATA* ratsnest = getModel()->GetRatsnest(); + + editFrame->OnModify(); + editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED ); + + // Prepare a list, so the items can be sorted by their X coordinate + std::list itemsList; + for( int i = 0; i < selection.Size(); ++i ) + itemsList.push_back( selection.Item( i ) ); + + // Sort items by X coordinate + itemsList.sort( compareX ); + + // Expected X coordinate for the next item (=minX) + int position = (*itemsList.begin())->GetBoundingBox().Centre().x; + + // X coordinate for the last item + const int maxX = (*itemsList.rbegin())->GetBoundingBox().Centre().x; + + // Distance between items + const int distance = ( maxX - position ) / ( itemsList.size() - 1 ); + + BOOST_FOREACH( BOARD_ITEM* item, itemsList ) + { + int difference = position - item->GetBoundingBox().Centre().x; + + item->Move( wxPoint( difference, 0 ) ); + item->ViewUpdate(); + ratsnest->Update( item ); + + position += distance; + } + + getModel()->GetRatsnest()->Recalculate(); + } + + setTransitions(); + + return 0; +} + + +int PLACEMENT_TOOL::DistributeVertically( TOOL_EVENT& aEvent ) +{ + const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + + if( selection.Size() > 1 ) + { + PCB_BASE_FRAME* editFrame = getEditFrame(); + RN_DATA* ratsnest = getModel()->GetRatsnest(); + + editFrame->OnModify(); + editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED ); + + // Prepare a list, so the items can be sorted by their Y coordinate + std::list itemsList; + for( int i = 0; i < selection.Size(); ++i ) + itemsList.push_back( selection.Item( i ) ); + + // Sort items by Y coordinate + itemsList.sort( compareY ); + + // Expected Y coordinate for the next item (=minY) + int position = (*itemsList.begin())->GetBoundingBox().Centre().y; + + // Y coordinate for the last item + const int maxY = (*itemsList.rbegin())->GetBoundingBox().Centre().y; + + // Distance between items + const int distance = ( maxY - position ) / ( itemsList.size() - 1 ); + + BOOST_FOREACH( BOARD_ITEM* item, itemsList ) + { + int difference = position - item->GetBoundingBox().Centre().y; + + item->Move( wxPoint( 0, difference ) ); + item->ViewUpdate(); + ratsnest->Update( item ); + + position += distance; + } + + getModel()->GetRatsnest()->Recalculate(); + } + + setTransitions(); + + return 0; +} + + +void PLACEMENT_TOOL::setTransitions() +{ + Go( &PLACEMENT_TOOL::AlignTop, COMMON_ACTIONS::alignTop.MakeEvent() ); + Go( &PLACEMENT_TOOL::AlignBottom, COMMON_ACTIONS::alignBottom.MakeEvent() ); + Go( &PLACEMENT_TOOL::AlignLeft, COMMON_ACTIONS::alignLeft.MakeEvent() ); + Go( &PLACEMENT_TOOL::AlignRight, COMMON_ACTIONS::alignRight.MakeEvent() ); + + Go( &PLACEMENT_TOOL::DistributeHorizontally, COMMON_ACTIONS::distributeHorizontally.MakeEvent() ); + Go( &PLACEMENT_TOOL::DistributeVertically, COMMON_ACTIONS::distributeVertically.MakeEvent() ); +} diff --git a/pcbnew/tools/placement_tool.h b/pcbnew/tools/placement_tool.h new file mode 100644 index 0000000000..09f6983ac2 --- /dev/null +++ b/pcbnew/tools/placement_tool.h @@ -0,0 +1,73 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 CERN + * @author Maciej Suminski + * + * 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 PLACEMENT_TOOL_H_ +#define PLACEMENT_TOOL_H_ + +#include + +class SELECTION_TOOL; + +/** + * TODO description + */ + +class PLACEMENT_TOOL : public TOOL_INTERACTIVE +{ +public: + PLACEMENT_TOOL(); + virtual ~PLACEMENT_TOOL(); + + /// @copydoc TOOL_INTERACTIVE::Reset() + void Reset( RESET_REASON aReason ) {}; + + /// @copydoc TOOL_INTERACTIVE::Init() + bool Init(); + + /// TODO + int AlignTop( TOOL_EVENT& aEvent ); + + /// TODO + int AlignBottom( TOOL_EVENT& aEvent ); + + /// TODO + int AlignLeft( TOOL_EVENT& aEvent ); + + /// TODO + int AlignRight( TOOL_EVENT& aEvent ); + + /// TODO + int DistributeHorizontally( TOOL_EVENT& aEvent ); + + /// TODO + int DistributeVertically( TOOL_EVENT& aEvent ); + +private: + /// TODO + void setTransitions(); + + SELECTION_TOOL* m_selectionTool; +}; + +#endif /* PLACEMENT_TOOL_H_ */ From 8bddf33ab5690c2f8d85602635be00b5c076f924 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 14:23:13 +0200 Subject: [PATCH 070/123] Context menu for the Placement Tool. --- pcbnew/router/router_tool.cpp | 2 +- pcbnew/tools/placement_tool.cpp | 11 ++++++++++- pcbnew/tools/selection_tool.cpp | 6 ++++++ pcbnew/tools/selection_tool.h | 9 +++++++++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index f961722180..312b060920 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -220,7 +220,7 @@ public: Add( ACT_CustomTrackWidth ); - AppendSeparator ( ); + AppendSeparator(); Add( ACT_RouterOptions ); } }; diff --git a/pcbnew/tools/placement_tool.cpp b/pcbnew/tools/placement_tool.cpp index 05ac2522ba..5305d855ee 100644 --- a/pcbnew/tools/placement_tool.cpp +++ b/pcbnew/tools/placement_tool.cpp @@ -54,7 +54,16 @@ bool PLACEMENT_TOOL::Init() return false; } - // TODO create a context menu and add it to the selection tool + // Create a context menu and make it available through selection tool + CONTEXT_MENU* menu = new CONTEXT_MENU; + menu->Add( COMMON_ACTIONS::alignTop ); + menu->Add( COMMON_ACTIONS::alignBottom ); + menu->Add( COMMON_ACTIONS::alignLeft ); + menu->Add( COMMON_ACTIONS::alignRight ); + menu->AppendSeparator(); + menu->Add( COMMON_ACTIONS::distributeHorizontally ); + menu->Add( COMMON_ACTIONS::distributeVertically ); + m_selectionTool->AddSubMenu( menu, wxString( "Placement" ) ); setTransitions(); diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index ac9f1aa51c..d0abb1d60a 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -198,6 +198,12 @@ void SELECTION_TOOL::AddMenuItem( const TOOL_ACTION& aAction ) } +void SELECTION_TOOL::AddSubMenu( CONTEXT_MENU* aMenu, const wxString& aLabel ) +{ + m_menu.AppendSubMenu( aMenu, aLabel ); +} + + void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem ) { if( aItem->IsSelected() ) diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index 6f5e06606d..4891610d16 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -122,6 +122,15 @@ public: */ void AddMenuItem( const TOOL_ACTION& aAction ); + /** + * Function AddSubMenu() + * + * Adds a submenu to the selection tool right-click context menu. + * @param aMenu is the submenu to be added. + * @param aLabel is the label of added submenu. + */ + void AddSubMenu( CONTEXT_MENU* aMenu, const wxString& aLabel ); + /** * Function EditModules() * Toggles edit module mode. When enabled, one may select parts of modules individually From 8c1f783dd9ede7486d88c53a5e878bd78f67e4b7 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 14:41:52 +0200 Subject: [PATCH 071/123] Code formatting. --- pcbnew/import_dxf/dxf2brd_items.cpp | 166 +++++++++++++--------------- pcbnew/import_dxf/dxf2brd_items.h | 96 ++++++++-------- 2 files changed, 124 insertions(+), 138 deletions(-) diff --git a/pcbnew/import_dxf/dxf2brd_items.cpp b/pcbnew/import_dxf/dxf2brd_items.cpp index 6cd7e86fc4..322b787670 100644 --- a/pcbnew/import_dxf/dxf2brd_items.cpp +++ b/pcbnew/import_dxf/dxf2brd_items.cpp @@ -67,13 +67,13 @@ DXF2BRD_CONVERTER::~DXF2BRD_CONVERTER() // coordinate conversions from dxf to internal units int DXF2BRD_CONVERTER::mapX( double aDxfCoordX ) { - return Millimeter2iu( m_xOffset + (aDxfCoordX * m_Dfx2mm) ); + return Millimeter2iu( m_xOffset + ( aDxfCoordX * m_Dfx2mm ) ); } int DXF2BRD_CONVERTER::mapY( double aDxfCoordY ) { - return Millimeter2iu( m_yOffset - (aDxfCoordY * m_Dfx2mm) ); + return Millimeter2iu( m_yOffset - ( aDxfCoordY * m_Dfx2mm ) ); } @@ -95,23 +95,22 @@ bool DXF2BRD_CONVERTER::ImportDxfFile( const wxString& aFile, BOARD* aBoard ) return success; } -// Add aItem the the board -// this item is also added to the list of new items -// (for undo command for instance) -void DXF2BRD_CONVERTER::appendToBoard( BOARD_ITEM * aItem ) + +void DXF2BRD_CONVERTER::appendToBoard( BOARD_ITEM* aItem ) { m_brd->Add( aItem ); m_newItemsList.push_back( aItem ); } + /* * Implementation of the method which handles layers. */ -void DXF2BRD_CONVERTER::addLayer( const DRW_Layer& data ) +void DXF2BRD_CONVERTER::addLayer( const DRW_Layer& aData ) { // Not yet useful in Pcbnew. #if 0 - wxString name = wxString::FromUTF8( data.name.c_str() ); + wxString name = wxString::FromUTF8( aData.name.c_str() ); wxLogMessage( name ); #endif } @@ -120,25 +119,20 @@ void DXF2BRD_CONVERTER::addLayer( const DRW_Layer& data ) /* * Import line entities. */ -void DXF2BRD_CONVERTER::addLine( const DRW_Line& data ) +void DXF2BRD_CONVERTER::addLine( const DRW_Line& aData ) { - DRAWSEGMENT* segm = new DRAWSEGMENT( m_brd ); + DRAWSEGMENT* segm = new DRAWSEGMENT( m_brd ); segm->SetLayer( ToLAYER_ID( m_brdLayer ) ); - - wxPoint start( mapX( data.basePoint.x ), mapY( data.basePoint.y ) ); - + wxPoint start( mapX( aData.basePoint.x ), mapY( aData.basePoint.y ) ); segm->SetStart( start ); - - wxPoint end( mapX( data.secPoint.x ), mapY( data.secPoint.y ) ); - + wxPoint end( mapX( aData.secPoint.x ), mapY( aData.secPoint.y ) ); segm->SetEnd( end ); - - segm->SetWidth( mapDim( data.thickness == 0 ? m_defaultThickness : data.thickness ) ); + segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness : aData.thickness ) ); appendToBoard( segm ); } -void DXF2BRD_CONVERTER::addPolyline(const DRW_Polyline& data ) +void DXF2BRD_CONVERTER::addPolyline(const DRW_Polyline& aData ) { // Currently, Pcbnew does not know polylines, for boards. // So we have to convert a polyline to a set of segments. @@ -146,9 +140,9 @@ void DXF2BRD_CONVERTER::addPolyline(const DRW_Polyline& data ) wxPoint startpoint; - for( unsigned ii = 0; ii < data.vertlist.size(); ii++ ) + for( unsigned ii = 0; ii < aData.vertlist.size(); ii++ ) { - DRW_Vertex* vertex = data.vertlist[ii]; + DRW_Vertex* vertex = aData.vertlist[ii]; if( ii == 0 ) { @@ -163,14 +157,14 @@ void DXF2BRD_CONVERTER::addPolyline(const DRW_Polyline& data ) segm->SetStart( startpoint ); wxPoint endpoint( mapX( vertex->basePoint.x ), mapY( vertex->basePoint.y ) ); segm->SetEnd( endpoint ); - segm->SetWidth( mapDim( data.thickness == 0 ? m_defaultThickness - : data.thickness ) ); + segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness + : aData.thickness ) ); appendToBoard( segm ); startpoint = endpoint; } } -void DXF2BRD_CONVERTER::addLWPolyline(const DRW_LWPolyline& data ) +void DXF2BRD_CONVERTER::addLWPolyline(const DRW_LWPolyline& aData ) { // Currently, Pcbnew does not know polylines, for boards. // So we have to convert a polyline to a set of segments. @@ -179,9 +173,9 @@ void DXF2BRD_CONVERTER::addLWPolyline(const DRW_LWPolyline& data ) // the variable width of each vertex (when exists) is not used. wxPoint startpoint; - for( unsigned ii = 0; ii < data.vertlist.size(); ii++ ) + for( unsigned ii = 0; ii < aData.vertlist.size(); ii++ ) { - DRW_Vertex2D* vertex = data.vertlist[ii]; + DRW_Vertex2D* vertex = aData.vertlist[ii]; if( ii == 0 ) { @@ -196,8 +190,8 @@ void DXF2BRD_CONVERTER::addLWPolyline(const DRW_LWPolyline& data ) segm->SetStart( startpoint ); wxPoint endpoint( mapX( vertex->x ), mapY( vertex->y ) ); segm->SetEnd( endpoint ); - segm->SetWidth( mapDim( data.thickness == 0 ? m_defaultThickness - : data.thickness ) ); + segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness + : aData.thickness ) ); appendToBoard( segm ); startpoint = endpoint; } @@ -206,19 +200,17 @@ void DXF2BRD_CONVERTER::addLWPolyline(const DRW_LWPolyline& data ) /* * Import Circle entities. */ -void DXF2BRD_CONVERTER::addCircle( const DRW_Circle& data ) +void DXF2BRD_CONVERTER::addCircle( const DRW_Circle& aData ) { DRAWSEGMENT* segm = new DRAWSEGMENT( m_brd ); segm->SetLayer( ToLAYER_ID( m_brdLayer ) ); segm->SetShape( S_CIRCLE ); - wxPoint center( mapX( data.basePoint.x ), mapY( data.basePoint.y ) ); + wxPoint center( mapX( aData.basePoint.x ), mapY( aData.basePoint.y ) ); segm->SetCenter( center ); - wxPoint circle_start( mapX( data.basePoint.x + data.radious ), - mapY( data.basePoint.y ) ); + wxPoint circle_start( mapX( aData.basePoint.x + aData.radious ), mapY( aData.basePoint.y ) ); segm->SetArcStart( circle_start ); - segm->SetWidth( mapDim( data.thickness == 0 ? m_defaultThickness - : data.thickness ) ); + segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness : aData.thickness ) ); appendToBoard( segm ); } @@ -256,25 +248,24 @@ void DXF2BRD_CONVERTER::addArc( const DRW_Arc& data ) segm->SetAngle( angle ); - segm->SetWidth( mapDim( data.thickness == 0 ? m_defaultThickness - : data.thickness ) ); + segm->SetWidth( mapDim( data.thickness == 0 ? m_defaultThickness : data.thickness ) ); appendToBoard( segm ); } /** * Import texts (TEXT). */ -void DXF2BRD_CONVERTER::addText(const DRW_Text& data) +void DXF2BRD_CONVERTER::addText( const DRW_Text& aData ) { - TEXTE_PCB* pcb_text = new TEXTE_PCB( m_brd ); + TEXTE_PCB* pcb_text = new TEXTE_PCB( m_brd ); pcb_text->SetLayer( ToLAYER_ID( m_brdLayer ) ); - wxPoint refPoint( mapX(data.basePoint.x), mapY(data.basePoint.y) ); - wxPoint secPoint( mapX(data.secPoint.x), mapY(data.secPoint.y) ); + wxPoint refPoint( mapX( aData.basePoint.x ), mapY( aData.basePoint.y ) ); + wxPoint secPoint( mapX( aData.secPoint.x ), mapY( aData.secPoint.y ) ); - if (data.alignV !=0 || data.alignH !=0 ||data.alignH ==DRW_Text::HMiddle) + if( aData.alignV != 0 || aData.alignH != 0 || aData.alignH == DRW_Text::HMiddle ) { - if (data.alignH !=DRW_Text::HAligned && data.alignH !=DRW_Text::HFit) + if( aData.alignH != DRW_Text::HAligned && aData.alignH != DRW_Text::HFit ) { wxPoint tmp = secPoint; secPoint = refPoint; @@ -282,7 +273,7 @@ void DXF2BRD_CONVERTER::addText(const DRW_Text& data) } } - switch( data.alignV ) + switch( aData.alignV ) { case DRW_Text::VBaseLine: pcb_text->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM ); @@ -301,7 +292,7 @@ void DXF2BRD_CONVERTER::addText(const DRW_Text& data) break; } - switch( data.alignH ) + switch( aData.alignH ) { case DRW_Text::HLeft: pcb_text->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); @@ -332,13 +323,13 @@ void DXF2BRD_CONVERTER::addText(const DRW_Text& data) } #if 0 - wxString sty = wxString::FromUTF8(data.style.c_str()); + wxString sty = wxString::FromUTF8(aData.style.c_str()); sty=sty.ToLower(); - if (data.textgen==2) + if (aData.textgen==2) { // Text dir = left to right; - } else if (data.textgen==4) + } else if (aData.textgen==4) { / Text dir = top to bottom; } else @@ -346,15 +337,14 @@ void DXF2BRD_CONVERTER::addText(const DRW_Text& data) } #endif - wxString text = toNativeString( wxString::FromUTF8( data.text.c_str() ) ); + wxString text = toNativeString( wxString::FromUTF8( aData.text.c_str() ) ); pcb_text->SetTextPosition( refPoint ); - pcb_text->SetOrientation( data.angle * 10 ); + pcb_text->SetOrientation( aData.angle * 10 ); // The 0.8 factor gives a better height/width ratio with our font - pcb_text->SetWidth( mapDim( data.height * 0.8 ) ); - pcb_text->SetHeight( mapDim( data.height ) ); - pcb_text->SetThickness( mapDim( data.thickness == 0 ? m_defaultThickness - : data.thickness ) ); + pcb_text->SetWidth( mapDim( aData.height * 0.8 ) ); + pcb_text->SetHeight( mapDim( aData.height ) ); + pcb_text->SetThickness( mapDim( aData.thickness == 0 ? m_defaultThickness : aData.thickness ) ); pcb_text->SetText( text ); appendToBoard( pcb_text ); @@ -364,9 +354,9 @@ void DXF2BRD_CONVERTER::addText(const DRW_Text& data) /** * Import multi line texts (MTEXT). */ -void DXF2BRD_CONVERTER::addMText( const DRW_MText& data ) +void DXF2BRD_CONVERTER::addMText( const DRW_MText& aData ) { - wxString text = toNativeString( wxString::FromUTF8( data.text.c_str() ) ); + wxString text = toNativeString( wxString::FromUTF8( aData.text.c_str() ) ); wxString attrib, tmp; /* Some texts start by '\' and have formating chars (font name, font option...) @@ -396,23 +386,21 @@ void DXF2BRD_CONVERTER::addMText( const DRW_MText& data ) TEXTE_PCB* pcb_text = new TEXTE_PCB( m_brd ); pcb_text->SetLayer( ToLAYER_ID( m_brdLayer ) ); - - wxPoint textpos( mapX( data.basePoint.x ), mapY( data.basePoint.y ) ); + wxPoint textpos( mapX( aData.basePoint.x ), mapY( aData.basePoint.y ) ); pcb_text->SetTextPosition( textpos ); - pcb_text->SetOrientation( data.angle * 10 ); + pcb_text->SetOrientation( aData.angle * 10 ); // The 0.8 factor gives a better height/width ratio with our font - pcb_text->SetWidth( mapDim( data.height * 0.8 ) ); - pcb_text->SetHeight( mapDim( data.height ) ); - pcb_text->SetThickness( mapDim( data.thickness == 0 ? m_defaultThickness - : data.thickness ) ); + pcb_text->SetWidth( mapDim( aData.height * 0.8 ) ); + pcb_text->SetHeight( mapDim( aData.height ) ); + pcb_text->SetThickness( mapDim( aData.thickness == 0 ? m_defaultThickness : aData.thickness ) ); pcb_text->SetText( text ); // Initialize text justifications: - if( data.textgen <= 3 ) + if( aData.textgen <= 3 ) { pcb_text->SetVertJustify( GR_TEXT_VJUSTIFY_TOP ); } - else if( data.textgen <= 6 ) + else if( aData.textgen <= 6 ) { pcb_text->SetVertJustify( GR_TEXT_VJUSTIFY_CENTER ); } @@ -421,11 +409,11 @@ void DXF2BRD_CONVERTER::addMText( const DRW_MText& data ) pcb_text->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM ); } - if( data.textgen % 3 == 1 ) + if( aData.textgen % 3 == 1 ) { pcb_text->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); } - else if( data.textgen % 3 == 2 ) + else if( aData.textgen % 3 == 2 ) { pcb_text->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER ); } @@ -448,7 +436,7 @@ void DXF2BRD_CONVERTER::addMText( const DRW_MText& data ) // use ByStyle; } - if( data.alignV==1 ) + if( aData.alignV==1 ) { // use AtLeast; } @@ -490,24 +478,24 @@ void DXF2BRD_CONVERTER::addHeader( const DRW_Header* data ) * - %%%d for a degree sign * - %%%p for a plus/minus sign */ -wxString DXF2BRD_CONVERTER::toDxfString( const wxString& str ) +wxString DXF2BRD_CONVERTER::toDxfString( const wxString& aStr ) { wxString res; int j = 0; - for( unsigned i = 0; i175 || c<11 ) + if( c > 175 || c < 11 ) { - res.append( str.Mid( j, i - j ) ); + res.append( aStr.Mid( j, i - j ) ); j = i; switch( c ) { case 0x0A: - res += wxT("\\P"); + res += wxT( "\\P" ); break; // diameter: @@ -517,17 +505,17 @@ wxString DXF2BRD_CONVERTER::toDxfString( const wxString& str ) #else case 0x2205: #endif - res += wxT("%%C"); + res += wxT( "%%C" ); break; // degree: case 0x00B0: - res += wxT("%%D"); + res += wxT( "%%D" ); break; // plus/minus case 0x00B1: - res += wxT("%%P"); + res += wxT( "%%P" ); break; default: @@ -539,7 +527,7 @@ wxString DXF2BRD_CONVERTER::toDxfString( const wxString& str ) } } - res.append( str.Mid( j ) ); + res.append( aStr.Mid( j ) ); return res; } @@ -547,26 +535,26 @@ wxString DXF2BRD_CONVERTER::toDxfString( const wxString& str ) /** * Converts a DXF encoded string into a native Unicode string. */ -wxString DXF2BRD_CONVERTER::toNativeString( const wxString& data ) +wxString DXF2BRD_CONVERTER::toNativeString( const wxString& aData ) { wxString res; // Ignore font tags: int j = 0; - for( unsigned i = 0; i m_newItemsList; // The list of new items added - // to the board - BOARD * m_brd; + std::vector m_newItemsList; // The list of new items added to the board + BOARD* m_brd; double m_xOffset; // X coord offset for conversion (in mm) double m_yOffset; // Y coord offset for conversion (in mm) double m_defaultThickness; // default line thickness for conversion (in mm) double m_Dfx2mm; // The scale factor to convert DXF units to mm // Seems DRW_Interface always converts DXF coordinates in mm // (to be confirmed) - int m_brdLayer; // The board layer to place imported dfx items + int m_brdLayer; // The board layer to place imported dfx items int m_version; // the dxf version, not used here std::string m_codePage; // The code page, not used here @@ -85,7 +84,7 @@ public: * @param aFile = the full filename. * @param aBoard = where to store the graphical items and text */ - bool ImportDxfFile( const wxString& aFile, BOARD * aBoard ); + bool ImportDxfFile( const wxString& aFile, BOARD* aBoard ); /** * @return the list of new BOARD_ITEM @@ -104,65 +103,65 @@ private: // Add aItem the the board // this item is also added to the list of new items // (for undo command for instance) - void appendToBoard( BOARD_ITEM * aItem ); + void appendToBoard( BOARD_ITEM* aItem ); // Methods from DRW_CreationInterface: // They are "call back" fonctions, called when the corresponding object // is read in dxf file // Depending of the application, they can do something or not - virtual void addHeader( const DRW_Header* data ); - virtual void addLType( const DRW_LType& data ){} - virtual void addLayer( const DRW_Layer& data ); - virtual void addDimStyle( const DRW_Dimstyle& data ){} - virtual void addBlock(const DRW_Block& data ){} - virtual void endBlock(){} - virtual void addPoint(const DRW_Point& data ){} - virtual void addLine(const DRW_Line& data); - virtual void addRay(const DRW_Ray& data ){} - virtual void addXline(const DRW_Xline& data ){} - virtual void addCircle(const DRW_Circle& data ); - virtual void addArc(const DRW_Arc& data ); - virtual void addEllipse(const DRW_Ellipse& data ){} - virtual void addLWPolyline(const DRW_LWPolyline& data ); - virtual void addText(const DRW_Text& data ); - virtual void addPolyline(const DRW_Polyline& data ); - virtual void addSpline(const DRW_Spline* data ){} - virtual void addKnot(const DRW_Entity&) {} - virtual void addInsert(const DRW_Insert& data ){} - virtual void addTrace(const DRW_Trace& data ){} - virtual void addSolid(const DRW_Solid& data ){} - virtual void addMText(const DRW_MText& data); - virtual void addDimAlign(const DRW_DimAligned *data ){} - virtual void addDimLinear(const DRW_DimLinear *data ){} - virtual void addDimRadial(const DRW_DimRadial *data ){} - virtual void addDimDiametric(const DRW_DimDiametric *data ){} - virtual void addDimAngular(const DRW_DimAngular *data ){} - virtual void addDimAngular3P(const DRW_DimAngular3p *data ){} - virtual void addDimOrdinate(const DRW_DimOrdinate *data ){} - virtual void addLeader(const DRW_Leader *data ){} - virtual void addHatch(const DRW_Hatch* data ){} - virtual void addImage(const DRW_Image* data ){} - virtual void linkImage(const DRW_ImageDef* data ){} + virtual void addHeader( const DRW_Header* aData ); + virtual void addLType( const DRW_LType& aData ) {} + virtual void addLayer( const DRW_Layer& aData ); + virtual void addDimStyle( const DRW_Dimstyle& aData ) {} + virtual void addBlock( const DRW_Block& aData ) {} + virtual void endBlock() {} + virtual void addPoint( const DRW_Point& aData ) {} + virtual void addLine( const DRW_Line& aData); + virtual void addRay( const DRW_Ray& aData ) {} + virtual void addXline( const DRW_Xline& aData ) {} + virtual void addCircle( const DRW_Circle& aData ); + virtual void addArc( const DRW_Arc& aData ); + virtual void addEllipse( const DRW_Ellipse& aData ) {} + virtual void addLWPolyline( const DRW_LWPolyline& aData ); + virtual void addText( const DRW_Text& aData ); + virtual void addPolyline( const DRW_Polyline& aData ); + virtual void addSpline( const DRW_Spline* aData ) {} + virtual void addKnot( const DRW_Entity&) {} + virtual void addInsert( const DRW_Insert& aData ){} + virtual void addTrace( const DRW_Trace& aData ){} + virtual void addSolid( const DRW_Solid& aData ){} + virtual void addMText( const DRW_MText& aData); + virtual void addDimAlign( const DRW_DimAligned* aData ) {} + virtual void addDimLinear( const DRW_DimLinear* aData ) {} + virtual void addDimRadial( const DRW_DimRadial* aData ) {} + virtual void addDimDiametric( const DRW_DimDiametric* aData ) {} + virtual void addDimAngular( const DRW_DimAngular* aData ) {} + virtual void addDimAngular3P( const DRW_DimAngular3p* aData ) {} + virtual void addDimOrdinate( const DRW_DimOrdinate* aData ) {} + virtual void addLeader( const DRW_Leader* aData ) {} + virtual void addHatch( const DRW_Hatch* aData ) {} + virtual void addImage( const DRW_Image* aData ) {} + virtual void linkImage( const DRW_ImageDef* aData ) {} - virtual void add3dFace(const DRW_3Dface& data ){} - virtual void addComment(const char*){} + virtual void add3dFace( const DRW_3Dface& aData ) {} + virtual void addComment( const char*) {} - virtual void addVport(const DRW_Vport& data) {} + virtual void addVport( const DRW_Vport& aData ) {} - virtual void addTextStyle(const DRW_Textstyle& data); + virtual void addTextStyle( const DRW_Textstyle& aData ); - virtual void addViewport(const DRW_Viewport& data) {} + virtual void addViewport( const DRW_Viewport& aData ) {} - virtual void setBlock(const int handle) {} + virtual void setBlock( const int aHandle ) {} - static wxString toDxfString(const wxString& str); - static wxString toNativeString(const wxString& data); + static wxString toDxfString( const wxString& aStr ); + static wxString toNativeString( const wxString& aData ); // These functions are not used in Kicad. // But because they are virtual pure in DRW_Interface, they should be defined virtual void writeTextstyles() {} virtual void writeVports() {} - virtual void writeHeader(DRW_Header& data) {} + virtual void writeHeader( DRW_Header& aData ) {} virtual void writeEntities() {} virtual void writeLTypes() {} virtual void writeLayers() {} @@ -172,7 +171,6 @@ private: void writeLine(); void writeMtext(); - }; #endif // FILTERDXFRW_H From b4b7f947a9394ccbd83f42a31eeb94c0c4dbe2aa Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:02:56 +0200 Subject: [PATCH 072/123] Refactored DXF import routines: - DIALOG_DXF_IMPORT works with PCB_BASE_FRAME instead of PCB_EDIT_FRAME - imported items are not immediately added to a BOARD - imported items are held in a list, instead of vector - imported items are instantly visible in GAL view - added DIALOG_DXF_IMPORT::GetImportedItems() - code formatting --- pcbnew/edit.cpp | 3 +- pcbnew/import_dxf/dialog_dxf_import.cpp | 89 +++++++++++++++---------- pcbnew/import_dxf/dxf2brd_items.cpp | 40 +++++------ pcbnew/import_dxf/dxf2brd_items.h | 14 ++-- pcbnew/invoke_pcb_dialog.h | 13 ++-- 5 files changed, 82 insertions(+), 77 deletions(-) diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index efb92a7064..79fc20b730 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -1219,8 +1219,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) default: wxString msg; - msg.Printf( wxT( "PCB_EDIT_FRAME::Process_Special_Functions() unknown event id %d" ), - id ); + msg.Printf( wxT( "PCB_EDIT_FRAME::Process_Special_Functions() unknown event id %d" ), id ); DisplayError( this, msg ); break; } diff --git a/pcbnew/import_dxf/dialog_dxf_import.cpp b/pcbnew/import_dxf/dialog_dxf_import.cpp index f442b9a352..49ab35cd79 100644 --- a/pcbnew/import_dxf/dialog_dxf_import.cpp +++ b/pcbnew/import_dxf/dialog_dxf_import.cpp @@ -34,6 +34,8 @@ #include #include #include +#include +#include // Keys to store setup in config @@ -43,20 +45,29 @@ class DIALOG_DXF_IMPORT : public DIALOG_DXF_IMPORT_BASE { -private: - PCB_EDIT_FRAME * m_parent; - wxConfigBase* m_config; // Current config - - static wxString m_dxfFilename; - static int m_offsetSelection; - static LAYER_NUM m_layer; - public: - - DIALOG_DXF_IMPORT( PCB_EDIT_FRAME* aParent ); + DIALOG_DXF_IMPORT( PCB_BASE_FRAME* aParent ); ~DIALOG_DXF_IMPORT(); + /** + * Function GetImportedItems() + * + * Returns a list of items imported from a DXF file. + */ + const std::list& GetImportedItems() const + { + return m_dxfImporter.GetItemsList(); + } + private: + PCB_BASE_FRAME* m_parent; + wxConfigBase* m_config; // Current config + DXF2BRD_CONVERTER m_dxfImporter; + + static wxString m_dxfFilename; + static int m_offsetSelection; + static LAYER_NUM m_layer; + // Virtual event handlers void OnCancelClick( wxCommandEvent& event ) { event.Skip(); } void OnOKClick( wxCommandEvent& event ); @@ -70,8 +81,8 @@ int DIALOG_DXF_IMPORT::m_offsetSelection = 4; LAYER_NUM DIALOG_DXF_IMPORT::m_layer = Dwgs_User; -DIALOG_DXF_IMPORT::DIALOG_DXF_IMPORT( PCB_EDIT_FRAME* aParent ) : - DIALOG_DXF_IMPORT_BASE( aParent ) +DIALOG_DXF_IMPORT::DIALOG_DXF_IMPORT( PCB_BASE_FRAME* aParent ) + : DIALOG_DXF_IMPORT_BASE( aParent ) { m_parent = aParent; m_config = Kiface().KifaceSettings(); @@ -130,7 +141,7 @@ void DIALOG_DXF_IMPORT::OnBrowseDxfFiles( wxCommandEvent& event ) wxFileDialog dlg( m_parent, wxT( "Open File" ), path, m_dxfFilename, - wxT( "dxf Files (*.dxf)|*.dxf|*.DXF" ), + wxT( "dxf Files (*.dxf)|*.dxf" ), wxFD_OPEN|wxFD_FILE_MUST_EXIST ); dlg.ShowModal(); @@ -143,6 +154,7 @@ void DIALOG_DXF_IMPORT::OnBrowseDxfFiles( wxCommandEvent& event ) m_textCtrlFileName->SetValue( fileName ); } + void DIALOG_DXF_IMPORT::OnOKClick( wxCommandEvent& event ) { m_dxfFilename = m_textCtrlFileName->GetValue(); @@ -173,41 +185,50 @@ void DIALOG_DXF_IMPORT::OnOKClick( wxCommandEvent& event ) break; } - BOARD * brd = m_parent->GetBoard(); - DXF2BRD_CONVERTER dxf_importer; - // Set coordinates offset for import (offset is given in mm) - dxf_importer.SetOffset( offsetX, offsetY ); + m_dxfImporter.SetOffset( offsetX, offsetY ); m_layer = m_SelLayerBox->GetLayerSelection(); - dxf_importer.SetBrdLayer( m_layer ); + m_dxfImporter.SetBrdLayer( m_layer ); // Read dxf file: - dxf_importer.ImportDxfFile( m_dxfFilename, brd ); - - // Prepare the undo list - std::vector& list = dxf_importer.GetItemsList(); - PICKED_ITEMS_LIST picklist; - - // Build the undo list - for( unsigned ii = 0; ii < list.size(); ii++ ) - { - ITEM_PICKER itemWrapper( list[ii], UR_NEW ); - picklist.PushItem( itemWrapper ); - } - - m_parent->SaveCopyInUndoList( picklist, UR_NEW, wxPoint(0,0) ); + m_dxfImporter.ImportDxfFile( m_dxfFilename ); EndModal( wxID_OK ); } -bool InvokeDXFDialogImport( PCB_EDIT_FRAME* aCaller ) +bool InvokeDXFDialogImport( PCB_BASE_FRAME* aCaller ) { DIALOG_DXF_IMPORT dlg( aCaller ); - bool success = dlg.ShowModal() == wxID_OK; + bool success = ( dlg.ShowModal() == wxID_OK ); if( success ) + { + // Prepare the undo list + const std::list& list = dlg.GetImportedItems(); + PICKED_ITEMS_LIST picklist; + + BOARD* board = aCaller->GetBoard(); + KIGFX::VIEW* view = aCaller->GetGalCanvas()->GetView(); + + // Build the undo list & add items to the current view + std::list::const_iterator it, itEnd; + for( it = list.begin(), itEnd = list.end(); it != itEnd; ++it ) + { + BOARD_ITEM* item = *it; + + board->Add( item ); + + ITEM_PICKER itemWrapper( item, UR_NEW ); + picklist.PushItem( itemWrapper ); + + if( aCaller->IsGalCanvasActive() ) + view->Add( item ); + } + + aCaller->SaveCopyInUndoList( picklist, UR_NEW, wxPoint( 0, 0 ) ); aCaller->OnModify(); + } return success; } diff --git a/pcbnew/import_dxf/dxf2brd_items.cpp b/pcbnew/import_dxf/dxf2brd_items.cpp index 322b787670..d9ffbbf63b 100644 --- a/pcbnew/import_dxf/dxf2brd_items.cpp +++ b/pcbnew/import_dxf/dxf2brd_items.cpp @@ -52,7 +52,6 @@ DXF2BRD_CONVERTER::DXF2BRD_CONVERTER() : DRW_Interface() m_xOffset = 0.0; // X coord offset for conversion (in mm) m_yOffset = 0.0; // Y coord offset for conversion (in mm) m_Dfx2mm = 1.0; // The scale factor to convert DXF units to mm - m_brd = NULL; m_version = 0; m_defaultThickness = 0.1; m_brdLayer = Dwgs_User; @@ -83,10 +82,8 @@ int DXF2BRD_CONVERTER::mapDim( double aDxfValue ) } -bool DXF2BRD_CONVERTER::ImportDxfFile( const wxString& aFile, BOARD* aBoard ) +bool DXF2BRD_CONVERTER::ImportDxfFile( const wxString& aFile ) { - m_brd = aBoard; - dxfRW* dxf = new dxfRW( aFile.ToUTF8() ); bool success = dxf->read( this, true ); @@ -96,13 +93,6 @@ bool DXF2BRD_CONVERTER::ImportDxfFile( const wxString& aFile, BOARD* aBoard ) } -void DXF2BRD_CONVERTER::appendToBoard( BOARD_ITEM* aItem ) -{ - m_brd->Add( aItem ); - m_newItemsList.push_back( aItem ); -} - - /* * Implementation of the method which handles layers. */ @@ -121,7 +111,7 @@ void DXF2BRD_CONVERTER::addLayer( const DRW_Layer& aData ) */ void DXF2BRD_CONVERTER::addLine( const DRW_Line& aData ) { - DRAWSEGMENT* segm = new DRAWSEGMENT( m_brd ); + DRAWSEGMENT* segm = new DRAWSEGMENT; segm->SetLayer( ToLAYER_ID( m_brdLayer ) ); wxPoint start( mapX( aData.basePoint.x ), mapY( aData.basePoint.y ) ); @@ -129,7 +119,7 @@ void DXF2BRD_CONVERTER::addLine( const DRW_Line& aData ) wxPoint end( mapX( aData.secPoint.x ), mapY( aData.secPoint.y ) ); segm->SetEnd( end ); segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness : aData.thickness ) ); - appendToBoard( segm ); + m_newItemsList.push_back( segm ); } void DXF2BRD_CONVERTER::addPolyline(const DRW_Polyline& aData ) @@ -151,7 +141,7 @@ void DXF2BRD_CONVERTER::addPolyline(const DRW_Polyline& aData ) continue; } - DRAWSEGMENT* segm = new DRAWSEGMENT( m_brd ); + DRAWSEGMENT* segm = new DRAWSEGMENT( NULL ); segm->SetLayer( ToLAYER_ID( m_brdLayer ) ); segm->SetStart( startpoint ); @@ -159,7 +149,7 @@ void DXF2BRD_CONVERTER::addPolyline(const DRW_Polyline& aData ) segm->SetEnd( endpoint ); segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness : aData.thickness ) ); - appendToBoard( segm ); + m_newItemsList.push_back( segm ); startpoint = endpoint; } } @@ -184,7 +174,7 @@ void DXF2BRD_CONVERTER::addLWPolyline(const DRW_LWPolyline& aData ) continue; } - DRAWSEGMENT* segm = new DRAWSEGMENT( m_brd ); + DRAWSEGMENT* segm = new DRAWSEGMENT( NULL ); segm->SetLayer( ToLAYER_ID( m_brdLayer ) ); segm->SetStart( startpoint ); @@ -192,7 +182,7 @@ void DXF2BRD_CONVERTER::addLWPolyline(const DRW_LWPolyline& aData ) segm->SetEnd( endpoint ); segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness : aData.thickness ) ); - appendToBoard( segm ); + m_newItemsList.push_back( segm ); startpoint = endpoint; } } @@ -202,7 +192,7 @@ void DXF2BRD_CONVERTER::addLWPolyline(const DRW_LWPolyline& aData ) */ void DXF2BRD_CONVERTER::addCircle( const DRW_Circle& aData ) { - DRAWSEGMENT* segm = new DRAWSEGMENT( m_brd ); + DRAWSEGMENT* segm = new DRAWSEGMENT; segm->SetLayer( ToLAYER_ID( m_brdLayer ) ); segm->SetShape( S_CIRCLE ); @@ -211,7 +201,7 @@ void DXF2BRD_CONVERTER::addCircle( const DRW_Circle& aData ) wxPoint circle_start( mapX( aData.basePoint.x + aData.radious ), mapY( aData.basePoint.y ) ); segm->SetArcStart( circle_start ); segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness : aData.thickness ) ); - appendToBoard( segm ); + m_newItemsList.push_back( segm ); } @@ -220,7 +210,7 @@ void DXF2BRD_CONVERTER::addCircle( const DRW_Circle& aData ) */ void DXF2BRD_CONVERTER::addArc( const DRW_Arc& data ) { - DRAWSEGMENT* segm = new DRAWSEGMENT( m_brd ); + DRAWSEGMENT* segm = new DRAWSEGMENT; segm->SetLayer( ToLAYER_ID( m_brdLayer ) ); segm->SetShape( S_ARC ); @@ -249,7 +239,7 @@ void DXF2BRD_CONVERTER::addArc( const DRW_Arc& data ) segm->SetAngle( angle ); segm->SetWidth( mapDim( data.thickness == 0 ? m_defaultThickness : data.thickness ) ); - appendToBoard( segm ); + m_newItemsList.push_back( segm ); } /** @@ -257,7 +247,7 @@ void DXF2BRD_CONVERTER::addArc( const DRW_Arc& data ) */ void DXF2BRD_CONVERTER::addText( const DRW_Text& aData ) { - TEXTE_PCB* pcb_text = new TEXTE_PCB( m_brd ); + TEXTE_PCB* pcb_text = new TEXTE_PCB( NULL ); pcb_text->SetLayer( ToLAYER_ID( m_brdLayer ) ); wxPoint refPoint( mapX( aData.basePoint.x ), mapY( aData.basePoint.y ) ); @@ -347,7 +337,7 @@ void DXF2BRD_CONVERTER::addText( const DRW_Text& aData ) pcb_text->SetThickness( mapDim( aData.thickness == 0 ? m_defaultThickness : aData.thickness ) ); pcb_text->SetText( text ); - appendToBoard( pcb_text ); + m_newItemsList.push_back( pcb_text ); } @@ -384,7 +374,7 @@ void DXF2BRD_CONVERTER::addMText( const DRW_MText& aData ) text = tmp; } - TEXTE_PCB* pcb_text = new TEXTE_PCB( m_brd ); + TEXTE_PCB* pcb_text = new TEXTE_PCB( NULL ); pcb_text->SetLayer( ToLAYER_ID( m_brdLayer ) ); wxPoint textpos( mapX( aData.basePoint.x ), mapY( aData.basePoint.y ) ); pcb_text->SetTextPosition( textpos ); @@ -446,7 +436,7 @@ void DXF2BRD_CONVERTER::addMText( const DRW_MText& aData ) } #endif - appendToBoard( pcb_text ); + m_newItemsList.push_back( pcb_text ); } diff --git a/pcbnew/import_dxf/dxf2brd_items.h b/pcbnew/import_dxf/dxf2brd_items.h index f89e4b88d0..f4be640138 100644 --- a/pcbnew/import_dxf/dxf2brd_items.h +++ b/pcbnew/import_dxf/dxf2brd_items.h @@ -28,6 +28,7 @@ #include "drw_interface.h" #include "wx/wx.h" +#include class BOARD; class BOARD_ITEM; @@ -41,8 +42,7 @@ class BOARD_ITEM; class DXF2BRD_CONVERTER : public DRW_Interface { private: - std::vector m_newItemsList; // The list of new items added to the board - BOARD* m_brd; + std::list m_newItemsList; // The list of new items added to the board double m_xOffset; // X coord offset for conversion (in mm) double m_yOffset; // Y coord offset for conversion (in mm) double m_defaultThickness; // default line thickness for conversion (in mm) @@ -82,14 +82,13 @@ public: * with this filter. * * @param aFile = the full filename. - * @param aBoard = where to store the graphical items and text */ - bool ImportDxfFile( const wxString& aFile, BOARD* aBoard ); + bool ImportDxfFile( const wxString& aFile ); /** * @return the list of new BOARD_ITEM */ - std::vector& GetItemsList() + const std::list& GetItemsList() const { return m_newItemsList; } @@ -100,11 +99,6 @@ private: int mapY( double aDxfCoordY ); int mapDim( double aDxfValue ); - // Add aItem the the board - // this item is also added to the list of new items - // (for undo command for instance) - void appendToBoard( BOARD_ITEM* aItem ); - // Methods from DRW_CreationInterface: // They are "call back" fonctions, called when the corresponding object // is read in dxf file diff --git a/pcbnew/invoke_pcb_dialog.h b/pcbnew/invoke_pcb_dialog.h index ff9e89e40a..151ce609a6 100644 --- a/pcbnew/invoke_pcb_dialog.h +++ b/pcbnew/invoke_pcb_dialog.h @@ -49,10 +49,11 @@ class wxSize; //class wxRealPoint; class wxString; +class BOARD; // Often this is not used in the prototypes, since wxFrame is good enough and would // represent maximum information hiding. -class PCB_EDIT_FRAME; +class PCB_BASE_FRAME; class FP_LIB_TABLE; class BOARD; class PCB_PLOT_PARAMS; @@ -81,13 +82,13 @@ void InvokePluginOptionsEditor( wxTopLevelWindow* aCaller, const wxString& aNick const wxString& aPluginType, const wxString& aOptions, wxString* aResult ); /** - * Function InvokePcbLibTableEditor - * shows the modal DIALOG_FP_LIB_TABLE for purposes of editing two lib tables. - * + * Function InvokeDXFDialogBoardImport + * shows the modal DIALOG_DXF_IMPORT for importing a DXF file to a board. + * @param aCaller is the wxTopLevelWindow which is invoking the dialog. - * @return true if the ilport was made. + * @return true if the import was made. */ -bool InvokeDXFDialogImport( PCB_EDIT_FRAME* aCaller ); +bool InvokeDXFDialogImport( PCB_BASE_FRAME* aCaller ); /** * Function InvokeLayerSetup From 069dac540739a117275c365313c45049923bd2bd Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:02:56 +0200 Subject: [PATCH 073/123] DXF files import is supported by module editor. --- pcbnew/edit.cpp | 2 +- pcbnew/import_dxf/dialog_dxf_import.cpp | 70 ++++++++++++++++++++++++- pcbnew/invoke_pcb_dialog.h | 12 ++++- pcbnew/menubar_modedit.cpp | 7 +++ pcbnew/modedit.cpp | 6 +++ pcbnew/moduleframe.cpp | 1 + 6 files changed, 94 insertions(+), 4 deletions(-) diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index 79fc20b730..787a73827e 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -1213,7 +1213,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) break; case ID_GEN_IMPORT_DXF_FILE: - InvokeDXFDialogImport( this ); + InvokeDXFDialogBoardImport( this ); m_canvas->Refresh(); break; diff --git a/pcbnew/import_dxf/dialog_dxf_import.cpp b/pcbnew/import_dxf/dialog_dxf_import.cpp index 49ab35cd79..612fba07c4 100644 --- a/pcbnew/import_dxf/dialog_dxf_import.cpp +++ b/pcbnew/import_dxf/dialog_dxf_import.cpp @@ -35,7 +35,12 @@ #include #include #include + #include +#include +#include +#include +#include // Keys to store setup in config @@ -197,7 +202,7 @@ void DIALOG_DXF_IMPORT::OnOKClick( wxCommandEvent& event ) } -bool InvokeDXFDialogImport( PCB_BASE_FRAME* aCaller ) +bool InvokeDXFDialogBoardImport( PCB_BASE_FRAME* aCaller ) { DIALOG_DXF_IMPORT dlg( aCaller ); bool success = ( dlg.ShowModal() == wxID_OK ); @@ -216,7 +221,6 @@ bool InvokeDXFDialogImport( PCB_BASE_FRAME* aCaller ) for( it = list.begin(), itEnd = list.end(); it != itEnd; ++it ) { BOARD_ITEM* item = *it; - board->Add( item ); ITEM_PICKER itemWrapper( item, UR_NEW ); @@ -232,3 +236,65 @@ bool InvokeDXFDialogImport( PCB_BASE_FRAME* aCaller ) return success; } + + +bool InvokeDXFDialogModuleImport( PCB_BASE_FRAME* aCaller, MODULE* aModule ) +{ + DIALOG_DXF_IMPORT dlg( aCaller ); + bool success = ( dlg.ShowModal() == wxID_OK ); + + if( success ) + { + // Prepare the undo list + const std::list& list = dlg.GetImportedItems(); + PICKED_ITEMS_LIST picklist; + + MODULE* module = aCaller->GetBoard()->m_Modules; + KIGFX::VIEW* view = aCaller->GetGalCanvas()->GetView(); + + aCaller->SaveCopyInUndoList( module, UR_MODEDIT ); + aCaller->OnModify(); + + // Build the undo list & add items to the current view + std::list::const_iterator it, itEnd; + for( it = list.begin(), itEnd = list.end(); it != itEnd; ++it ) + { + BOARD_ITEM* item = *it; + BOARD_ITEM* converted = NULL; + + // Modules use different types for the same things, + // so we need to convert imported items to appropriate classes. + switch( item->Type() ) + { + case PCB_LINE_T: + { + converted = new EDGE_MODULE( module ); + *static_cast( converted ) = *static_cast( item ); + module->Add( converted ); + static_cast( converted )->SetLocalCoord(); + delete item; + break; + } + + case PCB_TEXT_T: + { + converted = new TEXTE_MODULE( module ); + *static_cast( converted ) = *static_cast( item ); + module->Add( module ); + static_cast( converted )->SetLocalCoord(); + delete item; + break; + } + + default: + assert( false ); // there is a type that is currently not handled here + break; + } + + if( aCaller->IsGalCanvasActive() ) + view->Add( converted ); + } + } + + return success; +} diff --git a/pcbnew/invoke_pcb_dialog.h b/pcbnew/invoke_pcb_dialog.h index 151ce609a6..5f264ca000 100644 --- a/pcbnew/invoke_pcb_dialog.h +++ b/pcbnew/invoke_pcb_dialog.h @@ -50,6 +50,7 @@ class wxSize; class wxString; class BOARD; +class MODULE; // Often this is not used in the prototypes, since wxFrame is good enough and would // represent maximum information hiding. @@ -88,7 +89,16 @@ void InvokePluginOptionsEditor( wxTopLevelWindow* aCaller, const wxString& aNick * @param aCaller is the wxTopLevelWindow which is invoking the dialog. * @return true if the import was made. */ -bool InvokeDXFDialogImport( PCB_BASE_FRAME* aCaller ); +bool InvokeDXFDialogBoardImport( PCB_BASE_FRAME* aCaller ); + +/** + * Function InvokeDXFDialogModuleImport + * shows the modal DIALOG_DXF_IMPORT for importing a DXF file.to a module. + * + * @param aCaller is the wxTopLevelWindow which is invoking the dialog. + * @return true if the import was made. + */ +bool InvokeDXFDialogModuleImport( PCB_BASE_FRAME* aCaller, MODULE* aModule ); /** * Function InvokeLayerSetup diff --git a/pcbnew/menubar_modedit.cpp b/pcbnew/menubar_modedit.cpp index ffbe9a681f..418cc5c342 100644 --- a/pcbnew/menubar_modedit.cpp +++ b/pcbnew/menubar_modedit.cpp @@ -125,6 +125,13 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar() _( "&Export Module" ), _( "Save current loaded module into file" ), KiBitmap( export_module_xpm ) ); + + // Import DXF File + AddMenuItem( fileMenu, ID_GEN_IMPORT_DXF_FILE, + _( "&Import DXF File" ), + _( "Import a 2D Drawing DXF file to Pcbnew on the Drawings layer" ), + KiBitmap( import_xpm ) ); + fileMenu->AppendSeparator(); // Print diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp index c813011dd6..3abe8f08ad 100644 --- a/pcbnew/modedit.cpp +++ b/pcbnew/modedit.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -777,6 +778,11 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) HandleBlockEnd( &dc ); break; + case ID_GEN_IMPORT_DXF_FILE: + InvokeDXFDialogModuleImport( this, GetBoard()->m_Modules ); + m_canvas->Refresh(); + break; + default: DisplayError( this, wxT( "FOOTPRINT_EDIT_FRAME::Process_Special_Functions error" ) ); diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index 603e4e0838..f237b245e0 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -92,6 +92,7 @@ BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME ) EVT_TOOL( ID_MODEDIT_CREATE_NEW_LIB_AND_SAVE_CURRENT_PART, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( ID_MODEDIT_SHEET_SET, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) + EVT_TOOL( ID_GEN_IMPORT_DXF_FILE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( wxID_PRINT, FOOTPRINT_EDIT_FRAME::ToPrinter ) EVT_TOOL( ID_MODEDIT_LOAD_MODULE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( ID_MODEDIT_CHECK, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) From 4f0e03bcc09c9d4b744f0826e237f70a083bfbdc Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:02:56 +0200 Subject: [PATCH 074/123] Fixed a few memory leaks and Valgrind warnings. --- common/painter.cpp | 1 + include/tool/context_menu.h | 2 + include/wxPcbStruct.h | 3 +- pcbnew/CMakeLists.txt | 1 - pcbnew/basepcbframe.cpp | 3 + pcbnew/dialogs/dialog_track_via_size.cpp | 1 + pcbnew/layer_widget.cpp | 9 +++ pcbnew/layer_widget.h | 2 + pcbnew/pcbframe.cpp | 36 +++++++++++- pcbnew/router/pns_routing_settings.cpp | 10 ++++ pcbnew/router/pns_routing_settings.h | 11 +--- pcbnew/router/router_tool.h | 5 -- pcbnew/tools/pcb_tools.cpp | 71 ------------------------ pcbnew/tools/selection_tool.cpp | 2 +- 14 files changed, 68 insertions(+), 89 deletions(-) delete mode 100644 pcbnew/tools/pcb_tools.cpp diff --git a/common/painter.cpp b/common/painter.cpp index 785d479a1f..0d6b1f0399 100644 --- a/common/painter.cpp +++ b/common/painter.cpp @@ -38,6 +38,7 @@ RENDER_SETTINGS::RENDER_SETTINGS() m_highlightEnabled = false; m_hiContrastEnabled = false; m_hiContrastFactor = 0.2; + m_highlightNetcode = -1; m_outlineWidth = 1; m_worksheetLineWidth = 100000; diff --git a/include/tool/context_menu.h b/include/tool/context_menu.h index e50ef207c2..0b5f28c41b 100644 --- a/include/tool/context_menu.h +++ b/include/tool/context_menu.h @@ -47,6 +47,8 @@ public: ///> Copy constructor CONTEXT_MENU( const CONTEXT_MENU& aMenu ); + virtual ~CONTEXT_MENU() {}; + /** * Function SetTitle() * Sets title for the context menu. The title is shown as a text label shown on the top of diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index fa7d78323e..cc2650fcde 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -117,9 +117,8 @@ protected: bool m_useCmpFileForFpNames; ///< is true, use the .cmp file from CvPcb, else use the netlist // to know the footprint name of components. - // Functions that handle the Tool Framework (de)initalization + // The Tool Framework initalization void setupTools(); - void destroyTools(); // we'll use lower case function names for private member functions. void createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu* aPopMenu ); diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index bab69a7b37..624418055a 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -264,7 +264,6 @@ set( PCBNEW_CLASS_SRCS tools/edit_tool.cpp tools/pcbnew_control.cpp tools/pcb_editor_control.cpp - tools/pcb_tools.cpp tools/placement_tool.cpp tools/common_actions.cpp ) diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index 3ff1a97f51..8369cb0a65 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -125,6 +125,9 @@ PCB_BASE_FRAME::~PCB_BASE_FRAME() { delete m_Collector; + delete m_toolManager; + delete m_toolDispatcher; + delete m_Pcb; delete GetGalCanvas(); } diff --git a/pcbnew/dialogs/dialog_track_via_size.cpp b/pcbnew/dialogs/dialog_track_via_size.cpp index 8a51cafdb4..07b681ad43 100644 --- a/pcbnew/dialogs/dialog_track_via_size.cpp +++ b/pcbnew/dialogs/dialog_track_via_size.cpp @@ -26,6 +26,7 @@ #include #include #include +#include DIALOG_TRACK_VIA_SIZE::DIALOG_TRACK_VIA_SIZE( wxWindow* aParent, PNS_ROUTING_SETTINGS& aSettings ) : DIALOG_TRACK_VIA_SIZE_BASE( aParent ), diff --git a/pcbnew/layer_widget.cpp b/pcbnew/layer_widget.cpp index df23c188e3..84cad5da02 100644 --- a/pcbnew/layer_widget.cpp +++ b/pcbnew/layer_widget.cpp @@ -587,6 +587,15 @@ LAYER_WIDGET::LAYER_WIDGET( wxWindow* aParent, wxWindow* aFocusOwner, int aPoint } +LAYER_WIDGET::~LAYER_WIDGET() +{ + delete m_BlankBitmap; + delete m_BlankAlternateBitmap; + delete m_RightArrowBitmap; + delete m_RightArrowAlternateBitmap; +} + + wxSize LAYER_WIDGET::GetBestSize() const { // size of m_LayerScrolledWindow -------------- diff --git a/pcbnew/layer_widget.h b/pcbnew/layer_widget.h index cfb6bc384f..e788cc4608 100644 --- a/pcbnew/layer_widget.h +++ b/pcbnew/layer_widget.h @@ -227,6 +227,8 @@ public: wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL ); + virtual ~LAYER_WIDGET(); + /** * Function GetBestSize * returns the preferred minimum size, taking into consideration the diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 45267d2e0a..e9c082533b 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -70,6 +70,17 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + #if defined(KICAD_SCRIPTING) || defined(KICAD_SCRIPTING_WXPYTHON) #include // The name of the pane info handling the python console: @@ -469,7 +480,6 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : PCB_EDIT_FRAME::~PCB_EDIT_FRAME() { - destroyTools(); m_RecordingMacros = -1; for( int i = 0; i < 10; i++ ) @@ -524,6 +534,30 @@ bool PCB_EDIT_FRAME::isAutoSaveRequired() const } +void PCB_EDIT_FRAME::setupTools() +{ + // Create the manager and dispatcher & route draw panel events to the dispatcher + m_toolManager = new TOOL_MANAGER; + m_toolManager->SetEnvironment( NULL, GetGalCanvas()->GetView(), + GetGalCanvas()->GetViewControls(), this ); + m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager ); + + // Register tools + m_toolManager->RegisterTool( new SELECTION_TOOL ); + m_toolManager->RegisterTool( new ROUTER_TOOL ); + m_toolManager->RegisterTool( new EDIT_TOOL ); + m_toolManager->RegisterTool( new DRAWING_TOOL ); + m_toolManager->RegisterTool( new POINT_EDITOR ); + m_toolManager->RegisterTool( new PCBNEW_CONTROL ); + m_toolManager->RegisterTool( new PCB_EDITOR_CONTROL ); + m_toolManager->RegisterTool( new PLACEMENT_TOOL ); + m_toolManager->ResetTools( TOOL_BASE::RUN ); + + // Run the selection tool, it is supposed to be always active + m_toolManager->InvokeTool( "pcbnew.InteractiveSelection" ); +} + + void PCB_EDIT_FRAME::ReFillLayerWidget() { m_Layers->ReFill(); diff --git a/pcbnew/router/pns_routing_settings.cpp b/pcbnew/router/pns_routing_settings.cpp index cf87359674..bb67840fbe 100644 --- a/pcbnew/router/pns_routing_settings.cpp +++ b/pcbnew/router/pns_routing_settings.cpp @@ -19,6 +19,7 @@ */ #include "pns_routing_settings.h" +#include "direction.h" PNS_ROUTING_SETTINGS::PNS_ROUTING_SETTINGS() { @@ -39,6 +40,15 @@ PNS_ROUTING_SETTINGS::PNS_ROUTING_SETTINGS() } +const DIRECTION_45 PNS_ROUTING_SETTINGS::InitialDirection() const +{ + if( m_startDiagonal ) + return DIRECTION_45( DIRECTION_45::NE ); + else + return DIRECTION_45( DIRECTION_45::N ); +} + + TIME_LIMIT PNS_ROUTING_SETTINGS::ShoveTimeLimit() const { return TIME_LIMIT ( m_shoveTimeLimit ); diff --git a/pcbnew/router/pns_routing_settings.h b/pcbnew/router/pns_routing_settings.h index 5f6de3fa92..84cfb5bf7e 100644 --- a/pcbnew/router/pns_routing_settings.h +++ b/pcbnew/router/pns_routing_settings.h @@ -21,8 +21,9 @@ #ifndef __PNS_ROUTING_SETTINGS #define __PNS_ROUTING_SETTINGS -#include "direction.h" #include "time_limit.h" + +class DIRECTION_45; ///> Routing modes enum PNS_MODE @@ -118,13 +119,7 @@ public: void SetViaDrill( int aDrill ) { m_viaDrill = aDrill; } int GetViaDrill() const { return m_viaDrill; } - const DIRECTION_45 InitialDirection() const - { - if( m_startDiagonal ) - return DIRECTION_45( DIRECTION_45::NE ); - else - return DIRECTION_45( DIRECTION_45::N ); - } + const DIRECTION_45 InitialDirection() const; int ShoveIterationLimit() const; TIME_LIMIT ShoveTimeLimit() const; diff --git a/pcbnew/router/router_tool.h b/pcbnew/router/router_tool.h index 4ad339f3a5..06dc75b7fe 100644 --- a/pcbnew/router/router_tool.h +++ b/pcbnew/router/router_tool.h @@ -22,18 +22,13 @@ #ifndef __ROUTER_TOOL_H #define __ROUTER_TOOL_H -#include -#include - #include #include #include -#include #include -#include "pns_layerset.h" #include "pns_routing_settings.h" class PNS_ROUTER; diff --git a/pcbnew/tools/pcb_tools.cpp b/pcbnew/tools/pcb_tools.cpp deleted file mode 100644 index 9e604a0b04..0000000000 --- a/pcbnew/tools/pcb_tools.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2013 CERN - * @author Tomasz Wlostowski - * - * 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 -#include - -#include -#include - -#include - -#include "selection_tool.h" -#include "edit_tool.h" -#include "drawing_tool.h" -#include "point_editor.h" -#include "pcbnew_control.h" -#include "pcb_editor_control.h" -#include "placement_tool.h" -#include "common_actions.h" -#include - -void PCB_EDIT_FRAME::setupTools() -{ - // Create the manager and dispatcher & route draw panel events to the dispatcher - m_toolManager = new TOOL_MANAGER; - m_toolManager->SetEnvironment( NULL, GetGalCanvas()->GetView(), - GetGalCanvas()->GetViewControls(), this ); - m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager ); - - // Register tools - m_toolManager->RegisterTool( new SELECTION_TOOL ); - m_toolManager->RegisterTool( new ROUTER_TOOL ); - m_toolManager->RegisterTool( new EDIT_TOOL ); - m_toolManager->RegisterTool( new DRAWING_TOOL ); - m_toolManager->RegisterTool( new POINT_EDITOR ); - m_toolManager->RegisterTool( new PCBNEW_CONTROL ); - m_toolManager->RegisterTool( new PCB_EDITOR_CONTROL ); - m_toolManager->RegisterTool( new PLACEMENT_TOOL ); - m_toolManager->ResetTools( TOOL_BASE::RUN ); - - // Run the selection tool, it is supposed to be always active - m_toolManager->InvokeTool( "pcbnew.InteractiveSelection" ); -} - - -void PCB_EDIT_FRAME::destroyTools() -{ - delete m_toolManager; - delete m_toolDispatcher; -} diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index d0abb1d60a..3ae883ed89 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -54,7 +54,7 @@ SELECTION_TOOL::SELECTION_TOOL() : SelectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.selected" ), DeselectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.deselected" ), ClearedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.cleared" ), - m_additive( false ), m_multiple( false ), m_editModules( false ) + m_frame( NULL ), m_additive( false ), m_multiple( false ), m_editModules( false ) { m_selArea = new SELECTION_AREA; m_selection.group = new KIGFX::VIEW_GROUP; From 7c7ab6f2adb1c4172fb0907bf74ca3ede9dbd1c2 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:02:56 +0200 Subject: [PATCH 075/123] Created dialog_dxf_import.h. Cleaned up some unnecessary stuff and fixed file open dialog DIALOG_DXF_IMPORT. --- pcbnew/import_dxf/dialog_dxf_import.cpp | 46 ++------------------ pcbnew/import_dxf/dialog_dxf_import.h | 58 +++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 42 deletions(-) create mode 100644 pcbnew/import_dxf/dialog_dxf_import.h diff --git a/pcbnew/import_dxf/dialog_dxf_import.cpp b/pcbnew/import_dxf/dialog_dxf_import.cpp index 612fba07c4..5f9ff5acf1 100644 --- a/pcbnew/import_dxf/dialog_dxf_import.cpp +++ b/pcbnew/import_dxf/dialog_dxf_import.cpp @@ -27,12 +27,10 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#include //#include #include -#include -#include #include -#include #include #include @@ -42,43 +40,11 @@ #include #include - // Keys to store setup in config #define DXF_IMPORT_LAYER_OPTION_KEY wxT("DxfImportBrdLayer") #define DXF_IMPORT_COORD_ORIGIN_KEY wxT("DxfImportCoordOrigin") #define DXF_IMPORT_LAST_FILE_KEY wxT("DxfImportLastFile") -class DIALOG_DXF_IMPORT : public DIALOG_DXF_IMPORT_BASE -{ -public: - DIALOG_DXF_IMPORT( PCB_BASE_FRAME* aParent ); - ~DIALOG_DXF_IMPORT(); - - /** - * Function GetImportedItems() - * - * Returns a list of items imported from a DXF file. - */ - const std::list& GetImportedItems() const - { - return m_dxfImporter.GetItemsList(); - } - -private: - PCB_BASE_FRAME* m_parent; - wxConfigBase* m_config; // Current config - DXF2BRD_CONVERTER m_dxfImporter; - - static wxString m_dxfFilename; - static int m_offsetSelection; - static LAYER_NUM m_layer; - - // Virtual event handlers - void OnCancelClick( wxCommandEvent& event ) { event.Skip(); } - void OnOKClick( wxCommandEvent& event ); - void OnBrowseDxfFiles( wxCommandEvent& event ); -}; - // Static members of DIALOG_DXF_IMPORT, to remember // the user's choices during the session wxString DIALOG_DXF_IMPORT::m_dxfFilename; @@ -137,15 +103,17 @@ DIALOG_DXF_IMPORT::~DIALOG_DXF_IMPORT() void DIALOG_DXF_IMPORT::OnBrowseDxfFiles( wxCommandEvent& event ) { wxString path; + wxString filename; if( !m_dxfFilename.IsEmpty() ) { wxFileName fn( m_dxfFilename ); path = fn.GetPath(); + filename = fn.GetFullName(); } wxFileDialog dlg( m_parent, wxT( "Open File" ), - path, m_dxfFilename, + path, filename, wxT( "dxf Files (*.dxf)|*.dxf" ), wxFD_OPEN|wxFD_FILE_MUST_EXIST ); dlg.ShowModal(); @@ -209,14 +177,12 @@ bool InvokeDXFDialogBoardImport( PCB_BASE_FRAME* aCaller ) if( success ) { - // Prepare the undo list const std::list& list = dlg.GetImportedItems(); PICKED_ITEMS_LIST picklist; BOARD* board = aCaller->GetBoard(); KIGFX::VIEW* view = aCaller->GetGalCanvas()->GetView(); - // Build the undo list & add items to the current view std::list::const_iterator it, itEnd; for( it = list.begin(), itEnd = list.end(); it != itEnd; ++it ) { @@ -245,17 +211,13 @@ bool InvokeDXFDialogModuleImport( PCB_BASE_FRAME* aCaller, MODULE* aModule ) if( success ) { - // Prepare the undo list const std::list& list = dlg.GetImportedItems(); - PICKED_ITEMS_LIST picklist; - MODULE* module = aCaller->GetBoard()->m_Modules; KIGFX::VIEW* view = aCaller->GetGalCanvas()->GetView(); aCaller->SaveCopyInUndoList( module, UR_MODEDIT ); aCaller->OnModify(); - // Build the undo list & add items to the current view std::list::const_iterator it, itEnd; for( it = list.begin(), itEnd = list.end(); it != itEnd; ++it ) { diff --git a/pcbnew/import_dxf/dialog_dxf_import.h b/pcbnew/import_dxf/dialog_dxf_import.h new file mode 100644 index 0000000000..2785732841 --- /dev/null +++ b/pcbnew/import_dxf/dialog_dxf_import.h @@ -0,0 +1,58 @@ +/* + * 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 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 +#include +#include + +class DIALOG_DXF_IMPORT : public DIALOG_DXF_IMPORT_BASE +{ +public: + DIALOG_DXF_IMPORT( PCB_BASE_FRAME* aParent ); + ~DIALOG_DXF_IMPORT(); + + /** + * Function GetImportedItems() + * + * Returns a list of items imported from a DXF file. + */ + const std::list& GetImportedItems() const + { + return m_dxfImporter.GetItemsList(); + } + +private: + PCB_BASE_FRAME* m_parent; + wxConfigBase* m_config; // Current config + DXF2BRD_CONVERTER m_dxfImporter; + + static wxString m_dxfFilename; + static int m_offsetSelection; + static LAYER_NUM m_layer; + + // Virtual event handlers + void OnCancelClick( wxCommandEvent& event ) { event.Skip(); } + void OnOKClick( wxCommandEvent& event ); + void OnBrowseDxfFiles( wxCommandEvent& event ); +}; From 422be4badb8755e58af7d1034e9a8980c95e19f7 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:02:56 +0200 Subject: [PATCH 076/123] DXF drawing placement tool for GAL. --- pcbnew/tools/common_actions.cpp | 7 ++ pcbnew/tools/common_actions.h | 3 + pcbnew/tools/drawing_tool.cpp | 192 ++++++++++++++++++++++++++++++++ pcbnew/tools/drawing_tool.h | 8 +- 4 files changed, 209 insertions(+), 1 deletion(-) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index a1b6966a06..e8ac80fcef 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -109,6 +109,10 @@ TOOL_ACTION COMMON_ACTIONS::placePad( "pcbnew.InteractiveDrawing.placePad", AS_GLOBAL, 0, "Add pads", "Add pads", AF_ACTIVATE ); +TOOL_ACTION COMMON_ACTIONS::placeDXF( "pcbnew.InteractiveDrawing.placeDXF", + AS_GLOBAL, 0, + "", "", AF_ACTIVATE ); + TOOL_ACTION COMMON_ACTIONS::setAnchor( "pcbnew.InteractiveDrawing.setAnchor", AS_GLOBAL, 0, "Place the footprint anchor", "Place the footprint anchor", @@ -358,6 +362,9 @@ boost::optional COMMON_ACTIONS::TranslateLegacyId( int aId ) case ID_MODEDIT_PAD_TOOL: return COMMON_ACTIONS::placePad.MakeEvent(); + case ID_GEN_IMPORT_DXF_FILE: + return COMMON_ACTIONS::placeDXF.MakeEvent(); + case ID_MODEDIT_ANCHOR_TOOL: return COMMON_ACTIONS::setAnchor.MakeEvent(); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 2cd367c05d..2abaf054bd 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -99,6 +99,9 @@ public: /// Activation of the drawing tool (placing a PAD) static TOOL_ACTION placePad; + /// Activation of the drawing tool (placing a drawing from DXF file) + static TOOL_ACTION placeDXF; + /// Activation of the drawing tool (placing the footprint anchor) static TOOL_ACTION setAnchor; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index d3da87ce44..dda1d36b6e 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -700,6 +701,196 @@ int DRAWING_TOOL::PlacePad( TOOL_EVENT& aEvent ) } +int DRAWING_TOOL::PlaceDXF( TOOL_EVENT& aEvent ) +{ + DIALOG_DXF_IMPORT dlg( m_frame ); + int dlgResult = dlg.ShowModal(); + + const std::list& list = dlg.GetImportedItems(); + MODULE* module = m_board->m_Modules; + + if( dlgResult != wxID_OK || module == NULL || list.empty() ) + { + setTransitions(); + + return 0; + } + + VECTOR2I cursorPos = m_controls->GetCursorPosition(); + VECTOR2I delta = cursorPos - (*list.begin())->GetPosition(); + + // Add a VIEW_GROUP that serves as a preview for the new item + KIGFX::VIEW_GROUP preview( m_view ); + + // Build the undo list & add items to the current view + std::list::const_iterator it, itEnd; + for( it = list.begin(), itEnd = list.end(); it != itEnd; ++it ) + { + BOARD_ITEM* item = *it; + BOARD_ITEM* converted = NULL; + + // Modules use different types for the same things, + // so we need to convert imported items to appropriate classes. + switch( item->Type() ) + { + case PCB_LINE_T: + { + if( m_editModules ) + { + converted = new EDGE_MODULE( module ); + *static_cast( converted ) = *static_cast( item ); + converted->Move( wxPoint( delta.x, delta.y ) ); + preview.Add( converted ); + delete item; + } + else + { + preview.Add( item ); + } + + break; + } + + case PCB_TEXT_T: + { + if( m_editModules ) + { + converted = new TEXTE_MODULE( module ); + *static_cast( converted ) = *static_cast( item ); + converted->Move( wxPoint( delta.x, delta.y ) ); + preview.Add( converted ); + delete item; + } + else + { + preview.Add( item ); + } + break; + } + + default: + assert( false ); // there is a type that is currently not handled here + break; + } + } + + BOARD_ITEM* firstItem = static_cast( *preview.Begin() ); + m_view->Add( &preview ); + + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_controls->ShowCursor( true ); + m_controls->SetSnapping( true ); + + Activate(); + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + cursorPos = m_controls->GetCursorPosition(); + + if( evt->IsMotion() ) + { + delta = cursorPos - firstItem->GetPosition(); + + for( KIGFX::VIEW_GROUP::iter it = preview.Begin(), end = preview.End(); it != end; ++it ) + static_cast( *it )->Move( wxPoint( delta.x, delta.y ) ); + + preview.ViewUpdate(); + } + + else if( evt->Category() == TC_COMMAND ) + { + if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) + { + for( KIGFX::VIEW_GROUP::iter it = preview.Begin(), end = preview.End(); it != end; ++it ) + static_cast( *it )->Rotate( wxPoint( cursorPos.x, cursorPos.y ), + m_frame->GetRotationAngle() ); + + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) + { + for( KIGFX::VIEW_GROUP::iter it = preview.Begin(), end = preview.End(); it != end; ++it ) + static_cast( *it )->Flip( wxPoint( cursorPos.x, cursorPos.y ) ); + + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else if( evt->IsCancel() || evt->IsActivate() ) + { + preview.FreeItems(); + break; + } + } + + else if( evt->IsClick( BUT_LEFT ) ) + { + // Place the drawing + + if( m_editModules ) + { + m_frame->SaveCopyInUndoList( module, UR_MODEDIT ); + module->SetLastEditTime(); + + for( KIGFX::VIEW_GROUP::iter it = preview.Begin(), end = preview.End(); it != end; ++it ) + { + BOARD_ITEM* item = static_cast( *it ); + module->Add( item ); + + switch( item->Type() ) + { + case PCB_MODULE_TEXT_T: + static_cast( item )->SetLocalCoord(); + break; + + case PCB_MODULE_EDGE_T: + static_cast( item )->SetLocalCoord(); + break; + + default: + assert( false ); + break; + } + + m_view->Add( item ); + } + } + else + { + PICKED_ITEMS_LIST picklist; + + for( KIGFX::VIEW_GROUP::iter it = preview.Begin(), end = preview.End(); it != end; ++it ) + { + BOARD_ITEM* item = static_cast( *it ); + m_board->Add( item ); + + ITEM_PICKER itemWrapper( item, UR_NEW ); + picklist.PushItem( itemWrapper ); + + m_view->Add( item ); + } + + m_frame->SaveCopyInUndoList( picklist, UR_NEW ); + } + + m_frame->OnModify(); + + break; + } + } + + preview.Clear(); + + m_controls->ShowCursor( false ); + m_controls->SetSnapping( false ); + m_controls->SetAutoPan( false ); + m_view->Remove( &preview ); + + setTransitions(); + + return 0; +} + + int DRAWING_TOOL::SetAnchor( TOOL_EVENT& aEvent ) { assert( m_editModules ); @@ -1580,5 +1771,6 @@ void DRAWING_TOOL::setTransitions() Go( &DRAWING_TOOL::PlaceTarget, COMMON_ACTIONS::placeTarget.MakeEvent() ); Go( &DRAWING_TOOL::PlaceModule, COMMON_ACTIONS::placeModule.MakeEvent() ); Go( &DRAWING_TOOL::PlacePad, COMMON_ACTIONS::placePad.MakeEvent() ); + Go( &DRAWING_TOOL::PlaceDXF, COMMON_ACTIONS::placeDXF.MakeEvent() ); Go( &DRAWING_TOOL::SetAnchor, COMMON_ACTIONS::setAnchor.MakeEvent() ); } diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index 293674a81f..b1bc2675b3 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -122,10 +122,16 @@ public: /** * Function PlacePad() - * Places a pad in the module editor. + * Places a pad in module editor. */ int PlacePad( TOOL_EVENT& aEvent ); + /** + * Function PlaceDXF() + * Places a drawing imported from a DXF file in module editor. + */ + int PlaceDXF( TOOL_EVENT& aEvent ); + /** * Function SetAnchor() * Places the footprint anchor (only in module editor). From 7091e285e6aaff097da9e0ed50d2d81cbd0eb780 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:02:56 +0200 Subject: [PATCH 077/123] Added support for module edge splitting with double click. --- pcbnew/tools/point_editor.cpp | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 64ad775a06..14e66424e3 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -40,6 +40,7 @@ #include #include #include +#include // Few constants to avoid using bare numbers for point indices enum SEG_POINTS @@ -710,8 +711,14 @@ void POINT_EDITOR::breakOutline( const VECTOR2I& aBreakPoint ) else if( item->Type() == PCB_LINE_T || item->Type() == PCB_MODULE_EDGE_T ) { + bool moduleEdge = item->Type() == PCB_MODULE_EDGE_T; + getEditFrame()->OnModify(); - getEditFrame()->SaveCopyInUndoList( selection.items, UR_CHANGED ); + + if( moduleEdge ) + getEditFrame()->SaveCopyInUndoList( getModel()->m_Modules, UR_MODEDIT ); + else + getEditFrame()->SaveCopyInUndoList( selection.items, UR_CHANGED ); DRAWSEGMENT* segment = static_cast( item ); @@ -724,12 +731,34 @@ void POINT_EDITOR::breakOutline( const VECTOR2I& aBreakPoint ) segment->SetEnd( wxPoint( nearestPoint.x, nearestPoint.y ) ); // and add another one starting from the break point - DRAWSEGMENT* newSegment = new DRAWSEGMENT( *segment ); + DRAWSEGMENT* newSegment; + + if( moduleEdge ) + { + EDGE_MODULE* edge = static_cast( segment ); + assert( segment->GetParent()->Type() == PCB_MODULE_T ); + newSegment = new EDGE_MODULE( *edge ); + edge->SetLocalCoord(); + } + else + { + newSegment = new DRAWSEGMENT( *segment ); + } + newSegment->ClearSelected(); newSegment->SetStart( wxPoint( nearestPoint.x, nearestPoint.y ) ); newSegment->SetEnd( wxPoint( seg.B.x, seg.B.y ) ); - getModel()->Add( newSegment ); + if( moduleEdge ) + { + static_cast( newSegment )->SetLocalCoord(); + getModel()->m_Modules->Add( newSegment ); + } + else + { + getModel()->Add( newSegment ); + } + getView()->Add( newSegment ); } } From 55a08a0bda2e58ff0a18373c6fbd442cbd5120f3 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:02:56 +0200 Subject: [PATCH 078/123] Changes in display options are handled by PCBNEW_CONTROL (GAL). --- pcbnew/dialogs/dialog_general_options.cpp | 33 ----------- pcbnew/tools/common_actions.cpp | 35 +++++++++++ pcbnew/tools/common_actions.h | 3 + pcbnew/tools/pcbnew_control.cpp | 71 ++++++++++++++++++++--- pcbnew/tools/pcbnew_control.h | 1 + 5 files changed, 101 insertions(+), 42 deletions(-) diff --git a/pcbnew/dialogs/dialog_general_options.cpp b/pcbnew/dialogs/dialog_general_options.cpp index 9004aecf26..696859b820 100644 --- a/pcbnew/dialogs/dialog_general_options.cpp +++ b/pcbnew/dialogs/dialog_general_options.cpp @@ -154,11 +154,6 @@ void PCB_EDIT_FRAME::OnSelectOptionToolbar( wxCommandEvent& event ) { int id = event.GetId(); bool state = event.IsChecked(); - KIGFX::PCB_PAINTER* painter = - static_cast ( GetGalCanvas()->GetView()->GetPainter() ); - KIGFX::PCB_RENDER_SETTINGS* settings = - static_cast ( painter->GetSettings() ); - KICAD_T updateType = EOT; switch( id ) { @@ -193,44 +188,33 @@ void PCB_EDIT_FRAME::OnSelectOptionToolbar( wxCommandEvent& event ) case ID_TB_OPTIONS_SHOW_ZONES: DisplayOpt.DisplayZonesMode = 0; - updateType = PCB_ZONE_AREA_T; m_canvas->Refresh(); break; case ID_TB_OPTIONS_SHOW_ZONES_DISABLE: DisplayOpt.DisplayZonesMode = 1; - updateType = PCB_ZONE_AREA_T; m_canvas->Refresh(); break; case ID_TB_OPTIONS_SHOW_ZONES_OUTLINES_ONLY: DisplayOpt.DisplayZonesMode = 2; - updateType = PCB_ZONE_AREA_T; m_canvas->Refresh(); break; case ID_TB_OPTIONS_SHOW_VIAS_SKETCH: m_DisplayViaFill = DisplayOpt.DisplayViaFill = !state; - updateType = PCB_VIA_T; m_canvas->Refresh(); break; case ID_TB_OPTIONS_SHOW_TRACKS_SKETCH: m_DisplayPcbTrackFill = DisplayOpt.DisplayPcbTrackFill = !state; - updateType = PCB_TRACE_T; m_canvas->Refresh(); break; case ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE: { DisplayOpt.ContrastModeDisplay = state; - - // Apply new display options to the GAL canvas (this is faster than recaching) - settings->LoadDisplayOptions( DisplayOpt ); - - GetGalCanvas()->SetHighContrastLayer( GetActiveLayer() ); m_canvas->Refresh(); - break; } @@ -260,21 +244,4 @@ void PCB_EDIT_FRAME::OnSelectOptionToolbar( wxCommandEvent& event ) wxT( "PCB_EDIT_FRAME::OnSelectOptionToolbar error \n (event not handled!)" ) ); break; } - - if( updateType != EOT ) - { - // Apply new display options to the GAL canvas - settings->LoadDisplayOptions( DisplayOpt ); - - // Find items that require update - KICAD_T scanList[] = { updateType, EOT }; - TYPE_COLLECTOR collector; - collector.Collect( GetBoard(), scanList ); - - for( int i = 0; i < collector.GetCount(); ++i ) - collector[i]->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - - if( IsGalCanvasActive() ) - GetGalCanvas()->Refresh(); } diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index e8ac80fcef..38190b8ea6 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -157,6 +157,18 @@ TOOL_ACTION COMMON_ACTIONS::viaDisplayMode( "pcbnew.Control.viaDisplayMode", AS_GLOBAL, 'L', // TODO temporarily, find a better hot key "", "" ); +TOOL_ACTION COMMON_ACTIONS::zoneDisplayEnable( "pcbnew.Control.zoneDisplayEnable", + AS_GLOBAL, 0, + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::zoneDisplayDisable( "pcbnew.Control.zoneDisplayDisable", + AS_GLOBAL, 0, + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::zoneDisplayOutlines( "pcbnew.Control.zoneDisplayOutlines", + AS_GLOBAL, 0, + "", "" ); + TOOL_ACTION COMMON_ACTIONS::highContrastMode( "pcbnew.Control.highContrastMode", AS_GLOBAL, 'H', "", "" ); @@ -381,6 +393,29 @@ boost::optional COMMON_ACTIONS::TranslateLegacyId( int aId ) case ID_ZOOM_PAGE: // toolbar button "Fit on Screen" return COMMON_ACTIONS::zoomFitScreen.MakeEvent(); + case ID_TB_OPTIONS_SHOW_TRACKS_SKETCH: + return COMMON_ACTIONS::trackDisplayMode.MakeEvent(); + + case ID_TB_OPTIONS_SHOW_PADS_SKETCH: + return COMMON_ACTIONS::padDisplayMode.MakeEvent(); + + case ID_TB_OPTIONS_SHOW_VIAS_SKETCH: + return COMMON_ACTIONS::viaDisplayMode.MakeEvent(); + + case ID_TB_OPTIONS_SHOW_ZONES: + return COMMON_ACTIONS::zoneDisplayEnable.MakeEvent(); + + case ID_TB_OPTIONS_SHOW_ZONES_DISABLE: + return COMMON_ACTIONS::zoneDisplayDisable.MakeEvent(); + + case ID_TB_OPTIONS_SHOW_ZONES_OUTLINES_ONLY: + return COMMON_ACTIONS::zoneDisplayOutlines.MakeEvent(); + + case ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE: + return COMMON_ACTIONS::highContrastMode.MakeEvent(); + + case ID_TB_OPTIONS_SHOW_MODULE_EDGE_SKETCH: + case ID_TB_OPTIONS_SHOW_MODULE_TEXT_SKETCH: case ID_PCB_DELETE_ITEM_BUTT: case ID_PCB_HIGHLIGHT_BUTT: case ID_PCB_SHOW_1_RATSNEST_BUTT: diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 2abaf054bd..c5b32dbc70 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -144,6 +144,9 @@ public: static TOOL_ACTION trackDisplayMode; static TOOL_ACTION padDisplayMode; static TOOL_ACTION viaDisplayMode; + static TOOL_ACTION zoneDisplayEnable; + static TOOL_ACTION zoneDisplayDisable; + static TOOL_ACTION zoneDisplayOutlines; static TOOL_ACTION highContrastMode; static TOOL_ACTION highContrastInc; static TOOL_ACTION highContrastDec; diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index 3a46cbacff..3eba7f495b 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -28,7 +28,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -129,17 +131,20 @@ int PCBNEW_CONTROL::TrackDisplayMode( TOOL_EVENT& aEvent ) KIGFX::PCB_PAINTER* painter = static_cast( m_frame->GetGalCanvas()->GetView()->GetPainter() ); KIGFX::PCB_RENDER_SETTINGS* settings = - static_cast ( painter->GetSettings() ); + static_cast( painter->GetSettings() ); // Apply new display options to the GAL canvas DisplayOpt.DisplayPcbTrackFill = !DisplayOpt.DisplayPcbTrackFill; m_frame->m_DisplayPcbTrackFill = DisplayOpt.DisplayPcbTrackFill; settings->LoadDisplayOptions( DisplayOpt ); - BOARD* board = getModel(); - for( TRACK* track = board->m_Track; track; track = track->Next() ) - track->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + for( TRACK* track = getModel()->m_Track; track; track = track->Next() ) + { + if( track->Type() == PCB_TRACE_T ) + track->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + m_frame->GetGalCanvas()->Refresh(); setTransitions(); return 0; @@ -148,8 +153,23 @@ int PCBNEW_CONTROL::TrackDisplayMode( TOOL_EVENT& aEvent ) int PCBNEW_CONTROL::PadDisplayMode( TOOL_EVENT& aEvent ) { - wxCommandEvent dummy; - m_frame->OnTogglePadDrawMode( dummy ); + KIGFX::PCB_PAINTER* painter = + static_cast( m_frame->GetGalCanvas()->GetView()->GetPainter() ); + KIGFX::PCB_RENDER_SETTINGS* settings = + static_cast( painter->GetSettings() ); + + // Apply new display options to the GAL canvas + DisplayOpt.DisplayPadFill = !DisplayOpt.DisplayPadFill; + m_frame->m_DisplayPadFill = DisplayOpt.DisplayPadFill; + settings->LoadDisplayOptions( DisplayOpt ); + + for( MODULE* module = getModel()->m_Modules; module; module = module->Next() ) + { + for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) + pad->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + + m_frame->GetGalCanvas()->Refresh(); setTransitions(); return 0; @@ -161,20 +181,50 @@ int PCBNEW_CONTROL::ViaDisplayMode( TOOL_EVENT& aEvent ) KIGFX::PCB_PAINTER* painter = static_cast( m_frame->GetGalCanvas()->GetView()->GetPainter() ); KIGFX::PCB_RENDER_SETTINGS* settings = - static_cast ( painter->GetSettings() ); + static_cast( painter->GetSettings() ); // Apply new display options to the GAL canvas DisplayOpt.DisplayViaFill = !DisplayOpt.DisplayViaFill; m_frame->m_DisplayViaFill = DisplayOpt.DisplayViaFill; settings->LoadDisplayOptions( DisplayOpt ); - BOARD* board = getModel(); - for( TRACK* track = board->m_Track; track; track = track->Next() ) + for( TRACK* track = getModel()->m_Track; track; track = track->Next() ) { if( track->Type() == PCB_VIA_T ) track->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } + m_frame->GetGalCanvas()->Refresh(); + setTransitions(); + + return 0; +} + + +int PCBNEW_CONTROL::ZoneDisplayMode( TOOL_EVENT& aEvent ) +{ + KIGFX::PCB_PAINTER* painter = + static_cast( m_frame->GetGalCanvas()->GetView()->GetPainter() ); + KIGFX::PCB_RENDER_SETTINGS* settings = + static_cast( painter->GetSettings() ); + + // Apply new display options to the GAL canvas + if( aEvent.IsAction( &COMMON_ACTIONS::zoneDisplayEnable ) ) + DisplayOpt.DisplayZonesMode = 0; + else if( aEvent.IsAction( &COMMON_ACTIONS::zoneDisplayDisable ) ) + DisplayOpt.DisplayZonesMode = 1; + else if( aEvent.IsAction( &COMMON_ACTIONS::zoneDisplayOutlines ) ) + DisplayOpt.DisplayZonesMode = 2; + else + assert( false ); + + settings->LoadDisplayOptions( DisplayOpt ); + + BOARD* board = getModel(); + for( int i = 0; i < board->GetAreaCount(); ++i ) + board->GetArea( i )->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + + m_frame->GetGalCanvas()->Refresh(); setTransitions(); return 0; @@ -529,6 +579,9 @@ void PCBNEW_CONTROL::setTransitions() Go( &PCBNEW_CONTROL::TrackDisplayMode, COMMON_ACTIONS::trackDisplayMode.MakeEvent() ); Go( &PCBNEW_CONTROL::PadDisplayMode, COMMON_ACTIONS::padDisplayMode.MakeEvent() ); Go( &PCBNEW_CONTROL::ViaDisplayMode, COMMON_ACTIONS::viaDisplayMode.MakeEvent() ); + Go( &PCBNEW_CONTROL::ZoneDisplayMode, COMMON_ACTIONS::zoneDisplayEnable.MakeEvent() ); + Go( &PCBNEW_CONTROL::ZoneDisplayMode, COMMON_ACTIONS::zoneDisplayDisable.MakeEvent() ); + Go( &PCBNEW_CONTROL::ZoneDisplayMode, COMMON_ACTIONS::zoneDisplayOutlines.MakeEvent() ); Go( &PCBNEW_CONTROL::HighContrastMode, COMMON_ACTIONS::highContrastMode.MakeEvent() ); Go( &PCBNEW_CONTROL::HighContrastInc, COMMON_ACTIONS::highContrastInc.MakeEvent() ); Go( &PCBNEW_CONTROL::HighContrastDec, COMMON_ACTIONS::highContrastDec.MakeEvent() ); diff --git a/pcbnew/tools/pcbnew_control.h b/pcbnew/tools/pcbnew_control.h index 62c7a9c7cd..61f7d5d511 100644 --- a/pcbnew/tools/pcbnew_control.h +++ b/pcbnew/tools/pcbnew_control.h @@ -56,6 +56,7 @@ public: int TrackDisplayMode( TOOL_EVENT& aEvent ); int PadDisplayMode( TOOL_EVENT& aEvent ); int ViaDisplayMode( TOOL_EVENT& aEvent ); + int ZoneDisplayMode( TOOL_EVENT& aEvent ); int HighContrastMode( TOOL_EVENT& aEvent ); int HighContrastInc( TOOL_EVENT& aEvent ); int HighContrastDec( TOOL_EVENT& aEvent ); From 35c31a3fb51130e50857487ab8cea8ee7c5cb954 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:02:56 +0200 Subject: [PATCH 079/123] Fixed grid drawing when the grid origin has negative coordinates. --- common/gal/graphics_abstraction_layer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/common/gal/graphics_abstraction_layer.cpp b/common/gal/graphics_abstraction_layer.cpp index 00e976b19a..d21b12b783 100644 --- a/common/gal/graphics_abstraction_layer.cpp +++ b/common/gal/graphics_abstraction_layer.cpp @@ -157,10 +157,10 @@ void GAL::DrawGrid() assert( gridEndY >= gridStartY ); // Correct the index, else some lines are not correctly painted - gridStartX -= ( gridOrigin.x / gridSize.x ) + 1; - gridStartY -= ( gridOrigin.y / gridSize.y ) + 1; - gridEndX += ( gridOrigin.x / gridSize.x ) + 1; - gridEndY += ( gridOrigin.y / gridSize.y ) + 1; + gridStartX -= abs( gridOrigin.x / gridSize.x ) + 1; + gridStartY -= abs( gridOrigin.y / gridSize.y ) + 1; + gridEndX += abs( gridOrigin.x / gridSize.x ) + 1; + gridEndY += abs( gridOrigin.y / gridSize.y ) + 1; // Draw the grid behind all other layers SetLayerDepth( depthRange.y * 0.75 ); From 31f6420197f390029837ca6547554d058c116e49 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:02:56 +0200 Subject: [PATCH 080/123] Renamed "Placement" context menu to "Align/distribute". --- pcbnew/tools/placement_tool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcbnew/tools/placement_tool.cpp b/pcbnew/tools/placement_tool.cpp index 5305d855ee..4956c51c45 100644 --- a/pcbnew/tools/placement_tool.cpp +++ b/pcbnew/tools/placement_tool.cpp @@ -63,7 +63,7 @@ bool PLACEMENT_TOOL::Init() menu->AppendSeparator(); menu->Add( COMMON_ACTIONS::distributeHorizontally ); menu->Add( COMMON_ACTIONS::distributeVertically ); - m_selectionTool->AddSubMenu( menu, wxString( "Placement" ) ); + m_selectionTool->AddSubMenu( menu, wxString( "Align/distribute" ) ); setTransitions(); From 66bbbec39405a79eecd634376985d2c73510d14c Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:02:56 +0200 Subject: [PATCH 081/123] Module anchors are visible in GAL canvas. --- pcbnew/class_module.cpp | 15 +++++++++++++++ pcbnew/class_module.h | 6 ++++++ pcbnew/pcb_draw_panel_gal.cpp | 4 +++- pcbnew/pcb_painter.cpp | 26 ++++++++++++++++++++++++-- pcbnew/pcb_painter.h | 1 + 5 files changed, 49 insertions(+), 3 deletions(-) diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index 6080fa0d98..4488598fd1 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -830,6 +830,21 @@ void MODULE::ViewUpdate( int aUpdateFlags ) } +void MODULE::ViewGetLayers( int aLayers[], int& aCount ) const +{ + aCount = 1; + aLayers[0] = ITEM_GAL_LAYER( ANCHOR_VISIBLE ); +} + + +unsigned int MODULE::ViewGetLOD( int aLayer ) const +{ + // Currently there is only one layer, so there is nothing to check +// if( aLayer == ITEM_GAL_LAYER( ANCHOR_VISIBLE ) ) + return 30; +} + + /* Test for validity of the name in a library of the footprint * ( no spaces, dir separators ... ) * return true if the given name is valid diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h index d1496f2425..b1309d758d 100644 --- a/pcbnew/class_module.h +++ b/pcbnew/class_module.h @@ -483,6 +483,12 @@ public: /// @copydoc VIEW_ITEM::ViewUpdate() void ViewUpdate( int aUpdateFlags = KIGFX::VIEW_ITEM::ALL ); + /// @copydoc VIEW_ITEM::ViewGetLayers() + virtual void ViewGetLayers( int aLayers[], int& aCount ) const; + + /// @copydoc VIEW_ITEM::ViewGetLOD() + virtual unsigned int ViewGetLOD( int aLayer ) const; + /** * Function CopyNetlistSettings * copies the netlist settings to \a aModule. diff --git a/pcbnew/pcb_draw_panel_gal.cpp b/pcbnew/pcb_draw_panel_gal.cpp index 12965f3e03..1aed5a86bd 100644 --- a/pcbnew/pcb_draw_panel_gal.cpp +++ b/pcbnew/pcb_draw_panel_gal.cpp @@ -47,7 +47,7 @@ const LAYER_NUM GAL_LAYER_ORDER[] = ITEM_GAL_LAYER( MOD_TEXT_FR_VISIBLE ), ITEM_GAL_LAYER( MOD_REFERENCES_VISIBLE), ITEM_GAL_LAYER( MOD_VALUES_VISIBLE ), - ITEM_GAL_LAYER( RATSNEST_VISIBLE ), + ITEM_GAL_LAYER( RATSNEST_VISIBLE ), ITEM_GAL_LAYER( ANCHOR_VISIBLE ), ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ), @@ -141,6 +141,8 @@ EDA_DRAW_PANEL_GAL( aParentWindow, aWindowId, aPosition, aSize, aGalType ) } } + m_view->SetLayerTarget( ITEM_GAL_LAYER( ANCHOR_VISIBLE ), KIGFX::TARGET_NONCACHED ); + // Some more required layers settings m_view->SetRequired( ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ) ); m_view->SetRequired( ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ) ); diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 9a9ac26e31..6d42a29d64 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -79,6 +79,7 @@ void PCB_RENDER_SETTINGS::ImportLegacyColors( const COLORS_DESIGN_SETTINGS* aSet m_layerColors[NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE )] = COLOR4D( 1.0, 1.0, 1.0, 0.9 ); m_layerColors[NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE )] = COLOR4D( 1.0, 1.0, 1.0, 0.9 ); m_layerColors[NETNAMES_GAL_LAYER( PAD_BK_NETNAMES_VISIBLE )] = COLOR4D( 1.0, 1.0, 1.0, 0.9 ); + m_layerColors[ITEM_GAL_LAYER( ANCHOR_VISIBLE )] = COLOR4D( 0.3, 0.3, 1.0, 0.9 ); m_layerColors[ITEM_GAL_LAYER( RATSNEST_VISIBLE )] = COLOR4D( 0.4, 0.4, 0.4, 0.8 ); m_layerColors[ITEM_GAL_LAYER( WORKSHEET )] = COLOR4D( 0.5, 0.0, 0.0, 0.8 ); m_layerColors[ITEM_GAL_LAYER( DRC_VISIBLE )] = COLOR4D( 1.0, 0.0, 0.0, 0.8 ); @@ -233,6 +234,10 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer ) draw( (TEXTE_MODULE*) item, aLayer ); break; + case PCB_MODULE_T: + draw( (MODULE*) item ); + break; + case PCB_ZONE_AREA_T: draw( (ZONE_CONTAINER*) item ); break; @@ -284,7 +289,7 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer ) // Set a proper color for the label const COLOR4D& color = m_pcbSettings.GetColor( aTrack, aTrack->GetLayer() ); - COLOR4D labelColor = m_pcbSettings.GetColor( NULL, aLayer ); + const COLOR4D labelColor = m_pcbSettings.GetColor( NULL, aLayer ); if( color.GetBrightness() > 0.5 ) m_gal->SetStrokeColor( labelColor.Inverted() ); @@ -421,7 +426,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer ) // Set a proper color for the label const COLOR4D& color = m_pcbSettings.GetColor( aPad, aPad->GetLayer() ); - COLOR4D labelColor = m_pcbSettings.GetColor( NULL, aLayer ); + const COLOR4D labelColor = m_pcbSettings.GetColor( NULL, aLayer ); if( color.GetBrightness() > 0.5 ) m_gal->SetStrokeColor( labelColor.Inverted() ); @@ -726,6 +731,23 @@ void PCB_PAINTER::draw( const TEXTE_MODULE* aText, int aLayer ) } +void PCB_PAINTER::draw( const MODULE* aModule ) +{ + const COLOR4D color = m_pcbSettings.GetColor( aModule, ITEM_GAL_LAYER( ANCHOR_VISIBLE ) ); + + // Draw anchor + m_gal->SetStrokeColor( color ); + m_gal->SetLineWidth( 1.0 ); + + // Keep the size constant, not related to the scale + double anchorSize = 5.0 / m_gal->GetWorldScale(); + + VECTOR2D center = aModule->GetPosition(); + m_gal->DrawLine( center - VECTOR2D( anchorSize, 0 ), center + VECTOR2D( anchorSize, 0 ) ); + m_gal->DrawLine( center - VECTOR2D( 0, anchorSize ), center + VECTOR2D( 0, anchorSize ) ); +} + + void PCB_PAINTER::draw( const ZONE_CONTAINER* aZone ) { const COLOR4D& color = m_pcbSettings.GetColor( aZone, aZone->GetLayer() ); diff --git a/pcbnew/pcb_painter.h b/pcbnew/pcb_painter.h index 46e7bb7da3..93bcb034f7 100644 --- a/pcbnew/pcb_painter.h +++ b/pcbnew/pcb_painter.h @@ -213,6 +213,7 @@ protected: void draw( const DRAWSEGMENT* aSegment ); void draw( const TEXTE_PCB* aText, int aLayer ); void draw( const TEXTE_MODULE* aText, int aLayer ); + void draw( const MODULE* aModule ); void draw( const ZONE_CONTAINER* aZone ); void draw( const DIMENSION* aDimension, int aLayer ); void draw( const PCB_TARGET* aTarget ); From 7fc5a9bc60887cc139925ea740d6260b16634f8f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:02:56 +0200 Subject: [PATCH 082/123] Fixed anchor placement tool in module editor (GAL). --- pcbnew/tools/drawing_tool.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index dda1d36b6e..54d9c8e691 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -917,6 +917,8 @@ int DRAWING_TOOL::SetAnchor( TOOL_EVENT& aEvent ) wxPoint moveVector = module->GetPosition() - wxPoint( cursorPos.x, cursorPos.y ); module->MoveAnchorPosition( moveVector ); + module->ViewUpdate(); + // Usually, we do not need to change twice the anchor position, // so deselect the active tool break; From 417dc0a9dc898adda94fb2965a757387a2d04a07 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:02:56 +0200 Subject: [PATCH 083/123] Drawing tools used to crash when the drawing tool was interrupted - fixed. --- pcbnew/tools/drawing_tool.cpp | 81 ++++++++++++++++++++++------------- pcbnew/tools/drawing_tool.h | 4 +- 2 files changed, 53 insertions(+), 32 deletions(-) diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 54d9c8e691..061fb41008 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -83,13 +83,16 @@ int DRAWING_TOOL::DrawLine( TOOL_EVENT& aEvent ) MODULE* module = m_board->m_Modules; EDGE_MODULE* line = new EDGE_MODULE( module ); - while( drawSegment( S_SEGMENT, line ) ) + while( drawSegment( S_SEGMENT, reinterpret_cast( line ) ) ) { - m_frame->OnModify(); - m_frame->SaveCopyInUndoList( module, UR_MODEDIT ); - line->SetLocalCoord(); - line->SetParent( module ); - module->GraphicalItems().PushFront( line ); + if( line ) + { + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( module, UR_MODEDIT ); + line->SetLocalCoord(); + line->SetParent( module ); + module->GraphicalItems().PushFront( line ); + } line = new EDGE_MODULE( module ); } @@ -102,9 +105,12 @@ int DRAWING_TOOL::DrawLine( TOOL_EVENT& aEvent ) while( drawSegment( S_SEGMENT, line ) ) { - m_board->Add( line ); - m_frame->OnModify(); - m_frame->SaveCopyInUndoList( line, UR_NEW ); + if( line ) + { + m_board->Add( line ); + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( line, UR_NEW ); + } line = new DRAWSEGMENT; } @@ -126,13 +132,16 @@ int DRAWING_TOOL::DrawCircle( TOOL_EVENT& aEvent ) MODULE* module = m_board->m_Modules; EDGE_MODULE* circle = new EDGE_MODULE( module ); - while( drawSegment( S_CIRCLE, circle ) ) + while( drawSegment( S_CIRCLE, reinterpret_cast( circle ) ) ) { - m_frame->OnModify(); - m_frame->SaveCopyInUndoList( module, UR_MODEDIT ); - circle->SetLocalCoord(); - circle->SetParent( module ); - module->GraphicalItems().PushFront( circle ); + if( circle ) + { + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( module, UR_MODEDIT ); + circle->SetLocalCoord(); + circle->SetParent( module ); + module->GraphicalItems().PushFront( circle ); + } circle = new EDGE_MODULE( module ); } @@ -145,9 +154,12 @@ int DRAWING_TOOL::DrawCircle( TOOL_EVENT& aEvent ) while( drawSegment( S_CIRCLE, circle ) ) { - m_board->Add( circle ); - m_frame->OnModify(); - m_frame->SaveCopyInUndoList( circle, UR_NEW ); + if( circle ) + { + m_board->Add( circle ); + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( circle, UR_NEW ); + } circle = new DRAWSEGMENT; } @@ -169,13 +181,16 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) MODULE* module = m_board->m_Modules; EDGE_MODULE* arc = new EDGE_MODULE( module ); - while( drawArc( arc ) ) + while( drawArc( reinterpret_cast( arc ) ) ) { - m_frame->OnModify(); - m_frame->SaveCopyInUndoList( module, UR_MODEDIT ); - arc->SetLocalCoord(); - arc->SetParent( module ); - module->GraphicalItems().PushFront( arc ); + if( arc ) + { + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( module, UR_MODEDIT ); + arc->SetLocalCoord(); + arc->SetParent( module ); + module->GraphicalItems().PushFront( arc ); + } arc = new EDGE_MODULE( module ); } @@ -188,9 +203,12 @@ int DRAWING_TOOL::DrawArc( TOOL_EVENT& aEvent ) while( drawArc( arc ) ) { - m_board->Add( arc ); - m_frame->OnModify(); - m_frame->SaveCopyInUndoList( arc, UR_NEW ); + if( arc ) + { + m_board->Add( arc ); + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( arc, UR_NEW ); + } arc = new DRAWSEGMENT; } @@ -939,7 +957,7 @@ int DRAWING_TOOL::SetAnchor( TOOL_EVENT& aEvent ) } -bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT* aGraphic ) +bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic ) { // Only two shapes are currently supported assert( aShape == S_SEGMENT || aShape == S_CIRCLE ); @@ -989,6 +1007,7 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT* aGraphic ) preview.Clear(); updatePreview = true; delete aGraphic; + aGraphic = NULL; break; } @@ -1049,7 +1068,8 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT* aGraphic ) else // User has clicked twice in the same spot { // a clear sign that the current drawing is finished delete aGraphic; // but only if at least one graphic was created - started = false; // otherwise - force user to draw more or cancel + aGraphic = NULL; // otherwise - force user to draw more or cancel + started = false; } preview.Clear(); @@ -1081,7 +1101,7 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT* aGraphic ) } -bool DRAWING_TOOL::drawArc( DRAWSEGMENT* aGraphic ) +bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic ) { bool clockwise = true; // drawing direction of the arc double startAngle = 0.0f; // angle of the first arc line @@ -1121,6 +1141,7 @@ bool DRAWING_TOOL::drawArc( DRAWSEGMENT* aGraphic ) preview.Clear(); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); delete aGraphic; + aGraphic = NULL; break; } diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index b1bc2675b3..c0735a8ec2 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -156,14 +156,14 @@ private: ///> be already created. The tool deletes the object if it is not added to a BOARD. ///> @return False if the tool was cancelled before the origin was set or origin and end are ///> the same point. - bool drawSegment( int aShape, DRAWSEGMENT* aGraphic ); + bool drawSegment( int aShape, DRAWSEGMENT*& aGraphic ); ///> Starts drawing an arc. ///> @param aGraphic is an object that is going to be used by the tool for drawing. It has to ///> be already created. The tool deletes the object if it is not added to a BOARD. ///> @return False if the tool was cancelled before the origin was set or origin and end are ///> the same point. - bool drawArc( DRAWSEGMENT* aGraphic ); + bool drawArc( DRAWSEGMENT*& aGraphic ); ///> Draws a polygon, that is added as a zone or a keepout area. ///> @param aKeepout decides if the drawn polygon is a zone or a keepout area. From f5e9774d553c4657da886e803feb5298fe6a0e8d Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:02:56 +0200 Subject: [PATCH 084/123] Added support for graphics on Edge.Cuts layer in modules. Tested functionality that works fine: - zone filling algorithm - printing - plotting (pdf & gerbers) - SVG export - Specctra export - 3D viewer --- pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp b/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp index 13b1203b66..5144e4c88e 100644 --- a/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp +++ b/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp @@ -297,13 +297,13 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) /* Add module edge items that are on copper layers * Pcbnew allows these items to be on copper layers in microwave applictions - * This is a bad thing, but must be handle here, until a better way is found + * This is a bad thing, but must be handled here, until a better way is found */ for( MODULE* module = aPcb->m_Modules; module; module = module->Next() ) { for( BOARD_ITEM* item = module->GraphicalItems(); item; item = item->Next() ) { - if( !item->IsOnLayer( GetLayer() ) ) + if( !item->IsOnLayer( GetLayer() ) && !item->IsOnLayer( EDGE_N ) ) continue; if( item->Type() != PCB_MODULE_EDGE_T ) From d87232f65292a28f2f639eb91f6ee815e3463a79 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:02:56 +0200 Subject: [PATCH 085/123] Moved module editor-specific tools to a separate class (MODULE_TOOLS). --- pcbnew/CMakeLists.txt | 1 + pcbnew/moduleframe.cpp | 2 + pcbnew/tools/common_actions.cpp | 26 +- pcbnew/tools/common_actions.h | 20 +- pcbnew/tools/drawing_tool.cpp | 152 ----------- pcbnew/tools/drawing_tool.h | 12 - pcbnew/tools/edit_tool.cpp | 226 ---------------- pcbnew/tools/edit_tool.h | 14 - pcbnew/tools/module_tools.cpp | 422 ++++++++++++++++++++++++++++++ pcbnew/tools/module_tools.h | 84 ++++++ pcbnew/tools/pcb_editor_control.h | 2 +- 11 files changed, 536 insertions(+), 425 deletions(-) create mode 100644 pcbnew/tools/module_tools.cpp create mode 100644 pcbnew/tools/module_tools.h diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 624418055a..1f032f2c93 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -264,6 +264,7 @@ set( PCBNEW_CLASS_SRCS tools/edit_tool.cpp tools/pcbnew_control.cpp tools/pcb_editor_control.cpp + tools/module_tools.cpp tools/placement_tool.cpp tools/common_actions.cpp ) diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index f237b245e0..a3af6dc5fe 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -61,6 +61,7 @@ #include "tools/drawing_tool.h" #include "tools/point_editor.h" #include "tools/pcbnew_control.h" +#include "tools/module_tools.h" #include "tools/placement_tool.h" #include "tools/common_actions.h" @@ -280,6 +281,7 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : m_toolManager->RegisterTool( new DRAWING_TOOL ); m_toolManager->RegisterTool( new POINT_EDITOR ); m_toolManager->RegisterTool( new PCBNEW_CONTROL ); + m_toolManager->RegisterTool( new MODULE_TOOLS ); m_toolManager->RegisterTool( new PLACEMENT_TOOL ); m_toolManager->GetTool()->EditModules( true ); diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 38190b8ea6..96c819e890 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -59,14 +59,6 @@ TOOL_ACTION COMMON_ACTIONS::properties( "pcbnew.InteractiveEdit.properties", AS_GLOBAL, 'E', "Properties...", "Displays properties window" ); -TOOL_ACTION COMMON_ACTIONS::copyItems( "pcbnew.InteractiveEdit.copyItems", - AS_GLOBAL, MD_CTRL + int( 'C' ), - "Copy items", "Copy items", AF_ACTIVATE ); - -TOOL_ACTION COMMON_ACTIONS::pasteItems( "pcbnew.InteractiveEdit.pasteItems", - AS_GLOBAL, MD_CTRL + int( 'V' ), - "Paste items", "Paste items", AF_ACTIVATE ); - // Drawing tool actions TOOL_ACTION COMMON_ACTIONS::drawLine( "pcbnew.InteractiveDrawing.line", @@ -105,10 +97,6 @@ TOOL_ACTION COMMON_ACTIONS::placeModule( "pcbnew.InteractiveDrawing.placeModule" AS_GLOBAL, 'O', "Add modules", "Add modules", AF_ACTIVATE ); -TOOL_ACTION COMMON_ACTIONS::placePad( "pcbnew.InteractiveDrawing.placePad", - AS_GLOBAL, 0, - "Add pads", "Add pads", AF_ACTIVATE ); - TOOL_ACTION COMMON_ACTIONS::placeDXF( "pcbnew.InteractiveDrawing.placeDXF", AS_GLOBAL, 0, "", "", AF_ACTIVATE ); @@ -276,6 +264,20 @@ TOOL_ACTION COMMON_ACTIONS::trackViaSizeChanged( "pcbnew.EditorControl.trackViaS "", "" ); +// Module editor tools +TOOL_ACTION COMMON_ACTIONS::placePad( "pcbnew.ModuleEditor.placePad", + AS_GLOBAL, 0, + "Add pads", "Add pads", AF_ACTIVATE ); + +TOOL_ACTION COMMON_ACTIONS::copyItems( "pcbnew.ModuleEditor.copyItems", + AS_GLOBAL, MD_CTRL + int( 'C' ), + "Copy items", "Copy items", AF_ACTIVATE ); + +TOOL_ACTION COMMON_ACTIONS::pasteItems( "pcbnew.ModuleEditor.pasteItems", + AS_GLOBAL, MD_CTRL + int( 'V' ), + "Paste items", "Paste items", AF_ACTIVATE ); + + // Miscellaneous TOOL_ACTION COMMON_ACTIONS::resetCoords( "pcbnew.Control.resetCoords", AS_GLOBAL, ' ', diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index c5b32dbc70..e25e4a431f 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -62,11 +62,6 @@ public: /// Deleting a BOARD_ITEM static TOOL_ACTION remove; - /// Copying pad to clipboard - static TOOL_ACTION copyItems; - - /// Pasting a pad from clipboard - static TOOL_ACTION pasteItems; // Drawing Tool /// Activation of the drawing tool (line) @@ -96,9 +91,6 @@ public: /// Activation of the drawing tool (placing a MODULE) static TOOL_ACTION placeModule; - /// Activation of the drawing tool (placing a PAD) - static TOOL_ACTION placePad; - /// Activation of the drawing tool (placing a drawing from DXF file) static TOOL_ACTION placeDXF; @@ -180,6 +172,18 @@ public: static TOOL_ACTION trackViaSizeChanged; // notification + + // Module editor tools + /// Activation of the drawing tool (placing a PAD) + static TOOL_ACTION placePad; + + /// Copying module items to clipboard + static TOOL_ACTION copyItems; + + /// Pasting module items from clipboard + static TOOL_ACTION pasteItems; + + // Miscellaneous static TOOL_ACTION resetCoords; static TOOL_ACTION switchUnits; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 061fb41008..9d19cc3541 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -615,110 +615,6 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) } -int DRAWING_TOOL::PlacePad( TOOL_EVENT& aEvent ) -{ - assert( m_editModules ); - - m_frame->SetToolID( ID_MODEDIT_PAD_TOOL, wxCURSOR_PENCIL, _( "Add pads" ) ); - - MODULE* module = m_board->m_Modules; - assert( module ); - - D_PAD* pad = new D_PAD( module ); - m_frame->Import_Pad_Settings( pad, false ); // use the global settings for pad - - VECTOR2I cursorPos = m_controls->GetCursorPosition(); - pad->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); - - // Add a VIEW_GROUP that serves as a preview for the new item - KIGFX::VIEW_GROUP preview( m_view ); - preview.Add( pad ); - m_view->Add( &preview ); - - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); - m_controls->ShowCursor( true ); - m_controls->SetSnapping( true ); - - Activate(); - - // Main loop: keep receiving events - while( OPT_TOOL_EVENT evt = Wait() ) - { - cursorPos = m_controls->GetCursorPosition(); - - if( evt->IsMotion() ) - { - pad->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); - preview.ViewUpdate(); - } - - else if( evt->Category() == TC_COMMAND ) - { - if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) - { - pad->Rotate( pad->GetPosition(), m_frame->GetRotationAngle() ); - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) - { - pad->Flip( pad->GetPosition() ); - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - else if( evt->IsCancel() || evt->IsActivate() ) - { - preview.Clear(); - delete pad; - break; - } - } - - else if( evt->IsClick( BUT_LEFT ) ) - { - m_frame->OnModify(); - m_frame->SaveCopyInUndoList( module, UR_MODEDIT ); - - m_board->m_Status_Pcb = 0; // I have no clue why, but it is done in the legacy view - module->SetLastEditTime(); - module->Pads().PushBack( pad ); - - pad->SetNetCode( NETINFO_LIST::UNCONNECTED ); - - // Set the relative pad position - // ( pad position for module orient, 0, and relative to the module position) - pad->SetLocalCoord(); - - /* NPTH pads take empty pad number (since they can't be connected), - * other pads get incremented from the last one edited */ - wxString padName; - - if( pad->GetAttribute() != PAD_HOLE_NOT_PLATED ) - padName = getNextPadName(); - - pad->SetPadName( padName ); - - // Handle the view aspect - preview.Remove( pad ); - m_view->Add( pad ); - - // Start placing next pad - pad = new D_PAD( module ); - m_frame->Import_Pad_Settings( pad, false ); - preview.Add( pad ); - } - } - - m_controls->ShowCursor( false ); - m_controls->SetSnapping( false ); - m_controls->SetAutoPan( false ); - m_view->Remove( &preview ); - - setTransitions(); - m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); - - return 0; -} - - int DRAWING_TOOL::PlaceDXF( TOOL_EVENT& aEvent ) { DIALOG_DXF_IMPORT dlg( m_frame ); @@ -1735,53 +1631,6 @@ void DRAWING_TOOL::make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper ) } -bool isNotDigit( char aChar ) -{ - return ( aChar < '0' || aChar > '9' ); -} - - -wxString DRAWING_TOOL::getNextPadName() const -{ - std::set usedNumbers; - - // Find the first, not used pad number - for( MODULE* module = m_board->m_Modules; module; module = module->Next() ) - { - for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) - { - wxString padName = pad->GetPadName(); - int padNumber = 0; - int base = 1; - - // Trim and extract the trailing numeric part - while( padName.Len() && padName.Last() >= '0' && padName.Last() <= '9' ) - { - padNumber += ( padName.Last() - '0' ) * base; - padName.RemoveLast(); - base *= 10; - } - - usedNumbers.insert( padNumber ); - } - } - - int candidate = *usedNumbers.begin(); - - // Look for a gap in pad numbering - for( std::set::iterator it = usedNumbers.begin(), - itEnd = usedNumbers.end(); it != itEnd; ++it ) - { - if( *it - candidate > 1 ) - break; - - candidate = *it; - } - - return wxString::Format( wxT( "%i" ), ++candidate ); -} - - void DRAWING_TOOL::setTransitions() { Go( &DRAWING_TOOL::DrawLine, COMMON_ACTIONS::drawLine.MakeEvent() ); @@ -1793,7 +1642,6 @@ void DRAWING_TOOL::setTransitions() Go( &DRAWING_TOOL::PlaceText, COMMON_ACTIONS::placeText.MakeEvent() ); Go( &DRAWING_TOOL::PlaceTarget, COMMON_ACTIONS::placeTarget.MakeEvent() ); Go( &DRAWING_TOOL::PlaceModule, COMMON_ACTIONS::placeModule.MakeEvent() ); - Go( &DRAWING_TOOL::PlacePad, COMMON_ACTIONS::placePad.MakeEvent() ); Go( &DRAWING_TOOL::PlaceDXF, COMMON_ACTIONS::placeDXF.MakeEvent() ); Go( &DRAWING_TOOL::SetAnchor, COMMON_ACTIONS::setAnchor.MakeEvent() ); } diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index c0735a8ec2..42a6dbfdf3 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -120,12 +120,6 @@ public: */ int PlaceModule( TOOL_EVENT& aEvent ); - /** - * Function PlacePad() - * Places a pad in module editor. - */ - int PlacePad( TOOL_EVENT& aEvent ); - /** * Function PlaceDXF() * Places a drawing imported from a DXF file in module editor. @@ -192,12 +186,6 @@ private: */ void make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper ) const; - /** - * Function getNextPadName() - * Compute the 'next' pad number for autoincrement. - * */ - wxString getNextPadName() const; - ///> Sets up handlers for various events. void setTransitions(); diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 6b833b2290..5bea4c9829 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -431,229 +430,6 @@ int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) } -int EDIT_TOOL::CopyItems( TOOL_EVENT& aEvent ) -{ - const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); - - if( !m_editModules || !makeSelection( selection ) ) - { - setTransitions(); - - return 0; - } - - Activate(); - - KIGFX::VIEW_CONTROLS* controls = getViewControls(); - controls->SetSnapping( true ); - controls->ShowCursor( true ); - controls->SetAutoPan( true ); - - PCB_BASE_FRAME* frame = getEditFrame(); - frame->DisplayToolMsg( _( "Select reference point" ) ); - - bool cancelled = false; - VECTOR2I cursorPos = getViewControls()->GetCursorPosition(); - - while( OPT_TOOL_EVENT evt = Wait() ) - { - if( evt->IsMotion() ) - { - cursorPos = getViewControls()->GetCursorPosition(); - } - else if( evt->IsClick( BUT_LEFT ) ) - { - break; - } - else if( evt->IsCancel() || evt->IsActivate() ) - { - cancelled = true; - break; - } - } - - if( !cancelled ) - { - PCB_IO io( CTL_FOR_CLIPBOARD ); - - // Create a temporary module that contains selected items to ease serialization - MODULE module( getModel() ); - - for( int i = 0; i < selection.Size(); ++i ) - { - BOARD_ITEM* clone = static_cast( selection.Item( i )->Clone() ); - - // Do not add reference/value - convert them to the common type - if( TEXTE_MODULE* text = dyn_cast( clone ) ) - text->SetType( TEXTE_MODULE::TEXT_is_DIVERS ); - - module.Add( clone ); - } - - // Set the new relative internal local coordinates of copied items - MODULE* editedModule = getModel()->m_Modules; - wxPoint moveVector = module.GetPosition() + editedModule->GetPosition() - - wxPoint( cursorPos.x, cursorPos.y ); - module.MoveAnchorPosition( moveVector ); - - io.Format( &module, 0 ); - std::string data = io.GetStringOutput( true ); - m_toolMgr->SaveClipboard( data ); - } - - frame->DisplayToolMsg( wxString::Format( _( "Copied %d item(s)" ), selection.Size() ) ); - controls->SetSnapping( false ); - controls->ShowCursor( false ); - controls->SetAutoPan( false ); - - setTransitions(); - - return 0; -} - - -int EDIT_TOOL::PasteItems( TOOL_EVENT& aEvent ) -{ - if( !m_editModules ) - { - setTransitions(); - - return 0; - } - - // Parse clipboard - PCB_IO io( CTL_FOR_CLIPBOARD ); - MODULE* currentModule = getModel()->m_Modules; - MODULE* pastedModule = NULL; - - try - { - BOARD_ITEM* item = io.Parse( wxString( m_toolMgr->GetClipboard().c_str(), wxConvUTF8 ) ); - assert( item->Type() == PCB_MODULE_T ); - pastedModule = dyn_cast( item ); - } - catch( ... ) - { - setTransitions(); - - return 0; - } - - // Placement tool part - KIGFX::VIEW* view = getView(); - KIGFX::VIEW_CONTROLS* controls = getViewControls(); - BOARD* board = getModel(); - PCB_EDIT_FRAME* frame = getEditFrame(); - VECTOR2I cursorPos = getViewControls()->GetCursorPosition(); - - // Add a VIEW_GROUP that serves as a preview for the new item - KIGFX::VIEW_GROUP preview( view ); - pastedModule->SetParent( board ); - pastedModule->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); - pastedModule->RunOnChildren( boost::bind( &KIGFX::VIEW_GROUP::Add, boost::ref( preview ), _1 ) ); - preview.Add( pastedModule ); - view->Add( &preview ); - - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); - controls->ShowCursor( true ); - controls->SetSnapping( true ); - controls->SetAutoPan( true ); - - Activate(); - - // Main loop: keep receiving events - while( OPT_TOOL_EVENT evt = Wait() ) - { - cursorPos = controls->GetCursorPosition(); - - if( evt->IsMotion() ) - { - pastedModule->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); - preview.ViewUpdate(); - } - - else if( evt->Category() == TC_COMMAND ) - { - if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) - { - pastedModule->Rotate( pastedModule->GetPosition(), frame->GetRotationAngle() ); - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) - { - pastedModule->Flip( pastedModule->GetPosition() ); - preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - } - else if( evt->IsCancel() || evt->IsActivate() ) - { - preview.Clear(); - break; - } - } - - else if( evt->IsClick( BUT_LEFT ) ) - { - frame->OnModify(); - frame->SaveCopyInUndoList( currentModule, UR_MODEDIT ); - - board->m_Status_Pcb = 0; // I have no clue why, but it is done in the legacy view - currentModule->SetLastEditTime(); - - // MODULE::RunOnChildren is infeasible here: we need to create copies of items, do not - // directly modify them - - for( D_PAD* pad = pastedModule->Pads(); pad; pad = pad->Next() ) - { - D_PAD* clone = static_cast( pad->Clone() ); - - currentModule->Add( clone ); - clone->SetLocalCoord(); - view->Add( clone ); - } - - for( BOARD_ITEM* drawing = pastedModule->GraphicalItems(); - drawing; drawing = drawing->Next() ) - { - BOARD_ITEM* clone = static_cast( drawing->Clone() ); - - if( TEXTE_MODULE* text = dyn_cast( clone ) ) - { - // Do not add reference/value - convert them to the common type - text->SetType( TEXTE_MODULE::TEXT_is_DIVERS ); - currentModule->Add( text ); - text->SetLocalCoord(); - - // Whyyyyyyyyyyyyyyyyyyyyyy?! All other items conform to rotation performed - // on its parent module, but texts are so independent.. - text->Rotate( text->GetPosition(), pastedModule->GetOrientation() ); - } - else if( EDGE_MODULE* edge = dyn_cast( clone ) ) - { - currentModule->Add( edge ); - edge->SetLocalCoord(); - } - - view->Add( clone ); - } - - preview.Clear(); - - break; - } - } - - delete pastedModule; - controls->ShowCursor( false ); - controls->SetSnapping( false ); - controls->SetAutoPan( false ); - view->Remove( &preview ); - - setTransitions(); - - return 0; -} - - void EDIT_TOOL::remove( BOARD_ITEM* aItem ) { BOARD* board = getModel(); @@ -741,8 +517,6 @@ void EDIT_TOOL::setTransitions() Go( &EDIT_TOOL::Flip, COMMON_ACTIONS::flip.MakeEvent() ); Go( &EDIT_TOOL::Remove, COMMON_ACTIONS::remove.MakeEvent() ); Go( &EDIT_TOOL::Properties, COMMON_ACTIONS::properties.MakeEvent() ); - Go( &EDIT_TOOL::CopyItems, COMMON_ACTIONS::copyItems.MakeEvent() ); - Go( &EDIT_TOOL::PasteItems, COMMON_ACTIONS::pasteItems.MakeEvent() ); } diff --git a/pcbnew/tools/edit_tool.h b/pcbnew/tools/edit_tool.h index e68cd74894..5e9d93a7c2 100644 --- a/pcbnew/tools/edit_tool.h +++ b/pcbnew/tools/edit_tool.h @@ -91,20 +91,6 @@ public: */ int Remove( TOOL_EVENT& aEvent ); - /** - * Function CopyItems() - * - * Copies selected items to the clipboard. Works only in "edit modules" mode. - */ - int CopyItems( TOOL_EVENT& aEvent ); - - /** - * Function PastePad() - * - * Pastes items from the clipboard. Works only in "edit modules" mode. - */ - int PasteItems( TOOL_EVENT& aEvent ); - /** * Function EditModules() * diff --git a/pcbnew/tools/module_tools.cpp b/pcbnew/tools/module_tools.cpp new file mode 100644 index 0000000000..091823366d --- /dev/null +++ b/pcbnew/tools/module_tools.cpp @@ -0,0 +1,422 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 CERN + * @author Maciej Suminski + * + * 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 "module_tools.h" +#include "selection_tool.h" +#include "common_actions.h" + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +MODULE_TOOLS::MODULE_TOOLS() : + TOOL_INTERACTIVE( "pcbnew.ModuleEditor" ) +{ +} + + +void MODULE_TOOLS::Reset( RESET_REASON aReason ) +{ + // Init variables used by every drawing tool + m_view = getView(); + m_controls = getViewControls(); + m_board = getModel(); + m_frame = getEditFrame(); +} + + +bool MODULE_TOOLS::Init() +{ + setTransitions(); + + return true; +} + + +static wxString getNextPadName( MODULE* aModule ) +{ + std::set usedNumbers; + + // Create a set of used pad numbers + for( D_PAD* pad = aModule->Pads(); pad; pad = pad->Next() ) + { + wxString padName = pad->GetPadName(); + int padNumber = 0; + int base = 1; + + // Trim and extract the trailing numeric part + while( padName.Len() && padName.Last() >= '0' && padName.Last() <= '9' ) + { + padNumber += ( padName.Last() - '0' ) * base; + padName.RemoveLast(); + base *= 10; + } + + usedNumbers.insert( padNumber ); + } + + int candidate = *usedNumbers.begin(); + + // Look for a gap in pad numbering + for( std::set::iterator it = usedNumbers.begin(), + itEnd = usedNumbers.end(); it != itEnd; ++it ) + { + if( *it - candidate > 1 ) + break; + + candidate = *it; + } + + return wxString::Format( wxT( "%i" ), ++candidate ); +} + + +int MODULE_TOOLS::PlacePad( TOOL_EVENT& aEvent ) +{ + m_frame->SetToolID( ID_MODEDIT_PAD_TOOL, wxCURSOR_PENCIL, _( "Add pads" ) ); + + MODULE* module = m_board->m_Modules; + assert( module ); + + D_PAD* pad = new D_PAD( module ); + m_frame->Import_Pad_Settings( pad, false ); // use the global settings for pad + + VECTOR2I cursorPos = m_controls->GetCursorPosition(); + pad->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); + + // Add a VIEW_GROUP that serves as a preview for the new item + KIGFX::VIEW_GROUP preview( m_view ); + preview.Add( pad ); + m_view->Add( &preview ); + + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_controls->ShowCursor( true ); + m_controls->SetSnapping( true ); + + Activate(); + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + cursorPos = m_controls->GetCursorPosition(); + + if( evt->IsMotion() ) + { + pad->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); + preview.ViewUpdate(); + } + + else if( evt->Category() == TC_COMMAND ) + { + if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) + { + pad->Rotate( pad->GetPosition(), m_frame->GetRotationAngle() ); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) + { + pad->Flip( pad->GetPosition() ); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else if( evt->IsCancel() || evt->IsActivate() ) + { + preview.Clear(); + delete pad; + break; + } + } + + else if( evt->IsClick( BUT_LEFT ) ) + { + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( module, UR_MODEDIT ); + + m_board->m_Status_Pcb = 0; // I have no clue why, but it is done in the legacy view + module->SetLastEditTime(); + module->Pads().PushBack( pad ); + + pad->SetNetCode( NETINFO_LIST::UNCONNECTED ); + + // Set the relative pad position + // ( pad position for module orient, 0, and relative to the module position) + pad->SetLocalCoord(); + + /* NPTH pads take empty pad number (since they can't be connected), + * other pads get incremented from the last one edited */ + wxString padName; + + if( pad->GetAttribute() != PAD_HOLE_NOT_PLATED ) + padName = getNextPadName( module ); + + pad->SetPadName( padName ); + + // Handle the view aspect + preview.Remove( pad ); + m_view->Add( pad ); + + // Start placing next pad + pad = new D_PAD( module ); + m_frame->Import_Pad_Settings( pad, false ); + preview.Add( pad ); + } + } + + m_controls->ShowCursor( false ); + m_controls->SetSnapping( false ); + m_controls->SetAutoPan( false ); + m_view->Remove( &preview ); + + setTransitions(); + m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); + + return 0; +} + + +int MODULE_TOOLS::CopyItems( TOOL_EVENT& aEvent ) +{ + const SELECTION_TOOL::SELECTION& selection = m_toolMgr->GetTool()->GetSelection(); + + Activate(); + + KIGFX::VIEW_CONTROLS* controls = getViewControls(); + controls->SetSnapping( true ); + controls->ShowCursor( true ); + controls->SetAutoPan( true ); + + PCB_BASE_FRAME* frame = getEditFrame(); + frame->DisplayToolMsg( _( "Select reference point" ) ); + + bool cancelled = false; + VECTOR2I cursorPos = getViewControls()->GetCursorPosition(); + + while( OPT_TOOL_EVENT evt = Wait() ) + { + if( evt->IsMotion() ) + { + cursorPos = getViewControls()->GetCursorPosition(); + } + else if( evt->IsClick( BUT_LEFT ) ) + { + break; + } + else if( evt->IsCancel() || evt->IsActivate() ) + { + cancelled = true; + break; + } + } + + if( !cancelled ) + { + PCB_IO io( CTL_FOR_CLIPBOARD ); + + // Create a temporary module that contains selected items to ease serialization + MODULE module( getModel() ); + + for( int i = 0; i < selection.Size(); ++i ) + { + BOARD_ITEM* clone = static_cast( selection.Item( i )->Clone() ); + + // Do not add reference/value - convert them to the common type + if( TEXTE_MODULE* text = dyn_cast( clone ) ) + text->SetType( TEXTE_MODULE::TEXT_is_DIVERS ); + + module.Add( clone ); + } + + // Set the new relative internal local coordinates of copied items + MODULE* editedModule = getModel()->m_Modules; + wxPoint moveVector = module.GetPosition() + editedModule->GetPosition() - + wxPoint( cursorPos.x, cursorPos.y ); + module.MoveAnchorPosition( moveVector ); + + io.Format( &module, 0 ); + std::string data = io.GetStringOutput( true ); + m_toolMgr->SaveClipboard( data ); + } + + frame->DisplayToolMsg( wxString::Format( _( "Copied %d item(s)" ), selection.Size() ) ); + controls->SetSnapping( false ); + controls->ShowCursor( false ); + controls->SetAutoPan( false ); + + setTransitions(); + + return 0; +} + + +int MODULE_TOOLS::PasteItems( TOOL_EVENT& aEvent ) +{ + // Parse clipboard + PCB_IO io( CTL_FOR_CLIPBOARD ); + MODULE* currentModule = getModel()->m_Modules; + MODULE* pastedModule = NULL; + + try + { + BOARD_ITEM* item = io.Parse( wxString( m_toolMgr->GetClipboard().c_str(), wxConvUTF8 ) ); + assert( item->Type() == PCB_MODULE_T ); + pastedModule = dyn_cast( item ); + } + catch( ... ) + { + m_frame->DisplayToolMsg( _( "Invalid clipboard contents" ) ); + setTransitions(); + + return 0; + } + + // Placement tool part + KIGFX::VIEW* view = getView(); + KIGFX::VIEW_CONTROLS* controls = getViewControls(); + BOARD* board = getModel(); + PCB_EDIT_FRAME* frame = getEditFrame(); + VECTOR2I cursorPos = getViewControls()->GetCursorPosition(); + + // Add a VIEW_GROUP that serves as a preview for the new item + KIGFX::VIEW_GROUP preview( view ); + pastedModule->SetParent( board ); + pastedModule->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); + pastedModule->RunOnChildren( boost::bind( &KIGFX::VIEW_GROUP::Add, boost::ref( preview ), _1 ) ); + preview.Add( pastedModule ); + view->Add( &preview ); + + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + controls->ShowCursor( true ); + controls->SetSnapping( true ); + controls->SetAutoPan( true ); + + Activate(); + + // Main loop: keep receiving events + while( OPT_TOOL_EVENT evt = Wait() ) + { + cursorPos = controls->GetCursorPosition(); + + if( evt->IsMotion() ) + { + pastedModule->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); + preview.ViewUpdate(); + } + + else if( evt->Category() == TC_COMMAND ) + { + if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) + { + pastedModule->Rotate( pastedModule->GetPosition(), frame->GetRotationAngle() ); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) + { + pastedModule->Flip( pastedModule->GetPosition() ); + preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + else if( evt->IsCancel() || evt->IsActivate() ) + { + preview.Clear(); + break; + } + } + + else if( evt->IsClick( BUT_LEFT ) ) + { + frame->OnModify(); + frame->SaveCopyInUndoList( currentModule, UR_MODEDIT ); + + board->m_Status_Pcb = 0; // I have no clue why, but it is done in the legacy view + currentModule->SetLastEditTime(); + + // MODULE::RunOnChildren is infeasible here: we need to create copies of items, do not + // directly modify them + + for( D_PAD* pad = pastedModule->Pads(); pad; pad = pad->Next() ) + { + D_PAD* clone = static_cast( pad->Clone() ); + + currentModule->Add( clone ); + clone->SetLocalCoord(); + view->Add( clone ); + } + + for( BOARD_ITEM* drawing = pastedModule->GraphicalItems(); + drawing; drawing = drawing->Next() ) + { + BOARD_ITEM* clone = static_cast( drawing->Clone() ); + + if( TEXTE_MODULE* text = dyn_cast( clone ) ) + { + // Do not add reference/value - convert them to the common type + text->SetType( TEXTE_MODULE::TEXT_is_DIVERS ); + currentModule->Add( text ); + text->SetLocalCoord(); + + // Whyyyyyyyyyyyyyyyyyyyyyy?! All other items conform to rotation performed + // on its parent module, but texts are so independent.. + text->Rotate( text->GetPosition(), pastedModule->GetOrientation() ); + } + else if( EDGE_MODULE* edge = dyn_cast( clone ) ) + { + currentModule->Add( edge ); + edge->SetLocalCoord(); + } + + view->Add( clone ); + } + + preview.Clear(); + + break; + } + } + + delete pastedModule; + controls->ShowCursor( false ); + controls->SetSnapping( false ); + controls->SetAutoPan( false ); + view->Remove( &preview ); + + setTransitions(); + + return 0; +} + + +void MODULE_TOOLS::setTransitions() +{ + Go( &MODULE_TOOLS::PlacePad, COMMON_ACTIONS::placePad.MakeEvent() ); + Go( &MODULE_TOOLS::CopyItems, COMMON_ACTIONS::copyItems.MakeEvent() ); + Go( &MODULE_TOOLS::PasteItems, COMMON_ACTIONS::pasteItems.MakeEvent() ); +} diff --git a/pcbnew/tools/module_tools.h b/pcbnew/tools/module_tools.h new file mode 100644 index 0000000000..b23898c02c --- /dev/null +++ b/pcbnew/tools/module_tools.h @@ -0,0 +1,84 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 CERN + * @author Maciej Suminski + * + * 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 MODULE_TOOLS_H +#define MODULE_TOOLS_H + +#include + +namespace KIGFX +{ + class VIEW; + class VIEW_CONTROLS; +} +class BOARD; +class PCB_EDIT_FRAME; + +/** + * Class MODULE_TOOLS + * + * Module editor specific tools. + */ +class MODULE_TOOLS : public TOOL_INTERACTIVE +{ +public: + MODULE_TOOLS(); + + /// @copydoc TOOL_INTERACTIVE::Reset() + void Reset( RESET_REASON aReason ); + + /// @copydoc TOOL_INTERACTIVE::Init() + bool Init(); + + /** + * Function PlacePad() + * Places a pad in module editor. + */ + int PlacePad( TOOL_EVENT& aEvent ); + + /** + * Function CopyItems() + * + * Copies selected items to the clipboard. Works only in "edit modules" mode. + */ + int CopyItems( TOOL_EVENT& aEvent ); + + /** + * Function PastePad() + * + * Pastes items from the clipboard. Works only in "edit modules" mode. + */ + int PasteItems( TOOL_EVENT& aEvent ); + +private: + ///> Sets up handlers for various events. + void setTransitions(); + + KIGFX::VIEW* m_view; + KIGFX::VIEW_CONTROLS* m_controls; + BOARD* m_board; + PCB_EDIT_FRAME* m_frame; +}; + +#endif diff --git a/pcbnew/tools/pcb_editor_control.h b/pcbnew/tools/pcb_editor_control.h index 50b9a6c691..8d879907fa 100644 --- a/pcbnew/tools/pcb_editor_control.h +++ b/pcbnew/tools/pcb_editor_control.h @@ -55,7 +55,7 @@ private: ///> Sets up handlers for various events. void setTransitions(); - ///> Pointerto the currently used edit frame. + ///> Pointer to the currently used edit frame. PCB_EDIT_FRAME* m_frame; }; From fb7b8fd9b142056fca0a0ce0b0e70d5cb25ef478 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:02:56 +0200 Subject: [PATCH 086/123] Removed redundant accessor calls in MODULE_TOOLS. --- pcbnew/tools/module_tools.cpp | 68 ++++++++++++++++------------------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/pcbnew/tools/module_tools.cpp b/pcbnew/tools/module_tools.cpp index 091823366d..dffc355133 100644 --- a/pcbnew/tools/module_tools.cpp +++ b/pcbnew/tools/module_tools.cpp @@ -210,22 +210,20 @@ int MODULE_TOOLS::CopyItems( TOOL_EVENT& aEvent ) Activate(); - KIGFX::VIEW_CONTROLS* controls = getViewControls(); - controls->SetSnapping( true ); - controls->ShowCursor( true ); - controls->SetAutoPan( true ); + m_controls->SetSnapping( true ); + m_controls->ShowCursor( true ); + m_controls->SetAutoPan( true ); - PCB_BASE_FRAME* frame = getEditFrame(); - frame->DisplayToolMsg( _( "Select reference point" ) ); + m_frame->DisplayToolMsg( _( "Select reference point" ) ); bool cancelled = false; - VECTOR2I cursorPos = getViewControls()->GetCursorPosition(); + VECTOR2I cursorPos = m_controls->GetCursorPosition(); while( OPT_TOOL_EVENT evt = Wait() ) { if( evt->IsMotion() ) { - cursorPos = getViewControls()->GetCursorPosition(); + cursorPos = m_controls->GetCursorPosition(); } else if( evt->IsClick( BUT_LEFT ) ) { @@ -243,7 +241,7 @@ int MODULE_TOOLS::CopyItems( TOOL_EVENT& aEvent ) PCB_IO io( CTL_FOR_CLIPBOARD ); // Create a temporary module that contains selected items to ease serialization - MODULE module( getModel() ); + MODULE module( m_board ); for( int i = 0; i < selection.Size(); ++i ) { @@ -257,7 +255,7 @@ int MODULE_TOOLS::CopyItems( TOOL_EVENT& aEvent ) } // Set the new relative internal local coordinates of copied items - MODULE* editedModule = getModel()->m_Modules; + MODULE* editedModule = m_board->m_Modules; wxPoint moveVector = module.GetPosition() + editedModule->GetPosition() - wxPoint( cursorPos.x, cursorPos.y ); module.MoveAnchorPosition( moveVector ); @@ -267,10 +265,10 @@ int MODULE_TOOLS::CopyItems( TOOL_EVENT& aEvent ) m_toolMgr->SaveClipboard( data ); } - frame->DisplayToolMsg( wxString::Format( _( "Copied %d item(s)" ), selection.Size() ) ); - controls->SetSnapping( false ); - controls->ShowCursor( false ); - controls->SetAutoPan( false ); + m_frame->DisplayToolMsg( wxString::Format( _( "Copied %d item(s)" ), selection.Size() ) ); + m_controls->SetSnapping( false ); + m_controls->ShowCursor( false ); + m_controls->SetAutoPan( false ); setTransitions(); @@ -282,7 +280,7 @@ int MODULE_TOOLS::PasteItems( TOOL_EVENT& aEvent ) { // Parse clipboard PCB_IO io( CTL_FOR_CLIPBOARD ); - MODULE* currentModule = getModel()->m_Modules; + MODULE* currentModule = m_board->m_Modules; MODULE* pastedModule = NULL; try @@ -300,31 +298,27 @@ int MODULE_TOOLS::PasteItems( TOOL_EVENT& aEvent ) } // Placement tool part - KIGFX::VIEW* view = getView(); - KIGFX::VIEW_CONTROLS* controls = getViewControls(); - BOARD* board = getModel(); - PCB_EDIT_FRAME* frame = getEditFrame(); - VECTOR2I cursorPos = getViewControls()->GetCursorPosition(); + VECTOR2I cursorPos = m_controls->GetCursorPosition(); // Add a VIEW_GROUP that serves as a preview for the new item - KIGFX::VIEW_GROUP preview( view ); - pastedModule->SetParent( board ); + KIGFX::VIEW_GROUP preview( m_view ); + pastedModule->SetParent( m_board ); pastedModule->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); pastedModule->RunOnChildren( boost::bind( &KIGFX::VIEW_GROUP::Add, boost::ref( preview ), _1 ) ); preview.Add( pastedModule ); - view->Add( &preview ); + m_view->Add( &preview ); m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); - controls->ShowCursor( true ); - controls->SetSnapping( true ); - controls->SetAutoPan( true ); + m_controls->ShowCursor( true ); + m_controls->SetSnapping( true ); + m_controls->SetAutoPan( true ); Activate(); // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { - cursorPos = controls->GetCursorPosition(); + cursorPos = m_controls->GetCursorPosition(); if( evt->IsMotion() ) { @@ -336,7 +330,7 @@ int MODULE_TOOLS::PasteItems( TOOL_EVENT& aEvent ) { if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) { - pastedModule->Rotate( pastedModule->GetPosition(), frame->GetRotationAngle() ); + pastedModule->Rotate( pastedModule->GetPosition(), m_frame->GetRotationAngle() ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) @@ -353,10 +347,10 @@ int MODULE_TOOLS::PasteItems( TOOL_EVENT& aEvent ) else if( evt->IsClick( BUT_LEFT ) ) { - frame->OnModify(); - frame->SaveCopyInUndoList( currentModule, UR_MODEDIT ); + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( currentModule, UR_MODEDIT ); - board->m_Status_Pcb = 0; // I have no clue why, but it is done in the legacy view + m_board->m_Status_Pcb = 0; // I have no clue why, but it is done in the legacy view currentModule->SetLastEditTime(); // MODULE::RunOnChildren is infeasible here: we need to create copies of items, do not @@ -368,7 +362,7 @@ int MODULE_TOOLS::PasteItems( TOOL_EVENT& aEvent ) currentModule->Add( clone ); clone->SetLocalCoord(); - view->Add( clone ); + m_view->Add( clone ); } for( BOARD_ITEM* drawing = pastedModule->GraphicalItems(); @@ -393,7 +387,7 @@ int MODULE_TOOLS::PasteItems( TOOL_EVENT& aEvent ) edge->SetLocalCoord(); } - view->Add( clone ); + m_view->Add( clone ); } preview.Clear(); @@ -403,10 +397,10 @@ int MODULE_TOOLS::PasteItems( TOOL_EVENT& aEvent ) } delete pastedModule; - controls->ShowCursor( false ); - controls->SetSnapping( false ); - controls->SetAutoPan( false ); - view->Remove( &preview ); + m_controls->ShowCursor( false ); + m_controls->SetSnapping( false ); + m_controls->SetAutoPan( false ); + m_view->Remove( &preview ); setTransitions(); From a961961105cb5c575fb32d2a58447f4dabc58642 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:02:56 +0200 Subject: [PATCH 087/123] Initial version of the Pad Enumeration tool. --- pcbnew/tools/common_actions.cpp | 4 ++ pcbnew/tools/common_actions.h | 3 + pcbnew/tools/module_tools.cpp | 116 ++++++++++++++++++++++++++++++++ pcbnew/tools/module_tools.h | 6 ++ 4 files changed, 129 insertions(+) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 96c819e890..c1b538ba04 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -269,6 +269,10 @@ TOOL_ACTION COMMON_ACTIONS::placePad( "pcbnew.ModuleEditor.placePad", AS_GLOBAL, 0, "Add pads", "Add pads", AF_ACTIVATE ); +TOOL_ACTION COMMON_ACTIONS::enumeratePads( "pcbnew.ModuleEditor.enumeratePads", + AS_GLOBAL, 0, + "Enumerate pads", "Enumerate pads", AF_ACTIVATE ); + TOOL_ACTION COMMON_ACTIONS::copyItems( "pcbnew.ModuleEditor.copyItems", AS_GLOBAL, MD_CTRL + int( 'C' ), "Copy items", "Copy items", AF_ACTIVATE ); diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index e25e4a431f..78bc6f50d1 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -177,6 +177,9 @@ public: /// Activation of the drawing tool (placing a PAD) static TOOL_ACTION placePad; + /// Tool for quick pad enumeration + static TOOL_ACTION enumeratePads; + /// Copying module items to clipboard static TOOL_ACTION copyItems; diff --git a/pcbnew/tools/module_tools.cpp b/pcbnew/tools/module_tools.cpp index dffc355133..2a297052e0 100644 --- a/pcbnew/tools/module_tools.cpp +++ b/pcbnew/tools/module_tools.cpp @@ -32,6 +32,8 @@ #include #include +#include +#include #include #include @@ -39,6 +41,7 @@ #include #include +#include MODULE_TOOLS::MODULE_TOOLS() : TOOL_INTERACTIVE( "pcbnew.ModuleEditor" ) @@ -58,6 +61,17 @@ void MODULE_TOOLS::Reset( RESET_REASON aReason ) bool MODULE_TOOLS::Init() { + // Find the selection tool, so they can cooperate + SELECTION_TOOL* selectionTool = m_toolMgr->GetTool(); + + if( !selectionTool ) + { + DisplayError( NULL, wxT( "pcbnew.InteractiveSelection tool is not available" ) ); + return false; + } + + selectionTool->AddMenuItem( COMMON_ACTIONS::enumeratePads ); + setTransitions(); return true; @@ -204,6 +218,107 @@ int MODULE_TOOLS::PlacePad( TOOL_EVENT& aEvent ) } +int MODULE_TOOLS::EnumeratePads( TOOL_EVENT& aEvent ) +{ + std::list pads; + std::set allPads; + MODULE* module = m_board->m_Modules; + + GENERAL_COLLECTOR collector; + const KICAD_T types[] = { PCB_PAD_T, EOT }; + + GENERAL_COLLECTORS_GUIDE guide = m_frame->GetCollectorsGuide(); + guide.SetIgnoreMTextsMarkedNoShow( true ); + guide.SetIgnoreMTextsOnCopper( true ); + guide.SetIgnoreMTextsOnCmp( true ); + guide.SetIgnoreModulesOnCu( true ); + guide.SetIgnoreModulesOnCmp( true ); + guide.SetIgnoreModulesVals( true ); + guide.SetIgnoreModulesRefs( true ); + + // Create a set containing all pads (to avoid double adding to a list); + for( D_PAD* p = module->Pads(); p; p = p->Next() ) + allPads.insert( p ); + + // TODO display settings window + int padNumber = 1; + wxString padPrefix = ""; + + m_frame->DisplayToolMsg( _( "Hold left mouse button and move cursor over pads to enumerate them" ) ); + + Activate(); + + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_controls->ShowCursor( true ); + + while( OPT_TOOL_EVENT evt = Wait() ) + { + if( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) + { + // Add pads to the list according to the selection order + VECTOR2I cursorPos = m_controls->GetCursorPosition(); + + collector.Empty(); + collector.Collect( m_board, types, wxPoint( cursorPos.x, cursorPos.y ), guide ); + + for( int i = 0; i < collector.GetCount(); ++i ) + { + if( collector[i]->Type() == PCB_PAD_T ) + { + D_PAD* pad = static_cast( collector[i] ); + + std::set::iterator it = allPads.find( pad ); + + // Add the pad to the list, if it was not selected previously.. + if( it != allPads.end() ) + { + allPads.erase( it ); + pads.push_back( pad ); + pad->SetSelected(); + } + + // ..or remove it from the list if it was clicked + else if( evt->IsClick( BUT_LEFT ) ) + { + allPads.insert( pad ); + pads.remove( pad ); + pad->ClearSelected(); + } + } + } + } + + else if( ( evt->IsKeyPressed() && evt->KeyCode() == WXK_RETURN ) || + evt->IsDblClick( BUT_LEFT ) ) + { + // Accept changes + m_frame->OnModify(); + m_frame->SaveCopyInUndoList( module, UR_MODEDIT ); + + BOOST_FOREACH( D_PAD* pad, pads ) + pad->SetPadName( wxString::Format( "%s%d", padPrefix, padNumber++ ) ); + + break; + } + + else if( evt->IsCancel() || evt->IsActivate() ) + { + break; + } + } + + BOOST_FOREACH( D_PAD* pad, pads ) + pad->ClearSelected(); + + m_frame->DisplayToolMsg( wxEmptyString ); + m_controls->ShowCursor( false ); + + setTransitions(); + + return 0; +} + + int MODULE_TOOLS::CopyItems( TOOL_EVENT& aEvent ) { const SELECTION_TOOL::SELECTION& selection = m_toolMgr->GetTool()->GetSelection(); @@ -411,6 +526,7 @@ int MODULE_TOOLS::PasteItems( TOOL_EVENT& aEvent ) void MODULE_TOOLS::setTransitions() { Go( &MODULE_TOOLS::PlacePad, COMMON_ACTIONS::placePad.MakeEvent() ); + Go( &MODULE_TOOLS::EnumeratePads, COMMON_ACTIONS::enumeratePads.MakeEvent() ); Go( &MODULE_TOOLS::CopyItems, COMMON_ACTIONS::copyItems.MakeEvent() ); Go( &MODULE_TOOLS::PasteItems, COMMON_ACTIONS::pasteItems.MakeEvent() ); } diff --git a/pcbnew/tools/module_tools.h b/pcbnew/tools/module_tools.h index b23898c02c..64899e4182 100644 --- a/pcbnew/tools/module_tools.h +++ b/pcbnew/tools/module_tools.h @@ -57,6 +57,12 @@ public: */ int PlacePad( TOOL_EVENT& aEvent ); + /** + * Function EnumeratePads() + * Tool for quick pad enumeration. + */ + int EnumeratePads( TOOL_EVENT& aEvent ); + /** * Function CopyItems() * From c9d72036d8c6e62ea21ad61408d1f79b7b9fb38d Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:10:32 +0200 Subject: [PATCH 088/123] Added settings dialog for Pad Enumeration tool. --- pcbnew/CMakeLists.txt | 2 + pcbnew/dialogs/dialog_enum_pads.cpp | 42 ++ pcbnew/dialogs/dialog_enum_pads.h | 49 ++ pcbnew/dialogs/dialog_enum_pads_base.cpp | 68 +++ pcbnew/dialogs/dialog_enum_pads_base.fbp | 572 +++++++++++++++++++++++ pcbnew/dialogs/dialog_enum_pads_base.h | 53 +++ pcbnew/tools/module_tools.cpp | 16 +- 7 files changed, 799 insertions(+), 3 deletions(-) create mode 100644 pcbnew/dialogs/dialog_enum_pads.cpp create mode 100644 pcbnew/dialogs/dialog_enum_pads.h create mode 100644 pcbnew/dialogs/dialog_enum_pads_base.cpp create mode 100644 pcbnew/dialogs/dialog_enum_pads_base.fbp create mode 100644 pcbnew/dialogs/dialog_enum_pads_base.h diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 1f032f2c93..187b73a45a 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -59,6 +59,8 @@ set( PCBNEW_DIALOGS dialogs/dialog_edit_module_for_Modedit.cpp dialogs/dialog_edit_module_text.cpp dialogs/dialog_edit_module_text_base.cpp + dialogs/dialog_enum_pads.cpp + dialogs/dialog_enum_pads_base.cpp dialogs/dialog_exchange_modules_base.cpp dialogs/dialog_export_idf.cpp dialogs/dialog_export_idf_base.cpp diff --git a/pcbnew/dialogs/dialog_enum_pads.cpp b/pcbnew/dialogs/dialog_enum_pads.cpp new file mode 100644 index 0000000000..51f822047e --- /dev/null +++ b/pcbnew/dialogs/dialog_enum_pads.cpp @@ -0,0 +1,42 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 CERN + * @author Maciej Suminski + * + * 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 "dialog_enum_pads.h" + +DIALOG_ENUM_PADS::DIALOG_ENUM_PADS( wxWindow* aParent ) : + DIALOG_ENUM_PADS_BASE( aParent ) +{ +} + + +int DIALOG_ENUM_PADS::GetStartNumber() const +{ + return m_padStartNum->GetValue(); +} + + +wxString DIALOG_ENUM_PADS::GetPrefix() const +{ + return m_padPrefix->GetValue(); +} diff --git a/pcbnew/dialogs/dialog_enum_pads.h b/pcbnew/dialogs/dialog_enum_pads.h new file mode 100644 index 0000000000..188c7328dc --- /dev/null +++ b/pcbnew/dialogs/dialog_enum_pads.h @@ -0,0 +1,49 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 CERN + * @author Maciej Suminski + * + * 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 __dialog_enum_pads__ +#define __dialog_enum_pads__ + +/** +@file +Subclass of DIALOG_ENUM_PADS_BASE, which is generated by wxFormBuilder. +*/ + +#include "dialog_enum_pads_base.h" + +/** Implementing DIALOG_ENUM_PADS_BASE */ +class DIALOG_ENUM_PADS : public DIALOG_ENUM_PADS_BASE +{ +public: + /** Constructor */ + DIALOG_ENUM_PADS( wxWindow* parent ); + + ///> Returns the starting number that is going to be used for the first enumerated pad. + int GetStartNumber() const; + + ///> Returns common prefix for all enumerated pads. + wxString GetPrefix() const; +}; + +#endif // __dialog_enum_pads__ diff --git a/pcbnew/dialogs/dialog_enum_pads_base.cpp b/pcbnew/dialogs/dialog_enum_pads_base.cpp new file mode 100644 index 0000000000..af1ac745f3 --- /dev/null +++ b/pcbnew/dialogs/dialog_enum_pads_base.cpp @@ -0,0 +1,68 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Apr 30 2013) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "dialog_enum_pads_base.h" + +/////////////////////////////////////////////////////////////////////////// + +DIALOG_ENUM_PADS_BASE::DIALOG_ENUM_PADS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bMainSizer; + bMainSizer = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bPrefixSizer; + bPrefixSizer = new wxBoxSizer( wxHORIZONTAL ); + + m_lblPadPrefix = new wxStaticText( this, wxID_ANY, _("Pad name prefix:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_lblPadPrefix->Wrap( -1 ); + bPrefixSizer->Add( m_lblPadPrefix, 1, wxALL, 5 ); + + m_padPrefix = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_padPrefix->SetMaxLength( 4 ); + bPrefixSizer->Add( m_padPrefix, 0, wxALL, 5 ); + + + bMainSizer->Add( bPrefixSizer, 1, wxEXPAND, 5 ); + + wxBoxSizer* bPadNumSizer; + bPadNumSizer = new wxBoxSizer( wxHORIZONTAL ); + + m_lblPadStartNum = new wxStaticText( this, wxID_ANY, _("First pad number:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_lblPadStartNum->Wrap( -1 ); + bPadNumSizer->Add( m_lblPadStartNum, 1, wxALL, 5 ); + + m_padStartNum = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 999, 1 ); + bPadNumSizer->Add( m_padStartNum, 0, wxALL, 5 ); + + + bMainSizer->Add( bPadNumSizer, 1, wxEXPAND, 5 ); + + m_lblInfo = new wxStaticText( this, wxID_ANY, _("Pad names are restricted to 4 characters (including number)."), wxDefaultPosition, wxDefaultSize, 0 ); + m_lblInfo->Wrap( 320 ); + bMainSizer->Add( m_lblInfo, 0, wxALL, 5 ); + + m_stdButtons = new wxStdDialogButtonSizer(); + m_stdButtonsOK = new wxButton( this, wxID_OK ); + m_stdButtons->AddButton( m_stdButtonsOK ); + m_stdButtonsCancel = new wxButton( this, wxID_CANCEL ); + m_stdButtons->AddButton( m_stdButtonsCancel ); + m_stdButtons->Realize(); + + bMainSizer->Add( m_stdButtons, 2, wxEXPAND, 5 ); + + + this->SetSizer( bMainSizer ); + this->Layout(); + + this->Centre( wxBOTH ); +} + +DIALOG_ENUM_PADS_BASE::~DIALOG_ENUM_PADS_BASE() +{ +} diff --git a/pcbnew/dialogs/dialog_enum_pads_base.fbp b/pcbnew/dialogs/dialog_enum_pads_base.fbp new file mode 100644 index 0000000000..f17006d1f9 --- /dev/null +++ b/pcbnew/dialogs/dialog_enum_pads_base.fbp @@ -0,0 +1,572 @@ + + + + + + C++ + 1 + source_name + 0 + 0 + res + UTF-8 + connect + dialog_enum_pads_base + 1000 + none + 1 + DIALOG_ENUM_PADS_BASE + + . + + 1 + 1 + 1 + 0 + 0 + + 0 + wxAUI_MGR_DEFAULT + + wxBOTH + + 1 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + DIALOG_ENUM_PADS_BASE + + 340,240 + wxDEFAULT_DIALOG_STYLE + + Pad enumeration settings + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bMainSizer + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bPrefixSizer + wxHORIZONTAL + none + + 5 + wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Pad name prefix: + + 0 + + + 0 + + 1 + m_lblPadPrefix + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 4 + + 0 + + 1 + m_padPrefix + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + bPadNumSizer + wxHORIZONTAL + none + + 5 + wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + First pad number: + + 0 + + + 0 + + 1 + m_lblPadStartNum + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + 1 + 999 + + 0 + + 0 + + 0 + + 1 + m_padStartNum + 1 + + + protected + 1 + + Resizable + 1 + + wxSP_ARROW_KEYS + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Pad names are restricted to 4 characters (including number). + + 0 + + + 0 + + 1 + m_lblInfo + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + 320 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 2 + + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + + m_stdButtons + protected + + + + + + + + + + + + + + diff --git a/pcbnew/dialogs/dialog_enum_pads_base.h b/pcbnew/dialogs/dialog_enum_pads_base.h new file mode 100644 index 0000000000..caed966dcd --- /dev/null +++ b/pcbnew/dialogs/dialog_enum_pads_base.h @@ -0,0 +1,53 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Apr 30 2013) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#ifndef __DIALOG_ENUM_PADS_BASE_H__ +#define __DIALOG_ENUM_PADS_BASE_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +/// Class DIALOG_ENUM_PADS_BASE +/////////////////////////////////////////////////////////////////////////////// +class DIALOG_ENUM_PADS_BASE : public wxDialog +{ + private: + + protected: + wxStaticText* m_lblPadPrefix; + wxTextCtrl* m_padPrefix; + wxStaticText* m_lblPadStartNum; + wxSpinCtrl* m_padStartNum; + wxStaticText* m_lblInfo; + wxStdDialogButtonSizer* m_stdButtons; + wxButton* m_stdButtonsOK; + wxButton* m_stdButtonsCancel; + + public: + + DIALOG_ENUM_PADS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Pad enumeration settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 340,240 ), long style = wxDEFAULT_DIALOG_STYLE ); + ~DIALOG_ENUM_PADS_BASE(); + +}; + +#endif //__DIALOG_ENUM_PADS_BASE_H__ diff --git a/pcbnew/tools/module_tools.cpp b/pcbnew/tools/module_tools.cpp index 2a297052e0..447e249229 100644 --- a/pcbnew/tools/module_tools.cpp +++ b/pcbnew/tools/module_tools.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -42,6 +43,7 @@ #include #include +#include MODULE_TOOLS::MODULE_TOOLS() : TOOL_INTERACTIVE( "pcbnew.ModuleEditor" ) @@ -240,9 +242,17 @@ int MODULE_TOOLS::EnumeratePads( TOOL_EVENT& aEvent ) for( D_PAD* p = module->Pads(); p; p = p->Next() ) allPads.insert( p ); - // TODO display settings window - int padNumber = 1; - wxString padPrefix = ""; + DIALOG_ENUM_PADS settingsDlg( m_frame ); + + if( settingsDlg.ShowModal() == wxID_CANCEL ) + { + setTransitions(); + + return 0; + } + + int padNumber = settingsDlg.GetStartNumber(); + wxString padPrefix = settingsDlg.GetPrefix(); m_frame->DisplayToolMsg( _( "Hold left mouse button and move cursor over pads to enumerate them" ) ); From 53660ad91f8edf3cc232dcd24f5b53c65beed834 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:10:32 +0200 Subject: [PATCH 089/123] Pad Enumeration tool support for SMD pads. --- pcbnew/tools/module_tools.cpp | 4 +--- pcbnew/tools/selection_tool.cpp | 6 +++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/pcbnew/tools/module_tools.cpp b/pcbnew/tools/module_tools.cpp index 447e249229..d3e5b85cf3 100644 --- a/pcbnew/tools/module_tools.cpp +++ b/pcbnew/tools/module_tools.cpp @@ -233,12 +233,10 @@ int MODULE_TOOLS::EnumeratePads( TOOL_EVENT& aEvent ) guide.SetIgnoreMTextsMarkedNoShow( true ); guide.SetIgnoreMTextsOnCopper( true ); guide.SetIgnoreMTextsOnCmp( true ); - guide.SetIgnoreModulesOnCu( true ); - guide.SetIgnoreModulesOnCmp( true ); guide.SetIgnoreModulesVals( true ); guide.SetIgnoreModulesRefs( true ); - // Create a set containing all pads (to avoid double adding to a list); + // Create a set containing all pads (to avoid double adding to a list) for( D_PAD* p = module->Pads(); p; p = p->Next() ) allPads.insert( p ); diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 3ae883ed89..511564c216 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -47,8 +47,6 @@ #include "bright_box.h" #include "common_actions.h" -using boost::optional; - SELECTION_TOOL::SELECTION_TOOL() : TOOL_INTERACTIVE( "pcbnew.InteractiveSelection" ), SelectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.selected" ), @@ -393,6 +391,7 @@ int SELECTION_TOOL::SingleSelection( TOOL_EVENT& aEvent ) return 0; } + int SELECTION_TOOL::ClearSelection( TOOL_EVENT& aEvent ) { clearSelection(); @@ -401,6 +400,7 @@ int SELECTION_TOOL::ClearSelection( TOOL_EVENT& aEvent ) return 0; } + void SELECTION_TOOL::clearSelection() { if( m_selection.Empty() ) @@ -472,7 +472,7 @@ BOARD_ITEM* SELECTION_TOOL::disambiguationMenu( GENERAL_COLLECTOR* aCollector ) } else if( evt->Action() == TA_CONTEXT_MENU_CHOICE ) { - optional id = evt->GetCommandId(); + boost::optional id = evt->GetCommandId(); // User has selected an item, so this one will be returned if( id && ( *id >= 0 ) ) From c68bea5a6b864abb8333b002bb814c7ba5098621 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:10:32 +0200 Subject: [PATCH 090/123] Moved SELECTION out of SELECTION_TOOL class. --- pcbnew/tools/edit_tool.cpp | 16 ++++---- pcbnew/tools/edit_tool.h | 4 +- pcbnew/tools/module_tools.cpp | 2 +- pcbnew/tools/placement_tool.cpp | 12 +++--- pcbnew/tools/point_editor.cpp | 4 +- pcbnew/tools/selection_tool.cpp | 2 +- pcbnew/tools/selection_tool.h | 71 ++++++++++++++++----------------- 7 files changed, 55 insertions(+), 56 deletions(-) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 5bea4c9829..72cb824dd0 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -73,7 +73,7 @@ bool EDIT_TOOL::Init() int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) { - const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + const SELECTION& selection = m_selectionTool->GetSelection(); // Shall the selection be cleared at the end? bool unselect = selection.Empty(); @@ -218,7 +218,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) { - const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + const SELECTION& selection = m_selectionTool->GetSelection(); PCB_BASE_EDIT_FRAME* editFrame = getEditFrame(); if( !makeSelection( selection ) ) @@ -287,7 +287,7 @@ int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) { - const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + const SELECTION& selection = m_selectionTool->GetSelection(); PCB_BASE_EDIT_FRAME* editFrame = getEditFrame(); // Shall the selection be cleared at the end? @@ -341,7 +341,7 @@ int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) { - const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + const SELECTION& selection = m_selectionTool->GetSelection(); PCB_BASE_FRAME* editFrame = getEditFrame(); // Shall the selection be cleared at the end? @@ -395,7 +395,7 @@ int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) { - const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + const SELECTION& selection = m_selectionTool->GetSelection(); if( !makeSelection( selection ) ) { @@ -522,7 +522,7 @@ void EDIT_TOOL::setTransitions() void EDIT_TOOL::updateRatsnest( bool aRedraw ) { - const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + const SELECTION& selection = m_selectionTool->GetSelection(); RN_DATA* ratsnest = getModel()->GetRatsnest(); ratsnest->ClearSimple(); @@ -538,7 +538,7 @@ void EDIT_TOOL::updateRatsnest( bool aRedraw ) } -wxPoint EDIT_TOOL::getModificationPoint( const SELECTION_TOOL::SELECTION& aSelection ) +wxPoint EDIT_TOOL::getModificationPoint( const SELECTION& aSelection ) { if( aSelection.Size() == 1 ) { @@ -556,7 +556,7 @@ wxPoint EDIT_TOOL::getModificationPoint( const SELECTION_TOOL::SELECTION& aSelec } -bool EDIT_TOOL::makeSelection( const SELECTION_TOOL::SELECTION& aSelection ) +bool EDIT_TOOL::makeSelection( const SELECTION& aSelection ) { if( aSelection.Empty() ) // Try to find an item that could be modified m_toolMgr->RunAction( COMMON_ACTIONS::selectionSingle ); diff --git a/pcbnew/tools/edit_tool.h b/pcbnew/tools/edit_tool.h index 5e9d93a7c2..76b161ae01 100644 --- a/pcbnew/tools/edit_tool.h +++ b/pcbnew/tools/edit_tool.h @@ -143,11 +143,11 @@ private: ///> Returns the right modification point (e.g. for rotation), depending on the number of ///> selected items. - wxPoint getModificationPoint( const SELECTION_TOOL::SELECTION& aSelection ); + wxPoint getModificationPoint( const SELECTION& aSelection ); ///> If there are no items currently selected, it tries to choose the item that is under ///> the cursor or displays a disambiguation menu if there are multpile items. - bool makeSelection( const SELECTION_TOOL::SELECTION& aSelection ); + bool makeSelection( const SELECTION& aSelection ); ///> Updates view with the changes in the list. void processChanges( const PICKED_ITEMS_LIST* aList ); diff --git a/pcbnew/tools/module_tools.cpp b/pcbnew/tools/module_tools.cpp index d3e5b85cf3..a23dec3be3 100644 --- a/pcbnew/tools/module_tools.cpp +++ b/pcbnew/tools/module_tools.cpp @@ -329,7 +329,7 @@ int MODULE_TOOLS::EnumeratePads( TOOL_EVENT& aEvent ) int MODULE_TOOLS::CopyItems( TOOL_EVENT& aEvent ) { - const SELECTION_TOOL::SELECTION& selection = m_toolMgr->GetTool()->GetSelection(); + const SELECTION& selection = m_toolMgr->GetTool()->GetSelection(); Activate(); diff --git a/pcbnew/tools/placement_tool.cpp b/pcbnew/tools/placement_tool.cpp index 4956c51c45..d436862394 100644 --- a/pcbnew/tools/placement_tool.cpp +++ b/pcbnew/tools/placement_tool.cpp @@ -73,7 +73,7 @@ bool PLACEMENT_TOOL::Init() int PLACEMENT_TOOL::AlignTop( TOOL_EVENT& aEvent ) { - const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + const SELECTION& selection = m_selectionTool->GetSelection(); if( selection.Size() > 1 ) { @@ -116,7 +116,7 @@ int PLACEMENT_TOOL::AlignTop( TOOL_EVENT& aEvent ) int PLACEMENT_TOOL::AlignBottom( TOOL_EVENT& aEvent ) { - const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + const SELECTION& selection = m_selectionTool->GetSelection(); if( selection.Size() > 1 ) { @@ -159,7 +159,7 @@ int PLACEMENT_TOOL::AlignBottom( TOOL_EVENT& aEvent ) int PLACEMENT_TOOL::AlignLeft( TOOL_EVENT& aEvent ) { - const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + const SELECTION& selection = m_selectionTool->GetSelection(); if( selection.Size() > 1 ) { @@ -202,7 +202,7 @@ int PLACEMENT_TOOL::AlignLeft( TOOL_EVENT& aEvent ) int PLACEMENT_TOOL::AlignRight( TOOL_EVENT& aEvent ) { - const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + const SELECTION& selection = m_selectionTool->GetSelection(); if( selection.Size() > 1 ) { @@ -257,7 +257,7 @@ static bool compareY( const BOARD_ITEM* aA, const BOARD_ITEM* aB ) int PLACEMENT_TOOL::DistributeHorizontally( TOOL_EVENT& aEvent ) { - const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + const SELECTION& selection = m_selectionTool->GetSelection(); if( selection.Size() > 1 ) { @@ -306,7 +306,7 @@ int PLACEMENT_TOOL::DistributeHorizontally( TOOL_EVENT& aEvent ) int PLACEMENT_TOOL::DistributeVertically( TOOL_EVENT& aEvent ) { - const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + const SELECTION& selection = m_selectionTool->GetSelection(); if( selection.Size() > 1 ) { diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 14e66424e3..3df09c4ce0 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -203,7 +203,7 @@ bool POINT_EDITOR::Init() int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) { - const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + const SELECTION& selection = m_selectionTool->GetSelection(); if( selection.Size() == 1 ) { @@ -666,7 +666,7 @@ EDIT_POINT POINT_EDITOR::get45DegConstrainer() const void POINT_EDITOR::breakOutline( const VECTOR2I& aBreakPoint ) { EDA_ITEM* item = m_editPoints->GetParent(); - const SELECTION_TOOL::SELECTION& selection = m_selectionTool->GetSelection(); + const SELECTION& selection = m_selectionTool->GetSelection(); if( item->Type() == PCB_ZONE_AREA_T ) { diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 511564c216..2fa5508685 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -764,7 +764,7 @@ BOARD_ITEM* SELECTION_TOOL::prefer( GENERAL_COLLECTOR& aCollector, const KICAD_T } -void SELECTION_TOOL::SELECTION::clear() +void SELECTION::clear() { items.ClearItemsList(); group->Clear(); diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index 4891610d16..55108221a3 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -41,6 +41,41 @@ namespace KIGFX class VIEW_GROUP; } +struct SELECTION +{ + /// Set of selected items + PICKED_ITEMS_LIST items; + + /// VIEW_GROUP that holds currently selected items + KIGFX::VIEW_GROUP* group; + + /// Checks if there is anything selected + bool Empty() const + { + return ( items.GetCount() == 0 ); + } + + /// Returns the number of selected parts + int Size() const + { + return items.GetCount(); + } + + /// Alias to make code shorter and clearer + template + T* Item( unsigned int aIndex ) const + { + return static_cast( items.GetPickedItem( aIndex ) ); + } + +private: + /// Clears both the VIEW_GROUP and set of selected items. Please note that it does not + /// change properties of selected items (e.g. selection flag). + void clear(); + + friend class SELECTION_TOOL; +}; + /** * Class SELECTION_TOOL * @@ -52,48 +87,12 @@ class VIEW_GROUP; * - takes into account high-contrast & layer visibility settings * - invokes InteractiveEdit tool when user starts to drag selected items */ - class SELECTION_TOOL : public TOOL_INTERACTIVE { public: SELECTION_TOOL(); ~SELECTION_TOOL(); - struct SELECTION - { - /// Set of selected items - PICKED_ITEMS_LIST items; - - /// VIEW_GROUP that holds currently selected items - KIGFX::VIEW_GROUP* group; - - /// Checks if there is anything selected - bool Empty() const - { - return ( items.GetCount() == 0 ); - } - - /// Returns the number of selected parts - int Size() const - { - return items.GetCount(); - } - - /// Alias to make code shorter and clearer - template - T* Item( unsigned int aIndex ) const - { - return static_cast( items.GetPickedItem( aIndex ) ); - } - - private: - /// Clears both the VIEW_GROUP and set of selected items. Please note that it does not - /// change properties of selected items (e.g. selection flag). - void clear(); - - friend class SELECTION_TOOL; - }; - /// @copydoc TOOL_INTERACTIVE::Reset() void Reset( RESET_REASON aReason ); From 82ff9ceca7602bc94f8611e22fc970e53ed6e401 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:10:32 +0200 Subject: [PATCH 091/123] Introduced SELECTION_CONDITIONS to determine which menu entries should be visible in the SELECTION_TOOL context menu, depending on the selection. --- common/tool/context_menu.cpp | 50 ++++++++- include/tool/context_menu.h | 5 +- include/tool/tool_event.h | 4 +- pcbnew/CMakeLists.txt | 1 + pcbnew/tools/edit_tool.cpp | 10 +- pcbnew/tools/placement_tool.cpp | 3 +- pcbnew/tools/selection_conditions.cpp | 120 +++++++++++++++++++++ pcbnew/tools/selection_conditions.h | 148 ++++++++++++++++++++++++++ pcbnew/tools/selection_tool.cpp | 42 +++++--- pcbnew/tools/selection_tool.h | 36 +++++-- 10 files changed, 382 insertions(+), 37 deletions(-) create mode 100644 pcbnew/tools/selection_conditions.cpp create mode 100644 pcbnew/tools/selection_conditions.h diff --git a/common/tool/context_menu.cpp b/common/tool/context_menu.cpp index e68473dd6c..57756e66fc 100644 --- a/common/tool/context_menu.cpp +++ b/common/tool/context_menu.cpp @@ -71,6 +71,47 @@ CONTEXT_MENU::CONTEXT_MENU( const CONTEXT_MENU& aMenu ) : } +CONTEXT_MENU& CONTEXT_MENU::operator=( const CONTEXT_MENU& aMenu ) +{ + Clear(); + + m_titleSet = aMenu.m_titleSet; + m_selected = aMenu.m_selected; + m_tool = aMenu.m_tool; + m_toolActions = aMenu.m_toolActions; + m_customHandler = aMenu.m_customHandler; + + // Copy all the menu entries + for( unsigned i = 0; i < aMenu.GetMenuItemCount(); ++i ) + { + wxMenuItem* item = aMenu.FindItemByPosition( i ); + + if( item->IsSubMenu() ) + { +#ifdef DEBUG + // Submenus of a CONTEXT_MENU are supposed to be CONTEXT_MENUs as well + assert( dynamic_cast( item->GetSubMenu() ) ); +#endif + + CONTEXT_MENU* menu = new CONTEXT_MENU( static_cast( *item->GetSubMenu() ) ); + AppendSubMenu( menu, item->GetItemLabel(), wxEmptyString ); + } + else + { + wxMenuItem* newItem = new wxMenuItem( this, item->GetId(), item->GetItemLabel(), + wxEmptyString, item->GetKind() ); + + Append( newItem ); + copyItem( item, newItem ); + } + } + + setupEvents(); + + return *this; +} + + void CONTEXT_MENU::setupEvents() { Connect( wxEVT_MENU_HIGHLIGHT, wxEventHandler( CONTEXT_MENU::onMenuEvent ), NULL, this ); @@ -144,11 +185,12 @@ void CONTEXT_MENU::Clear() { m_titleSet = false; - // Remove all the entries from context menu - for( unsigned i = 0; i < GetMenuItemCount(); ++i ) - Destroy( FindItemByPosition( 0 ) ); - + GetMenuItems().DeleteContents( true ); + GetMenuItems().Clear(); m_toolActions.clear(); + GetMenuItems().DeleteContents( false ); // restore the default so destructor does not go wild + + assert( GetMenuItemCount() == 0 ); } diff --git a/include/tool/context_menu.h b/include/tool/context_menu.h index 0b5f28c41b..72b69315d6 100644 --- a/include/tool/context_menu.h +++ b/include/tool/context_menu.h @@ -47,7 +47,9 @@ public: ///> Copy constructor CONTEXT_MENU( const CONTEXT_MENU& aMenu ); - virtual ~CONTEXT_MENU() {}; + CONTEXT_MENU& operator=( const CONTEXT_MENU& aMenu ); + + virtual ~CONTEXT_MENU() {} /** * Function SetTitle() @@ -74,7 +76,6 @@ public: */ void Add( const TOOL_ACTION& aAction ); - /** * Function Clear() * Removes all the entries from the menu (as well as its title). It leaves the menu in the diff --git a/include/tool/tool_event.h b/include/tool/tool_event.h index fd6eaa2c72..b140fa3953 100644 --- a/include/tool/tool_event.h +++ b/include/tool/tool_event.h @@ -328,10 +328,10 @@ public: if( m_category == TC_COMMAND || m_category == TC_MESSAGE ) { - if( m_commandStr && aEvent.m_commandStr ) + if( (bool) m_commandStr && (bool) aEvent.m_commandStr ) return *m_commandStr == *aEvent.m_commandStr; - if( m_commandId && aEvent.m_commandId ) + if( (bool) m_commandId && (bool) aEvent.m_commandId ) return *m_commandId == *aEvent.m_commandId; } diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 187b73a45a..8b66ab9a49 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -258,6 +258,7 @@ set( PCBNEW_CLASS_SRCS tools/selection_tool.cpp tools/selection_area.cpp + tools/selection_conditions.cpp tools/bright_box.cpp tools/edit_points.cpp tools/edit_constraints.cpp diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 72cb824dd0..ed69da782b 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -59,11 +59,11 @@ bool EDIT_TOOL::Init() } // Add context menu entries that are displayed when selection tool is active - m_selectionTool->AddMenuItem( COMMON_ACTIONS::editActivate ); - m_selectionTool->AddMenuItem( COMMON_ACTIONS::rotate ); - m_selectionTool->AddMenuItem( COMMON_ACTIONS::flip ); - m_selectionTool->AddMenuItem( COMMON_ACTIONS::remove ); - m_selectionTool->AddMenuItem( COMMON_ACTIONS::properties ); + m_selectionTool->AddMenuItem( COMMON_ACTIONS::editActivate, SELECTION_CONDITIONS::NotEmpty ); + m_selectionTool->AddMenuItem( COMMON_ACTIONS::rotate, SELECTION_CONDITIONS::NotEmpty ); + m_selectionTool->AddMenuItem( COMMON_ACTIONS::flip, SELECTION_CONDITIONS::NotEmpty ); + m_selectionTool->AddMenuItem( COMMON_ACTIONS::remove, SELECTION_CONDITIONS::NotEmpty ); + m_selectionTool->AddMenuItem( COMMON_ACTIONS::properties, SELECTION_CONDITIONS::NotEmpty ); setTransitions(); diff --git a/pcbnew/tools/placement_tool.cpp b/pcbnew/tools/placement_tool.cpp index d436862394..82d7570e5e 100644 --- a/pcbnew/tools/placement_tool.cpp +++ b/pcbnew/tools/placement_tool.cpp @@ -63,7 +63,8 @@ bool PLACEMENT_TOOL::Init() menu->AppendSeparator(); menu->Add( COMMON_ACTIONS::distributeHorizontally ); menu->Add( COMMON_ACTIONS::distributeVertically ); - m_selectionTool->AddSubMenu( menu, wxString( "Align/distribute" ) ); + m_selectionTool->AddSubMenu( menu, wxString( "Align/distribute" ), + SELECTION_CONDITIONS::MoreThan( 1 ) ); setTransitions(); diff --git a/pcbnew/tools/selection_conditions.cpp b/pcbnew/tools/selection_conditions.cpp new file mode 100644 index 0000000000..f1679dac8b --- /dev/null +++ b/pcbnew/tools/selection_conditions.cpp @@ -0,0 +1,120 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 CERN + * @author Maciej Suminski + * + * 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 "selection_conditions.h" +#include "selection_tool.h" + +#include + + +bool SELECTION_CONDITIONS::NotEmpty( const SELECTION& aSelection ) +{ + return !aSelection.Empty(); +} + + +SELECTION_CONDITION SELECTION_CONDITIONS::HasType( KICAD_T aType ) +{ + return boost::bind( &SELECTION_CONDITIONS::hasTypeFunc, _1, aType ); +} + + +SELECTION_CONDITION SELECTION_CONDITIONS::OnlyType( KICAD_T aType ) +{ + return boost::bind( &SELECTION_CONDITIONS::onlyTypeFunc, _1, aType ); +} + + +SELECTION_CONDITION SELECTION_CONDITIONS::Count( int aNumber ) +{ + return boost::bind( &SELECTION_CONDITIONS::countFunc, _1, aNumber ); +} + + +SELECTION_CONDITION SELECTION_CONDITIONS::MoreThan( int aNumber ) +{ + return boost::bind( &SELECTION_CONDITIONS::moreThanFunc, _1, aNumber ); +} + + +SELECTION_CONDITION SELECTION_CONDITIONS::LessThan( int aNumber ) +{ + return boost::bind( &SELECTION_CONDITIONS::lessThanFunc, _1, aNumber ); +} + + +bool SELECTION_CONDITIONS::hasTypeFunc( const SELECTION& aSelection, KICAD_T aType ) +{ + for( int i = 0; i < aSelection.Size(); ++i ) + { + if( aSelection.Item( i )->Type() == aType ) + return true; + } + + return false; +} + + +bool SELECTION_CONDITIONS::onlyTypeFunc( const SELECTION& aSelection, KICAD_T aType ) +{ + for( int i = 0; i < aSelection.Size(); ++i ) + { + if( aSelection.Item( i )->Type() != aType ) + return false; + } + + return true; +} + + +bool SELECTION_CONDITIONS::countFunc( const SELECTION& aSelection, int aNumber ) +{ + return aSelection.Size() == aNumber; +} + + +bool SELECTION_CONDITIONS::moreThanFunc( const SELECTION& aSelection, int aNumber ) +{ + return aSelection.Size() > aNumber; +} + + +bool SELECTION_CONDITIONS::lessThanFunc( const SELECTION& aSelection, int aNumber ) +{ + return aSelection.Size() > aNumber; +} + + +SELECTION_CONDITION operator||( const SELECTION_CONDITION& aConditionA, + const SELECTION_CONDITION& aConditionB ) +{ + return boost::bind( &SELECTION_CONDITIONS::orFunc, aConditionA, aConditionB, _1 ); +} + + +SELECTION_CONDITION operator&&( const SELECTION_CONDITION& aConditionA, + const SELECTION_CONDITION& aConditionB ) +{ + return boost::bind( &SELECTION_CONDITIONS::andFunc, aConditionA, aConditionB, _1 ); +} diff --git a/pcbnew/tools/selection_conditions.h b/pcbnew/tools/selection_conditions.h new file mode 100644 index 0000000000..39827b3bd0 --- /dev/null +++ b/pcbnew/tools/selection_conditions.h @@ -0,0 +1,148 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 CERN + * @author Maciej Suminski + * + * 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 SELECTION_CONDITIONS_H_ +#define SELECTION_CONDITIONS_H_ + +#include +#include + +class SELECTION; + +///> Functor type that checks a specific condition for selected items. +typedef boost::function SELECTION_CONDITION; + +SELECTION_CONDITION operator||( const SELECTION_CONDITION& aConditionA, + const SELECTION_CONDITION& aConditionB ); + +SELECTION_CONDITION operator&&( const SELECTION_CONDITION& aConditionA, + const SELECTION_CONDITION& aConditionB ); + + +/** + * Class that groups generic conditions for selected items. + */ +class SELECTION_CONDITIONS +{ +public: + /** + * Function ShowAlways + * The default condition function (always returns true). + * @param aSelection is the selection to be tested. + * @return Always true; + */ + static bool ShowAlways( const SELECTION& aSelection ) + { + return true; + } + + /** + * Function NotEmpty + * Tests if there are any items selected. + * @param aSelection is the selection to be tested. + * @return True if there is at least one item selected. + */ + static bool NotEmpty( const SELECTION& aSelection ); + + /** + * Function HasType + * Creates functor that tests if among the selected items there is at least one of a given type. + * @param aType is the type that is searched. + * @return Functor testing for presence of items of a given type. + */ + static SELECTION_CONDITION HasType( KICAD_T aType ); + + /** + * Function OnlyType + * Creates functor that tests if the selected items are *only* of given type. + * @param aType is the type that is searched. + * @return Functor testing if selected items are exclusively of one type.. + */ + static SELECTION_CONDITION OnlyType( KICAD_T aType ); + + /** + * Function Count + * Creates functor that tests if the number of selected items is equal to the value given as + * parameter. + * @param aNumber is the number of expected items. + * @return Functor testing if the number of selected items is equal aNumber. + */ + static SELECTION_CONDITION Count( int aNumber ); + + /** + * Function MoreThan + * Creates functor that tests if the number of selected items is greater than the value given + * as parameter. + * @param aNumber is the number used for comparison. + * @return Functor testing if the number of selected items is greater than aNumber. + */ + static SELECTION_CONDITION MoreThan( int aNumber ); + + /** + * Function LessThan + * Creates functor that tests if the number of selected items is smaller than the value given + * as parameter. + * @param aNumber is the number used for comparison. + * @return Functor testing if the number of selected items is smaller than aNumber. + */ + static SELECTION_CONDITION LessThan( int aNumber ); + +private: + ///> Helper function used by HasType() + static bool hasTypeFunc( const SELECTION& aSelection, KICAD_T aType ); + + ///> Helper function used by OnlyType() + static bool onlyTypeFunc( const SELECTION& aSelection, KICAD_T aType ); + + ///> Helper function used by Count() + static bool countFunc( const SELECTION& aSelection, int aNumber ); + + ///> Helper function used by MoreThan() + static bool moreThanFunc( const SELECTION& aSelection, int aNumber ); + + ///> Helper function used by LessThan() + static bool lessThanFunc( const SELECTION& aSelection, int aNumber ); + + ///> Helper function used by operator|| + static bool orFunc( const SELECTION_CONDITION& aConditionA, + const SELECTION_CONDITION& aConditionB, const SELECTION& aSelection ) + { + return aConditionA( aSelection ) || aConditionB( aSelection ); + } + + ///> Helper function used by operator&& + static bool andFunc( const SELECTION_CONDITION& aConditionA, + const SELECTION_CONDITION& aConditionB, const SELECTION& aSelection ) + { + return aConditionA( aSelection ) && aConditionB( aSelection ); + } + + friend SELECTION_CONDITION operator||( const SELECTION_CONDITION& aConditionA, + const SELECTION_CONDITION& aConditionB ); + + friend SELECTION_CONDITION operator&&( const SELECTION_CONDITION& aConditionA, + const SELECTION_CONDITION& aConditionB ); +}; + +#endif /* SELECTION_CONDITIONS_H_ */ diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 2fa5508685..b281091923 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -117,8 +117,7 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) if( m_selection.Empty() ) selectSingle( evt->Position() ); - if( !m_selection.Empty() ) - SetContextMenu( &m_menu, CMENU_NOW ); + generateMenu(); } // double click? Display the properties window @@ -188,17 +187,19 @@ int SELECTION_TOOL::Main( TOOL_EVENT& aEvent ) } -void SELECTION_TOOL::AddMenuItem( const TOOL_ACTION& aAction ) +void SELECTION_TOOL::AddMenuItem( const TOOL_ACTION& aAction, const SELECTION_CONDITION& aCondition ) { assert( aAction.GetId() > 0 ); // Check if the action was registered before in ACTION_MANAGER m_menu.Add( aAction ); + m_menuConditions.push_back( aCondition ); } -void SELECTION_TOOL::AddSubMenu( CONTEXT_MENU* aMenu, const wxString& aLabel ) +void SELECTION_TOOL::AddSubMenu( CONTEXT_MENU* aMenu, const wxString& aLabel, const SELECTION_CONDITION& aCondition ) { m_menu.AppendSubMenu( aMenu, aLabel ); + m_menuConditions.push_back( aCondition ); } @@ -420,9 +421,6 @@ void SELECTION_TOOL::clearSelection() getEditFrame()->SetCurItem( NULL ); - // Do not show the context menu when there is nothing selected - SetContextMenu( &m_menu, CMENU_OFF ); - // Inform other potentially interested tools TOOL_EVENT clearEvent( ClearedEvent ); m_toolMgr->ProcessEvent( clearEvent ); @@ -622,14 +620,10 @@ void SELECTION_TOOL::select( BOARD_ITEM* aItem ) ITEM_PICKER picker( aItem ); m_selection.items.PushItem( picker ); - // It is enough to do it only for the first selected item if( m_selection.Size() == 1 ) { // Set as the current item, so the information about selection is displayed m_frame->SetCurItem( aItem, true ); - - // Now the context menu should be enabled - SetContextMenu( &m_menu, CMENU_BUTTON ); } else if( m_selection.Size() == 2 ) // Check only for 2, so it will not be { // called for every next selected item @@ -655,12 +649,8 @@ void SELECTION_TOOL::deselect( BOARD_ITEM* aItem ) if( itemIdx >= 0 ) m_selection.items.RemovePicker( itemIdx ); - // If there is nothing selected, disable the context menu if( m_selection.Empty() ) - { - SetContextMenu( &m_menu, CMENU_OFF ); m_frame->SetCurItem( NULL ); - } // Inform other potentially interested tools TOOL_EVENT deselected( DeselectedEvent ); @@ -764,6 +754,28 @@ BOARD_ITEM* SELECTION_TOOL::prefer( GENERAL_COLLECTOR& aCollector, const KICAD_T } +void SELECTION_TOOL::generateMenu() +{ + // Create a copy of the master context menu + m_menuCopy = m_menu; + + assert( m_menuCopy.GetMenuItemCount() == m_menuConditions.size() ); + + // Filter out entries that does not apply to the current selection + for( int i = m_menuCopy.GetMenuItemCount() - 1; i >= 0; --i ) + { + if( !m_menuConditions[i]( m_selection ) ) + { + wxMenuItem* item = m_menuCopy.FindItemByPosition( i ); + m_menuCopy.Destroy( item ); + } + } + + if( m_menuCopy.GetMenuItemCount() > 0 ) + SetContextMenu( &m_menuCopy, CMENU_NOW ); +} + + void SELECTION::clear() { items.ClearItemsList(); diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index 55108221a3..06a0af35e6 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -31,6 +31,8 @@ #include #include +#include "selection_conditions.h" + class PCB_BASE_FRAME; class SELECTION_AREA; class BOARD_ITEM; @@ -118,8 +120,10 @@ public: * * Adds a menu entry to run a TOOL_ACTION on selected items. * @param aAction is a menu entry to be added. + * @param aCondition is a condition that has to be fulfilled to enable the menu entry. */ - void AddMenuItem( const TOOL_ACTION& aAction ); + void AddMenuItem( const TOOL_ACTION& aAction, + const SELECTION_CONDITION& aCondition = SELECTION_CONDITIONS::ShowAlways ); /** * Function AddSubMenu() @@ -127,11 +131,14 @@ public: * Adds a submenu to the selection tool right-click context menu. * @param aMenu is the submenu to be added. * @param aLabel is the label of added submenu. + * @param aCondition is a condition that has to be fulfilled to enable the submenu entry. */ - void AddSubMenu( CONTEXT_MENU* aMenu, const wxString& aLabel ); + void AddSubMenu( CONTEXT_MENU* aMenu, const wxString& aLabel, + const SELECTION_CONDITION& aCondition = SELECTION_CONDITIONS::ShowAlways ); /** * Function EditModules() + * * Toggles edit module mode. When enabled, one may select parts of modules individually * (graphics, pads, etc.), so they can be modified. * @param aEnabled decides if the mode should be enabled. @@ -275,26 +282,39 @@ private: */ BOARD_ITEM* prefer( GENERAL_COLLECTOR& aCollector, const KICAD_T aTypes[] ) const; + /** + * Function generateMenu() + * Creates a copy of context menu that is filtered by menu conditions and displayed to + * the user. + */ + void generateMenu(); + /// Pointer to the parent frame. PCB_BASE_FRAME* m_frame; - /// Visual representation of selection box + /// Visual representation of selection box. SELECTION_AREA* m_selArea; - /// Current state of selection + /// Current state of selection. SELECTION m_selection; - /// Flag saying if items should be added to the current selection or rather replace it + /// Flag saying if items should be added to the current selection or rather replace it. bool m_additive; - /// Flag saying if multiple selection mode is active + /// Flag saying if multiple selection mode is active. bool m_multiple; - /// Right click popup menu + /// Right click popup menu (master instance). CONTEXT_MENU m_menu; - /// Edit module mode flag + /// Copy of the context menu that is filtered by menu conditions and displayed to the user. + CONTEXT_MENU m_menuCopy; + + /// Edit module mode flag. bool m_editModules; + + /// Conditions for specific context menu entries. + std::deque m_menuConditions; }; #endif From 30ea3b7962af3c6e492bee14913e905e63dab453 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:10:32 +0200 Subject: [PATCH 092/123] Fixed module viewer crash. --- pcbnew/modview_frame.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp index cd0622fd12..75a20bcdee 100644 --- a/pcbnew/modview_frame.cpp +++ b/pcbnew/modview_frame.cpp @@ -149,6 +149,8 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent m_footprintList = new wxListBox( this, ID_MODVIEW_FOOTPRINT_LIST, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_HSCROLL ); + SetBoard( new BOARD() ); + // Ensure all layers and items are visible: GetBoard()->SetVisibleAlls(); SetScreen( new PCB_SCREEN( GetPageSizeIU() ) ); From d4487f19257b237c589f0c8a4220853e35330a95 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:10:32 +0200 Subject: [PATCH 093/123] Fixed autozooming with empty board/module. --- pcbnew/moduleframe.cpp | 20 +------------------- pcbnew/modview_frame.cpp | 26 ++++++++++++++++++++------ pcbnew/modview_frame.h | 2 +- pcbnew/tools/pcbnew_control.cpp | 28 ++++++++++++++++++++-------- 4 files changed, 42 insertions(+), 34 deletions(-) diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index a3af6dc5fe..bd5b92e70a 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -696,24 +696,6 @@ void FOOTPRINT_EDIT_FRAME::updateTitle() void FOOTPRINT_EDIT_FRAME::updateView() { static_cast( GetGalCanvas() )->DisplayBoard( GetBoard() ); - - m_Pcb->ComputeBoundingBox( false ); - EDA_RECT boardBbox = m_Pcb->GetBoundingBox(); - BOX2D bbox; - - if( boardBbox.GetSize().x > 0 && boardBbox.GetSize().y > 0 ) - { - bbox.SetOrigin( VECTOR2D( boardBbox.GetOrigin() ) ); - bbox.SetSize( VECTOR2D( boardBbox.GetSize() ) ); - } - else - { - // Default empty view - bbox.SetOrigin( VECTOR2D( -1000, -1000 ) ); - bbox.SetSize( VECTOR2D( 2000, 2000 ) ); - } - - GetGalCanvas()->GetView()->SetViewport( bbox ); - + m_toolManager->RunAction( COMMON_ACTIONS::zoomFitScreen ); m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD ); } diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp index 75a20bcdee..3404a5b349 100644 --- a/pcbnew/modview_frame.cpp +++ b/pcbnew/modview_frame.cpp @@ -466,7 +466,7 @@ void FOOTPRINT_VIEWER_FRAME::ClickOnFootprintList( wxCommandEvent& event ) UpdateTitle(); if( IsGalCanvasActive() ) - redrawGal(); + updateView(); Zoom_Automatique( false ); m_canvas->Refresh(); @@ -851,7 +851,7 @@ void FOOTPRINT_VIEWER_FRAME::SelectAndViewFootprint( int aMode ) Update3D_Frame(); if( IsGalCanvasActive() ) - redrawGal(); + updateView(); } @@ -880,12 +880,26 @@ void FOOTPRINT_VIEWER_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg ) } -void FOOTPRINT_VIEWER_FRAME::redrawGal() +void FOOTPRINT_VIEWER_FRAME::updateView() { - static_cast( GetGalCanvas() )->DisplayBoard( m_Pcb ); + static_cast( GetGalCanvas() )->DisplayBoard( GetBoard() ); - // Autozoom m_Pcb->ComputeBoundingBox( false ); EDA_RECT boardBbox = m_Pcb->GetBoundingBox(); - GetGalCanvas()->GetView()->SetViewport( BOX2D( boardBbox.GetOrigin(), boardBbox.GetSize() ) ); + BOX2D bbox; + + // Autozoom + if( boardBbox.GetSize().x > 0 && boardBbox.GetSize().y > 0 ) + { + bbox.SetOrigin( VECTOR2D( boardBbox.GetOrigin() ) ); + bbox.SetSize( VECTOR2D( boardBbox.GetSize() ) ); + } + else + { + // Default empty view + bbox.SetOrigin( VECTOR2D( -1000, -1000 ) ); + bbox.SetSize( VECTOR2D( 2000, 2000 ) ); + } + + GetGalCanvas()->GetView()->SetViewport( bbox ); } diff --git a/pcbnew/modview_frame.h b/pcbnew/modview_frame.h index 4dd1210979..311f150ed8 100644 --- a/pcbnew/modview_frame.h +++ b/pcbnew/modview_frame.h @@ -172,7 +172,7 @@ private: void SaveCopyInUndoList( BOARD_ITEM*, UNDO_REDO_T, const wxPoint& ) {} void SaveCopyInUndoList( const PICKED_ITEMS_LIST&, UNDO_REDO_T, const wxPoint &) {} - void redrawGal(); + void updateView(); DECLARE_EVENT_TABLE() }; diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index 3eba7f495b..0a75ce975e 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -109,17 +109,29 @@ int PCBNEW_CONTROL::ZoomFitScreen( TOOL_EVENT& aEvent ) KIGFX::VIEW* view = m_frame->GetGalCanvas()->GetView(); KIGFX::GAL* gal = m_frame->GetGalCanvas()->GetGAL(); BOX2I boardBBox = getModel()->ViewBBox(); - VECTOR2I screenSize = gal->GetScreenPixelSize(); - double iuPerX = screenSize.x ? boardBBox.GetWidth() / screenSize.x : 1.0; - double iuPerY = screenSize.y ? boardBBox.GetHeight() / screenSize.y : 1.0; + if( boardBBox.GetSize().x == 0 || boardBBox.GetSize().y == 0 ) + { + // Empty view + view->SetScale( 100000.0 ); + view->SetCenter( VECTOR2D( 0, 0 ) ); + } + else + { + // Autozoom to board + VECTOR2I screenSize = gal->GetScreenPixelSize(); - double bestZoom = std::max( iuPerX, iuPerY ); - double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor(); - double zoom = 1.0 / ( zoomFactor * bestZoom ); + double iuPerX = screenSize.x ? boardBBox.GetWidth() / screenSize.x : 1.0; + double iuPerY = screenSize.y ? boardBBox.GetHeight() / screenSize.y : 1.0; + + double bestZoom = std::max( iuPerX, iuPerY ); + double zoomFactor = gal->GetWorldScale() / gal->GetZoomFactor(); + double zoom = 1.0 / ( zoomFactor * bestZoom ); + + view->SetScale( zoom ); + view->SetCenter( boardBBox.Centre() ); + } - view->SetScale( zoom ); - view->SetCenter( boardBBox.Centre() ); setTransitions(); return 0; From 0b51dd7e018063d30b6f5c17ef8cbe8a5af17062 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:10:32 +0200 Subject: [PATCH 094/123] Added support for changing the cursor size. --- common/gal/cairo/cairo_gal.cpp | 16 ++++++++++++++++ include/gal/cairo/cairo_gal.h | 3 +++ include/gal/graphics_abstraction_layer.h | 12 +++++++++++- pcbnew/tools/common_actions.cpp | 20 +++++++++++++++----- pcbnew/tools/common_actions.h | 1 + pcbnew/tools/pcbnew_control.cpp | 19 +++++++++++++++++++ pcbnew/tools/pcbnew_control.h | 1 + 7 files changed, 66 insertions(+), 6 deletions(-) diff --git a/common/gal/cairo/cairo_gal.cpp b/common/gal/cairo/cairo_gal.cpp index 73ca64294d..b0b033d037 100644 --- a/common/gal/cairo/cairo_gal.cpp +++ b/common/gal/cairo/cairo_gal.cpp @@ -75,6 +75,9 @@ CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, SetSize( aParent->GetSize() ); screenSize = VECTOR2I( aParent->GetSize() ); + + cursorPixels = NULL; + cursorPixelsSaved = NULL; initCursor(); // Grid color settings are different in Cairo and OpenGL @@ -808,6 +811,13 @@ void CAIRO_GAL::ClearTarget( RENDER_TARGET aTarget ) } +void CAIRO_GAL::SetCursorSize( unsigned int aCursorSize ) +{ + GAL::SetCursorSize( aCursorSize ); + initCursor(); +} + + void CAIRO_GAL::DrawCursor( const VECTOR2D& aCursorPosition ) { // Now we should only store the position of the mouse cursor @@ -890,6 +900,12 @@ void CAIRO_GAL::skipMouseEvent( wxMouseEvent& aEvent ) void CAIRO_GAL::initCursor() { + if( cursorPixels ) + delete cursorPixels; + + if( cursorPixelsSaved ) + delete cursorPixelsSaved; + cursorPixels = new wxBitmap( cursorSize, cursorSize ); cursorPixelsSaved = new wxBitmap( cursorSize, cursorSize ); diff --git a/include/gal/cairo/cairo_gal.h b/include/gal/cairo/cairo_gal.h index e0b1dba963..dca18acc05 100644 --- a/include/gal/cairo/cairo_gal.h +++ b/include/gal/cairo/cairo_gal.h @@ -229,6 +229,9 @@ public: // Cursor // ------- + /// @copydoc GAL::SetCursorSize() + virtual void SetCursorSize( unsigned int aCursorSize ); + /// @copydoc GAL::DrawCursor() virtual void DrawCursor( const VECTOR2D& aCursorPosition ); diff --git a/include/gal/graphics_abstraction_layer.h b/include/gal/graphics_abstraction_layer.h index f607e96975..3fef15d1fc 100644 --- a/include/gal/graphics_abstraction_layer.h +++ b/include/gal/graphics_abstraction_layer.h @@ -783,12 +783,22 @@ public: cursorColor = aCursorColor; } + /** + * @brief Returns the cursor size. + * + * @return The current cursor size (in pixels). + */ + inline unsigned int GetCursorSize() const + { + return cursorSize; + } + /** * @brief Set the cursor size. * * @param aCursorSize is the size of the cursor expressed in pixels. */ - inline void SetCursorSize( unsigned int aCursorSize ) + virtual inline void SetCursorSize( unsigned int aCursorSize ) { cursorSize = aCursorSize; } diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index c1b538ba04..3e2118eb84 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -29,13 +29,16 @@ // Selection tool actions TOOL_ACTION COMMON_ACTIONS::selectionActivate( "pcbnew.InteractiveSelection", - AS_GLOBAL, 0, "", "", AF_ACTIVATE ); // No description, it is not supposed to be shown anywhere + AS_GLOBAL, 0, + "", "", AF_ACTIVATE ); // No description, it is not supposed to be shown anywhere TOOL_ACTION COMMON_ACTIONS::selectionSingle( "pcbnew.InteractiveSelection.Single", - AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere + AS_GLOBAL, 0, + "", "" ); // No description, it is not supposed to be shown anywhere TOOL_ACTION COMMON_ACTIONS::selectionClear( "pcbnew.InteractiveSelection.Clear", - AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere + AS_GLOBAL, 0, + "", "" ); // No description, it is not supposed to be shown anywhere // Edit tool actions @@ -287,6 +290,10 @@ TOOL_ACTION COMMON_ACTIONS::resetCoords( "pcbnew.Control.resetCoords", AS_GLOBAL, ' ', "", "" ); +TOOL_ACTION COMMON_ACTIONS::switchCursor( "pcbnew.Control.switchCursor", + AS_GLOBAL, 0, + "", "" ); + TOOL_ACTION COMMON_ACTIONS::switchUnits( "pcbnew.Control.switchUnits", AS_GLOBAL, MD_CTRL + int( 'U' ), "", "" ); @@ -304,7 +311,8 @@ TOOL_ACTION COMMON_ACTIONS::routerActivate( "pcbnew.InteractiveRouter", "Run push & shove router", "Run push & shove router", AF_ACTIVATE ); TOOL_ACTION COMMON_ACTIONS::pointEditorUpdate( "pcbnew.PointEditor.update", - AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere + AS_GLOBAL, 0, + "", "" ); // No description, it is not supposed to be shown anywhere // Placement tool @@ -420,6 +428,9 @@ boost::optional COMMON_ACTIONS::TranslateLegacyId( int aId ) case ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE: return COMMON_ACTIONS::highContrastMode.MakeEvent(); + case ID_TB_OPTIONS_SELECT_CURSOR: + return COMMON_ACTIONS::switchCursor.MakeEvent(); + case ID_TB_OPTIONS_SHOW_MODULE_EDGE_SKETCH: case ID_TB_OPTIONS_SHOW_MODULE_TEXT_SKETCH: case ID_PCB_DELETE_ITEM_BUTT: @@ -427,7 +438,6 @@ boost::optional COMMON_ACTIONS::TranslateLegacyId( int aId ) case ID_PCB_SHOW_1_RATSNEST_BUTT: case ID_PCB_PLACE_OFFSET_COORD_BUTT: case ID_TB_OPTIONS_SHOW_MODULE_RATSNEST: - case ID_TB_OPTIONS_SELECT_CURSOR: case ID_TB_OPTIONS_SHOW_EXTRA_VERTICAL_TOOLBAR_MICROWAVE: case ID_MENU_PCB_SHOW_HIDE_MUWAVE_TOOLBAR: case ID_MICROWAVE_V_TOOLBAR: diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 78bc6f50d1..a47513acd9 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -189,6 +189,7 @@ public: // Miscellaneous static TOOL_ACTION resetCoords; + static TOOL_ACTION switchCursor; static TOOL_ACTION switchUnits; static TOOL_ACTION showHelp; static TOOL_ACTION toBeDone; diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index 0a75ce975e..2d92566530 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -541,6 +541,24 @@ int PCBNEW_CONTROL::ResetCoords( TOOL_EVENT& aEvent ) } +int PCBNEW_CONTROL::SwitchCursor( TOOL_EVENT& aEvent ) +{ + const unsigned int BIG_CURSOR = 4000; + const unsigned int SMALL_CURSOR = 80; + + KIGFX::GAL* gal = getEditFrame()->GetGalCanvas()->GetGAL(); + + if( gal->GetCursorSize() == BIG_CURSOR ) + gal->SetCursorSize( SMALL_CURSOR ); + else + gal->SetCursorSize( BIG_CURSOR ); + + setTransitions(); + + return 0; +} + + int PCBNEW_CONTROL::SwitchUnits( TOOL_EVENT& aEvent ) { // TODO should not it be refactored to pcb_frame member function? @@ -621,6 +639,7 @@ void PCBNEW_CONTROL::setTransitions() // Miscellaneous Go( &PCBNEW_CONTROL::ResetCoords, COMMON_ACTIONS::resetCoords.MakeEvent() ); + Go( &PCBNEW_CONTROL::SwitchCursor, COMMON_ACTIONS::switchCursor.MakeEvent() ); Go( &PCBNEW_CONTROL::SwitchUnits, COMMON_ACTIONS::switchUnits.MakeEvent() ); Go( &PCBNEW_CONTROL::ShowHelp, COMMON_ACTIONS::showHelp.MakeEvent() ); Go( &PCBNEW_CONTROL::ToBeDone, COMMON_ACTIONS::toBeDone.MakeEvent() ); diff --git a/pcbnew/tools/pcbnew_control.h b/pcbnew/tools/pcbnew_control.h index 61f7d5d511..4c11b9777b 100644 --- a/pcbnew/tools/pcbnew_control.h +++ b/pcbnew/tools/pcbnew_control.h @@ -90,6 +90,7 @@ public: // Miscellaneous int ResetCoords( TOOL_EVENT& aEvent ); + int SwitchCursor( TOOL_EVENT& aEvent ); int SwitchUnits( TOOL_EVENT& aEvent ); int ShowHelp( TOOL_EVENT& aEvent ); int ToBeDone( TOOL_EVENT& aEvent ); From 21a86dc6461063574cc30ce23a165ba4d6c428d9 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:10:32 +0200 Subject: [PATCH 095/123] Modules inserted from the module editor are instantly visible in GAL. Ratsnest is updated after exporting changes from the module editor to the layout editor. --- pcbnew/modedit.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp index 3abe8f08ad..933339b3e3 100644 --- a/pcbnew/modedit.cpp +++ b/pcbnew/modedit.cpp @@ -45,6 +45,7 @@ #include #include +#include #include #include #include @@ -59,6 +60,8 @@ #include #include +#include + // Functions defined in block_module_editor, but used here // These 2 functions are used in modedit to rotate or mirror the whole footprint @@ -452,15 +455,31 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) pcbframe->SetCrossHairPosition( wxPoint( 0, 0 ) ); pcbframe->PlaceModule( newmodule, NULL ); + newmodule->SetPosition( wxPoint( 0, 0 ) ); pcbframe->SetCrossHairPosition( cursor_pos ); newmodule->SetTimeStamp( GetNewTimeStamp() ); pcbframe->SaveCopyInUndoList( newmodule, UR_NEW ); + + if( IsGalCanvasActive() ) + { + KIGFX::VIEW* view = pcbframe->GetGalCanvas()->GetView(); + + newmodule->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) ); + view->Add( newmodule ); + } } newmodule->ClearFlags(); GetScreen()->ClrModify(); pcbframe->SetCurItem( NULL ); mainpcb->m_Status_Pcb = 0; + + if( IsGalCanvasActive() ) + { + RN_DATA* ratsnest = pcbframe->GetBoard()->GetRatsnest(); + ratsnest->Update( newmodule ); + ratsnest->Recalculate(); + } } break; From 23b113b0c37d7ac3e761cbe2e23b0b429b60513c Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:10:32 +0200 Subject: [PATCH 096/123] Outline display mode for module edges & texts in the module editor. --- pcbnew/pcb_painter.cpp | 59 +++++++++++++++++++---- pcbnew/pcb_painter.h | 8 +--- pcbnew/tools/common_actions.cpp | 16 ++++++- pcbnew/tools/common_actions.h | 6 +++ pcbnew/tools/module_tools.cpp | 85 +++++++++++++++++++++++++++++++-- pcbnew/tools/module_tools.h | 14 ++++++ 6 files changed, 165 insertions(+), 23 deletions(-) diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 6d42a29d64..fce609d27e 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -223,7 +223,7 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer ) case PCB_LINE_T: case PCB_MODULE_EDGE_T: - draw( (DRAWSEGMENT*) item ); + draw( (DRAWSEGMENT*) item, aLayer ); break; case PCB_TEXT_T: @@ -325,6 +325,7 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer ) m_gal->SetFillColor( color ); m_gal->SetIsFill( true ); } + m_gal->DrawSegment( start, end, width ); } } @@ -622,14 +623,26 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer ) } -void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment ) +void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment, int aLayer ) { const COLOR4D& color = m_pcbSettings.GetColor( aSegment, aSegment->GetLayer() ); - m_gal->SetIsFill( false ); m_gal->SetIsStroke( true ); m_gal->SetStrokeColor( color ); - m_gal->SetLineWidth( aSegment->GetWidth() ); + + if( m_pcbSettings.m_sketchMode[aLayer] ) + { + // Outline mode + m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth ); + m_gal->SetIsFill( false ); + } + else + { + // Filled mode + m_gal->SetLineWidth( aSegment->GetWidth() ); + m_gal->SetFillColor( color ); + m_gal->SetIsFill( true ); + } switch( aSegment->GetShape() ) { @@ -704,12 +717,25 @@ void PCB_PAINTER::draw( const TEXTE_PCB* aText, int aLayer ) if( aText->GetText().Length() == 0 ) return; - const COLOR4D& strokeColor = m_pcbSettings.GetColor( aText, aText->GetLayer() ); + const COLOR4D& color = m_pcbSettings.GetColor( aText, aText->GetLayer() ); VECTOR2D position( aText->GetTextPosition().x, aText->GetTextPosition().y ); double orientation = aText->GetOrientation() * M_PI / 1800.0; - m_gal->SetStrokeColor( strokeColor ); - m_gal->SetLineWidth( aText->GetThickness() ); + if( m_pcbSettings.m_sketchMode[aLayer] ) + { + // Outline mode + m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth ); + m_gal->SetIsFill( false ); + } + else + { + // Filled mode + m_gal->SetLineWidth( aText->GetThickness() ); + m_gal->SetFillColor( color ); + m_gal->SetIsFill( true ); + } + + m_gal->SetStrokeColor( color ); m_gal->SetTextAttributes( aText ); m_gal->StrokeText( aText->GetText(), position, orientation ); } @@ -720,12 +746,25 @@ void PCB_PAINTER::draw( const TEXTE_MODULE* aText, int aLayer ) if( aText->GetLength() == 0 ) return; - const COLOR4D& strokeColor = m_pcbSettings.GetColor( aText, aLayer ); + const COLOR4D& color = m_pcbSettings.GetColor( aText, aLayer ); VECTOR2D position( aText->GetTextPosition().x, aText->GetTextPosition().y ); double orientation = aText->GetDrawRotation() * M_PI / 1800.0; - m_gal->SetStrokeColor( strokeColor ); - m_gal->SetLineWidth( aText->GetThickness() ); + if( m_pcbSettings.m_sketchMode[aLayer] ) + { + // Outline mode + m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth ); + m_gal->SetIsFill( false ); + } + else + { + // Filled mode + m_gal->SetLineWidth( aText->GetThickness() ); + m_gal->SetFillColor( color ); + m_gal->SetIsFill( true ); + } + + m_gal->SetStrokeColor( color ); m_gal->SetTextAttributes( aText ); m_gal->StrokeText( aText->GetText(), position, orientation ); } diff --git a/pcbnew/pcb_painter.h b/pcbnew/pcb_painter.h index 93bcb034f7..2b79696ec3 100644 --- a/pcbnew/pcb_painter.h +++ b/pcbnew/pcb_painter.h @@ -124,9 +124,6 @@ public: */ inline void SetSketchMode( int aItemLayer, bool aEnabled ) { - // It is supposed to work only with item layers - assert( aItemLayer >= ITEM_GAL_LAYER( 0 ) ); - m_sketchMode[aItemLayer] = aEnabled; } @@ -137,9 +134,6 @@ public: */ inline bool GetSketchMode( int aItemLayer ) const { - // It is supposed to work only with item layers - assert( aItemLayer >= ITEM_GAL_LAYER( 0 ) ); - return m_sketchMode[aItemLayer]; } @@ -210,7 +204,7 @@ protected: void draw( const TRACK* aTrack, int aLayer ); void draw( const VIA* aVia, int aLayer ); void draw( const D_PAD* aPad, int aLayer ); - void draw( const DRAWSEGMENT* aSegment ); + void draw( const DRAWSEGMENT* aSegment, int aLayer ); void draw( const TEXTE_PCB* aText, int aLayer ); void draw( const TEXTE_MODULE* aText, int aLayer ); void draw( const MODULE* aModule ); diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 3e2118eb84..0e1ebc0818 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -284,6 +284,14 @@ TOOL_ACTION COMMON_ACTIONS::pasteItems( "pcbnew.ModuleEditor.pasteItems", AS_GLOBAL, MD_CTRL + int( 'V' ), "Paste items", "Paste items", AF_ACTIVATE ); +TOOL_ACTION COMMON_ACTIONS::moduleEdgeOutlines( "pcbnew.ModuleEditor.graphicOutlines", + AS_GLOBAL, 0, + "", "" ); + +TOOL_ACTION COMMON_ACTIONS::moduleTextOutlines( "pcbnew.ModuleEditor.textOutlines", + AS_GLOBAL, 0, + "", "" ); + // Miscellaneous TOOL_ACTION COMMON_ACTIONS::resetCoords( "pcbnew.Control.resetCoords", @@ -425,14 +433,18 @@ boost::optional COMMON_ACTIONS::TranslateLegacyId( int aId ) case ID_TB_OPTIONS_SHOW_ZONES_OUTLINES_ONLY: return COMMON_ACTIONS::zoneDisplayOutlines.MakeEvent(); + case ID_TB_OPTIONS_SHOW_MODULE_EDGE_SKETCH: + return COMMON_ACTIONS::moduleEdgeOutlines.MakeEvent(); + + case ID_TB_OPTIONS_SHOW_MODULE_TEXT_SKETCH: + return COMMON_ACTIONS::moduleTextOutlines.MakeEvent(); + case ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE: return COMMON_ACTIONS::highContrastMode.MakeEvent(); case ID_TB_OPTIONS_SELECT_CURSOR: return COMMON_ACTIONS::switchCursor.MakeEvent(); - case ID_TB_OPTIONS_SHOW_MODULE_EDGE_SKETCH: - case ID_TB_OPTIONS_SHOW_MODULE_TEXT_SKETCH: case ID_PCB_DELETE_ITEM_BUTT: case ID_PCB_HIGHLIGHT_BUTT: case ID_PCB_SHOW_1_RATSNEST_BUTT: diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index a47513acd9..fb53fed993 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -186,6 +186,12 @@ public: /// Pasting module items from clipboard static TOOL_ACTION pasteItems; + /// Display module edges as outlines + static TOOL_ACTION moduleEdgeOutlines; + + /// Display module texts as outlines + static TOOL_ACTION moduleTextOutlines; + // Miscellaneous static TOOL_ACTION resetCoords; diff --git a/pcbnew/tools/module_tools.cpp b/pcbnew/tools/module_tools.cpp index a23dec3be3..e9302b6c60 100644 --- a/pcbnew/tools/module_tools.cpp +++ b/pcbnew/tools/module_tools.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -531,10 +532,86 @@ int MODULE_TOOLS::PasteItems( TOOL_EVENT& aEvent ) } +int MODULE_TOOLS::ModuleTextOutlines( TOOL_EVENT& aEvent ) +{ + KIGFX::PCB_PAINTER* painter = + static_cast( m_frame->GetGalCanvas()->GetView()->GetPainter() ); + KIGFX::PCB_RENDER_SETTINGS* settings = + static_cast( painter->GetSettings() ); + + const LAYER_NUM layers[] = { ITEM_GAL_LAYER( MOD_TEXT_BK_VISIBLE ), + ITEM_GAL_LAYER( MOD_TEXT_FR_VISIBLE ), + ITEM_GAL_LAYER( MOD_TEXT_INVISIBLE ), + ITEM_GAL_LAYER( MOD_REFERENCES_VISIBLE ), + ITEM_GAL_LAYER( MOD_VALUES_VISIBLE ) }; + + bool enable = !settings->GetSketchMode( layers[0] ); + + BOOST_FOREACH( LAYER_NUM layer, layers ) + settings->SetSketchMode( layer, enable ); + + for( MODULE* module = getModel()->m_Modules; module; module = module->Next() ) + { + for( BOARD_ITEM* item = module->GraphicalItems(); item; item = item ->Next() ) + { + if( item->Type() == PCB_MODULE_TEXT_T ) + item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + + module->Reference().ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + module->Value().ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + + m_frame->GetGalCanvas()->Refresh(); + setTransitions(); + + return 0; +} + + +int MODULE_TOOLS::ModuleEdgeOutlines( TOOL_EVENT& aEvent ) +{ + KIGFX::PCB_PAINTER* painter = + static_cast( m_frame->GetGalCanvas()->GetView()->GetPainter() ); + KIGFX::PCB_RENDER_SETTINGS* settings = + static_cast( painter->GetSettings() ); + + const LAYER_NUM layers[] = { ADHESIVE_N_FRONT, ADHESIVE_N_BACK,\ + SOLDERPASTE_N_FRONT, SOLDERPASTE_N_BACK,\ + SILKSCREEN_N_FRONT, SILKSCREEN_N_BACK,\ + SOLDERMASK_N_FRONT, SOLDERMASK_N_BACK,\ + DRAW_N,\ + COMMENT_N,\ + ECO1_N, ECO2_N,\ + EDGE_N }; + + bool enable = !settings->GetSketchMode( layers[0] ); + + BOOST_FOREACH( LAYER_NUM layer, layers ) + settings->SetSketchMode( layer, enable ); + + for( MODULE* module = getModel()->m_Modules; module; module = module->Next() ) + { + for( BOARD_ITEM* item = module->GraphicalItems(); item; item = item ->Next() ) + { + if( item->Type() == PCB_MODULE_EDGE_T ) + item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); + } + } + + m_frame->GetGalCanvas()->Refresh(); + setTransitions(); + + return 0; +} + + void MODULE_TOOLS::setTransitions() { - Go( &MODULE_TOOLS::PlacePad, COMMON_ACTIONS::placePad.MakeEvent() ); - Go( &MODULE_TOOLS::EnumeratePads, COMMON_ACTIONS::enumeratePads.MakeEvent() ); - Go( &MODULE_TOOLS::CopyItems, COMMON_ACTIONS::copyItems.MakeEvent() ); - Go( &MODULE_TOOLS::PasteItems, COMMON_ACTIONS::pasteItems.MakeEvent() ); + Go( &MODULE_TOOLS::PlacePad, COMMON_ACTIONS::placePad.MakeEvent() ); + Go( &MODULE_TOOLS::EnumeratePads, COMMON_ACTIONS::enumeratePads.MakeEvent() ); + Go( &MODULE_TOOLS::CopyItems, COMMON_ACTIONS::copyItems.MakeEvent() ); + Go( &MODULE_TOOLS::PasteItems, COMMON_ACTIONS::pasteItems.MakeEvent() ); + Go( &MODULE_TOOLS::ModuleTextOutlines, COMMON_ACTIONS::moduleTextOutlines.MakeEvent() ); + Go( &MODULE_TOOLS::ModuleEdgeOutlines, COMMON_ACTIONS::moduleEdgeOutlines.MakeEvent() ); } diff --git a/pcbnew/tools/module_tools.h b/pcbnew/tools/module_tools.h index 64899e4182..71d83acc7e 100644 --- a/pcbnew/tools/module_tools.h +++ b/pcbnew/tools/module_tools.h @@ -77,6 +77,20 @@ public: */ int PasteItems( TOOL_EVENT& aEvent ); + /** + * Function ModuleTextOutlines() + * + * Toggles display mode for module texts (outline/filled). + */ + int ModuleTextOutlines( TOOL_EVENT& aEvent ); + + /** + * Function ModuleEdgeOutlines() + * + * Toggles display mode for module edges (outline/filled). + */ + int ModuleEdgeOutlines( TOOL_EVENT& aEvent ); + private: ///> Sets up handlers for various events. void setTransitions(); From 3e3626728a673a7502c26d4c77d4a75b9064d64d Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:10:32 +0200 Subject: [PATCH 097/123] Tool indicator is resetted on canvas switch. --- common/draw_frame.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/draw_frame.cpp b/common/draw_frame.cpp index 0d8030953f..b43d1669d0 100644 --- a/common/draw_frame.cpp +++ b/common/draw_frame.cpp @@ -1033,6 +1033,9 @@ void EDA_DRAW_FRAME::UseGalCanvas( bool aEnable ) m_auimgr.GetPane( wxT( "DrawFrameGal" ) ).Show( aEnable ); m_auimgr.Update(); + // Reset current tool on switch(); + SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); + m_galCanvasActive = aEnable; } From 1495429f68fcd7e7d10cd8f5f5f964041fc2ffe9 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:10:32 +0200 Subject: [PATCH 098/123] Ratsnest is recalculated after global deletion of tracks and after importing a netlist. --- pcbnew/dialogs/dialog_global_deletion.cpp | 3 +++ pcbnew/ratsnest_data.cpp | 2 ++ 2 files changed, 5 insertions(+) diff --git a/pcbnew/dialogs/dialog_global_deletion.cpp b/pcbnew/dialogs/dialog_global_deletion.cpp index e06f990b29..b4998f2a4d 100644 --- a/pcbnew/dialogs/dialog_global_deletion.cpp +++ b/pcbnew/dialogs/dialog_global_deletion.cpp @@ -254,6 +254,9 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete( ) if( gen_rastnest ) m_Parent->Compile_Ratsnest( NULL, true ); + if( m_Parent->IsGalCanvasActive() ) + pcb->GetRatsnest()->Recalculate(); + } m_Parent->GetCanvas()->Refresh(); diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index 3c069e1932..deb6d08024 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -1009,6 +1009,8 @@ void RN_DATA::ProcessBoard() if( netCode > 0 ) m_nets[netCode].AddItem( zone ); } + + Recalculate(); } From 242d9812ebf6080220557255400b37746daff7b5 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:10:32 +0200 Subject: [PATCH 099/123] Fixed minor bugs introduced with outline mode display for module texts and edges. --- pcbnew/pcb_painter.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index fce609d27e..1c299c6984 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -627,6 +627,7 @@ void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment, int aLayer ) { const COLOR4D& color = m_pcbSettings.GetColor( aSegment, aSegment->GetLayer() ); + m_gal->SetIsFill( false ); m_gal->SetIsStroke( true ); m_gal->SetStrokeColor( color ); @@ -634,14 +635,11 @@ void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment, int aLayer ) { // Outline mode m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth ); - m_gal->SetIsFill( false ); } else { // Filled mode m_gal->SetLineWidth( aSegment->GetWidth() ); - m_gal->SetFillColor( color ); - m_gal->SetIsFill( true ); } switch( aSegment->GetShape() ) @@ -725,16 +723,15 @@ void PCB_PAINTER::draw( const TEXTE_PCB* aText, int aLayer ) { // Outline mode m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth ); - m_gal->SetIsFill( false ); } else { // Filled mode m_gal->SetLineWidth( aText->GetThickness() ); - m_gal->SetFillColor( color ); - m_gal->SetIsFill( true ); } + m_gal->SetIsFill( false ); + m_gal->SetIsStroke( true ); m_gal->SetStrokeColor( color ); m_gal->SetTextAttributes( aText ); m_gal->StrokeText( aText->GetText(), position, orientation ); @@ -754,16 +751,15 @@ void PCB_PAINTER::draw( const TEXTE_MODULE* aText, int aLayer ) { // Outline mode m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth ); - m_gal->SetIsFill( false ); } else { // Filled mode m_gal->SetLineWidth( aText->GetThickness() ); - m_gal->SetFillColor( color ); - m_gal->SetIsFill( true ); } + m_gal->SetIsFill( false ); + m_gal->SetIsStroke( true ); m_gal->SetStrokeColor( color ); m_gal->SetTextAttributes( aText ); m_gal->StrokeText( aText->GetText(), position, orientation ); From dd93dea448cef6a3e434e62cb4a10cbdd3bd8fc6 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:10:32 +0200 Subject: [PATCH 100/123] wxWidgets 2.8 compatibility fixes. --- pcbnew/tools/module_tools.cpp | 2 +- pcbnew/tools/placement_tool.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pcbnew/tools/module_tools.cpp b/pcbnew/tools/module_tools.cpp index e9302b6c60..cf9a142448 100644 --- a/pcbnew/tools/module_tools.cpp +++ b/pcbnew/tools/module_tools.cpp @@ -305,7 +305,7 @@ int MODULE_TOOLS::EnumeratePads( TOOL_EVENT& aEvent ) m_frame->SaveCopyInUndoList( module, UR_MODEDIT ); BOOST_FOREACH( D_PAD* pad, pads ) - pad->SetPadName( wxString::Format( "%s%d", padPrefix, padNumber++ ) ); + pad->SetPadName( wxString::Format( wxT( "%s%d" ), padPrefix.c_str(), padNumber++ ) ); break; } diff --git a/pcbnew/tools/placement_tool.cpp b/pcbnew/tools/placement_tool.cpp index 82d7570e5e..d77f05089b 100644 --- a/pcbnew/tools/placement_tool.cpp +++ b/pcbnew/tools/placement_tool.cpp @@ -63,7 +63,7 @@ bool PLACEMENT_TOOL::Init() menu->AppendSeparator(); menu->Add( COMMON_ACTIONS::distributeHorizontally ); menu->Add( COMMON_ACTIONS::distributeVertically ); - m_selectionTool->AddSubMenu( menu, wxString( "Align/distribute" ), + m_selectionTool->AddSubMenu( menu, _( "Align/distribute" ), SELECTION_CONDITIONS::MoreThan( 1 ) ); setTransitions(); From ebf59807dcd250cfcbf95676546298236f2d194f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:10:32 +0200 Subject: [PATCH 101/123] Fixed continous line drawing. Outline mode can be set up on any layer. --- pcbnew/modedit.cpp | 5 +++- pcbnew/pcb_painter.cpp | 18 +++++++------- pcbnew/tools/drawing_tool.cpp | 46 +++++++++++++++++++++++++++++------ pcbnew/tools/drawing_tool.h | 4 ++- 4 files changed, 54 insertions(+), 19 deletions(-) diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp index 933339b3e3..ff22550845 100644 --- a/pcbnew/modedit.cpp +++ b/pcbnew/modedit.cpp @@ -295,7 +295,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) case ID_MODEDIT_NEW_MODULE: { - if( ! Clear_Pcb( true ) ) + if( !Clear_Pcb( true ) ) break; SetCrossHairPosition( wxPoint( 0, 0 ) ); @@ -317,6 +317,9 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) Zoom_Automatique( false ); } + if( IsGalCanvasActive() ) + updateView(); + GetScreen()->ClrModify(); } break; diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 1c299c6984..4adc0bc13c 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -50,7 +50,7 @@ PCB_RENDER_SETTINGS::PCB_RENDER_SETTINGS() m_displayZoneMode = DZ_SHOW_FILLED; // By default everything should be displayed as filled - for( unsigned int i = 0; i < END_PCB_VISIBLE_LIST; ++i ) + for( unsigned int i = 0; i < TOTAL_LAYER_COUNT; ++i ) { m_sketchMode[i] = false; } @@ -102,9 +102,9 @@ void PCB_RENDER_SETTINGS::LoadDisplayOptions( const DISPLAY_OPTIONS& aOptions ) m_padNumbers = aOptions.DisplayPadNum; // Whether to draw tracks, vias & pads filled or as outlines - m_sketchMode[PADS_VISIBLE] = !aOptions.DisplayPadFill; - m_sketchMode[VIA_THROUGH_VISIBLE] = !aOptions.DisplayViaFill; - m_sketchMode[TRACKS_VISIBLE] = !aOptions.DisplayPcbTrackFill; + m_sketchMode[ITEM_GAL_LAYER( PADS_VISIBLE )] = !aOptions.DisplayPadFill; + m_sketchMode[ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE )] = !aOptions.DisplayViaFill; + m_sketchMode[ITEM_GAL_LAYER( TRACKS_VISIBLE )] = !aOptions.DisplayPcbTrackFill; switch( aOptions.DisplayNetNamesMode ) { @@ -313,7 +313,7 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer ) m_gal->SetStrokeColor( color ); m_gal->SetIsStroke( true ); - if( m_pcbSettings.m_sketchMode[TRACKS_VISIBLE] ) + if( m_pcbSettings.m_sketchMode[ITEM_GAL_LAYER( TRACKS_VISIBLE )] ) { // Outline mode m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth ); @@ -350,7 +350,7 @@ void PCB_PAINTER::draw( const VIA* aVia, int aLayer ) const COLOR4D& color = m_pcbSettings.GetColor( aVia, aLayer ); - if( m_pcbSettings.m_sketchMode[VIA_THROUGH_VISIBLE] ) + if( m_pcbSettings.m_sketchMode[ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE )] ) { // Outline mode m_gal->SetIsFill( false ); @@ -481,7 +481,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer ) // Pad drawing const COLOR4D& color = m_pcbSettings.GetColor( aPad, aLayer ); - if( m_pcbSettings.m_sketchMode[PADS_VISIBLE] ) + if( m_pcbSettings.m_sketchMode[ITEM_GAL_LAYER( PADS_VISIBLE )] ) { // Outline mode m_gal->SetIsFill( false ); @@ -544,7 +544,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer ) m = ( size.y - size.x ); n = size.x; - if( m_pcbSettings.m_sketchMode[PADS_VISIBLE] ) + if( m_pcbSettings.m_sketchMode[ITEM_GAL_LAYER( PADS_VISIBLE )] ) { // Outline mode m_gal->DrawArc( VECTOR2D( 0, -m ), n, -M_PI, 0 ); @@ -565,7 +565,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer ) m = ( size.x - size.y ); n = size.y; - if( m_pcbSettings.m_sketchMode[PADS_VISIBLE] ) + if( m_pcbSettings.m_sketchMode[ITEM_GAL_LAYER( PADS_VISIBLE )] ) { // Outline mode m_gal->DrawArc( VECTOR2D( -m, 0 ), n, M_PI / 2, 3 * M_PI / 2 ); diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 9d19cc3541..170f723e09 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -76,6 +76,8 @@ void DRAWING_TOOL::Reset( RESET_REASON aReason ) int DRAWING_TOOL::DrawLine( TOOL_EVENT& aEvent ) { + boost::optional startingPoint; + if( m_editModules ) { m_frame->SetToolID( ID_MODEDIT_LINE_TOOL, wxCURSOR_PENCIL, _( "Add graphic line" ) ); @@ -83,7 +85,7 @@ int DRAWING_TOOL::DrawLine( TOOL_EVENT& aEvent ) MODULE* module = m_board->m_Modules; EDGE_MODULE* line = new EDGE_MODULE( module ); - while( drawSegment( S_SEGMENT, reinterpret_cast( line ) ) ) + while( drawSegment( S_SEGMENT, reinterpret_cast( line ), startingPoint ) ) { if( line ) { @@ -92,6 +94,11 @@ int DRAWING_TOOL::DrawLine( TOOL_EVENT& aEvent ) line->SetLocalCoord(); line->SetParent( module ); module->GraphicalItems().PushFront( line ); + startingPoint = line->GetEnd(); + } + else + { + startingPoint = boost::none; } line = new EDGE_MODULE( module ); @@ -103,13 +110,18 @@ int DRAWING_TOOL::DrawLine( TOOL_EVENT& aEvent ) DRAWSEGMENT* line = new DRAWSEGMENT; - while( drawSegment( S_SEGMENT, line ) ) + while( drawSegment( S_SEGMENT, line, startingPoint ) ) { if( line ) { m_board->Add( line ); m_frame->OnModify(); m_frame->SaveCopyInUndoList( line, UR_NEW ); + startingPoint = line->GetEnd(); + } + else + { + startingPoint = boost::none; } line = new DRAWSEGMENT; @@ -853,7 +865,8 @@ int DRAWING_TOOL::SetAnchor( TOOL_EVENT& aEvent ) } -bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic ) +bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic, + boost::optional aStartingPoint ) { // Only two shapes are currently supported assert( aShape == S_SEGMENT || aShape == S_CIRCLE ); @@ -872,12 +885,33 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic ) bool direction45 = false; // 45 degrees only mode bool started = false; + VECTOR2I cursorPos = m_controls->GetCursorPosition(); + + if( aStartingPoint ) + { + LAYER_NUM layer = m_frame->GetScreen()->m_Active_Layer; + + // Init the new item attributes + aGraphic->SetShape( (STROKE_T) aShape ); + aGraphic->SetWidth( m_board->GetDesignSettings().m_DrawSegmentWidth ); + aGraphic->SetStart( wxPoint( aStartingPoint->x, aStartingPoint->y ) ); + aGraphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); + aGraphic->SetLayer( layer ); + + if( aShape == S_SEGMENT ) + line45 = *aGraphic; // used only for direction 45 mode with lines + + preview.Add( aGraphic ); + m_controls->SetAutoPan( true ); + + started = true; + } // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { bool updatePreview = false; // should preview be updated - VECTOR2I cursorPos = m_controls->GetCursorPosition(); + cursorPos = m_controls->GetCursorPosition(); // Enable 45 degrees lines only mode by holding control if( direction45 != evt->Modifier( MD_CTRL ) && started && aShape == S_SEGMENT ) @@ -940,10 +974,7 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic ) aGraphic->SetLayer( layer ); if( aShape == S_SEGMENT ) - { line45 = *aGraphic; // used only for direction 45 mode with lines - line45.SetLayer( layer ); - } preview.Add( aGraphic ); m_controls->SetAutoPan( true ); @@ -965,7 +996,6 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic ) { // a clear sign that the current drawing is finished delete aGraphic; // but only if at least one graphic was created aGraphic = NULL; // otherwise - force user to draw more or cancel - started = false; } preview.Clear(); diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index 42a6dbfdf3..178d751a8f 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -26,6 +26,7 @@ #define __DRAWING_TOOL_H #include +#include namespace KIGFX { @@ -150,7 +151,8 @@ private: ///> be already created. The tool deletes the object if it is not added to a BOARD. ///> @return False if the tool was cancelled before the origin was set or origin and end are ///> the same point. - bool drawSegment( int aShape, DRAWSEGMENT*& aGraphic ); + bool drawSegment( int aShape, DRAWSEGMENT*& aGraphic, + boost::optional aStartingPoint = boost::none ); ///> Starts drawing an arc. ///> @param aGraphic is an object that is going to be used by the tool for drawing. It has to From 7f13fd0ffd023738264fbb3809c6c870f0eb16d0 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 15:10:32 +0200 Subject: [PATCH 102/123] Added AF_NOTIFY flag for TOOL_ACTIONs. --- common/tool/tool_manager.cpp | 4 ++-- include/tool/tool_action.h | 10 ++++++++++ include/tool/tool_event.h | 3 ++- pcbnew/tools/common_actions.cpp | 2 +- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index cb91124f31..14d963839e 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -448,8 +448,8 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent ) { if( st->waitEvents.Matches( aEvent ) ) { - // By default, already processed events are not passed further - m_passEvent = false; + // By default, only messages are passed further + m_passEvent = ( aEvent.m_category == TC_MESSAGE ); // got matching event? clear wait list and wake up the coroutine st->wakeupEvent = aEvent; diff --git a/include/tool/tool_action.h b/include/tool/tool_action.h index e215efba83..5db3701301 100644 --- a/include/tool/tool_action.h +++ b/include/tool/tool_action.h @@ -148,6 +148,8 @@ public: { if( IsActivation() ) return TOOL_EVENT( TC_COMMAND, TA_ACTIVATE, m_name, m_scope ); + else if( IsNotification() ) + return TOOL_EVENT( TC_MESSAGE, TA_ANY, m_name, m_scope ); else return TOOL_EVENT( TC_COMMAND, TA_ACTION, m_name, m_scope ); } @@ -192,6 +194,14 @@ public: return m_flags & AF_ACTIVATE; } + /** + * Returns true if the action is a notification. + */ + bool IsNotification() const + { + return m_flags & AF_NOTIFY; + } + private: friend class ACTION_MANAGER; diff --git a/include/tool/tool_event.h b/include/tool/tool_event.h index b140fa3953..bffca332f5 100644 --- a/include/tool/tool_event.h +++ b/include/tool/tool_event.h @@ -130,7 +130,8 @@ enum TOOL_ACTION_SCOPE enum TOOL_ACTION_FLAGS { AF_NONE = 0, - AF_ACTIVATE = 1 ///> Action activates a tool + AF_ACTIVATE = 1, ///> Action activates a tool + AF_NOTIFY = 2 ///> Action is a notification (it is by default passed to all tools) }; /// Defines when a context menu is opened. diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 0e1ebc0818..0ef2778256 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -264,7 +264,7 @@ TOOL_ACTION COMMON_ACTIONS::viaSizeDec( "pcbnew.EditorControl.viaSizeDec", TOOL_ACTION COMMON_ACTIONS::trackViaSizeChanged( "pcbnew.EditorControl.trackViaSizeChanged", AS_GLOBAL, 0, - "", "" ); + "", "", AF_NOTIFY ); // Module editor tools From 942a38349adde212550176c38d257a93c3b915c4 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 16:25:50 +0200 Subject: [PATCH 103/123] Simplified code for switching layers in GAL view. Tools are notified of layer change event. --- pcbnew/pcbframe.cpp | 3 + pcbnew/tools/common_actions.cpp | 4 + pcbnew/tools/common_actions.h | 2 + pcbnew/tools/drawing_tool.cpp | 2 +- pcbnew/tools/module_tools.cpp | 11 +- pcbnew/tools/pcbnew_control.cpp | 120 +++++------------- pcbnew/tools/pcbnew_control.h | 9 +- ...nvert_brd_items_to_polygons_with_Boost.cpp | 2 +- 8 files changed, 50 insertions(+), 103 deletions(-) diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index e9c082533b..eb72a49fd6 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -828,7 +828,10 @@ void PCB_EDIT_FRAME::SetActiveLayer( LAYER_ID aLayer ) syncLayerWidgetLayer(); if( IsGalCanvasActive() ) + { + m_toolManager->RunAction( COMMON_ACTIONS::layerChanged ); // notify other tools GetGalCanvas()->Refresh(); + } } diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 0ef2778256..cf2879e725 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -222,6 +222,10 @@ TOOL_ACTION COMMON_ACTIONS::layerAlphaDec( "pcbnew.Control.layerAlphaDec", AS_GLOBAL, '{', "", "" ); +TOOL_ACTION COMMON_ACTIONS::layerChanged( "pcbnew.Control.layerChanged", + AS_GLOBAL, 0, + "", "", AF_NOTIFY ); + // Grid control TOOL_ACTION COMMON_ACTIONS::gridFast1( "pcbnew.Control.gridFast1", diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index fb53fed993..6df00fae9b 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -157,6 +157,8 @@ public: static TOOL_ACTION layerAlphaInc; static TOOL_ACTION layerAlphaDec; + static TOOL_ACTION layerChanged; // notification + // Grid control static TOOL_ACTION gridFast1; static TOOL_ACTION gridFast2; diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 170f723e09..83ae2129b8 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -889,7 +889,7 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic, if( aStartingPoint ) { - LAYER_NUM layer = m_frame->GetScreen()->m_Active_Layer; + LAYER_ID layer = m_frame->GetScreen()->m_Active_Layer; // Init the new item attributes aGraphic->SetShape( (STROKE_T) aShape ); diff --git a/pcbnew/tools/module_tools.cpp b/pcbnew/tools/module_tools.cpp index cf9a142448..3a6827a9d9 100644 --- a/pcbnew/tools/module_tools.cpp +++ b/pcbnew/tools/module_tools.cpp @@ -576,14 +576,9 @@ int MODULE_TOOLS::ModuleEdgeOutlines( TOOL_EVENT& aEvent ) KIGFX::PCB_RENDER_SETTINGS* settings = static_cast( painter->GetSettings() ); - const LAYER_NUM layers[] = { ADHESIVE_N_FRONT, ADHESIVE_N_BACK,\ - SOLDERPASTE_N_FRONT, SOLDERPASTE_N_BACK,\ - SILKSCREEN_N_FRONT, SILKSCREEN_N_BACK,\ - SOLDERMASK_N_FRONT, SOLDERMASK_N_BACK,\ - DRAW_N,\ - COMMENT_N,\ - ECO1_N, ECO2_N,\ - EDGE_N }; + const LAYER_ID layers[] = { F_Adhes, B_Adhes, F_Paste, B_Paste, + F_SilkS, B_SilkS, F_Mask, B_Mask, + Dwgs_User, Cmts_User, Eco1_User, Eco2_User, Edge_Cuts }; bool enable = !settings->GetSketchMode( layers[0] ); diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index 2d92566530..537b051bed 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -279,79 +279,25 @@ int PCBNEW_CONTROL::HighContrastDec( TOOL_EVENT& aEvent ) // Layer control -int PCBNEW_CONTROL::LayerTop( TOOL_EVENT& aEvent ) +int PCBNEW_CONTROL::LayerSwitch( TOOL_EVENT& aEvent ) { - m_frame->SwitchLayer( NULL, F_Cu ); - m_frame->GetGalCanvas()->SetFocus(); - setTransitions(); + if( aEvent.IsAction( &COMMON_ACTIONS::layerTop ) ) + m_frame->SwitchLayer( NULL, F_Cu ); + else if( aEvent.IsAction( &COMMON_ACTIONS::layerInner1 ) ) + m_frame->SwitchLayer( NULL, In1_Cu ); + else if( aEvent.IsAction( &COMMON_ACTIONS::layerInner2 ) ) + m_frame->SwitchLayer( NULL, In2_Cu ); + else if( aEvent.IsAction( &COMMON_ACTIONS::layerInner3 ) ) + m_frame->SwitchLayer( NULL, In3_Cu ); + else if( aEvent.IsAction( &COMMON_ACTIONS::layerInner4 ) ) + m_frame->SwitchLayer( NULL, In4_Cu ); + else if( aEvent.IsAction( &COMMON_ACTIONS::layerInner5 ) ) + m_frame->SwitchLayer( NULL, In5_Cu ); + else if( aEvent.IsAction( &COMMON_ACTIONS::layerInner6 ) ) + m_frame->SwitchLayer( NULL, In6_Cu ); + else if( aEvent.IsAction( &COMMON_ACTIONS::layerBottom ) ) + m_frame->SwitchLayer( NULL, B_Cu ); - return 0; -} - - -int PCBNEW_CONTROL::LayerInner1( TOOL_EVENT& aEvent ) -{ - m_frame->SwitchLayer( NULL, In1_Cu ); - m_frame->GetGalCanvas()->SetFocus(); - setTransitions(); - - return 0; -} - - -int PCBNEW_CONTROL::LayerInner2( TOOL_EVENT& aEvent ) -{ - m_frame->SwitchLayer( NULL, In2_Cu ); - m_frame->GetGalCanvas()->SetFocus(); - setTransitions(); - - return 0; -} - - -int PCBNEW_CONTROL::LayerInner3( TOOL_EVENT& aEvent ) -{ - m_frame->SwitchLayer( NULL, In3_Cu ); - m_frame->GetGalCanvas()->SetFocus(); - setTransitions(); - - return 0; -} - - -int PCBNEW_CONTROL::LayerInner4( TOOL_EVENT& aEvent ) -{ - m_frame->SwitchLayer( NULL, In4_Cu ); - m_frame->GetGalCanvas()->SetFocus(); - setTransitions(); - - return 0; -} - - -int PCBNEW_CONTROL::LayerInner5( TOOL_EVENT& aEvent ) -{ - m_frame->SwitchLayer( NULL, In5_Cu ); - m_frame->GetGalCanvas()->SetFocus(); - setTransitions(); - - return 0; -} - - -int PCBNEW_CONTROL::LayerInner6( TOOL_EVENT& aEvent ) -{ - m_frame->SwitchLayer( NULL, In6_Cu ); - m_frame->GetGalCanvas()->SetFocus(); - setTransitions(); - - return 0; -} - - -int PCBNEW_CONTROL::LayerBottom( TOOL_EVENT& aEvent ) -{ - m_frame->SetActiveLayer( B_Cu ); m_frame->GetGalCanvas()->SetFocus(); setTransitions(); @@ -364,15 +310,17 @@ int PCBNEW_CONTROL::LayerNext( TOOL_EVENT& aEvent ) PCB_BASE_FRAME* editFrame = m_frame; LAYER_NUM layer = editFrame->GetActiveLayer(); - if( layer < F_Cu || layer >= B_Cu ) + if( layer < F_Cu || layer > B_Cu ) { setTransitions(); return 0; } - if( getModel()->GetCopperLayerCount() < 2 ) // Single layer + int layerCount = getModel()->GetCopperLayerCount(); + + if( layer == layerCount - 2 || layerCount < 2 ) layer = B_Cu; - else if( layer >= getModel()->GetCopperLayerCount() - 2 ) + else if( layer == B_Cu ) layer = F_Cu; else ++layer; @@ -390,16 +338,18 @@ int PCBNEW_CONTROL::LayerPrev( TOOL_EVENT& aEvent ) PCB_BASE_FRAME* editFrame = m_frame; LAYER_NUM layer = editFrame->GetActiveLayer(); - if( layer <= F_Cu || layer > B_Cu ) + if( layer < F_Cu || layer > B_Cu ) { setTransitions(); return 0; } - if( getModel()->GetCopperLayerCount() < 2 ) // Single layer + int layerCount = getModel()->GetCopperLayerCount(); + + if( layer == F_Cu || layerCount < 2 ) layer = B_Cu; else if( layer == B_Cu ) - layer = std::max( int( F_Cu ), getModel()->GetCopperLayerCount() - 2 ); + layer = layerCount - 2; else --layer; @@ -617,14 +567,14 @@ void PCBNEW_CONTROL::setTransitions() Go( &PCBNEW_CONTROL::HighContrastDec, COMMON_ACTIONS::highContrastDec.MakeEvent() ); // Layer control - Go( &PCBNEW_CONTROL::LayerTop, COMMON_ACTIONS::layerTop.MakeEvent() ); - Go( &PCBNEW_CONTROL::LayerInner1, COMMON_ACTIONS::layerInner1.MakeEvent() ); - Go( &PCBNEW_CONTROL::LayerInner2, COMMON_ACTIONS::layerInner2.MakeEvent() ); - Go( &PCBNEW_CONTROL::LayerInner3, COMMON_ACTIONS::layerInner3.MakeEvent() ); - Go( &PCBNEW_CONTROL::LayerInner4, COMMON_ACTIONS::layerInner4.MakeEvent() ); - Go( &PCBNEW_CONTROL::LayerInner5, COMMON_ACTIONS::layerInner5.MakeEvent() ); - Go( &PCBNEW_CONTROL::LayerInner6, COMMON_ACTIONS::layerInner6.MakeEvent() ); - Go( &PCBNEW_CONTROL::LayerBottom, COMMON_ACTIONS::layerBottom.MakeEvent() ); + Go( &PCBNEW_CONTROL::LayerSwitch, COMMON_ACTIONS::layerTop.MakeEvent() ); + Go( &PCBNEW_CONTROL::LayerSwitch, COMMON_ACTIONS::layerInner1.MakeEvent() ); + Go( &PCBNEW_CONTROL::LayerSwitch, COMMON_ACTIONS::layerInner2.MakeEvent() ); + Go( &PCBNEW_CONTROL::LayerSwitch, COMMON_ACTIONS::layerInner3.MakeEvent() ); + Go( &PCBNEW_CONTROL::LayerSwitch, COMMON_ACTIONS::layerInner4.MakeEvent() ); + Go( &PCBNEW_CONTROL::LayerSwitch, COMMON_ACTIONS::layerInner5.MakeEvent() ); + Go( &PCBNEW_CONTROL::LayerSwitch, COMMON_ACTIONS::layerInner6.MakeEvent() ); + Go( &PCBNEW_CONTROL::LayerSwitch, COMMON_ACTIONS::layerBottom.MakeEvent() ); Go( &PCBNEW_CONTROL::LayerNext, COMMON_ACTIONS::layerNext.MakeEvent() ); Go( &PCBNEW_CONTROL::LayerPrev, COMMON_ACTIONS::layerPrev.MakeEvent() ); Go( &PCBNEW_CONTROL::LayerAlphaInc, COMMON_ACTIONS::layerAlphaInc.MakeEvent() ); diff --git a/pcbnew/tools/pcbnew_control.h b/pcbnew/tools/pcbnew_control.h index 4c11b9777b..7fc9978b60 100644 --- a/pcbnew/tools/pcbnew_control.h +++ b/pcbnew/tools/pcbnew_control.h @@ -62,14 +62,7 @@ public: int HighContrastDec( TOOL_EVENT& aEvent ); // Layer control - int LayerTop( TOOL_EVENT& aEvent ); - int LayerInner1( TOOL_EVENT& aEvent ); - int LayerInner2( TOOL_EVENT& aEvent ); - int LayerInner3( TOOL_EVENT& aEvent ); - int LayerInner4( TOOL_EVENT& aEvent ); - int LayerInner5( TOOL_EVENT& aEvent ); - int LayerInner6( TOOL_EVENT& aEvent ); - int LayerBottom( TOOL_EVENT& aEvent ); + int LayerSwitch( TOOL_EVENT& aEvent ); int LayerNext( TOOL_EVENT& aEvent ); int LayerPrev( TOOL_EVENT& aEvent ); int LayerAlphaInc( TOOL_EVENT& aEvent ); diff --git a/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp b/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp index 5144e4c88e..4d2117592e 100644 --- a/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp +++ b/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp @@ -303,7 +303,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) { for( BOARD_ITEM* item = module->GraphicalItems(); item; item = item->Next() ) { - if( !item->IsOnLayer( GetLayer() ) && !item->IsOnLayer( EDGE_N ) ) + if( !item->IsOnLayer( GetLayer() ) && !item->IsOnLayer( Edge_Cuts ) ) continue; if( item->Type() != PCB_MODULE_EDGE_T ) From 9cfb71262476f27be98eed67b986606d2e334a3a Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 16:25:50 +0200 Subject: [PATCH 104/123] Code formatting. --- pcbnew/router/pns_line_placer.cpp | 10 +++++----- pcbnew/router/pns_line_placer.h | 2 +- pcbnew/router/pns_router.cpp | 2 +- pcbnew/router/pns_router.h | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pcbnew/router/pns_line_placer.cpp b/pcbnew/router/pns_line_placer.cpp index 2c26df7c96..ba52d3544b 100644 --- a/pcbnew/router/pns_line_placer.cpp +++ b/pcbnew/router/pns_line_placer.cpp @@ -790,12 +790,12 @@ void PNS_LINE_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem ) m_currentEnd = p; m_currentNet = net; - PNS_NODE *rootNode = Router()->GetWorld()->Branch(); + PNS_NODE* rootNode = Router()->GetWorld()->Branch(); if( splitSeg ) splitAdjacentSegments( rootNode, aStartItem, p ); - setWorld ( rootNode ); + setWorld( rootNode ); setInitialDirection( Settings().InitialDirection() ); startPlacement( p, m_currentNet, m_currentWidth, m_currentLayer ); } @@ -848,7 +848,7 @@ bool PNS_LINE_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem ) PNS_LINE pl = Trace(); - if (m_currentMode == RM_MarkObstacles && + if( m_currentMode == RM_MarkObstacles && !Settings().CanViolateDRC() && m_world->CheckColliding( &pl ) ) return false; @@ -889,9 +889,9 @@ bool PNS_LINE_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem ) m_lastNode->Add( pl.Via().Clone() ); if( realEnd ) - simplifyNewLine ( m_lastNode, lastSeg ); + simplifyNewLine( m_lastNode, lastSeg ); - Router()->CommitRouting ( m_lastNode ); + Router()->CommitRouting( m_lastNode ); m_lastNode = NULL; diff --git a/pcbnew/router/pns_line_placer.h b/pcbnew/router/pns_line_placer.h index 1ae3b2d69c..e859180674 100644 --- a/pcbnew/router/pns_line_placer.h +++ b/pcbnew/router/pns_line_placer.h @@ -55,7 +55,7 @@ public: * Starts routing a single track at point aP, taking item aStartItem as anchor * (unless NULL). */ - void Start ( const VECTOR2I& aP, PNS_ITEM* aStartItem ); + void Start( const VECTOR2I& aP, PNS_ITEM* aStartItem ); /** * Function Move() diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp index 8813a854f1..5e16d95993 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -612,7 +612,7 @@ void PNS_ROUTER::moveDragging( const VECTOR2I& aP, PNS_ITEM* aEndItem ) m_dragger->Drag( aP ); PNS_ITEMSET dragged = m_dragger->Traces(); - updateView ( m_dragger->CurrentNode(), dragged ); + updateView( m_dragger->CurrentNode(), dragged ); } diff --git a/pcbnew/router/pns_router.h b/pcbnew/router/pns_router.h index b5fc2a6daa..8a92794f16 100644 --- a/pcbnew/router/pns_router.h +++ b/pcbnew/router/pns_router.h @@ -234,7 +234,7 @@ private: PNS_NODE* m_world; PNS_NODE* m_lastNode; PNS_LINE_PLACER* m_placer; - PNS_DRAGGER *m_dragger; + PNS_DRAGGER* m_dragger; PNS_LINE* m_draggedLine; PNS_SHOVE* m_shove; int m_draggedSegmentIndex; From a3eb60e0680540fb99f44a81d74d5ea19de61fe3 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 16:25:50 +0200 Subject: [PATCH 105/123] Added event queue to handle events at the end of the event processing cycle. --- common/tool/action_manager.cpp | 35 ++++++++++++-------------- common/tool/tool_manager.cpp | 45 ++++++++++++++++++++++++++++++---- include/tool/action_manager.h | 18 ++++---------- include/tool/tool_manager.h | 36 +++++++++++++++++++-------- pcbnew/router/router_tool.cpp | 6 +---- pcbnew/tools/edit_tool.cpp | 2 +- 6 files changed, 88 insertions(+), 54 deletions(-) diff --git a/common/tool/action_manager.cpp b/common/tool/action_manager.cpp index b065cb2d55..a64ab9e1d5 100644 --- a/common/tool/action_manager.cpp +++ b/common/tool/action_manager.cpp @@ -89,24 +89,14 @@ int ACTION_MANAGER::MakeActionId( const std::string& aActionName ) } -bool ACTION_MANAGER::RunAction( const std::string& aActionName ) const +TOOL_ACTION* ACTION_MANAGER::FindAction( const std::string& aActionName ) const { std::map::const_iterator it = m_actionNameIndex.find( aActionName ); - if( it == m_actionNameIndex.end() ) - return false; // no action with given name found + if( it != m_actionNameIndex.end() ) + return it->second; - RunAction( it->second ); - - return true; -} - - -void ACTION_MANAGER::RunAction( const TOOL_ACTION* aAction ) const -{ - TOOL_EVENT event = aAction->MakeEvent(); - - m_toolMgr->ProcessEvent( event ); + return NULL; } @@ -153,6 +143,8 @@ bool ACTION_MANAGER::RunHotKey( int aHotKey ) const if( tool ) { + // Choose the action that goes to the tool with highest priority + // (i.e. is on the top of active tools stack) priority = m_toolMgr->GetPriority( tool->GetId() ); if( priority >= 0 && priority > highestPriority ) @@ -163,13 +155,16 @@ bool ACTION_MANAGER::RunHotKey( int aHotKey ) const } } - if( !global && !context ) // currently there is no valid action to run - return false; - if( context ) - RunAction( context ); + { + m_toolMgr->RunAction( *context, true ); + return true; + } else if( global ) - RunAction( global ); + { + m_toolMgr->RunAction( *global, true ); + return true; + } - return true; + return false; } diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index 14d963839e..7a6df985fe 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -290,15 +290,40 @@ void TOOL_MANAGER::UnregisterAction( TOOL_ACTION* aAction ) } -bool TOOL_MANAGER::RunAction( const std::string& aActionName ) +bool TOOL_MANAGER::RunAction( const std::string& aActionName, bool aNow ) { - return m_actionMgr->RunAction( aActionName ); + TOOL_ACTION* action = m_actionMgr->FindAction( aActionName ); + + if( action ) + { + if( aNow ) + { + TOOL_EVENT event = action->MakeEvent(); + ProcessEvent( event ); + } + else + { + PostEvent( action->MakeEvent() ); + } + + return true; + } + + return false; } -void TOOL_MANAGER::RunAction( const TOOL_ACTION& aAction ) +void TOOL_MANAGER::RunAction( const TOOL_ACTION& aAction, bool aNow ) { - m_actionMgr->RunAction( &aAction ); + if( aNow ) + { + TOOL_EVENT event = aAction.MakeEvent(); + ProcessEvent( event ); + } + else + { + PostEvent( aAction.MakeEvent() ); + } } @@ -424,6 +449,8 @@ optional TOOL_MANAGER::ScheduleWait( TOOL_BASE* aTool, { TOOL_STATE* st = m_toolState[aTool]; + assert( !st->pendingWait ); // everything collapses on two Yield() in a row + // indicate to the manager that we are going to sleep and we shall be // woken up when an event matching aConditions arrive st->pendingWait = true; @@ -477,7 +504,7 @@ void TOOL_MANAGER::dispatchInternal( TOOL_EVENT& aEvent ) { if( tr.first.Matches( aEvent ) ) { - // no tool context allocated yet? Create one. + // if there is already a context, then store it if( st->cofunc ) st->Push(); @@ -590,6 +617,14 @@ bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent ) dispatchActivation( aEvent ); dispatchContextMenu( aEvent ); + // Dispatch queue + while( !m_eventQueue.empty() ) + { + TOOL_EVENT event = m_eventQueue.front(); + m_eventQueue.pop_front(); + ProcessEvent( event ); + } + if( m_view->IsDirty() ) { PCB_EDIT_FRAME* f = static_cast( GetEditFrame() ); diff --git a/include/tool/action_manager.h b/include/tool/action_manager.h index 626f795eff..7c4c52cd4d 100644 --- a/include/tool/action_manager.h +++ b/include/tool/action_manager.h @@ -75,20 +75,12 @@ public: static int MakeActionId( const std::string& aActionName ); /** - * Function RunAction() - * Runs an action with a given name (if there is one available). - * @param aActionName is the name of action to be run. - * @return True if there was an action associated with the name, false otherwise. + * Function FindAction() + * Finds an action with a given name (if there is one available). + * @param aActionName is the searched action. + * @return Pointer to a TOOL_ACTION object or NULL if there is no such action. */ - bool RunAction( const std::string& aActionName ) const; - - /** - * Function RunAction() - * Prepares an appropriate event and sends it to the destination specified in a TOOL_ACTION - * object. - * @param aAction is the action to be run. - */ - void RunAction( const TOOL_ACTION* aAction ) const; + TOOL_ACTION* FindAction( const std::string& aActionName ) const; /** * Function RunHotKey() diff --git a/include/tool/tool_manager.h b/include/tool/tool_manager.h index 1935cf1b14..e5d4ce9458 100644 --- a/include/tool/tool_manager.h +++ b/include/tool/tool_manager.h @@ -106,17 +106,21 @@ public: * Runs the specified action. The common format for action names is "application.ToolName.Action". * * @param aActionName is the name of action to be invoked. - * @return True if the action finished successfully, false otherwise. + * @param aNow decides if the action has to be run immediately or after the current coroutine + * is preemptied. + * @return False if the action was not found. */ - bool RunAction( const std::string& aActionName ); + bool RunAction( const std::string& aActionName, bool aNow = false ); /** * Function RunAction() * Runs the specified action. * * @param aAction is the action to be invoked. + * @param aNow decides if the action has to be run immediately or after the current coroutine + * is preemptied. */ - void RunAction( const TOOL_ACTION& aAction ); + void RunAction( const TOOL_ACTION& aAction, bool aNow = false ); /** * Function FindTool() @@ -158,11 +162,20 @@ public: void ResetTools( TOOL_BASE::RESET_REASON aReason ); /** - * Takes an event from the TOOL_DISPATCHER and propagates it to - * tools that requested events of matching type(s) + * Propagates an event to tools that requested events of matching type(s). + * @param aEvent is the event to be processed. */ bool ProcessEvent( TOOL_EVENT& aEvent ); + /** + * Puts an event to the event queue to be processed at the end of event processing cycle. + * @param aEvent is the event to be put into the queue. + */ + inline void PostEvent( const TOOL_EVENT& aEvent ) + { + m_eventQueue.push_back( aEvent ); + } + /** * Sets the work environment (model, view, view controls and the parent window). * These are made available to the tool. Called by the parent frame (PCB_EDIT_FRAME) @@ -177,17 +190,17 @@ public: return m_view; } - KIGFX::VIEW_CONTROLS* GetViewControls() const + inline KIGFX::VIEW_CONTROLS* GetViewControls() const { return m_viewControls; } - EDA_ITEM* GetModel() const + inline EDA_ITEM* GetModel() const { return m_model; } - wxWindow* GetEditFrame() const + inline wxWindow* GetEditFrame() const { return m_editFrame; } @@ -197,7 +210,7 @@ public: * (was invoked the most recently). * @return Id of the currently used tool. */ - int GetCurrentToolId() const + inline int GetCurrentToolId() const { return m_activeTools.front(); } @@ -207,7 +220,7 @@ public: * (was invoked the most recently). * @return Pointer to the currently used tool. */ - TOOL_BASE* GetCurrentTool() const + inline TOOL_BASE* GetCurrentTool() const { return FindTool( GetCurrentToolId() ); } @@ -405,6 +418,9 @@ private: KIGFX::VIEW_CONTROLS* m_viewControls; wxWindow* m_editFrame; + /// Queue that stores events to be processed at the end of the event processing cycle. + std::list m_eventQueue; + /// Flag saying if the currently processed event should be passed to other tools. bool m_passEvent; }; diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 312b060920..4dc89ddebb 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -404,11 +404,7 @@ void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& aEvent ) bds.SetCustomViaDrill( m_router->Settings().GetViaDrill() ); bds.UseCustomTrackViaSize( true ); - // TODO Should be done another way, but RunAction() won't work here. As the ROUTER_TOOL - // did not call Wait(), it does not wait for events and therefore the sent event - // won't arrive here - TOOL_EVENT event = COMMON_ACTIONS::trackViaSizeChanged.MakeEvent(); - handleCommonEvents( event ); + m_toolMgr->RunAction( COMMON_ACTIONS::trackViaSizeChanged ); } else if( aEvent.IsAction( &COMMON_ACTIONS::trackViaSizeChanged ) ) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index ed69da782b..6c5a6082fd 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -559,7 +559,7 @@ wxPoint EDIT_TOOL::getModificationPoint( const SELECTION& aSelection ) bool EDIT_TOOL::makeSelection( const SELECTION& aSelection ) { if( aSelection.Empty() ) // Try to find an item that could be modified - m_toolMgr->RunAction( COMMON_ACTIONS::selectionSingle ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionSingle, true ); return !aSelection.Empty(); } From 7a940570bbb594c9fe6a63a1934c9f117fa1e9bd Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 16:44:22 +0200 Subject: [PATCH 106/123] Workarounded restoring focus to GAL canvas after layer switching. --- pcbnew/pcbframe.cpp | 1 + pcbnew/router/router_tool.cpp | 2 -- pcbnew/tools/pcbnew_control.cpp | 4 +--- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index eb72a49fd6..08eb9e36a0 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -830,6 +830,7 @@ void PCB_EDIT_FRAME::SetActiveLayer( LAYER_ID aLayer ) if( IsGalCanvasActive() ) { m_toolManager->RunAction( COMMON_ACTIONS::layerChanged ); // notify other tools + GetGalCanvas()->SetFocus(); // otherwise hotkeys are stuck somewhere GetGalCanvas()->Refresh(); } } diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 4dc89ddebb..a77d5e32b5 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -532,9 +532,7 @@ void ROUTER_TOOL::performRouting() } m_router->SwitchLayer( m_startLayer ); - frame->SetActiveLayer( ToLAYER_ID( m_startLayer ) ); - frame->GetGalCanvas()->SetFocus(); if( m_startItem && m_startItem->Net() >= 0 ) highlightNet( true, m_startItem->Net() ); diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index 537b051bed..1bbddbc432 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -298,7 +298,6 @@ int PCBNEW_CONTROL::LayerSwitch( TOOL_EVENT& aEvent ) else if( aEvent.IsAction( &COMMON_ACTIONS::layerBottom ) ) m_frame->SwitchLayer( NULL, B_Cu ); - m_frame->GetGalCanvas()->SetFocus(); setTransitions(); return 0; @@ -325,8 +324,8 @@ int PCBNEW_CONTROL::LayerNext( TOOL_EVENT& aEvent ) else ++layer; + assert( IsCopperLayer( layer ) ); editFrame->SwitchLayer( NULL, ToLAYER_ID( layer ) ); - editFrame->GetGalCanvas()->SetFocus(); setTransitions(); return 0; @@ -355,7 +354,6 @@ int PCBNEW_CONTROL::LayerPrev( TOOL_EVENT& aEvent ) assert( IsCopperLayer( layer ) ); editFrame->SwitchLayer( NULL, ToLAYER_ID( layer ) ); - editFrame->GetGalCanvas()->SetFocus(); setTransitions(); return 0; From 746786a110da931a077a60de00746d5a169adf5b Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 16:44:23 +0200 Subject: [PATCH 107/123] Fixed module editor crash when pcbnew is started from the main launcher. --- pcbnew/moduleframe.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index bd5b92e70a..58dc823b44 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -182,9 +182,9 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : updateTitle(); // Create GAL canvas - EDA_DRAW_FRAME* drawFrame = static_cast( aParent ); + PCB_BASE_FRAME* parentFrame = static_cast( Kiway().Player( FRAME_PCB, true ) ); PCB_DRAW_PANEL_GAL* drawPanel = new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), m_FrameSize, - drawFrame->GetGalCanvas()->GetBackend() ); + parentFrame->GetGalCanvas()->GetBackend() ); SetGalCanvas( drawPanel ); SetBoard( new BOARD() ); @@ -252,7 +252,7 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : // Add the layer manager ( most right side of pcbframe ) m_auimgr.AddPane( m_Layers, lyrs.Name( wxT( "m_LayersManagerToolBar" ) ).Right().Layer( 2 ) ); // Layers manager is visible and served only in GAL canvas mode. - m_auimgr.GetPane( wxT( "m_LayersManagerToolBar" ) ).Show( drawFrame->IsGalCanvasActive() ); + m_auimgr.GetPane( wxT( "m_LayersManagerToolBar" ) ).Show( parentFrame->IsGalCanvasActive() ); // The left vertical toolbar (fast acces to display options) m_auimgr.AddPane( m_optionsToolBar, @@ -272,7 +272,7 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : drawPanel->GetViewControls(), this ); m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager ); - if( drawFrame->IsGalCanvasActive() ) + if( parentFrame->IsGalCanvasActive() ) { drawPanel->SetEventDispatcher( m_toolDispatcher ); From df1dfbbb920ec42ba54c1ea4bdca299072761846 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 16:44:23 +0200 Subject: [PATCH 108/123] Clear selection before opening the module editor. --- pcbnew/tools/edit_tool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 6c5a6082fd..55db5259bb 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -253,7 +253,7 @@ int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) std::vector& undoList = editFrame->GetScreen()->m_UndoList.m_CommandsList; // Some of properties dialogs alter pointers, so we should deselect them - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); STATUS_FLAGS flags = item->GetFlags(); item->ClearFlags(); From e5c0926571f252faf6891a5abab7fc8912c6db3e Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 16:50:31 +0200 Subject: [PATCH 109/123] FIx layer switching after via placement in PNS router. --- pcbnew/router/pns_line_placer.cpp | 18 +++++++++++++--- pcbnew/router/pns_line_placer.h | 2 +- pcbnew/router/pns_router.cpp | 6 ++++-- pcbnew/router/pns_router.h | 4 ++-- pcbnew/router/pns_routing_settings.h | 21 +++++++++++++++++++ pcbnew/router/router_tool.cpp | 31 +++++++++++++--------------- 6 files changed, 57 insertions(+), 25 deletions(-) diff --git a/pcbnew/router/pns_line_placer.cpp b/pcbnew/router/pns_line_placer.cpp index ba52d3544b..c967008b74 100644 --- a/pcbnew/router/pns_line_placer.cpp +++ b/pcbnew/router/pns_line_placer.cpp @@ -758,9 +758,12 @@ void PNS_LINE_PLACER::splitAdjacentSegments( PNS_NODE* aNode, PNS_ITEM* aSeg, co } -void PNS_LINE_PLACER::SetLayer(int aLayer) +void PNS_LINE_PLACER::SetLayer( int aLayer ) { m_currentLayer = aLayer; + + m_head.SetLayer( aLayer ); + m_tail.SetLayer( aLayer ); } @@ -901,9 +904,18 @@ bool PNS_LINE_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem ) VECTOR2I p_start = m_placingVia ? p_last : p_pre_last; if( m_placingVia ) - m_currentLayer = Router()->NextCopperLayer( true ); + { + int layerTop = Router()->Settings().GetLayerTop(); + int layerBottom = Router()->Settings().GetLayerBottom(); - setWorld ( Router()->GetWorld()->Branch() ); + // Change the current layer to the other side of the board + if( m_currentLayer == layerTop ) + m_currentLayer = layerBottom; + else + m_currentLayer = layerTop; + } + + setWorld( Router()->GetWorld()->Branch() ); startPlacement( p_start, m_head.Net(), m_head.Width(), m_currentLayer ); m_startsOnVia = m_placingVia; diff --git a/pcbnew/router/pns_line_placer.h b/pcbnew/router/pns_line_placer.h index e859180674..4d126866ea 100644 --- a/pcbnew/router/pns_line_placer.h +++ b/pcbnew/router/pns_line_placer.h @@ -212,7 +212,7 @@ private: * * Sets the board to route. */ - void setWorld ( PNS_NODE* aWorld ); + void setWorld( PNS_NODE* aWorld ); /** * Function startPlacement() diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp index 5e16d95993..67d54ceda5 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -323,6 +323,7 @@ PNS_ROUTER::PNS_ROUTER() m_currentLayer = 1; m_placingVia = false; + m_startsOnVia = false; m_currentNet = -1; m_state = IDLE; m_world = NULL; @@ -758,6 +759,7 @@ void PNS_ROUTER::CommitRouting( PNS_NODE* aNode ) via_board->SetWidth( via->Diameter() ); via_board->SetDrill( via->Drill() ); via_board->SetNetCode( via->Net() ); + via_board->SetLayerPair( m_settings.GetLayerTop(), m_settings.GetLayerBottom() ); newBI = via_board; break; } @@ -809,6 +811,7 @@ bool PNS_ROUTER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem ) { case ROUTE_TRACK: rv = m_placer->FixRoute( aP, aEndItem ); + m_startsOnVia = m_placingVia; m_placingVia = false; break; @@ -874,8 +877,7 @@ void PNS_ROUTER::SwitchLayer( int aLayer ) if( m_startsOnVia ) { m_currentLayer = aLayer; - //m_placer->StartPlacement( m_currentStart, m_currentNet, m_currentWidth, - // m_currentLayer ); + m_placer->SetLayer( aLayer ); } break; diff --git a/pcbnew/router/pns_router.h b/pcbnew/router/pns_router.h index 8a92794f16..fc22c60d16 100644 --- a/pcbnew/router/pns_router.h +++ b/pcbnew/router/pns_router.h @@ -107,7 +107,7 @@ public: void DisplayItems( const PNS_ITEMSET& aItems ); void DisplayDebugLine( const SHAPE_LINE_CHAIN& aLine, int aType = 0, int aWidth = 0 ); - void DisplayDebugPoint( const VECTOR2I aPos, int aType = 0); + void DisplayDebugPoint( const VECTOR2I aPos, int aType = 0 ); void DisplayDebugBox( const BOX2I& aBox, int aType = 0, int aWidth = 0 ); void SwitchLayer( int layer ); @@ -223,7 +223,7 @@ private: void highlightCurrent( bool enabled ); - void markViolations( PNS_NODE *aNode, PNS_ITEMSET& aCurrent, PNS_NODE::ITEM_VECTOR& aRemoved ); + void markViolations( PNS_NODE* aNode, PNS_ITEMSET& aCurrent, PNS_NODE::ITEM_VECTOR& aRemoved ); int m_currentLayer; int m_currentNet; diff --git a/pcbnew/router/pns_routing_settings.h b/pcbnew/router/pns_routing_settings.h index 84cfb5bf7e..0cd615cecb 100644 --- a/pcbnew/router/pns_routing_settings.h +++ b/pcbnew/router/pns_routing_settings.h @@ -127,6 +127,23 @@ public: int WalkaroundIterationLimit() const { return m_walkaroundIterationLimit; }; TIME_LIMIT WalkaroundTimeLimit() const; + void SetLayerPair( int aLayer1, int aLayer2 ) + { + if( aLayer1 > aLayer2 ) + { + m_layerTop = aLayer1; + m_layerBottom = aLayer2; + } + else + { + m_layerBottom = aLayer1; + m_layerTop = aLayer2; + } + } + + int GetLayerTop() const { return m_layerTop; } + int GetLayerBottom() const { return m_layerBottom; } + private: bool m_shoveVias; bool m_startDiagonal; @@ -150,6 +167,10 @@ private: int m_shoveIterationLimit; TIME_LIMIT m_shoveTimeLimit; TIME_LIMIT m_walkaroundTimeLimit; + + // Routing layers pair + int m_layerTop; + int m_layerBottom; }; #endif diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index a77d5e32b5..884af6a172 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -478,7 +478,7 @@ void ROUTER_TOOL::updateEndItem( TOOL_EVENT& aEvent ) int layer; bool snapEnabled = !aEvent.Modifier( MD_SHIFT ); - m_router->EnableSnapping ( snapEnabled ); + m_router->EnableSnapping( snapEnabled ); if( !snapEnabled || m_router->GetCurrentNet() < 0 || !m_startItem ) { @@ -566,39 +566,36 @@ void ROUTER_TOOL::performRouting() if( m_router->FixRoute( m_endSnapPoint, m_endItem ) ) break; + // Synchronize the indicated layer + frame->SetActiveLayer( m_router->GetCurrentLayer() ); + m_router->Move( m_endSnapPoint, m_endItem ); } else if( evt->IsAction( &ACT_PlaceThroughVia ) ) { + m_router->Settings().SetLayerPair( frame->GetScreen()->m_Route_Layer_TOP, + frame->GetScreen()->m_Route_Layer_BOTTOM ); m_router->ToggleViaPlacement(); - frame->GetGalCanvas()->SetTopLayer( ToLAYER_ID( m_router->GetCurrentLayer() ) ); - m_router->Move( m_endSnapPoint, m_endItem ); + m_router->Move( m_endSnapPoint, m_endItem ); // refresh } else if( evt->IsAction( &ACT_SwitchPosture ) ) { m_router->FlipPosture(); - m_router->Move( m_endSnapPoint, m_endItem ); + m_router->Move( m_endSnapPoint, m_endItem ); // refresh } - else if( evt->IsAction( &COMMON_ACTIONS::layerNext ) ) + else if( evt->IsAction( &COMMON_ACTIONS::layerChanged ) ) { - m_router->SwitchLayer( m_router->NextCopperLayer( true ) ); updateEndItem( *evt ); - frame->SetActiveLayer( ToLAYER_ID( m_router->GetCurrentLayer() ) ); - m_router->Move( m_endSnapPoint, m_endItem ); - } - else if( evt->IsAction( &COMMON_ACTIONS::layerPrev ) ) - { - m_router->SwitchLayer( m_router->NextCopperLayer( false ) ); - frame->SetActiveLayer( ToLAYER_ID( m_router->GetCurrentLayer() ) ); - m_router->Move( m_endSnapPoint, m_endItem ); + m_router->SwitchLayer( frame->GetActiveLayer() ); + m_router->Move( m_endSnapPoint, m_endItem ); // refresh } else if( evt->IsAction( &ACT_EndTrack ) ) { if( m_router->FixRoute( m_endSnapPoint, m_endItem ) ) break; } - - handleCommonEvents(*evt); + + handleCommonEvents( *evt ); } m_router->StopRouting(); @@ -642,7 +639,7 @@ int ROUTER_TOOL::Main( TOOL_EVENT& aEvent ) m_router->Settings().SetViaDiameter( bds.GetCurrentViaSize() ); m_router->Settings().SetViaDrill( bds.GetCurrentViaDrill() ); - ROUTER_TOOL_MENU *ctxMenu = new ROUTER_TOOL_MENU( board ); + ROUTER_TOOL_MENU* ctxMenu = new ROUTER_TOOL_MENU( board ); SetContextMenu ( ctxMenu ); From c8512f059264c6badee33ad361dd102eea97349f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 16:50:31 +0200 Subject: [PATCH 110/123] New pads in the module editor does not show up in the center of the edited module. --- pcbnew/tools/module_tools.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pcbnew/tools/module_tools.cpp b/pcbnew/tools/module_tools.cpp index 3a6827a9d9..effaf732dc 100644 --- a/pcbnew/tools/module_tools.cpp +++ b/pcbnew/tools/module_tools.cpp @@ -137,7 +137,7 @@ int MODULE_TOOLS::PlacePad( TOOL_EVENT& aEvent ) preview.Add( pad ); m_view->Add( &preview ); - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); @@ -205,6 +205,7 @@ int MODULE_TOOLS::PlacePad( TOOL_EVENT& aEvent ) // Start placing next pad pad = new D_PAD( module ); m_frame->Import_Pad_Settings( pad, false ); + pad->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) ); preview.Add( pad ); } } From 88319139ed8592c04239133ff575a1d64d91930d Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 16:50:31 +0200 Subject: [PATCH 111/123] Dragged items offset is cleared when dragging is finished. --- pcbnew/tools/edit_tool.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 55db5259bb..9d6e646c96 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -65,6 +65,9 @@ bool EDIT_TOOL::Init() m_selectionTool->AddMenuItem( COMMON_ACTIONS::remove, SELECTION_CONDITIONS::NotEmpty ); m_selectionTool->AddMenuItem( COMMON_ACTIONS::properties, SELECTION_CONDITIONS::NotEmpty ); + m_offset.x = 0; + m_offset.y = 0; + setTransitions(); return true; @@ -186,6 +189,8 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) } m_dragging = false; + m_offset.x = 0; + m_offset.y = 0; if( restore ) { From 53c0b9d85b72a9790ce837f175c7288a7f52a567 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 16:50:31 +0200 Subject: [PATCH 112/123] Some of the Tool Actions need to be run in immediate mode - fixed. --- pcbnew/router/router_tool.cpp | 2 +- pcbnew/tools/drawing_tool.cpp | 18 +++++++++--------- pcbnew/tools/edit_tool.cpp | 16 ++++++++-------- pcbnew/tools/module_tools.cpp | 4 ++-- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 884af6a172..03298fd9a1 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -626,7 +626,7 @@ int ROUTER_TOOL::Main( TOOL_EVENT& aEvent ) BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings(); // Deselect all items - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); getEditFrame()->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Interactive Router" ) ); diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index 83ae2129b8..e1e15322fa 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -251,7 +251,7 @@ int DRAWING_TOOL::DrawDimension( TOOL_EVENT& aEvent ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); @@ -450,7 +450,7 @@ int DRAWING_TOOL::PlaceTarget( TOOL_EVENT& aEvent ) m_view->Add( &preview ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_controls->SetSnapping( true ); m_controls->SetAutoPan( true ); @@ -525,7 +525,7 @@ int DRAWING_TOOL::PlaceModule( TOOL_EVENT& aEvent ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); m_controls->SetAutoPan( true ); @@ -703,7 +703,7 @@ int DRAWING_TOOL::PlaceDXF( TOOL_EVENT& aEvent ) BOARD_ITEM* firstItem = static_cast( *preview.Begin() ); m_view->Add( &preview ); - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); @@ -877,7 +877,7 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic, KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); @@ -1042,7 +1042,7 @@ bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); @@ -1212,7 +1212,7 @@ int DRAWING_TOOL::drawZone( bool aKeepout ) KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); @@ -1421,7 +1421,7 @@ int DRAWING_TOOL::placeTextModule() KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); m_controls->SetAutoPan( true ); @@ -1539,7 +1539,7 @@ int DRAWING_TOOL::placeTextPcb() KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); m_controls->SetAutoPan( true ); diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 9d6e646c96..da350c4aa8 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -181,7 +181,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) } selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); - m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate ); + m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true ); } else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) @@ -205,7 +205,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) } if( unselect ) - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); RN_DATA* ratsnest = getModel()->GetRatsnest(); ratsnest->ClearSimple(); @@ -278,7 +278,7 @@ int EDIT_TOOL::Properties( TOOL_EVENT& aEvent ) getModel()->GetRatsnest()->Recalculate(); item->ViewUpdate(); - m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate ); + m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true ); } item->SetFlags( flags ); @@ -335,9 +335,9 @@ int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) getModel()->GetRatsnest()->Recalculate(); if( unselect ) - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); - m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate ); + m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true ); setTransitions(); return 0; @@ -389,9 +389,9 @@ int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) getModel()->GetRatsnest()->Recalculate(); if( unselect ) - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); - m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate ); + m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true ); setTransitions(); return 0; @@ -414,7 +414,7 @@ int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) PCB_BASE_FRAME* editFrame = getEditFrame(); // As we are about to remove items, they have to be removed from the selection first - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); // Save them for( unsigned int i = 0; i < selectedItems.GetCount(); ++i ) diff --git a/pcbnew/tools/module_tools.cpp b/pcbnew/tools/module_tools.cpp index effaf732dc..a03ea3adcf 100644 --- a/pcbnew/tools/module_tools.cpp +++ b/pcbnew/tools/module_tools.cpp @@ -258,7 +258,7 @@ int MODULE_TOOLS::EnumeratePads( TOOL_EVENT& aEvent ) Activate(); - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_controls->ShowCursor( true ); while( OPT_TOOL_EVENT evt = Wait() ) @@ -433,7 +433,7 @@ int MODULE_TOOLS::PasteItems( TOOL_EVENT& aEvent ) preview.Add( pastedModule ); m_view->Add( &preview ); - m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); + m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); m_controls->SetAutoPan( true ); From f3bdc29e8eb68e311e12d483ad59acd6cdc4aae9 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 16:50:31 +0200 Subject: [PATCH 113/123] Support for "locked" property for modules (GAL). --- pcbnew/tools/edit_tool.cpp | 9 +++-- pcbnew/tools/selection_tool.cpp | 59 ++++++++++++++++++++++++++++++--- pcbnew/tools/selection_tool.h | 18 ++++++---- 3 files changed, 72 insertions(+), 14 deletions(-) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index da350c4aa8..9b5924327e 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -158,6 +158,9 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) } else // Prepare to start dragging { + if( m_selectionTool->CheckLock() ) + break; + // Save items, so changes can be undone editFrame->OnModify(); editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED ); @@ -298,7 +301,7 @@ int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent ) // Shall the selection be cleared at the end? bool unselect = selection.Empty(); - if( !makeSelection( selection ) ) + if( !makeSelection( selection ) || m_selectionTool->CheckLock() ) { setTransitions(); @@ -352,7 +355,7 @@ int EDIT_TOOL::Flip( TOOL_EVENT& aEvent ) // Shall the selection be cleared at the end? bool unselect = selection.Empty(); - if( !makeSelection( selection ) ) + if( !makeSelection( selection ) || m_selectionTool->CheckLock() ) { setTransitions(); @@ -402,7 +405,7 @@ int EDIT_TOOL::Remove( TOOL_EVENT& aEvent ) { const SELECTION& selection = m_selectionTool->GetSelection(); - if( !makeSelection( selection ) ) + if( !makeSelection( selection ) || m_selectionTool->CheckLock() ) { setTransitions(); diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index b281091923..303dd30987 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -25,9 +25,7 @@ #include #include -#include -#include #include #include #include @@ -35,6 +33,9 @@ #include #include +#include + +#include #include #include #include @@ -52,7 +53,8 @@ SELECTION_TOOL::SELECTION_TOOL() : SelectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.selected" ), DeselectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.deselected" ), ClearedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.cleared" ), - m_frame( NULL ), m_additive( false ), m_multiple( false ), m_editModules( false ) + m_frame( NULL ), m_additive( false ), m_multiple( false ), + m_editModules( false ), m_locked( true ) { m_selArea = new SELECTION_AREA; m_selection.group = new KIGFX::VIEW_GROUP; @@ -77,6 +79,7 @@ void SELECTION_TOOL::Reset( RESET_REASON aReason ) clearSelection(); m_frame = getEditFrame(); + m_locked = true; // Reinsert the VIEW_GROUP, in case it was removed from the VIEW getView()->Remove( m_selection.group ); @@ -384,6 +387,48 @@ void SELECTION_TOOL::setTransitions() } +bool SELECTION_TOOL::CheckLock() +{ + if( !m_locked ) + return false; + + bool containsLocked = false; + + // Check if the selection contains locked items + for( int i = 0; i < m_selection.Size(); ++i ) + { + BOARD_ITEM* item = m_selection.Item( i ); + + switch( item->Type() ) + { + case PCB_MODULE_T: + if( static_cast( item )->IsLocked() ) + containsLocked = true; + break; + + case PCB_MODULE_EDGE_T: + case PCB_MODULE_TEXT_T: + if( static_cast( item->GetParent() )->IsLocked() ) + containsLocked = true; + break; + + default: // suppress warnings + break; + } + } + + if( containsLocked && + !IsOK( m_frame, _( "Selection contains locked items. Do you want to continue?" ) ) ) + { + return true; + } + + m_locked = false; + + return false; +} + + int SELECTION_TOOL::SingleSelection( TOOL_EVENT& aEvent ) { selectSingle( getView()->ToWorld( getViewControls()->GetMousePosition() ) ); @@ -419,7 +464,8 @@ void SELECTION_TOOL::clearSelection() } m_selection.clear(); - getEditFrame()->SetCurItem( NULL ); + m_frame->SetCurItem( NULL ); + m_locked = true; // Inform other potentially interested tools TOOL_EVENT clearEvent( ClearedEvent ); @@ -650,7 +696,10 @@ void SELECTION_TOOL::deselect( BOARD_ITEM* aItem ) m_selection.items.RemovePicker( itemIdx ); if( m_selection.Empty() ) + { m_frame->SetCurItem( NULL ); + m_locked = true; + } // Inform other potentially interested tools TOOL_EVENT deselected( DeselectedEvent ); @@ -772,7 +821,7 @@ void SELECTION_TOOL::generateMenu() } if( m_menuCopy.GetMenuItemCount() > 0 ) - SetContextMenu( &m_menuCopy, CMENU_NOW ); + SetContextMenu( &m_menuCopy, CMENU_NOW ); } diff --git a/pcbnew/tools/selection_tool.h b/pcbnew/tools/selection_tool.h index 06a0af35e6..beceefee5d 100644 --- a/pcbnew/tools/selection_tool.h +++ b/pcbnew/tools/selection_tool.h @@ -148,6 +148,15 @@ public: m_editModules = aEnabled; } + ///> Checks if the user has agreed to modify locked items for the given selection. + bool CheckLock(); + + ///> Select single item event handler. + int SingleSelection( TOOL_EVENT& aEvent ); + + ///> Clear current selection event handler. + int ClearSelection( TOOL_EVENT& aEvent ); + ///> Event sent after an item is selected. const TOOL_EVENT SelectedEvent; @@ -157,12 +166,6 @@ public: ///> Event sent after selection is cleared. const TOOL_EVENT ClearedEvent; - ///> Select single item event handler. - int SingleSelection( TOOL_EVENT& aEvent ); - - ///> Clear current selection event handler. - int ClearSelection( TOOL_EVENT& aEvent ); - private: /** * Function selectSingle() @@ -313,6 +316,9 @@ private: /// Edit module mode flag. bool m_editModules; + /// Can other tools modify locked items. + bool m_locked; + /// Conditions for specific context menu entries. std::deque m_menuConditions; }; From c3ab5c5da85dd23ea12d504426ba37cfd02d3166 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 16:50:31 +0200 Subject: [PATCH 114/123] Added module texts to the preferred types list in SELECTION_TOOL. --- pcbnew/tools/selection_tool.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 303dd30987..13151cdf65 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -239,7 +239,9 @@ bool SELECTION_TOOL::selectSingle( const VECTOR2I& aWhere, bool aAllowDisambigua BOARD_ITEM* item; GENERAL_COLLECTORS_GUIDE guide = m_frame->GetCollectorsGuide(); GENERAL_COLLECTOR collector; - const KICAD_T types[] = { PCB_TRACE_T, PCB_VIA_T, PCB_LINE_T, EOT }; // preferred types + + // Preferred types (they have the priority when if they are covered by a bigger item) + const KICAD_T types[] = { PCB_TRACE_T, PCB_VIA_T, PCB_LINE_T, PCB_MODULE_TEXT_T, EOT }; if( m_editModules ) collector.Collect( getModel(), GENERAL_COLLECTOR::ModuleItems, From cf0a9ee8af66266e5b3b10315fe63bbb816c83a9 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 16:50:31 +0200 Subject: [PATCH 115/123] Selection tool uses the real drag origin to compute offset when dragging items. --- pcbnew/tools/edit_tool.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 9b5924327e..f174753c6d 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -175,9 +176,11 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent ) } else { + const VECTOR2D& dragOrigin = getView()->GetGAL()->GetGridPoint( evt->DragOrigin() ); + // Update dragging offset (distance between cursor and the first dragged item) m_offset = static_cast( selection.items.GetPickedItem( 0 ) )->GetPosition() - - wxPoint( m_cursor.x, m_cursor.y ); + wxPoint( dragOrigin.x, dragOrigin.y ); } m_dragging = true; From 40361deb56ffffdaedd905b59d18414e4325f5ab Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 16:50:31 +0200 Subject: [PATCH 116/123] Cursor position is frozen when a context menu is displayed (GAL). --- common/tool/tool_manager.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index 7a6df985fe..cf64603b4d 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -37,6 +37,7 @@ #include #include +#include #include #include @@ -577,6 +578,10 @@ void TOOL_MANAGER::dispatchContextMenu( TOOL_EVENT& aEvent ) if( st->contextMenuTrigger == CMENU_NOW ) st->contextMenuTrigger = CMENU_OFF; + // Temporarily store the cursor position, so the tools could execute actions + // using the point where the user has invoked a context menu + m_viewControls->ForceCursorPosition( true, m_viewControls->GetCursorPosition() ); + boost::scoped_ptr menu( new CONTEXT_MENU( *st->contextMenu ) ); GetEditFrame()->PopupMenu( menu.get() ); @@ -587,6 +592,8 @@ void TOOL_MANAGER::dispatchContextMenu( TOOL_EVENT& aEvent ) dispatchInternal( evt ); } + m_viewControls->ForceCursorPosition( false ); + break; } } From 9280c29fa98da95bcb1954470a4e2df96622d579 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 16:50:31 +0200 Subject: [PATCH 117/123] "Create corner" context menu entry for draw segments and zone outlines (GAL). --- pcbnew/tools/common_actions.cpp | 6 +++++ pcbnew/tools/common_actions.h | 3 +++ pcbnew/tools/point_editor.cpp | 47 ++++++++++++++++++++++++++++----- pcbnew/tools/point_editor.h | 13 +++++---- 4 files changed, 56 insertions(+), 13 deletions(-) diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index cf2879e725..47321a67c5 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -322,10 +322,16 @@ TOOL_ACTION COMMON_ACTIONS::routerActivate( "pcbnew.InteractiveRouter", AS_GLOBAL, 'X', "Run push & shove router", "Run push & shove router", AF_ACTIVATE ); + +// Point editor TOOL_ACTION COMMON_ACTIONS::pointEditorUpdate( "pcbnew.PointEditor.update", AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere +TOOL_ACTION COMMON_ACTIONS::pointEditorBreakOutline( "pcbnew.PointEditor.breakOutline", + AS_GLOBAL, 0, + "Create corner", "Create corner" ); + // Placement tool TOOL_ACTION COMMON_ACTIONS::alignTop( "pcbnew.Place.alignTop", diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 6df00fae9b..79af0ee129 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -105,6 +105,9 @@ public: /// Update edit points static TOOL_ACTION pointEditorUpdate; + /// Break outline (insert additional points to an edge) + static TOOL_ACTION pointEditorBreakOutline; + // Placement tool /// Align items to the top edge of selection bounding box static TOOL_ACTION alignTop; diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 3df09c4ce0..8951cb3f25 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -195,6 +195,9 @@ bool POINT_EDITOR::Init() return false; } + m_selectionTool->AddMenuItem( COMMON_ACTIONS::pointEditorBreakOutline, + POINT_EDITOR::breakOutlineCondition ); + setTransitions(); return true; @@ -259,9 +262,10 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) m_dragPoint = point; } - else if( evt->IsDblClick( BUT_LEFT ) ) + else if( evt->IsAction( &COMMON_ACTIONS::pointEditorBreakOutline ) ) { breakOutline( controls->GetCursorPosition() ); + updatePoints(); } else if( evt->IsDrag( BUT_LEFT ) && m_dragPoint ) @@ -446,8 +450,9 @@ void POINT_EDITOR::updateItem() const for( int i = 0; i < outline->GetCornersCount(); ++i ) { - outline->SetX( i, m_editPoints->Point( i ).GetPosition().x ); - outline->SetY( i, m_editPoints->Point( i ).GetPosition().y ); + VECTOR2I point = m_editPoints->Point( i ).GetPosition(); + outline->SetX( i, point.x ); + outline->SetY( i, point.y ); } break; @@ -521,7 +526,7 @@ void POINT_EDITOR::finishItem() const } -void POINT_EDITOR::updatePoints() const +void POINT_EDITOR::updatePoints() { EDA_ITEM* item = m_editPoints->GetParent(); @@ -563,8 +568,17 @@ void POINT_EDITOR::updatePoints() const const ZONE_CONTAINER* zone = static_cast( item ); const CPolyLine* outline = zone->Outline(); - for( int i = 0; i < outline->GetCornersCount(); ++i ) - m_editPoints->Point( i ).SetPosition( outline->GetPos( i ) ); + if( m_editPoints->PointsSize() != (unsigned) outline->GetCornersCount() ) + { + getView()->Remove( m_editPoints.get() ); + m_editPoints = EDIT_POINTS_FACTORY::Make( item, getView()->GetGAL() ); + getView()->Add( m_editPoints.get() ); + } + else + { + for( int i = 0; i < outline->GetCornersCount(); ++i ) + m_editPoints->Point( i ).SetPosition( outline->GetPos( i ) ); + } break; } @@ -763,3 +777,24 @@ void POINT_EDITOR::breakOutline( const VECTOR2I& aBreakPoint ) } } } + + +void POINT_EDITOR::setTransitions() +{ + Go( &POINT_EDITOR::OnSelectionChange, m_selectionTool->SelectedEvent ); + Go( &POINT_EDITOR::OnSelectionChange, m_selectionTool->DeselectedEvent ); +} + + +bool POINT_EDITOR::breakOutlineCondition( const SELECTION& aSelection ) +{ + if( aSelection.Size() != 1 ) + return false; + + BOARD_ITEM* item = aSelection.Item( 0 ); + + // Works only for zones and line segments + return item->Type() == PCB_ZONE_AREA_T || + ( ( item->Type() == PCB_LINE_T || item->Type() == PCB_MODULE_EDGE_T ) && + static_cast( item )->GetShape() == S_SEGMENT ); +} diff --git a/pcbnew/tools/point_editor.h b/pcbnew/tools/point_editor.h index b87224f613..d6f4b30611 100644 --- a/pcbnew/tools/point_editor.h +++ b/pcbnew/tools/point_editor.h @@ -81,7 +81,7 @@ private: void finishItem() const; ///> Updates edit points with item's points. - void updatePoints() const; + void updatePoints(); ///> Returns true if aPoint is the currently modified point. inline bool isModified( const EDIT_POINT& aPoint ) const @@ -95,15 +95,14 @@ private: ///> Returns a point that should be used as a constrainer for 45 degrees mode. EDIT_POINT get45DegConstrainer() const; - ///> Adds a new edit point on a zone outline. + ///> Adds a new edit point on a zone outline/line. void breakOutline( const VECTOR2I& aBreakPoint ); ///> Sets up handlers for various events. - void setTransitions() - { - Go( &POINT_EDITOR::OnSelectionChange, m_selectionTool->SelectedEvent ); - Go( &POINT_EDITOR::OnSelectionChange, m_selectionTool->DeselectedEvent ); - } + void setTransitions(); + + ///> Condition to display "Create corner" context menu entry. + static bool breakOutlineCondition( const SELECTION& aSelection ); }; #endif From 6ed751752273235940d0740d1f059bf7b6db5d4f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 16:50:31 +0200 Subject: [PATCH 118/123] Fixed the only-type condition for empty selection case. --- pcbnew/tools/selection_conditions.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pcbnew/tools/selection_conditions.cpp b/pcbnew/tools/selection_conditions.cpp index f1679dac8b..fe130b9db4 100644 --- a/pcbnew/tools/selection_conditions.cpp +++ b/pcbnew/tools/selection_conditions.cpp @@ -78,6 +78,9 @@ bool SELECTION_CONDITIONS::hasTypeFunc( const SELECTION& aSelection, KICAD_T aTy bool SELECTION_CONDITIONS::onlyTypeFunc( const SELECTION& aSelection, KICAD_T aType ) { + if( aSelection.Empty() ) + return false; + for( int i = 0; i < aSelection.Size(); ++i ) { if( aSelection.Item( i )->Type() != aType ) From ed83558ae4983e23bc9c01851ff64c246ba5ba88 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 16:57:01 +0200 Subject: [PATCH 119/123] Zone fill/unfill actions in context menu (GAL). --- pcbnew/router/pns_router.cpp | 3 +- pcbnew/router/router_tool.cpp | 6 +- pcbnew/tools/common_actions.cpp | 15 +++++ pcbnew/tools/common_actions.h | 6 +- pcbnew/tools/pcb_editor_control.cpp | 90 +++++++++++++++++++++++++++++ pcbnew/tools/pcb_editor_control.h | 9 ++- pcbnew/tools/pcbnew_control.cpp | 1 + pcbnew/tools/pcbnew_control.h | 8 +-- 8 files changed, 123 insertions(+), 15 deletions(-) diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp index 67d54ceda5..d9db594a0f 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -759,7 +759,8 @@ void PNS_ROUTER::CommitRouting( PNS_NODE* aNode ) via_board->SetWidth( via->Diameter() ); via_board->SetDrill( via->Drill() ); via_board->SetNetCode( via->Net() ); - via_board->SetLayerPair( m_settings.GetLayerTop(), m_settings.GetLayerBottom() ); + via_board->SetLayerPair( ToLAYER_ID( m_settings.GetLayerTop() ), + ToLAYER_ID( m_settings.GetLayerBottom() ) ); newBI = via_board; break; } diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 03298fd9a1..29de1909db 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -212,8 +212,8 @@ public: Add( ACT_PlaceThroughVia ); Add( ACT_SwitchPosture ); - AppendSeparator ( ); - + AppendSeparator(); + CONTEXT_TRACK_WIDTH_MENU* trackMenu = new CONTEXT_TRACK_WIDTH_MENU; trackMenu->SetBoard( aBoard ); AppendSubMenu( trackMenu, wxT( "Select Track Width" ) ); @@ -567,7 +567,7 @@ void ROUTER_TOOL::performRouting() break; // Synchronize the indicated layer - frame->SetActiveLayer( m_router->GetCurrentLayer() ); + frame->SetActiveLayer( ToLAYER_ID( m_router->GetCurrentLayer() ) ); m_router->Move( m_endSnapPoint, m_endItem ); } diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp index 47321a67c5..0ce1c0f806 100644 --- a/pcbnew/tools/common_actions.cpp +++ b/pcbnew/tools/common_actions.cpp @@ -109,6 +109,7 @@ TOOL_ACTION COMMON_ACTIONS::setAnchor( "pcbnew.InteractiveDrawing.setAnchor", "Place the footprint anchor", "Place the footprint anchor", AF_ACTIVATE ); + // View Controls TOOL_ACTION COMMON_ACTIONS::zoomIn( "pcbnew.Control.zoomIn", AS_GLOBAL, WXK_F1, @@ -271,6 +272,20 @@ TOOL_ACTION COMMON_ACTIONS::trackViaSizeChanged( "pcbnew.EditorControl.trackViaS "", "", AF_NOTIFY ); +// Zone actions +TOOL_ACTION COMMON_ACTIONS::zoneFill( "pcbnew.EditorControl.zoneFill", + AS_GLOBAL, 0, + "Fill", "Fill zone(s)" ); + +TOOL_ACTION COMMON_ACTIONS::zoneFillAll( "pcbnew.EditorControl.zoneFillAll", + AS_GLOBAL, 0, + "Fill all", "Fill all zones" ); + +TOOL_ACTION COMMON_ACTIONS::zoneUnfill( "pcbnew.EditorControl.zoneUnfill", + AS_GLOBAL, 0, + "Unfill", "Unfill zone(s)" ); + + // Module editor tools TOOL_ACTION COMMON_ACTIONS::placePad( "pcbnew.ModuleEditor.placePad", AS_GLOBAL, 0, diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h index 79af0ee129..4712b42525 100644 --- a/pcbnew/tools/common_actions.h +++ b/pcbnew/tools/common_actions.h @@ -62,7 +62,6 @@ public: /// Deleting a BOARD_ITEM static TOOL_ACTION remove; - // Drawing Tool /// Activation of the drawing tool (line) static TOOL_ACTION drawLine; @@ -177,6 +176,10 @@ public: static TOOL_ACTION trackViaSizeChanged; // notification + // Zone actions + static TOOL_ACTION zoneFill; + static TOOL_ACTION zoneFillAll; + static TOOL_ACTION zoneUnfill; // Module editor tools /// Activation of the drawing tool (placing a PAD) @@ -197,7 +200,6 @@ public: /// Display module texts as outlines static TOOL_ACTION moduleTextOutlines; - // Miscellaneous static TOOL_ACTION resetCoords; static TOOL_ACTION switchCursor; diff --git a/pcbnew/tools/pcb_editor_control.cpp b/pcbnew/tools/pcb_editor_control.cpp index a1b46c8a46..f1c8fe3833 100644 --- a/pcbnew/tools/pcb_editor_control.cpp +++ b/pcbnew/tools/pcb_editor_control.cpp @@ -25,10 +25,26 @@ #include "pcb_editor_control.h" #include "common_actions.h" +#include "selection_tool.h" + #include #include +#include #include + +class ZONE_CONTEXT_MENU : public CONTEXT_MENU +{ +public: + ZONE_CONTEXT_MENU() + { + Add( COMMON_ACTIONS::zoneFill ); + Add( COMMON_ACTIONS::zoneFillAll ); + Add( COMMON_ACTIONS::zoneUnfill ); + } +}; + + PCB_EDITOR_CONTROL::PCB_EDITOR_CONTROL() : TOOL_INTERACTIVE( "pcbnew.EditorControl" ) { @@ -43,6 +59,14 @@ void PCB_EDITOR_CONTROL::Reset( RESET_REASON aReason ) bool PCB_EDITOR_CONTROL::Init() { + SELECTION_TOOL* selTool = m_toolMgr->GetTool(); + + if( selTool ) + { + selTool->AddSubMenu( new ZONE_CONTEXT_MENU, wxT( "Zones" ), + SELECTION_CONDITIONS::OnlyType( PCB_ZONE_AREA_T ) ); + } + setTransitions(); return true; @@ -134,6 +158,67 @@ int PCB_EDITOR_CONTROL::ViaSizeDec( TOOL_EVENT& aEvent ) } +// Zone actions +int PCB_EDITOR_CONTROL::ZoneFill( TOOL_EVENT& aEvent ) +{ + SELECTION_TOOL* selTool = m_toolMgr->GetTool(); + const SELECTION& selection = selTool->GetSelection(); + + for( int i = 0; i < selection.Size(); ++i ) + { + assert( selection.Item( i )->Type() == PCB_ZONE_AREA_T ); + + ZONE_CONTAINER* zone = selection.Item( i ); + m_frame->Fill_Zone( zone ); + zone->SetIsFilled( true ); + zone->ViewUpdate(); + } + + setTransitions(); + + return 0; +} + + +int PCB_EDITOR_CONTROL::ZoneFillAll( TOOL_EVENT& aEvent ) +{ + BOARD* board = getModel(); + + for( int i = 0; i < board->GetAreaCount(); ++i ) + { + ZONE_CONTAINER* zone = board->GetArea( i ); + m_frame->Fill_Zone( zone ); + zone->SetIsFilled( true ); + zone->ViewUpdate(); + } + + setTransitions(); + + return 0; +} + + +int PCB_EDITOR_CONTROL::ZoneUnfill( TOOL_EVENT& aEvent ) +{ + SELECTION_TOOL* selTool = m_toolMgr->GetTool(); + const SELECTION& selection = selTool->GetSelection(); + + for( int i = 0; i < selection.Size(); ++i ) + { + assert( selection.Item( i )->Type() == PCB_ZONE_AREA_T ); + + ZONE_CONTAINER* zone = selection.Item( i ); + zone->SetIsFilled( false ); + zone->ClearFilledPolysList(); + zone->ViewUpdate(); + } + + setTransitions(); + + return 0; +} + + void PCB_EDITOR_CONTROL::setTransitions() { // Track & via size control @@ -141,4 +226,9 @@ void PCB_EDITOR_CONTROL::setTransitions() Go( &PCB_EDITOR_CONTROL::TrackWidthDec, COMMON_ACTIONS::trackWidthDec.MakeEvent() ); Go( &PCB_EDITOR_CONTROL::ViaSizeInc, COMMON_ACTIONS::viaSizeInc.MakeEvent() ); Go( &PCB_EDITOR_CONTROL::ViaSizeDec, COMMON_ACTIONS::viaSizeDec.MakeEvent() ); + + // Zone actions + Go( &PCB_EDITOR_CONTROL::ZoneFill, COMMON_ACTIONS::zoneFill.MakeEvent() ); + Go( &PCB_EDITOR_CONTROL::ZoneFillAll, COMMON_ACTIONS::zoneFillAll.MakeEvent() ); + Go( &PCB_EDITOR_CONTROL::ZoneUnfill, COMMON_ACTIONS::zoneUnfill.MakeEvent() ); } diff --git a/pcbnew/tools/pcb_editor_control.h b/pcbnew/tools/pcb_editor_control.h index 8d879907fa..6d272884c9 100644 --- a/pcbnew/tools/pcb_editor_control.h +++ b/pcbnew/tools/pcb_editor_control.h @@ -30,9 +30,9 @@ class PCB_EDIT_FRAME; /** - * Class PCBNEW_CONTROL + * Class PCB_EDITOR_CONTROL * - * Handles hot keys that are not accepted by any other tool. + * Handles actions specific to the board editor in pcbnew. */ class PCB_EDITOR_CONTROL : public TOOL_INTERACTIVE { @@ -51,6 +51,11 @@ public: int ViaSizeInc( TOOL_EVENT& aEvent ); int ViaSizeDec( TOOL_EVENT& aEvent ); + // Zone actions + int ZoneFill( TOOL_EVENT& aEvent ); + int ZoneFillAll( TOOL_EVENT& aEvent ); + int ZoneUnfill( TOOL_EVENT& aEvent ); + private: ///> Sets up handlers for various events. void setTransitions(); diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index 1bbddbc432..a0573b3118 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -40,6 +40,7 @@ #include #include + PCBNEW_CONTROL::PCBNEW_CONTROL() : TOOL_INTERACTIVE( "pcbnew.Control" ) { diff --git a/pcbnew/tools/pcbnew_control.h b/pcbnew/tools/pcbnew_control.h index 7fc9978b60..e9e87cb1e4 100644 --- a/pcbnew/tools/pcbnew_control.h +++ b/pcbnew/tools/pcbnew_control.h @@ -32,7 +32,7 @@ class PCB_BASE_FRAME; /** * Class PCBNEW_CONTROL * - * Handles hot keys that are not accepted by any other tool. + * Handles actions that are shared between different frames in pcbnew. */ class PCBNEW_CONTROL : public TOOL_INTERACTIVE @@ -75,12 +75,6 @@ public: int GridPrev( TOOL_EVENT& aEvent ); int GridSetOrigin( TOOL_EVENT& aEvent ); - // Track & via size control - int TrackWidthInc( TOOL_EVENT& aEvent ); - int TrackWidthDec( TOOL_EVENT& aEvent ); - int ViaSizeInc( TOOL_EVENT& aEvent ); - int ViaSizeDec( TOOL_EVENT& aEvent ); - // Miscellaneous int ResetCoords( TOOL_EVENT& aEvent ); int SwitchCursor( TOOL_EVENT& aEvent ); From 26996d640f3837ecb4dd7bac28656e178138c794 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 9 Jul 2014 16:57:01 +0200 Subject: [PATCH 120/123] Fixed the Module viewer crash when there is no footprint loaded. --- common/gal/cairo/cairo_compositor.cpp | 3 +++ pcbnew/modview_frame.cpp | 10 ++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/common/gal/cairo/cairo_compositor.cpp b/common/gal/cairo/cairo_compositor.cpp index e749c4db9a..5afa67d55a 100644 --- a/common/gal/cairo/cairo_compositor.cpp +++ b/common/gal/cairo/cairo_compositor.cpp @@ -55,6 +55,9 @@ void CAIRO_COMPOSITOR::Resize( unsigned int aWidth, unsigned int aHeight ) { clean(); + assert( m_width > 0 ); + assert( m_height > 0 ); + m_width = aWidth; m_height = aHeight; diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp index 3404a5b349..d83e220234 100644 --- a/pcbnew/modview_frame.cpp +++ b/pcbnew/modview_frame.cpp @@ -168,11 +168,11 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent ReCreateLibraryList(); UpdateTitle(); - EDA_DRAW_FRAME* drawFrame = static_cast( aParent ); + PCB_BASE_FRAME* parentFrame = static_cast( Kiway().Player( FRAME_PCB, true ) ); // Create GAL canvas PCB_DRAW_PANEL_GAL* drawPanel = new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), m_FrameSize, - drawFrame->GetGalCanvas()->GetBackend() ); + parentFrame->GetGalCanvas()->GetBackend() ); SetGalCanvas( drawPanel ); // Create the manager and dispatcher & route draw panel events to the dispatcher @@ -193,9 +193,11 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent id.SetLibNickname( getCurNickname() ); id.SetFootprintName( getCurFootprintName() ); GetBoard()->Add( loadFootprint( id ) ); - drawPanel->DisplayBoard( m_Pcb ); } + drawPanel->DisplayBoard( m_Pcb ); + updateView(); + if( m_canvas ) m_canvas->SetAcceleratorTable( table ); @@ -273,7 +275,7 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent Show( true ); - UseGalCanvas( drawFrame->IsGalCanvasActive() ); + UseGalCanvas( parentFrame->IsGalCanvasActive() ); } From a0621448f6da8fdefb52288c8712d40660f5c0ac Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Mon, 14 Jul 2014 09:36:37 +0200 Subject: [PATCH 121/123] Gerber files generation: fix a rounding issue when drawing circles. (explains bug Bug #1339086 ). Gerbview: allows x.7 format (recently indroduced in Gerber format) Also minor coding style fixes. --- common/common_plotGERBER_functions.cpp | 7 ++- gerbview/rs274_read_XY_and_IJ_coordinates.cpp | 44 ++++++++++++------- gerbview/rs274d.cpp | 1 - gerbview/rs274x.cpp | 13 +++--- 4 files changed, 39 insertions(+), 26 deletions(-) diff --git a/common/common_plotGERBER_functions.cpp b/common/common_plotGERBER_functions.cpp index 94a84af4e3..6c5b07bcfb 100644 --- a/common/common_plotGERBER_functions.cpp +++ b/common/common_plotGERBER_functions.cpp @@ -356,14 +356,17 @@ void GERBER_PLOTTER::Arc( const wxPoint& aCenter, double aStAngle, double aEndAn DPOINT devEnd = userToDeviceCoordinates( end ); DPOINT devCenter = userToDeviceCoordinates( aCenter ) - userToDeviceCoordinates( start ); + fprintf( outputFile, "G75*\n" ); // Multiquadrant mode if( aStAngle < aEndAngle ) fprintf( outputFile, "G03" ); else fprintf( outputFile, "G02" ); - fprintf( outputFile, "X%dY%dI%dJ%dD01*\n", int( devEnd.x ), int( devEnd.y ), - int( devCenter.x ), int( devCenter.y ) ); + + fprintf( outputFile, "X%dY%dI%dJ%dD01*\n", + KiROUND( devEnd.x ), KiROUND( devEnd.y ), + KiROUND( devCenter.x ), KiROUND( devCenter.y ) ); fprintf( outputFile, "G74*\nG01*\n" ); // Back to single quadrant and linear interp. } diff --git a/gerbview/rs274_read_XY_and_IJ_coordinates.cpp b/gerbview/rs274_read_XY_and_IJ_coordinates.cpp index f3fa381310..d2b53fd86f 100644 --- a/gerbview/rs274_read_XY_and_IJ_coordinates.cpp +++ b/gerbview/rs274_read_XY_and_IJ_coordinates.cpp @@ -19,25 +19,24 @@ // depending on the gerber file format // this scale list assumes gerber units are imperial. // for metric gerber units, the imperial to metric conversion is made in read functions -static double scale_list[10] = +#define SCALE_LIST_SIZE 10 +static double scale_list[SCALE_LIST_SIZE] = { - 1000.0 * IU_PER_MILS, - 100.0 * IU_PER_MILS, - 10.0 * IU_PER_MILS, - 1.0 * IU_PER_MILS, - 0.1 * IU_PER_MILS, - 0.01 * IU_PER_MILS, - 0.001 * IU_PER_MILS, - 0.0001 * IU_PER_MILS, - 0.00001 * IU_PER_MILS, + 1000.0 * IU_PER_MILS, // x.1 format (certainly useless) + 100.0 * IU_PER_MILS, // x.2 format (certainly useless) + 10.0 * IU_PER_MILS, // x.3 format + 1.0 * IU_PER_MILS, // x.4 format + 0.1 * IU_PER_MILS, // x.5 format + 0.01 * IU_PER_MILS, // x.6 format + 0.0001 * IU_PER_MILS, // x.7 format + 0.00001 * IU_PER_MILS, // provided, but not used 0.000001 * IU_PER_MILS }; - -/** +/* * Function scale - * converts a distance given in floating point to our internal units - * (deci-mils or nano units) + * converts a coordinate given in floating point to Gerbvies internal units + * (currently = 10 nanometers) */ int scaletoIU( double aCoord, bool isMetric ) { @@ -78,6 +77,7 @@ wxPoint GERBER_IMAGE::ReadXYCoord( char*& Text ) Text++; text = line; nbdigits = 0; + while( IsNumber( *Text ) ) { if( *Text == '.' ) // Force decimat format if reading a floating point number @@ -90,6 +90,7 @@ wxPoint GERBER_IMAGE::ReadXYCoord( char*& Text ) } *text = 0; + if( is_float ) { // When X or Y values are float numbers, they are given in mm or inches @@ -101,6 +102,7 @@ wxPoint GERBER_IMAGE::ReadXYCoord( char*& Text ) else { int fmt_scale = (type_coord == 'X') ? m_FmtScale.x : m_FmtScale.y; + if( m_NoTrailingZeros ) { int min_digit = @@ -113,6 +115,7 @@ wxPoint GERBER_IMAGE::ReadXYCoord( char*& Text ) *text = 0; } + current_coord = atoi( line ); double real_scale = scale_list[fmt_scale]; @@ -177,6 +180,7 @@ wxPoint GERBER_IMAGE::ReadIJCoord( char*& Text ) // count digits only (sign and decimal point are not counted) if( (*Text >= '0') && (*Text <='9') ) nbdigits++; + *(text++) = *(Text++); } @@ -193,6 +197,7 @@ wxPoint GERBER_IMAGE::ReadIJCoord( char*& Text ) { int fmt_scale = (type_coord == 'I') ? m_FmtScale.x : m_FmtScale.y; + if( m_NoTrailingZeros ) { int min_digit = @@ -205,20 +210,21 @@ wxPoint GERBER_IMAGE::ReadIJCoord( char*& Text ) *text = 0; } + current_coord = atoi( line ); - if( fmt_scale < 0 || fmt_scale > 9 ) - fmt_scale = 4; // select scale 1.0 - double real_scale = scale_list[fmt_scale]; + if( m_GerbMetric ) real_scale = real_scale / 25.4; + current_coord = KiROUND( current_coord * real_scale ); } if( type_coord == 'I' ) pos.x = current_coord; else if( type_coord == 'J' ) pos.y = current_coord; + continue; } else @@ -246,8 +252,10 @@ int ReadInt( char*& text, bool aSkipSeparator = true ) int ret = (int) strtol( text, &text, 10 ); if( *text == ',' || isspace( *text ) ) + { if( aSkipSeparator ) ++text; + } return ret; } @@ -267,8 +275,10 @@ double ReadDouble( char*& text, bool aSkipSeparator = true ) double ret = strtod( text, &text ); if( *text == ',' || isspace( *text ) ) + { if( aSkipSeparator ) ++text; + } return ret; } diff --git a/gerbview/rs274d.cpp b/gerbview/rs274d.cpp index 74cb464cb9..cb9475d6a1 100644 --- a/gerbview/rs274d.cpp +++ b/gerbview/rs274d.cpp @@ -222,7 +222,6 @@ static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aL aGbrItem->m_Size = aPenSize; aGbrItem->m_Flashed = false; - if( aMultiquadrant ) center = aStart + aRelCenter; else diff --git a/gerbview/rs274x.cpp b/gerbview/rs274x.cpp index aeb7871429..b6ebbf7432 100644 --- a/gerbview/rs274x.cpp +++ b/gerbview/rs274x.cpp @@ -235,15 +235,16 @@ bool GERBER_IMAGE::ExecuteRS274XCommand( int command, if( code == 'X' ) { x_fmt_known = true; - // number of digits after the decimal point (0 to 6 allowed) + // number of digits after the decimal point (0 to 7 allowed) m_FmtScale.x = *text - '0'; m_FmtLen.x = ctmp + m_FmtScale.x; - // m_FmtScale is 0 to 6 + // m_FmtScale is 0 to 7 + // (Old Gerber specification was 0 to 6) if( m_FmtScale.x < 0 ) m_FmtScale.x = 0; - if( m_FmtScale.x > 6 ) - m_FmtScale.x = 6; + if( m_FmtScale.x > 7 ) + m_FmtScale.x = 7; } else { @@ -252,8 +253,8 @@ bool GERBER_IMAGE::ExecuteRS274XCommand( int command, m_FmtLen.y = ctmp + m_FmtScale.y; if( m_FmtScale.y < 0 ) m_FmtScale.y = 0; - if( m_FmtScale.y > 6 ) - m_FmtScale.y = 6; + if( m_FmtScale.y > 7 ) + m_FmtScale.y = 7; } text++; } From 5bd2beb6507e24f02661e3bb558d016be715cd40 Mon Sep 17 00:00:00 2001 From: Kirill Mavreshko Date: Mon, 14 Jul 2014 09:41:02 +0200 Subject: [PATCH 122/123] bugfix: pcbnew crashes when you try to save a file --- pcbnew/kicad_plugin.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index 3cfb646176..8c04a1e192 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -63,12 +63,14 @@ static const wxString traceFootprintLibrary( wxT( "KicadFootprintLib" ) ); ///> Removes empty nets (i.e. with node count equal zero) from net classes void filterNetClass( const BOARD& aBoard, NETCLASS& aNetClass ) { - for( NETCLASS::const_iterator it = aNetClass.begin(); it != aNetClass.end(); ++it ) + for( NETCLASS::const_iterator it = aNetClass.begin(); it != aNetClass.end(); ) { NETINFO_ITEM* netinfo = aBoard.FindNet( *it ); if( netinfo && netinfo->GetNodesCount() <= 0 ) // hopefully there are no nets with negative - aNetClass.Remove( it ); // node count, but you never know.. + aNetClass.Remove( it++ ); // node count, but you never know.. + else + ++it; } } From e6dfda51d1a96d18406e2cb194ed30c3e450df6f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 14 Jul 2014 09:43:20 +0200 Subject: [PATCH 123/123] Increase panning area in GAL view. --- pcbnew/pcb_draw_panel_gal.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/pcbnew/pcb_draw_panel_gal.cpp b/pcbnew/pcb_draw_panel_gal.cpp index 1aed5a86bd..8d2e89f275 100644 --- a/pcbnew/pcb_draw_panel_gal.cpp +++ b/pcbnew/pcb_draw_panel_gal.cpp @@ -229,9 +229,6 @@ void PCB_DRAW_PANEL_GAL::SetWorksheet( KIGFX::WORKSHEET_VIEWITEM* aWorksheet ) m_worksheet = aWorksheet; m_view->Add( m_worksheet ); - - // Limit panning to the size of worksheet frame - m_viewControls->SetPanBoundary( aWorksheet->ViewBBox() ); }