From d72491a4a518761b5607f6c31ca2d24c898217df Mon Sep 17 00:00:00 2001 From: Ethan Chien Date: Sat, 24 Feb 2024 15:10:50 +0000 Subject: [PATCH] ADDED: zone manager Fixes https://gitlab.com/kicad/code/kicad/-/issues/9636 --- pcbnew/CMakeLists.txt | 15 + pcbnew/menubar_pcb_editor.cpp | 4 + pcbnew/tools/global_edit_tool.cpp | 54 + pcbnew/tools/global_edit_tool.h | 1 + pcbnew/tools/pcb_actions.cpp | 5 + pcbnew/tools/pcb_actions.h | 1 + .../board_edges_bounding_item.cpp | 47 + .../zone_manager/board_edges_bounding_item.h | 44 + pcbnew/zone_manager/dialog_zone_manager.cpp | 454 +++ pcbnew/zone_manager/dialog_zone_manager.h | 143 + .../zone_manager/dialog_zone_manager_base.cpp | 195 + .../zone_manager/dialog_zone_manager_base.fbp | 611 +++ .../zone_manager/dialog_zone_manager_base.h | 84 + .../model_zones_overview_table.cpp | 275 ++ .../zone_manager/model_zones_overview_table.h | 154 + pcbnew/zone_manager/pane_zone_viewer.cpp | 191 + pcbnew/zone_manager/pane_zone_viewer.h | 58 + pcbnew/zone_manager/panel_zone_gal.cpp | 179 + pcbnew/zone_manager/panel_zone_gal.h | 75 + pcbnew/zone_manager/panel_zone_properties.cpp | 320 ++ pcbnew/zone_manager/panel_zone_properties.h | 106 + .../panel_zone_properties_base.cpp | 485 +++ .../panel_zone_properties_base.fbp | 3505 +++++++++++++++++ .../zone_manager/panel_zone_properties_base.h | 113 + pcbnew/zone_manager/zone_management_base.h | 42 + .../zone_manager/zone_manager_preference.cpp | 55 + pcbnew/zone_manager/zone_manager_preference.h | 53 + pcbnew/zone_manager/zone_painter.cpp | 68 + pcbnew/zone_manager/zone_painter.h | 43 + pcbnew/zone_manager/zone_priority_container.h | 72 + .../zone_selection_change_notifier.h | 64 + pcbnew/zone_manager/zones_container.cpp | 124 + pcbnew/zone_manager/zones_container.h | 83 + pcbnew/zones.h | 11 + 34 files changed, 7734 insertions(+) create mode 100644 pcbnew/zone_manager/board_edges_bounding_item.cpp create mode 100644 pcbnew/zone_manager/board_edges_bounding_item.h create mode 100644 pcbnew/zone_manager/dialog_zone_manager.cpp create mode 100644 pcbnew/zone_manager/dialog_zone_manager.h create mode 100644 pcbnew/zone_manager/dialog_zone_manager_base.cpp create mode 100644 pcbnew/zone_manager/dialog_zone_manager_base.fbp create mode 100644 pcbnew/zone_manager/dialog_zone_manager_base.h create mode 100644 pcbnew/zone_manager/model_zones_overview_table.cpp create mode 100644 pcbnew/zone_manager/model_zones_overview_table.h create mode 100644 pcbnew/zone_manager/pane_zone_viewer.cpp create mode 100644 pcbnew/zone_manager/pane_zone_viewer.h create mode 100644 pcbnew/zone_manager/panel_zone_gal.cpp create mode 100644 pcbnew/zone_manager/panel_zone_gal.h create mode 100644 pcbnew/zone_manager/panel_zone_properties.cpp create mode 100644 pcbnew/zone_manager/panel_zone_properties.h create mode 100644 pcbnew/zone_manager/panel_zone_properties_base.cpp create mode 100644 pcbnew/zone_manager/panel_zone_properties_base.fbp create mode 100644 pcbnew/zone_manager/panel_zone_properties_base.h create mode 100644 pcbnew/zone_manager/zone_management_base.h create mode 100644 pcbnew/zone_manager/zone_manager_preference.cpp create mode 100644 pcbnew/zone_manager/zone_manager_preference.h create mode 100644 pcbnew/zone_manager/zone_painter.cpp create mode 100644 pcbnew/zone_manager/zone_painter.h create mode 100644 pcbnew/zone_manager/zone_priority_container.h create mode 100644 pcbnew/zone_manager/zone_selection_change_notifier.h create mode 100644 pcbnew/zone_manager/zones_container.cpp create mode 100644 pcbnew/zone_manager/zones_container.h diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 21e452cf34..b0cb8e190e 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -271,6 +271,20 @@ set( PCBNEW_NETLIST_SRCS netlist_reader/netlist.cpp ) +set( ZONE_MANAGER_SRCS + zone_manager/board_edges_bounding_item.cpp + zone_manager/dialog_zone_manager.cpp + zone_manager/dialog_zone_manager_base.cpp + zone_manager/model_zones_overview_table.cpp + zone_manager/pane_zone_viewer.cpp + zone_manager/panel_zone_gal.cpp + zone_manager/panel_zone_properties.cpp + zone_manager/panel_zone_properties_base.cpp + zone_manager/zone_manager_preference.cpp + zone_manager/zone_painter.cpp + zone_manager/zones_container.cpp + ) + set( PCBNEW_CLASS_SRCS ${PCBNEW_DIALOGS} ${PCBNEW_EXPORTERS} @@ -278,6 +292,7 @@ set( PCBNEW_CLASS_SRCS ${PCBNEW_DRC_SRCS} ${PCBNEW_IMPORT_GFX} ${PCBNEW_NETLIST_SRCS} + ${ZONE_MANAGER_SRCS} ${PCBNEW_BRDSTACKUP_MGR} autorouter/spread_footprints.cpp diff --git a/pcbnew/menubar_pcb_editor.cpp b/pcbnew/menubar_pcb_editor.cpp index 9aada1ef59..ca2d9960a2 100644 --- a/pcbnew/menubar_pcb_editor.cpp +++ b/pcbnew/menubar_pcb_editor.cpp @@ -401,6 +401,10 @@ void PCB_EDIT_FRAME::doReCreateMenuBar() toolsMenu->Add( ACTIONS::showFootprintEditor ); toolsMenu->Add( PCB_ACTIONS::updateFootprints ); + //Zones management + toolsMenu->AppendSeparator(); + toolsMenu->Add( PCB_ACTIONS::zonesManager ); + if( ADVANCED_CFG::GetCfg().m_EnableGenerators ) { toolsMenu->AppendSeparator(); diff --git a/pcbnew/tools/global_edit_tool.cpp b/pcbnew/tools/global_edit_tool.cpp index ca79049b83..ecf4031234 100644 --- a/pcbnew/tools/global_edit_tool.cpp +++ b/pcbnew/tools/global_edit_tool.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,9 @@ #include #include #include +#include +#include + GLOBAL_EDIT_TOOL::GLOBAL_EDIT_TOOL() : PCB_TOOL_BASE( "pcbnew.GlobalEdit" ), @@ -211,6 +215,55 @@ int GLOBAL_EDIT_TOOL::RemoveUnusedPads( const TOOL_EVENT& aEvent ) return 0; } +int GLOBAL_EDIT_TOOL::ZonesManager( const TOOL_EVENT& aEvent ) +{ + PCB_EDIT_FRAME* editFrame = getEditFrame(); + + BOARD_COMMIT commit( editFrame ); + BOARD* board = editFrame->GetBoard(); + + for( ZONE* zone : board->Zones() ) + commit.Modify( zone ); + + ZONE_SETTINGS zoneInfo = board->GetDesignSettings().GetDefaultZoneSettings(); + int dialogResult = InvokeZonesManager( editFrame, &zoneInfo ); + + if( dialogResult == wxID_CANCEL ) + return 0; + + wxBusyCursor dummy; + + // Undraw old zone outlines + for( ZONE* zone : board->Zones() ) + editFrame->GetCanvas()->GetView()->Update( zone ); + + + board->GetDesignSettings().SetDefaultZoneSettings( zoneInfo ); + commit.Push( _( "Modify zones properties with zone manager" ), SKIP_CONNECTIVITY ); + editFrame->OnModify(); + + //rebuildConnectivity + board->BuildConnectivity(); + + if( TOOL_MANAGER* manger = GetManager() ) + { + manger->PostEvent( EVENTS::ConnectivityChangedEvent ); + } + + editFrame->GetCanvas()->RedrawRatsnest(); + + if( dialogResult == ZONE_MANAGER_REPOUR ) + { + if( TOOL_MANAGER* manger = GetManager() ) + { + manger->PostAction( PCB_ACTIONS::zoneFillAll ); + } + } + + return 0; +} + + void GLOBAL_EDIT_TOOL::setTransitions() { @@ -228,6 +281,7 @@ void GLOBAL_EDIT_TOOL::setTransitions() Go( &GLOBAL_EDIT_TOOL::CleanupTracksAndVias, PCB_ACTIONS::cleanupTracksAndVias.MakeEvent() ); Go( &GLOBAL_EDIT_TOOL::CleanupGraphics, PCB_ACTIONS::cleanupGraphics.MakeEvent() ); Go( &GLOBAL_EDIT_TOOL::RemoveUnusedPads, PCB_ACTIONS::removeUnusedPads.MakeEvent() ); + Go( &GLOBAL_EDIT_TOOL::ZonesManager, PCB_ACTIONS::zonesManager.MakeEvent() ); } diff --git a/pcbnew/tools/global_edit_tool.h b/pcbnew/tools/global_edit_tool.h index b76b603764..88563dfa0f 100644 --- a/pcbnew/tools/global_edit_tool.h +++ b/pcbnew/tools/global_edit_tool.h @@ -63,6 +63,7 @@ public: int CleanupTracksAndVias( const TOOL_EVENT& aEvent ); int CleanupGraphics( const TOOL_EVENT& aEvent ); int RemoveUnusedPads( const TOOL_EVENT& aEvent ); + int ZonesManager( const TOOL_EVENT& aEvent ); private: bool swapBoardItem( BOARD_ITEM* aItem, PCB_LAYER_ID* aLayerMap ); diff --git a/pcbnew/tools/pcb_actions.cpp b/pcbnew/tools/pcb_actions.cpp index 87b1a5469b..299265059e 100644 --- a/pcbnew/tools/pcb_actions.cpp +++ b/pcbnew/tools/pcb_actions.cpp @@ -1335,6 +1335,11 @@ TOOL_ACTION PCB_ACTIONS::showLayersManager( TOOL_ACTION_ARGS() .Tooltip( _( "Show/hide the appearance manager" ) ) .Icon( BITMAPS::layers_manager ) ); +TOOL_ACTION PCB_ACTIONS::zonesManager( "pcbnew.Control.zonesManager", + AS_GLOBAL, 0, "", + _( "Zone Manager" ), _( "Show the zone manager dialog" ), + BITMAPS::show_zone ); + TOOL_ACTION PCB_ACTIONS::flipBoard( TOOL_ACTION_ARGS() .Name( "pcbnew.Control.flipBoard" ) .Scope( AS_GLOBAL ) diff --git a/pcbnew/tools/pcb_actions.h b/pcbnew/tools/pcb_actions.h index 86686d3913..5aae6634dc 100644 --- a/pcbnew/tools/pcb_actions.h +++ b/pcbnew/tools/pcb_actions.h @@ -437,6 +437,7 @@ public: static TOOL_ACTION showLayersManager; static TOOL_ACTION showPythonConsole; + static TOOL_ACTION zonesManager; // Module editor tools diff --git a/pcbnew/zone_manager/board_edges_bounding_item.cpp b/pcbnew/zone_manager/board_edges_bounding_item.cpp new file mode 100644 index 0000000000..e3856c7f4d --- /dev/null +++ b/pcbnew/zone_manager/board_edges_bounding_item.cpp @@ -0,0 +1,47 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 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 "board_edges_bounding_item.h" +#include "layer_ids.h" + + +BOARD_EDGES_BOUNDING_ITEM::BOARD_EDGES_BOUNDING_ITEM( BOX2I box ) : m_box( std::move( box ) ) +{ +} + +BOARD_EDGES_BOUNDING_ITEM::~BOARD_EDGES_BOUNDING_ITEM() +{ +} + +const BOX2I BOARD_EDGES_BOUNDING_ITEM::ViewBBox() const +{ + return m_box; +} + +void BOARD_EDGES_BOUNDING_ITEM::ViewGetLayers( int aLayers[], int& aCount ) const +{ + // Basic fallback + aCount = 1; + aLayers[0] = Edge_Cuts; +} diff --git a/pcbnew/zone_manager/board_edges_bounding_item.h b/pcbnew/zone_manager/board_edges_bounding_item.h new file mode 100644 index 0000000000..c80dbc052a --- /dev/null +++ b/pcbnew/zone_manager/board_edges_bounding_item.h @@ -0,0 +1,44 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 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 BOARD_EDGES_BOUNDING_ITEM_H +#define BOARD_EDGES_BOUNDING_ITEM_H + +#include +class BOARD_EDGES_BOUNDING_ITEM : public KIGFX::VIEW_ITEM +{ +public: + BOARD_EDGES_BOUNDING_ITEM( BOX2I aBox ); + ~BOARD_EDGES_BOUNDING_ITEM() override; + + const BOX2I ViewBBox() const override; + + void ViewGetLayers( int aLayers[], int& aCount ) const override; + + +private: + BOX2I m_box; +}; + +#endif \ No newline at end of file diff --git a/pcbnew/zone_manager/dialog_zone_manager.cpp b/pcbnew/zone_manager/dialog_zone_manager.cpp new file mode 100644 index 0000000000..7ce0989e1e --- /dev/null +++ b/pcbnew/zone_manager/dialog_zone_manager.cpp @@ -0,0 +1,454 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dialog_zone_manager_base.h" +#include "model_zones_overview_table.h" +#include "panel_zone_properties.h" +#include "dialog_zone_manager.h" +#include "widgets/wx_progress_reporters.h" +#include "zone_management_base.h" +#include "zone_manager/model_zones_overview_table.h" +#include "zone_manager/panel_zone_gal.h" +#include "zone_manager/zone_manager_preference.h" +#include "zones_container.h" +#include "pane_zone_viewer.h" +#include "zone_manager_preference.h" + +inline void DIALOG_ZONE_MANAGER::PostProcessZoneViewSelectionChange( wxDataViewItem const& aItem ) +{ + bool textCtrlHasFocus = m_filterCtrl->HasFocus(); + long filterInsertPos = m_filterCtrl->GetInsertionPoint(); + + if( aItem.IsOk() ) + { + m_viewZonesOverview->Select( aItem ); + m_viewZonesOverview->EnsureVisible( aItem ); + } + else + { + if( m_modelZoneOverviewTable->GetCount() ) + { + wxDataViewItem first_item = m_modelZoneOverviewTable->GetItem( 0 ); + m_viewZonesOverview->Select( first_item ); + m_viewZonesOverview->EnsureVisible( first_item ); + m_zoneViewer->ActivateSelectedZone( m_modelZoneOverviewTable->GetZone( first_item ) ); + } + else + { + m_zoneViewer->ActivateSelectedZone( nullptr ); + } + } + + if( textCtrlHasFocus ) + { + m_filterCtrl->SetFocus(); + m_filterCtrl->SetInsertionPoint( filterInsertPos ); + } +} + + +inline void DIALOG_ZONE_MANAGER::GenericProcessChar( wxKeyEvent& aEvent ) +{ + aEvent.Skip(); + if( aEvent.GetKeyCode() == WXK_DOWN || aEvent.GetKeyCode() == WXK_UP ) + { + Bind( wxEVT_IDLE, &DIALOG_ZONE_MANAGER::OnIDle, this ); + } +} + +void DIALOG_ZONE_MANAGER::OnTableChar( wxKeyEvent& aEvent ) +{ + GenericProcessChar( aEvent ); +} + +void DIALOG_ZONE_MANAGER::OnTableCharHook( wxKeyEvent& aEvent ) +{ + GenericProcessChar( aEvent ); +} + + +void DIALOG_ZONE_MANAGER::OnIDle( wxIdleEvent& aEvent ) +{ + WXUNUSED( aEvent ) + m_viewZonesOverview->SetFocus(); + Unbind( wxEVT_IDLE, &DIALOG_ZONE_MANAGER::OnIDle, this ); + + //NOTE - Required on Linux + if( m_needZoomGAL ) + { + Canvas().ZoomFitScreen(); + m_needZoomGAL = false; + } +} + + +DIALOG_ZONE_MANAGER::DIALOG_ZONE_MANAGER( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aZoneInfo ) : + DIALOG_ZONE_MANAGER_BASE( aParent ), m_pcbFrame( aParent ), m_zoneInfo( aZoneInfo ), + m_zonesContainer( std::make_unique( aParent->GetBoard() ) ), + m_panelZoneProperties( new PANEL_ZONE_PROPERTIES( this, aParent, *m_zonesContainer ) ), + m_modelZoneOverviewTable( + new MODEL_ZONES_OVERVIEW_TABLE( m_zonesContainer->GetZonesPriorityContainers(), + aParent->GetBoard(), aParent, this ) ), + m_zoneViewer( new PANE_ZONE_VIEWER( this, aParent ) ), m_priorityDragIndex( {} ), + m_needZoomGAL( true ) +{ +#ifdef __APPLE__ + m_sizerZoneOP->InsertSpacer( m_sizerZoneOP->GetItemCount(), 5 ); +#endif + + m_btnMoveUp->SetBitmap( KiBitmapBundle( BITMAPS::small_up ) ); + m_btnMoveDown->SetBitmap( KiBitmapBundle( BITMAPS::small_down ) ); + m_sizerProperties->Add( m_panelZoneProperties, 1, wxALL | wxEXPAND ); + m_sizerTop->Add( m_zoneViewer, 1, wxALL | wxEXPAND, 0 ); + m_checkRepour->SetValue( ZONE_MANAGER_PREFERENCE::GetRepourOnClose() ); + m_zoneViewer->SetId( ZONE_VIEWER ); + + for( const auto& [k, v] : MODEL_ZONES_OVERVIEW_TABLE::GetColumnNames() ) + { + if( k == MODEL_ZONES_OVERVIEW_TABLE::LAYERS ) + m_viewZonesOverview->AppendIconTextColumn( v, k ); + else + m_viewZonesOverview->AppendTextColumn( v, k ); + } + + m_viewZonesOverview->AssociateModel( m_modelZoneOverviewTable.get() ); + +#if wxUSE_DRAG_AND_DROP + + m_viewZonesOverview->EnableDragSource( wxDF_UNICODETEXT ); + m_viewZonesOverview->EnableDropTarget( wxDF_UNICODETEXT ); + + Bind( wxEVT_DATAVIEW_ITEM_BEGIN_DRAG, &DIALOG_ZONE_MANAGER::OnBeginDrag, this, + VIEW_ZONE_TABLE ); + Bind( wxEVT_DATAVIEW_ITEM_DROP_POSSIBLE, &DIALOG_ZONE_MANAGER::OnDropPossible, this, + VIEW_ZONE_TABLE ); + Bind( wxEVT_DATAVIEW_ITEM_DROP, &DIALOG_ZONE_MANAGER::OnDrop, this, VIEW_ZONE_TABLE ); + +#endif // wxUSE_DRAG_AND_DROP + + Bind( wxEVT_BUTTON, &DIALOG_ZONE_MANAGER::OnOk, this, wxID_OK ); + Bind( EVT_ZONE_NAME_UPDATE, &DIALOG_ZONE_MANAGER::OnZoneNameUpdate, this ); + Bind( EVT_ZONES_OVERVIEW_COUNT_CHANGE, &DIALOG_ZONE_MANAGER::OnZonesTableRowCountChange, this ); + Bind( wxEVT_CHECKBOX, &DIALOG_ZONE_MANAGER::OnCheckBoxClicked, this ); + Bind( wxEVT_IDLE, &DIALOG_ZONE_MANAGER::OnIDle, this ); + Bind( wxEVT_BUTTON, &DIALOG_ZONE_MANAGER::OnMoveUpClick, this, BTN_MOVE_UP ); + Bind( wxEVT_BUTTON, &DIALOG_ZONE_MANAGER::OnMoveDownClick, this, BTN_MOVE_DOWN ); + Bind( + wxEVT_BOOKCTRL_PAGE_CHANGED, + [this]( wxNotebookEvent& aEvent ) + { + Layout(); + }, + ZONE_VIEWER ); + + bool foundZone = m_modelZoneOverviewTable->GetCount(); + + if( foundZone ) + SelectZoneTableItem( m_modelZoneOverviewTable->GetItem( 0 ) ); + + Layout(); + m_MainBoxSizer->Fit( this ); + + //NOTE - Works on Windows and MacOS , need further handling in IDLE on Ubuntu + Canvas().ZoomFitScreen(); +} + +DIALOG_ZONE_MANAGER::~DIALOG_ZONE_MANAGER() = default; + + +int InvokeZonesManager( PCB_BASE_FRAME* aCaller, ZONE_SETTINGS* aZoneInfo ) +{ + DIALOG_ZONE_MANAGER dlg( aCaller, aZoneInfo ); + + const int res = dlg.ShowQuasiModal(); + + if( res == wxID_OK && ZONE_MANAGER_PREFERENCE::GetRepourOnClose() ) + return ZONE_MANAGER_REPOUR; + + return res; +} + +void DIALOG_ZONE_MANAGER::OnZoneSelectionChanged( ZONE* zone ) +{ + for( ZONE_SELECTION_CHANGE_NOTIFIER* i : + std::list{ m_panelZoneProperties, m_zoneViewer } ) + { + i->OnZoneSelectionChanged( zone ); + } + Layout(); +} + +void DIALOG_ZONE_MANAGER::OnViewZonesOverviewOnLeftUp( wxMouseEvent& aEvent ) +{ + Bind( wxEVT_IDLE, &DIALOG_ZONE_MANAGER::OnIDle, this ); +} + +void DIALOG_ZONE_MANAGER::OnDataViewCtrlSelectionChanged( wxDataViewEvent& aEvent ) +{ + SelectZoneTableItem( aEvent.GetItem() ); +} + + +void DIALOG_ZONE_MANAGER::SelectZoneTableItem( wxDataViewItem const& aItem ) +{ + ZONE* zone = m_modelZoneOverviewTable->GetZone( aItem ); + + if( !zone ) + return; + + OnZoneSelectionChanged( zone ); +} + + +void DIALOG_ZONE_MANAGER::OnOk( wxCommandEvent& aEvt ) +{ + for( ZONE_MANAGEMENT_BASE* zone_management : + std::list{ m_panelZoneProperties, m_zonesContainer.get() } ) + { + zone_management->OnUserConfirmChange(); + } + + if( m_zoneInfo ) + { + if( std::shared_ptr zone = m_panelZoneProperties->GetZoneSettings() ) + *m_zoneInfo = *zone; + } + + aEvt.Skip(); +} + +#if wxUSE_DRAG_AND_DROP + +void DIALOG_ZONE_MANAGER::OnBeginDrag( wxDataViewEvent& aEvent ) +{ + wxTextDataObject* obj = new wxTextDataObject; + obj->SetText( "42" ); //FIXME - Workaround for drop on GTK + aEvent.SetDataObject( obj ); + aEvent.SetDragFlags( wxDrag_AllowMove ); + const wxDataViewItem it = aEvent.GetItem(); + + if( it.IsOk() ) + m_priorityDragIndex = m_modelZoneOverviewTable->GetRow( it ); +} + +void DIALOG_ZONE_MANAGER::OnDropPossible( wxDataViewEvent& aEvent ) +{ + aEvent.SetDropEffect( wxDragMove ); // check 'move' drop effect +} + +void DIALOG_ZONE_MANAGER::OnRepourCheck( wxCommandEvent& aEvent ) +{ + ZONE_MANAGER_PREFERENCE::SetRepourOnClose( m_checkRepour->IsChecked() ); +} + + +void DIALOG_ZONE_MANAGER::OnDrop( wxDataViewEvent& aEvent ) +{ + if( aEvent.GetDataFormat() != wxDF_UNICODETEXT ) + { + aEvent.Veto(); + return; + } + + if( !m_priorityDragIndex.has_value() ) + return; + + const wxDataViewItem it = aEvent.GetItem(); + + if( !it.IsOk() ) + { + aEvent.Veto(); + return; + } + + unsigned int drop_index = m_modelZoneOverviewTable->GetRow( it ); + const std::optional rtn = + m_modelZoneOverviewTable->SwapZonePriority( *m_priorityDragIndex, drop_index ); + + if( rtn.has_value() ) + { + const wxDataViewItem item = m_modelZoneOverviewTable->GetItem( *rtn ); + if( item.IsOk() ) + m_viewZonesOverview->Select( item ); + } +} +#endif // wxUSE_DRAG_AND_DROP + +void DIALOG_ZONE_MANAGER::OnMoveUpClick( wxCommandEvent& aEvent ) +{ + WXUNUSED( aEvent ); + MoveSelectedZonePriority( ZONE_INDEX_MOVEMENT::MOVE_UP ); +} + +void DIALOG_ZONE_MANAGER::OnMoveDownClick( wxCommandEvent& aEvent ) +{ + WXUNUSED( aEvent ); + MoveSelectedZonePriority( ZONE_INDEX_MOVEMENT::MOVE_DOWN ); +} + +void DIALOG_ZONE_MANAGER::OnFilterCtrlCancel( wxCommandEvent& aEvent ) +{ + PostProcessZoneViewSelectionChange( + m_modelZoneOverviewTable->ClearFilter( m_viewZonesOverview->GetSelection() ) ); + aEvent.Skip(); +} + +void DIALOG_ZONE_MANAGER::OnFilterCtrlSearch( wxCommandEvent& aEvent ) +{ + PostProcessZoneViewSelectionChange( m_modelZoneOverviewTable->ApplyFilter( + aEvent.GetString(), m_viewZonesOverview->GetSelection() ) ); + aEvent.Skip(); +} + +void DIALOG_ZONE_MANAGER::OnFilterCtrlTextChange( wxCommandEvent& aEvent ) +{ + PostProcessZoneViewSelectionChange( m_modelZoneOverviewTable->ApplyFilter( + aEvent.GetString(), m_viewZonesOverview->GetSelection() ) ); + aEvent.Skip(); +} + +void DIALOG_ZONE_MANAGER::OnFilterCtrlEnter( wxCommandEvent& aEvent ) +{ + PostProcessZoneViewSelectionChange( m_modelZoneOverviewTable->ApplyFilter( + aEvent.GetString(), m_viewZonesOverview->GetSelection() ) ); + aEvent.Skip(); +} + +void DIALOG_ZONE_MANAGER::OnButtonApplyClick( wxCommandEvent& aEvent ) +{ + m_zonesContainer->FlushZoneSettingsChange(); + m_zonesContainer->FlushPriorityChange(); + + BOARD* board = m_pcbFrame->GetBoard(); + board->IncrementTimeStamp(); + + m_commit = std::make_unique( m_pcbFrame ); + m_filler = std::make_unique( board, m_commit.get() ); + auto reporter = std::make_unique( this, _( "Fill All Zones" ), 5 ); + + m_filler->SetProgressReporter( reporter.get() ); + board->Zones() = m_zonesContainer->GetClonedZoneList(); + m_filler->Fill( board->Zones() ); + board->BuildConnectivity(); + board->Zones() = m_zonesContainer->GetOriginalZoneList(); + + PANEL_ZONE_GAL* gal = m_zoneViewer->GetZoneGAL(); + gal->RedrawRatsnest(); + gal->GetView()->UpdateItems(); + gal->Refresh(); + int layer = gal->GetLayer(); + gal->ActivateSelectedZone( + m_modelZoneOverviewTable->GetZone( m_viewZonesOverview->GetSelection() ) ); + gal->OnLayerSelected( layer ); +} + + +void DIALOG_ZONE_MANAGER::OnZoneNameUpdate( wxCommandEvent& aEvent ) +{ + if( ZONE* zone = m_panelZoneProperties->GetZone(); zone != nullptr ) + { + zone->SetZoneName( aEvent.GetString() ); + m_modelZoneOverviewTable->RowChanged( m_modelZoneOverviewTable->GetRow( + m_modelZoneOverviewTable->GetItemByZone( zone ) ) ); + } +} + +void DIALOG_ZONE_MANAGER::OnZonesTableRowCountChange( wxCommandEvent& aEvent ) +{ + unsigned count = aEvent.GetInt(); + + for( STD_BITMAP_BUTTON* btn : { m_btnMoveDown, m_btnMoveUp } ) + btn->Enable( count == m_modelZoneOverviewTable->GetAllZonesCount() ); +} + +void DIALOG_ZONE_MANAGER::OnCheckBoxClicked( wxCommandEvent& aEvent ) +{ + const wxObject* sender = aEvent.GetEventObject(); + + if( aEvent.GetEventObject() == m_checkName ) + { + m_modelZoneOverviewTable->EnableFitterByName( aEvent.IsChecked() ); + } + else if( aEvent.GetEventObject() == m_checkNet ) + { + m_modelZoneOverviewTable->EnableFitterByNet( aEvent.IsChecked() ); + } + + if( ( sender == m_checkName || sender == m_checkNet ) && !m_filterCtrl->IsEmpty() ) + { + m_modelZoneOverviewTable->ApplyFilter( m_filterCtrl->GetValue(), + m_viewZonesOverview->GetSelection() ); + } +} + +void DIALOG_ZONE_MANAGER::MoveSelectedZonePriority( ZONE_INDEX_MOVEMENT aMove ) +{ + if( !m_viewZonesOverview->HasSelection() ) + return; + + const wxDataViewItem selectedItem = m_viewZonesOverview->GetSelection(); + + if( !selectedItem.IsOk() ) + return; + + const unsigned int selectedRow = m_modelZoneOverviewTable->GetRow( selectedItem ); + const std::optional new_index = + m_modelZoneOverviewTable->MoveZoneIndex( selectedRow, aMove ); + + if( new_index.has_value() ) + { + wxDataViewItem new_item = m_modelZoneOverviewTable->GetItem( *new_index ); + PostProcessZoneViewSelectionChange( new_item ); + } +} + +PANEL_ZONE_GAL& DIALOG_ZONE_MANAGER::Canvas() +{ + return *m_zoneViewer->GetZoneGAL(); +} diff --git a/pcbnew/zone_manager/dialog_zone_manager.h b/pcbnew/zone_manager/dialog_zone_manager.h new file mode 100644 index 0000000000..b03d4e9066 --- /dev/null +++ b/pcbnew/zone_manager/dialog_zone_manager.h @@ -0,0 +1,143 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 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_ZONE_MANAGER_H +#define DIALOG_ZONE_MANAGER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dialog_zone_manager_base.h" + + +class PANEL_ZONE_PROPERTIES; +class MODEL_ZONES_PRIORITY_LIST; +class MODEL_ZONES_OVERVIEW_TABLE; +class MODEL_ZONE_LAYERS_LIST; +class ZONES_CONTAINER; +class PANE_ZONE_VIEWER; +class ZONE_FILLER; +class COMMIT; +class PANEL_ZONE_GAL; +enum class ZONE_INDEX_MOVEMENT; +class DIALOG_ZONE_MANAGER : public DIALOG_ZONE_MANAGER_BASE +{ + enum + { + ZONE_VIEWER = ID_DIALOG_COPPER_ZONE_BASE + 10, + }; + +public: + DIALOG_ZONE_MANAGER( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aZoneInfo ); + ~DIALOG_ZONE_MANAGER() override; + +protected: + void OnZoneSelectionChanged( ZONE* aZone ); + + void OnDataViewCtrlSelectionChanged( wxDataViewEvent& event ) override; + + void SelectZoneTableItem( wxDataViewItem const& aItem ); + + void OnViewZonesOverviewOnLeftUp( wxMouseEvent& aEvent ) override; + + + void OnOk( wxCommandEvent& aEvt ); + + +#if wxUSE_DRAG_AND_DROP + + void OnBeginDrag( wxDataViewEvent& aEvent ); + + void OnDropPossible( wxDataViewEvent& aEvent ); + + void OnDrop( wxDataViewEvent& aEvent ); + +#endif // wxUSE_DRAG_AND_DROP + + void OnZoneNameUpdate( wxCommandEvent& aEvent ); + + void OnZonesTableRowCountChange( wxCommandEvent& aEvent ); + + void OnCheckBoxClicked( wxCommandEvent& aEvent ); + + void MoveSelectedZonePriority( ZONE_INDEX_MOVEMENT aMove ); + + void OnMoveUpClick( wxCommandEvent& aEvent ); + + void OnMoveDownClick( wxCommandEvent& aEvent ); + + void OnFilterCtrlCancel( wxCommandEvent& aEvent ) override; + + void OnFilterCtrlSearch( wxCommandEvent& aEvent ) override; + + void OnFilterCtrlTextChange( wxCommandEvent& aEvent ) override; + + void OnFilterCtrlEnter( wxCommandEvent& aEvent ) override; + + void OnRepourCheck( wxCommandEvent& aEvent ) override; + + void OnButtonApplyClick( wxCommandEvent& aEvent ) override; + + void PostProcessZoneViewSelectionChange( wxDataViewItem const& item ); + + void OnTableChar( wxKeyEvent& event ) override; + + void OnTableCharHook( wxKeyEvent& event ) override; + + PANEL_ZONE_GAL& Canvas(); + +private: + void GenericProcessChar( wxKeyEvent& event ); + + void OnIDle( wxIdleEvent& aEvent ); + + +private: + PCB_BASE_FRAME* m_pcbFrame; + ZONE_SETTINGS* m_zoneInfo; + std::unique_ptr m_zonesContainer; + PANEL_ZONE_PROPERTIES* m_panelZoneProperties; + wxObjectDataPtr m_modelZoneOverviewTable; + PANE_ZONE_VIEWER* m_zoneViewer; + std::optional m_priorityDragIndex; + std::unique_ptr m_filler; + std::unique_ptr m_commit; + bool m_needZoomGAL; +}; + +#endif \ No newline at end of file diff --git a/pcbnew/zone_manager/dialog_zone_manager_base.cpp b/pcbnew/zone_manager/dialog_zone_manager_base.cpp new file mode 100644 index 0000000000..89f5b50978 --- /dev/null +++ b/pcbnew/zone_manager/dialog_zone_manager_base.cpp @@ -0,0 +1,195 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf) +// http://www.wxformbuilder.org/ +// +// PLEASE DO *NOT* EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "dialog_zone_manager_base.h" + +/////////////////////////////////////////////////////////////////////////// + +DIALOG_ZONE_MANAGER_BASE::DIALOG_ZONE_MANAGER_BASE( wxWindow* parent, wxWindowID id, + const wxString& title, const wxPoint& pos, + const wxSize& size, long style ) : + DIALOG_SHIM( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxSize( -1, -1 ), wxDefaultSize ); + + m_MainBoxSizer = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer12; + bSizer12 = new wxBoxSizer( wxVERTICAL ); + + m_sizerTop = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bSizer7; + bSizer7 = new wxBoxSizer( wxVERTICAL ); + + m_viewZonesOverview = + new wxDataViewCtrl( this, VIEW_ZONE_TABLE, wxDefaultPosition, wxSize( -1, 240 ), + wxDV_HORIZ_RULES | wxDV_ROW_LINES | wxDV_SINGLE | wxDV_VERT_RULES ); + m_viewZonesOverview->SetMinSize( wxSize( -1, 240 ) ); + + bSizer7->Add( m_viewZonesOverview, 1, wxALL | wxEXPAND, 0 ); + + m_sizerZoneOP = new wxBoxSizer( wxHORIZONTAL ); + + m_btnMoveUp = new STD_BITMAP_BUTTON( this, BTN_MOVE_UP, wxNullBitmap, wxDefaultPosition, + wxDefaultSize, wxBU_AUTODRAW | 0 ); + m_btnMoveUp->SetToolTip( + _( "Top zone has the highest priority. When a zone is inside another zone, if its " + "priority is higher, its outlines are removed from the other zone." ) ); + + m_sizerZoneOP->Add( m_btnMoveUp, 0, wxRIGHT, 5 ); + + m_btnMoveDown = new STD_BITMAP_BUTTON( this, BTN_MOVE_DOWN, wxNullBitmap, wxDefaultPosition, + wxDefaultSize, wxBU_AUTODRAW | 0 ); + m_btnMoveDown->SetToolTip( + _( "Top zone has the highest priority. When a zone is inside another zone, if its " + "priority is higher, its outlines are removed from the other zone." ) ); + + m_sizerZoneOP->Add( m_btnMoveDown, 0, 0, 5 ); + + + m_sizerZoneOP->Add( 0, 0, 0, wxEXPAND | wxLEFT | wxRIGHT, 10 ); + + m_checkName = + new wxCheckBox( this, CHECK_NAME, _( "Name" ), wxDefaultPosition, wxDefaultSize, 0 ); + m_checkName->SetValue( true ); + m_sizerZoneOP->Add( m_checkName, 0, wxBOTTOM | wxLEFT | wxTOP, 5 ); + + m_checkNet = new wxCheckBox( this, CHECK_NET, _( "Net" ), wxDefaultPosition, wxDefaultSize, 0 ); + m_checkNet->SetValue( true ); + m_sizerZoneOP->Add( m_checkNet, 0, wxALL, 5 ); + + m_filterCtrl = new wxSearchCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, + wxDefaultSize, wxTE_PROCESS_ENTER ); +#ifndef __WXMAC__ + m_filterCtrl->ShowSearchButton( true ); +#endif + m_filterCtrl->ShowCancelButton( true ); + m_sizerZoneOP->Add( m_filterCtrl, 1, wxALL, 0 ); + + + bSizer7->Add( m_sizerZoneOP, 0, wxBOTTOM | wxEXPAND | wxLEFT | wxTOP, 5 ); + + + m_sizerTop->Add( bSizer7, 1, wxALL | wxEXPAND, 5 ); + + + bSizer12->Add( m_sizerTop, 1, wxEXPAND, 5 ); + + m_sizerProperties = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _( "Properties" ) ), + wxVERTICAL ); + + + bSizer12->Add( m_sizerProperties, 0, wxALL | wxEXPAND, 5 ); + + + m_MainBoxSizer->Add( bSizer12, 1, wxEXPAND, 0 ); + + wxBoxSizer* bSizer61; + bSizer61 = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bSizer71; + bSizer71 = new wxBoxSizer( wxVERTICAL ); + + m_checkRepour = + new wxCheckBox( this, wxID_ANY, _( "Repour" ), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer71->Add( m_checkRepour, 0, wxLEFT | wxTOP, 10 ); + + + bSizer61->Add( bSizer71, 0, wxEXPAND | wxLEFT, 15 ); + + + bSizer61->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_sdbSizer = new wxStdDialogButtonSizer(); + m_sdbSizerOK = new wxButton( this, wxID_OK ); + m_sdbSizer->AddButton( m_sdbSizerOK ); + m_sdbSizerApply = new wxButton( this, wxID_APPLY ); + m_sdbSizer->AddButton( m_sdbSizerApply ); + m_sdbSizerCancel = new wxButton( this, wxID_CANCEL ); + m_sdbSizer->AddButton( m_sdbSizerCancel ); + m_sdbSizer->Realize(); + + bSizer61->Add( m_sdbSizer, 0, wxALL | wxEXPAND, 5 ); + + + m_MainBoxSizer->Add( bSizer61, 0, wxEXPAND, 5 ); + + + this->SetSizer( m_MainBoxSizer ); + this->Layout(); + m_MainBoxSizer->Fit( this ); + + // Connect Events + m_viewZonesOverview->Connect( + wxEVT_CHAR, wxKeyEventHandler( DIALOG_ZONE_MANAGER_BASE::OnTableChar ), NULL, this ); + m_viewZonesOverview->Connect( wxEVT_CHAR_HOOK, + wxKeyEventHandler( DIALOG_ZONE_MANAGER_BASE::OnTableCharHook ), + NULL, this ); + m_viewZonesOverview->Connect( + wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, + wxDataViewEventHandler( DIALOG_ZONE_MANAGER_BASE::OnDataViewCtrlSelectionChanged ), + NULL, this ); + m_viewZonesOverview->Connect( + wxEVT_LEFT_UP, + wxMouseEventHandler( DIALOG_ZONE_MANAGER_BASE::OnViewZonesOverviewOnLeftUp ), NULL, + this ); + m_filterCtrl->Connect( wxEVT_COMMAND_SEARCHCTRL_CANCEL_BTN, + wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnFilterCtrlCancel ), + NULL, this ); + m_filterCtrl->Connect( wxEVT_COMMAND_SEARCHCTRL_SEARCH_BTN, + wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnFilterCtrlSearch ), + NULL, this ); + m_filterCtrl->Connect( + wxEVT_COMMAND_TEXT_UPDATED, + wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnFilterCtrlTextChange ), NULL, this ); + m_filterCtrl->Connect( wxEVT_COMMAND_TEXT_ENTER, + wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnFilterCtrlEnter ), + NULL, this ); + m_checkRepour->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, + wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnRepourCheck ), NULL, + this ); + m_sdbSizerApply->Connect( wxEVT_COMMAND_BUTTON_CLICKED, + wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnButtonApplyClick ), + NULL, this ); +} + +DIALOG_ZONE_MANAGER_BASE::~DIALOG_ZONE_MANAGER_BASE() +{ + // Disconnect Events + m_viewZonesOverview->Disconnect( + wxEVT_CHAR, wxKeyEventHandler( DIALOG_ZONE_MANAGER_BASE::OnTableChar ), NULL, this ); + m_viewZonesOverview->Disconnect( wxEVT_CHAR_HOOK, + wxKeyEventHandler( DIALOG_ZONE_MANAGER_BASE::OnTableCharHook ), + NULL, this ); + m_viewZonesOverview->Disconnect( + wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, + wxDataViewEventHandler( DIALOG_ZONE_MANAGER_BASE::OnDataViewCtrlSelectionChanged ), + NULL, this ); + m_viewZonesOverview->Disconnect( + wxEVT_LEFT_UP, + wxMouseEventHandler( DIALOG_ZONE_MANAGER_BASE::OnViewZonesOverviewOnLeftUp ), NULL, + this ); + m_filterCtrl->Disconnect( wxEVT_COMMAND_SEARCHCTRL_CANCEL_BTN, + wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnFilterCtrlCancel ), + NULL, this ); + m_filterCtrl->Disconnect( wxEVT_COMMAND_SEARCHCTRL_SEARCH_BTN, + wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnFilterCtrlSearch ), + NULL, this ); + m_filterCtrl->Disconnect( + wxEVT_COMMAND_TEXT_UPDATED, + wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnFilterCtrlTextChange ), NULL, this ); + m_filterCtrl->Disconnect( wxEVT_COMMAND_TEXT_ENTER, + wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnFilterCtrlEnter ), + NULL, this ); + m_checkRepour->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, + wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnRepourCheck ), + NULL, this ); + m_sdbSizerApply->Disconnect( + wxEVT_COMMAND_BUTTON_CLICKED, + wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnButtonApplyClick ), NULL, this ); +} diff --git a/pcbnew/zone_manager/dialog_zone_manager_base.fbp b/pcbnew/zone_manager/dialog_zone_manager_base.fbp new file mode 100644 index 0000000000..2c9cf8f68e --- /dev/null +++ b/pcbnew/zone_manager/dialog_zone_manager_base.fbp @@ -0,0 +1,611 @@ + + + + + + C++ + 1 + source_name + 0 + 0 + res + UTF-8 + connect + dialog_zone_manager_base + 1000 + none + + + 1 + dialog_zone_manager_base + + . + + 1 + 1 + 1 + 1 + UI + 0 + 1 + 0 + + 0 + wxAUI_MGR_DEFAULT + + + + 1 + 0 + 1 + impl_virtual + + + + 0 + ID_DIALOG_COPPER_ZONE_BASE + + -1,-1 + DIALOG_ZONE_MANAGER_BASE + + -1,-1 + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + DIALOG_SHIM; dialog_shim.h + Zone Manager + + 0 + + + + + -1,-1 + m_MainBoxSizer + wxVERTICAL + protected + + 0 + wxEXPAND + 1 + + + bSizer12 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + m_sizerTop + wxHORIZONTAL + protected + + 5 + wxALL|wxEXPAND + 1 + + + bSizer7 + wxVERTICAL + none + + 0 + wxALL|wxEXPAND + 1 + + + + 1 + 0 + 1 + + + 0 + VIEW_ZONE_TABLE + + -1,240 + m_viewZonesOverview + protected + + -1,240 + wxDV_HORIZ_RULES|wxDV_ROW_LINES|wxDV_SINGLE|wxDV_VERT_RULES + ; ; forward_declare + + + + + OnTableChar + OnTableCharHook + OnDataViewCtrlSelectionChanged + OnViewZonesOverviewOnLeftUp + + + + 5 + wxBOTTOM|wxEXPAND|wxLEFT|wxTOP + 0 + + + m_sizerZoneOP + wxHORIZONTAL + protected + + 5 + wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + STD_BITMAP_BUTTON + 1 + m_btnMoveUp = new STD_BITMAP_BUTTON( this, BTN_MOVE_UP, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); + + 1 + + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + BTN_MOVE_UP + #include "widgets/std_bitmap_button.h" + + 0 + + + 0 + + 1 + m_btnMoveUp + 1 + + + protected + 1 + + Resizable + + 1 + + ; ; forward_declare + 0 + Top zone has the highest priority. When a zone is inside another zone, if its priority is higher, its outlines are removed from the other zone. + + + + + + + 5 + + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + STD_BITMAP_BUTTON + 1 + m_btnMoveDown = new STD_BITMAP_BUTTON( this, BTN_MOVE_DOWN, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); + + 1 + + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + BTN_MOVE_DOWN + #include "widgets/std_bitmap_button.h" + + 0 + + + 0 + + 1 + m_btnMoveDown + 1 + + + protected + 1 + + Resizable + + 1 + + ; ; forward_declare + 0 + Top zone has the highest priority. When a zone is inside another zone, if its priority is higher, its outlines are removed from the other zone. + + + + + + + 10 + wxEXPAND|wxLEFT|wxRIGHT + 0 + + 0 + protected + 0 + + + + 5 + wxBOTTOM|wxLEFT|wxTOP + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + CHECK_NAME + Name + + 0 + + + 0 + + 1 + m_checkName + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + CHECK_NET + Net + + 0 + + + 0 + + 1 + m_checkNet + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 0 + wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + + 1 + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_filterCtrl + 1 + + + protected + 1 + + Resizable + 1 + 1 + + wxTE_PROCESS_ENTER + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + OnFilterCtrlCancel + OnFilterCtrlSearch + OnFilterCtrlTextChange + OnFilterCtrlEnter + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + wxID_ANY + Properties + + m_sizerProperties + wxVERTICAL + 1 + protected + + + + + + 5 + wxEXPAND + 0 + + + bSizer61 + wxHORIZONTAL + none + + 15 + wxEXPAND|wxLEFT + 0 + + + bSizer71 + wxVERTICAL + none + + 10 + wxLEFT|wxTOP + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Repour + + 0 + + + 0 + + 1 + m_checkRepour + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnRepourCheck + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + + m_sdbSizer + protected + OnButtonApplyClick + + + + + + + + diff --git a/pcbnew/zone_manager/dialog_zone_manager_base.h b/pcbnew/zone_manager/dialog_zone_manager_base.h new file mode 100644 index 0000000000..4b239887a0 --- /dev/null +++ b/pcbnew/zone_manager/dialog_zone_manager_base.h @@ -0,0 +1,84 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf) +// http://www.wxformbuilder.org/ +// +// PLEASE DO *NOT* EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include +#include +#include "dialog_shim.h" +#include +#include +#include +#include +#include +#include +#include "widgets/std_bitmap_button.h" +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +/// Class DIALOG_ZONE_MANAGER_BASE +/////////////////////////////////////////////////////////////////////////////// +class DIALOG_ZONE_MANAGER_BASE : public DIALOG_SHIM +{ +private: +protected: + enum + { + ID_DIALOG_COPPER_ZONE_BASE = 1000, + VIEW_ZONE_TABLE, + BTN_MOVE_UP, + BTN_MOVE_DOWN, + CHECK_NAME, + CHECK_NET + }; + + wxBoxSizer* m_MainBoxSizer; + wxBoxSizer* m_sizerTop; + wxDataViewCtrl* m_viewZonesOverview; + wxBoxSizer* m_sizerZoneOP; + STD_BITMAP_BUTTON* m_btnMoveUp; + STD_BITMAP_BUTTON* m_btnMoveDown; + wxCheckBox* m_checkName; + wxCheckBox* m_checkNet; + wxSearchCtrl* m_filterCtrl; + wxStaticBoxSizer* m_sizerProperties; + wxCheckBox* m_checkRepour; + wxStdDialogButtonSizer* m_sdbSizer; + wxButton* m_sdbSizerOK; + wxButton* m_sdbSizerApply; + wxButton* m_sdbSizerCancel; + + // Virtual event handlers, override them in your derived class + virtual void OnTableChar( wxKeyEvent& event ) { event.Skip(); } + virtual void OnTableCharHook( wxKeyEvent& event ) { event.Skip(); } + virtual void OnDataViewCtrlSelectionChanged( wxDataViewEvent& event ) { event.Skip(); } + virtual void OnViewZonesOverviewOnLeftUp( wxMouseEvent& event ) { event.Skip(); } + virtual void OnFilterCtrlCancel( wxCommandEvent& event ) { event.Skip(); } + virtual void OnFilterCtrlSearch( wxCommandEvent& event ) { event.Skip(); } + virtual void OnFilterCtrlTextChange( wxCommandEvent& event ) { event.Skip(); } + virtual void OnFilterCtrlEnter( wxCommandEvent& event ) { event.Skip(); } + virtual void OnRepourCheck( wxCommandEvent& event ) { event.Skip(); } + virtual void OnButtonApplyClick( wxCommandEvent& event ) { event.Skip(); } + + +public: + DIALOG_ZONE_MANAGER_BASE( wxWindow* parent, wxWindowID id = ID_DIALOG_COPPER_ZONE_BASE, + const wxString& title = _( "Zone Manager" ), + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxSize( -1, -1 ), + long style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ); + + ~DIALOG_ZONE_MANAGER_BASE(); +}; diff --git a/pcbnew/zone_manager/model_zones_overview_table.cpp b/pcbnew/zone_manager/model_zones_overview_table.cpp new file mode 100644 index 0000000000..807d7da8a1 --- /dev/null +++ b/pcbnew/zone_manager/model_zones_overview_table.cpp @@ -0,0 +1,275 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 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 +#include +#include +#include +#include +#include +#include "zone_manager_preference.h" +#include "zone_priority_container.h" +#include "model_zones_overview_table.h" + +wxDEFINE_EVENT( EVT_ZONES_OVERVIEW_COUNT_CHANGE, wxCommandEvent ); + +inline void MODEL_ZONES_OVERVIEW_TABLE::SortZoneContainers() +{ + std::sort( m_filteredZoneContainers.begin(), m_filteredZoneContainers.end(), + []( std::shared_ptr const& l, + std::shared_ptr const& r + + ) + { + return l->GetCurrentPriority() > r->GetCurrentPriority(); + } ); +} + +inline void MODEL_ZONES_OVERVIEW_TABLE::OnRowCountChange() +{ + wxCommandEvent rowCountChange( EVT_ZONES_OVERVIEW_COUNT_CHANGE ); + rowCountChange.SetInt( GetCount() ); + wxPostEvent( m_dialog, rowCountChange ); +} + +static wxBitmap MakeBitmapForLayers( LSEQ const& layers, COLOR_SETTINGS const& settings, + const wxSize& aSize ) +{ + wxBitmap bitmap( aSize ); + wxBrush brush; + wxPen pen; + wxMemoryDC iconDC; + + iconDC.SelectObject( bitmap ); + brush.SetStyle( wxBRUSHSTYLE_SOLID ); + const int layer_cout = layers.size(); + std::vector layersToDraw; + + if( layer_cout > 4 ) + { + for( const PCB_LAYER_ID& i : + { layers[0], layers[1], layers[layer_cout - 1], layers[layer_cout - 2] } ) + layersToDraw.push_back( i ); + } + else + { + layersToDraw = layers; + } + + const int step = static_cast( aSize.x / layersToDraw.size() ); + + for( size_t i = 0; i < layersToDraw.size(); ++i ) + { + const KIGFX::COLOR4D color = settings.GetColor( layersToDraw[i] ); + brush.SetColour( color.ToColour() ); + pen.SetColour( color.ToColour() ); + iconDC.SetBrush( brush ); + iconDC.SetPen( pen ); + iconDC.DrawRectangle( 0, i * step, aSize.x, step ); + } + + return bitmap; +} + + +MODEL_ZONES_OVERVIEW_TABLE::MODEL_ZONES_OVERVIEW_TABLE( ZONE_PRIORITY_CONTAINER_LIST aZones, + BOARD* a_pcb, PCB_BASE_FRAME* aPCB_FRAME, + wxWindow* a_dialog ) : + m_allZoneContainers( aZones ), + m_filteredZoneContainers( std::move( aZones ) ), m_pcb( a_pcb ), m_PCB_FRAME( aPCB_FRAME ), + m_dialog( a_dialog ), m_sortByName( true ), m_sortByNet( true ) +{ + Reset( m_filteredZoneContainers.size() ); +} + +MODEL_ZONES_OVERVIEW_TABLE::~MODEL_ZONES_OVERVIEW_TABLE() = default; + +void MODEL_ZONES_OVERVIEW_TABLE::GetValueByRow( wxVariant& aVariant, unsigned aRow, + unsigned aCol ) const +{ + if( static_cast( aRow ) + 1 > m_filteredZoneContainers.size() ) + return; + + const ZONE& cur = m_filteredZoneContainers[aRow]->GetZone(); + + switch( aCol ) + { + case NAME: aVariant = cur.GetZoneName(); break; + case NET: aVariant = cur.GetNet()->GetNetname(); break; + case LAYERS: + { + wxArrayString layers; + + for( PCB_LAYER_ID layer : cur.GetLayerSet().Seq() ) + layers.Add( m_pcb->GetLayerName( layer ) ); + + aVariant << wxDataViewIconText( + wxJoin( layers, ',' ), + MakeBitmapForLayers( + cur.GetLayerSet().Seq(), *m_PCB_FRAME->GetColorSettings(), + { LAYER_BAR_WIDTH, ZONE_MANAGER_PREFERENCE::LAYER_ICON_SIZE::HEIGHT } ) ); + } + break; + default: break; + } +} + +void MODEL_ZONES_OVERVIEW_TABLE::EnableFitterByName( bool aEnable ) +{ + m_sortByName = aEnable; +} + +void MODEL_ZONES_OVERVIEW_TABLE::EnableFitterByNet( bool aEnable ) +{ + m_sortByNet = aEnable; +} + +bool MODEL_ZONES_OVERVIEW_TABLE::SetValueByRow( const wxVariant& aVariant, unsigned aRow, + unsigned aCol ) +{ + WXUNUSED( aVariant ) + WXUNUSED( aRow ) + WXUNUSED( aCol ) + return {}; +} + +unsigned int MODEL_ZONES_OVERVIEW_TABLE::GetCount() const +{ + return m_filteredZoneContainers.size(); +} + +ZONE* MODEL_ZONES_OVERVIEW_TABLE::GetZone( wxDataViewItem const& aItem ) const +{ + if( !aItem.IsOk() ) + return {}; + + unsigned int aRow = GetRow( aItem ); + + if( aRow + 1 > GetCount() ) + return {}; + + return &m_filteredZoneContainers[aRow]->GetZone(); +} + +wxDataViewItem MODEL_ZONES_OVERVIEW_TABLE::GetItemByZone( ZONE* aZone ) const +{ + if( !aZone ) + return {}; + + for( size_t i = 0; i < m_filteredZoneContainers.size(); i++ ) + { + if( &m_filteredZoneContainers[i]->GetZone() == aZone ) + return GetItem( i ); + } + + return {}; +} + + +std::optional MODEL_ZONES_OVERVIEW_TABLE::MoveZoneIndex( unsigned aIndex, + ZONE_INDEX_MOVEMENT aMovement ) +{ + switch( aMovement ) + { + case ZONE_INDEX_MOVEMENT::MOVE_UP: + { + return aIndex >= 1 && GetCount() > 1 ? SwapZonePriority( aIndex, aIndex - 1 ) + : std::optional{}; + } + case ZONE_INDEX_MOVEMENT::MOVE_DOWN: + { + return aIndex + 1 < GetCount() ? SwapZonePriority( aIndex, aIndex + 1 ) + : std::optional{}; + } + } + return {}; +} + +std::optional MODEL_ZONES_OVERVIEW_TABLE::SwapZonePriority( unsigned aDragIndex, + unsigned aDropIndex ) +{ + for( const unsigned i : { aDragIndex, aDropIndex } ) + { + if( !( i < GetCount() ) ) + return {}; + } + + if( aDragIndex == aDropIndex ) + return aDragIndex; + + std::swap( m_filteredZoneContainers[aDragIndex]->m_currentPriority, + m_filteredZoneContainers[aDropIndex]->m_currentPriority ); + std::swap( m_filteredZoneContainers[aDragIndex], m_filteredZoneContainers[aDropIndex] ); + + for( const unsigned int row : { aDragIndex, aDropIndex } ) + RowChanged( row ); + + return aDropIndex; +} + + +wxDataViewItem MODEL_ZONES_OVERVIEW_TABLE::ApplyFilter( wxString const& aFilterText, + wxDataViewItem aSelection ) +{ + if( !GetAllZonesCount() ) + return {}; + + wxString lowerFilterText = aFilterText.Strip( wxString::both ).Lower(); + + if( lowerFilterText.empty() ) + return ClearFilter( aSelection ); + + ZONE* selected_zone = GetZone( aSelection ); + m_filteredZoneContainers.clear(); + + for( const auto& container : m_allZoneContainers ) + { + const ZONE zone = container->GetZone(); + + if( ( m_sortByName && zone.GetZoneName().Lower().Contains( lowerFilterText ) ) + || ( m_sortByNet && zone.GetNetname().Lower().Contains( lowerFilterText ) ) ) + { + m_filteredZoneContainers.push_back( container ); + } + } + SortZoneContainers(); + Reset( GetCount() ); + OnRowCountChange(); + return GetItemByZone( selected_zone ); +} + +wxDataViewItem MODEL_ZONES_OVERVIEW_TABLE::ClearFilter( wxDataViewItem aSelection ) +{ + if( !GetAllZonesCount() ) + return {}; + + ZONE* zone = GetZone( aSelection ); + m_filteredZoneContainers = m_allZoneContainers; + SortZoneContainers(); + Reset( GetCount() ); + OnRowCountChange(); + return GetItemByZone( zone ); +} diff --git a/pcbnew/zone_manager/model_zones_overview_table.h b/pcbnew/zone_manager/model_zones_overview_table.h new file mode 100644 index 0000000000..b5d404da80 --- /dev/null +++ b/pcbnew/zone_manager/model_zones_overview_table.h @@ -0,0 +1,154 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 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 MODEL_ZONES_OVERVIEW_TABLE_H +#define MODEL_ZONES_OVERVIEW_TABLE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class PCB_BASE_FRAME; +class PCB_BASE_FRAME; +class ZONE_PRIORITY_CONTAINER; + +wxDECLARE_EVENT( EVT_ZONES_OVERVIEW_COUNT_CHANGE, wxCommandEvent ); + +using ZONE_PRIORITY_CONTAINER_LIST = std::vector>; + +enum class ZONE_INDEX_MOVEMENT +{ + MOVE_UP, + MOVE_DOWN +}; + +class MODEL_ZONES_OVERVIEW_TABLE : public wxDataViewVirtualListModel +{ +public: + enum + { + NAME, + NET, + LAYERS, + + COL_COUNT + }; + + enum WIDTH_SETTING + { + NAME_WIDTH = 128, + LAYER_BAR_WIDTH = 16, + //NOTE - Prevent the hor scroll bar + RESERVED = 10, + MINIMAL_WIDTH = NAME_WIDTH + LAYER_BAR_WIDTH + RESERVED + }; + + + static std::map GetColumnNames() + { + //NOTE - Build the column name dynamicly in case the display language changed + const std::map ColNames = std::map{ + std::make_pair( NAME, _( "Name" ) ), std::make_pair( NET, _( "Net" ) ), + std::make_pair( LAYERS, _( "Layers" ) ) + + }; + return ColNames; + } + + MODEL_ZONES_OVERVIEW_TABLE( ZONE_PRIORITY_CONTAINER_LIST aZones, BOARD* a_pcb, + PCB_BASE_FRAME* aPCB_FRAME, wxWindow* a_dialog ); + + ~MODEL_ZONES_OVERVIEW_TABLE() override; + + void EnableFitterByName( bool aEnable ); + + void EnableFitterByNet( bool aEnable ); + + void GetValueByRow( wxVariant& aVariant, unsigned aRow, unsigned aCol ) const override; + + bool SetValueByRow( const wxVariant& aVariant, unsigned aRow, unsigned aCol ) override; + + // returns the number of rows + unsigned int GetCount() const override; + + ZONE* GetZone( wxDataViewItem const& item ) const; + + wxDataViewItem GetItemByZone( ZONE* ) const; + + /** + * @brief Move selected zone up/down + * + * @return std::optional the new index for selected one if success + */ + std::optional MoveZoneIndex( unsigned aIndex, ZONE_INDEX_MOVEMENT aMovement ); + + /** + * @brief Swap two zone while drag && drop + * + * @return std::optional the new index for the dragged one if success + */ + std::optional SwapZonePriority( unsigned aDragIndex, unsigned aDropIndex ); + + /** + * @brief Filter the zones by the filter text + * + * @param aFilterText Sub text matching zone name, net name or layer name + * @param aSelection Current selection + * @return unsigned Selection after the filter is applied + */ + wxDataViewItem ApplyFilter( wxString const& aFilterText, wxDataViewItem aSelection ); + + /** + * @brief Clear up the filter + * + * @param aSelection Current selection + * @return unsigned + */ + wxDataViewItem ClearFilter( wxDataViewItem aSelection ); + + unsigned int GetAllZonesCount() const { return m_allZoneContainers.size(); } + +private: + void SortZoneContainers(); + + void OnRowCountChange(); + + +private: + ZONE_PRIORITY_CONTAINER_LIST m_allZoneContainers; + ZONE_PRIORITY_CONTAINER_LIST m_filteredZoneContainers; + BOARD* m_pcb; + PCB_BASE_FRAME* m_PCB_FRAME; + wxWindow* m_dialog; + bool m_sortByName; + bool m_sortByNet; +}; + +#endif \ No newline at end of file diff --git a/pcbnew/zone_manager/pane_zone_viewer.cpp b/pcbnew/zone_manager/pane_zone_viewer.cpp new file mode 100644 index 0000000000..9e5d7d5caf --- /dev/null +++ b/pcbnew/zone_manager/pane_zone_viewer.cpp @@ -0,0 +1,191 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 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 "pane_zone_viewer.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "panel_zone_gal.h" +#include +#include "settings/color_settings.h" +#include "zone_manager_preference.h" +#include "zone_manager/panel_zone_gal.h" +#include +#include "widgets/color_swatch.h" +class PANEL_ZONE_GAL_CONTAINER : public wxPanel +{ + wxBoxSizer* m_sizer; + PANEL_ZONE_GAL* m_gal{}; + int m_layer; + +public: + PANEL_ZONE_GAL_CONTAINER( wxWindow* aParent, int aLayer ) : + wxPanel( aParent ), m_sizer( new wxBoxSizer( wxHORIZONTAL ) ), m_layer( aLayer ) + { + SetSizer( m_sizer ); + } + int GetLayer() const { return m_layer; } + void TakeGAL( PANEL_ZONE_GAL*& now ) + { + if( !m_gal ) + return; + + m_sizer->Detach( m_gal ); + now = m_gal; + m_gal = nullptr; + } + + /** + * @brief Initialize the gal , shall only be called once while the gal is first constructed + * + * @param aGal The zone gal + */ + void InitZoneGAL( PANEL_ZONE_GAL* aGal ) + { + wxASSERT( !m_gal ); + m_gal = aGal; + m_sizer->Add( m_gal, 1, wxEXPAND ); + Layout(); + m_sizer->Fit( this ); + } + + /** + * @brief Reuse the only one zone gal between different container + * + * @param aGal The zone gal + */ + void ResetZoneGAL( PANEL_ZONE_GAL* aGal ) + { + if( aGal->GetParent() == this ) + return; + + static_cast( aGal->GetParent() )->TakeGAL( m_gal ); + m_gal->Reparent( this ); + m_sizer->Add( m_gal, 1, wxEXPAND ); + Layout(); + m_sizer->Fit( this ); + } +}; + +PANE_ZONE_VIEWER::PANE_ZONE_VIEWER( wxWindow* aParent, PCB_BASE_FRAME* aPcbFrame ) : + wxNotebook( aParent, -1, wxDefaultPosition, wxDefaultSize ), m_pcbFrame( aPcbFrame ) +{ + Bind( wxEVT_BOOKCTRL_PAGE_CHANGED, &PANE_ZONE_VIEWER::OnNotebook, this ); + + wxImageList* imageList = new wxImageList( ZONE_MANAGER_PREFERENCE::LAYER_ICON_SIZE::WIDTH, + ZONE_MANAGER_PREFERENCE::LAYER_ICON_SIZE::HEIGHT ); + + for( int i = 0; i < PCB_LAYER_ID::PCB_LAYER_ID_COUNT; i++ ) + { + const KIGFX::COLOR4D color = aPcbFrame->GetColorSettings()->GetColor( i ); + imageList->Add( COLOR_SWATCH::MakeBitmap( + color != COLOR4D::UNSPECIFIED ? color : COLOR4D::WHITE, COLOR4D::UNSPECIFIED, + wxSize( ZONE_MANAGER_PREFERENCE::LAYER_ICON_SIZE::WIDTH, + ZONE_MANAGER_PREFERENCE::LAYER_ICON_SIZE::HEIGHT ), + { 5, 6 }, COLOR4D::WHITE ) ); + } + + AssignImageList( imageList ); +} + + +PANE_ZONE_VIEWER::~PANE_ZONE_VIEWER() = default; + +void PANE_ZONE_VIEWER::ActivateSelectedZone( ZONE* aZone ) +{ + while( GetPageCount() ) + RemovePage( 0 ); + + if( !aZone ) + return; + + const PCB_LAYER_ID firstLayer = aZone->GetFirstLayer(); + + for( PCB_LAYER_ID layer : aZone->GetLayerSet().Seq() ) + { + wxString layerName = + m_pcbFrame->GetBoard()->GetLayerName( static_cast( layer ) ); + + if( auto existingContainer = m_zoneContainers.find( layer ); + existingContainer != m_zoneContainers.end() ) + { + AddPage( existingContainer->second, layerName, false, layer ); + } + else + { + PANEL_ZONE_GAL_CONTAINER* container = new PANEL_ZONE_GAL_CONTAINER( this, layer ); + m_zoneContainers.try_emplace( layer, container ); + AddPage( container, layerName, false, layer ); + } + } + + SetSelection( FindPage( m_zoneContainers[firstLayer] ) ); + + if( !m_zoneGAL ) + { + m_zoneGAL = ( new PANEL_ZONE_GAL( m_pcbFrame->GetBoard(), + m_zoneContainers[aZone->GetFirstLayer()], + m_pcbFrame->GetGalDisplayOptions() ) ); + m_zoneContainers[firstLayer]->InitZoneGAL( m_zoneGAL ); + } + else + { + m_zoneContainers[firstLayer]->ResetZoneGAL( m_zoneGAL ); + } + + m_zoneGAL->ActivateSelectedZone( aZone ); +} + +void PANE_ZONE_VIEWER::OnNotebook( wxNotebookEvent& aEvent ) +{ + const int idx = aEvent.GetSelection(); + PANEL_ZONE_GAL_CONTAINER* container = static_cast( GetPage( idx ) ); + container->ResetZoneGAL( m_zoneGAL ); + m_zoneGAL->OnLayerSelected( container->GetLayer() ); + SetSelection( idx ); + aEvent.Skip(); +} diff --git a/pcbnew/zone_manager/pane_zone_viewer.h b/pcbnew/zone_manager/pane_zone_viewer.h new file mode 100644 index 0000000000..17b0765c00 --- /dev/null +++ b/pcbnew/zone_manager/pane_zone_viewer.h @@ -0,0 +1,58 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 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 PANE_ZONE_VIEWER_H +#define PANE_ZONE_VIEWER_H + + +#include "zone_selection_change_notifier.h" +#include +#include +#include +#include +class wxDataViewCtrl; +class PANEL_ZONE_GAL; +class PCB_BASE_FRAME; +class PANEL_ZONE_GAL_CONTAINER; +class ROW_ICON_PROVIDER; +class PANE_ZONE_VIEWER : public wxNotebook, public ZONE_SELECTION_CHANGE_NOTIFIER +{ +public: + PANE_ZONE_VIEWER( wxWindow* aParent, PCB_BASE_FRAME* aPcbFrame ); + ~PANE_ZONE_VIEWER() override; + + void ActivateSelectedZone( ZONE* new_zone ) override; + + void OnNotebook( wxNotebookEvent& aEvent ); + + PANEL_ZONE_GAL* GetZoneGAL() const { return m_zoneGAL; } + + +private: + PCB_BASE_FRAME* m_pcbFrame; + std::unordered_map m_zoneContainers; + PANEL_ZONE_GAL* m_zoneGAL{}; +}; + +#endif \ No newline at end of file diff --git a/pcbnew/zone_manager/panel_zone_gal.cpp b/pcbnew/zone_manager/panel_zone_gal.cpp new file mode 100644 index 0000000000..b55de9a33a --- /dev/null +++ b/pcbnew/zone_manager/panel_zone_gal.cpp @@ -0,0 +1,179 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 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 "panel_zone_gal.h" +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "zone_manager_preference.h" +#include "zone_painter.h" +#include "zone_manager/board_edges_bounding_item.h" + + +enum DRAW_ORDER +{ + DRAW_ORDER_BOARD_BOUNDING, + DRAW_ORDER_ZONE + +}; + + +PANEL_ZONE_GAL::PANEL_ZONE_GAL( BOARD* aPcb, wxWindow* aParentWindow, + KIGFX::GAL_DISPLAY_OPTIONS& aOptions, wxWindowID aWindowId, + const wxPoint& aPosition, const wxSize& aSize, GAL_TYPE aGalType ) : + PCB_DRAW_PANEL_GAL( aParentWindow, aWindowId, aPosition, wxDefaultSize, aOptions, + aGalType ), + m_pcb( aPcb ), m_layer( UNDEFINED_LAYER ), + m_pcb_bounding_box( + std::make_unique( aPcb->GetBoardEdgesBoundingBox() ) ), + m_zone( nullptr ) +{ + m_view->UseDrawPriority( true ); + m_painter = std::make_unique( m_gal, FRAME_FOOTPRINT_PREVIEW ); + m_view->SetPainter( m_painter.get() ); + m_view->Add( m_pcb_bounding_box.get(), DRAW_ORDER_BOARD_BOUNDING ); + UpdateColors(); + ShowScrollbars( wxSHOW_SB_NEVER, wxSHOW_SB_NEVER ); + StartDrawing(); + m_painter->GetSettings()->SetBackgroundColor( + ZONE_MANAGER_PREFERENCE::GetCanvasBackgroundColor() ); +} + + +PANEL_ZONE_GAL::~PANEL_ZONE_GAL() +{ +} + +BOX2I PANEL_ZONE_GAL::GetBoardBoundingBox( bool aBoardEdgesOnly ) const +{ + BOX2I area = aBoardEdgesOnly ? m_pcb->GetBoardEdgesBoundingBox() : m_pcb->GetBoundingBox(); + + if( area.GetWidth() == 0 && area.GetHeight() == 0 ) + { + wxSize pageSize = GetPageSizeIU(); + area.SetOrigin( 0, 0 ); + area.SetEnd( pageSize.x, pageSize.y ); + } + + return area; +} + +const BOX2I PANEL_ZONE_GAL::GetDocumentExtents( bool aIncludeAllVisible ) const +{ + if( aIncludeAllVisible || !m_pcb->IsLayerVisible( Edge_Cuts ) ) + return GetBoardBoundingBox( false ); + else + return GetBoardBoundingBox( true ); +} + +bool PANEL_ZONE_GAL::OnLayerSelected( int aLayer ) +{ + if( m_layer == aLayer ) + return false; + + m_layer = aLayer; + // Load layer & elements visibility settings + + for( int i = 0; i < PCB_LAYER_ID_COUNT; ++i ) + m_view->SetLayerVisible( i, m_layer == i || Edge_Cuts == i ); + + Refresh(); + return true; +} + + +void PANEL_ZONE_GAL::ActivateSelectedZone( ZONE* aZone ) +{ + if( m_zone ) + m_view->Remove( m_zone ); + + if( aZone ) + { + m_view->Add( aZone, DRAW_ORDER_ZONE ); + + if( !OnLayerSelected( aZone->GetFirstLayer() ) ) + Refresh(); + } + else + { + Refresh(); + } + + m_zone = aZone; +} + +const wxSize PANEL_ZONE_GAL::GetPageSizeIU() const +{ + const VECTOR2D sizeIU = m_pcb->GetPageSettings().GetSizeIU( pcbIUScale.IU_PER_MILS ); + return wxSize( sizeIU.x, sizeIU.y ); +} + +void PANEL_ZONE_GAL::ZoomFitScreen() +{ + BOX2I bBox = GetDocumentExtents(); + BOX2I defaultBox = GetDefaultViewBBox(); + + m_view->SetScale( 1.0 ); + const wxSize clientSize = GetSize(); + VECTOR2D screenSize = m_view->ToWorld( + VECTOR2D( static_cast( clientSize.x ), static_cast( clientSize.y ) ), + false ); + + if( bBox.GetWidth() == 0 || bBox.GetHeight() == 0 ) + bBox = defaultBox; + + VECTOR2D vsize = bBox.GetSize(); + double scale = m_view->GetScale() + / std::max( fabs( vsize.x / screenSize.x ), fabs( vsize.y / screenSize.y ) ); + + if( !std::isfinite( scale ) ) + { + m_view->SetCenter( VECTOR2D( 0, 0 ) ); + Refresh(); + return; + } + + m_view->SetScale( scale ); + m_view->SetCenter( bBox.Centre() ); + Refresh(); +} diff --git a/pcbnew/zone_manager/panel_zone_gal.h b/pcbnew/zone_manager/panel_zone_gal.h new file mode 100644 index 0000000000..c60a479b1c --- /dev/null +++ b/pcbnew/zone_manager/panel_zone_gal.h @@ -0,0 +1,75 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 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 PANEL_ZONE_GAL_H +#define PANEL_ZONE_GAL_H + +#include +#include +#include +#include +#include +#include "board_edges_bounding_item.h" +#include "pcb_draw_panel_gal.h" +#include "zone_manager/zone_selection_change_notifier.h" + +class PANEL_ZONE_GAL : public PCB_DRAW_PANEL_GAL, public ZONE_SELECTION_CHANGE_NOTIFIER +{ +public: + PANEL_ZONE_GAL( BOARD* aPcb, wxWindow* aParentWindow, KIGFX::GAL_DISPLAY_OPTIONS& aOptions, + wxWindowID aWindowId = 0, const wxPoint& aPosition = wxDefaultPosition, + const wxSize& aSize = wxDefaultSize, GAL_TYPE aGalType = GAL_TYPE_OPENGL ); + ~PANEL_ZONE_GAL() override; + + + const wxSize GetPageSizeIU() const; + + void ZoomFitScreen(); + BOX2I GetBoardBoundingBox( bool aBoardEdgesOnly ) const; + + const BOX2I GetDocumentExtents( bool aIncludeAllVisible = true ) const; + + /** + * @brief Show the zone painting on layer + * + * @param aLayer The expected layer + * @return return true if the GAL updated the display else falue + */ + bool OnLayerSelected( int aLayer ); + + int GetLayer() const { return m_layer; } + + void ActivateSelectedZone( ZONE* aZone ) override; + + ZONE* GetZone() const { return m_zone; } + +private: + BOARD* m_pcb; + int m_layer; + std::unique_ptr m_pcb_bounding_box; + ZONE* m_zone; +}; + +#endif \ No newline at end of file diff --git a/pcbnew/zone_manager/panel_zone_properties.cpp b/pcbnew/zone_manager/panel_zone_properties.cpp new file mode 100644 index 0000000000..6df89e105e --- /dev/null +++ b/pcbnew/zone_manager/panel_zone_properties.cpp @@ -0,0 +1,320 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck + * Copyright (C) 1992-2022 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 "panel_zone_properties.h" +#include "zone_manager/panel_zone_properties_base.h" +#include "zone_manager/zones_container.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +wxDEFINE_EVENT( EVT_ZONE_NAME_UPDATE, wxCommandEvent ); + +PANEL_ZONE_PROPERTIES::PANEL_ZONE_PROPERTIES( wxWindow* aParent, PCB_BASE_FRAME* aPCB_FRAME, + ZONES_CONTAINER& aZoneContainer ) : + PANEL_ZONE_PROPERTIES_BASE( aParent ), + m_ZoneContainer( aZoneContainer ), m_PCB_Frame( aPCB_FRAME ), + m_cornerSmoothingType( ZONE_SETTINGS::SMOOTHING_UNDEFINED ), + m_outlineHatchPitch( aPCB_FRAME, m_stBorderHatchPitchText, m_outlineHatchPitchCtrl, + m_outlineHatchUnits ), + m_cornerRadius( aPCB_FRAME, m_cornerRadiusLabel, m_cornerRadiusCtrl, m_cornerRadiusUnits ), + m_clearance( aPCB_FRAME, m_clearanceLabel, m_clearanceCtrl, m_clearanceUnits ), + m_minThickness( aPCB_FRAME, m_minWidthLabel, m_minWidthCtrl, m_minWidthUnits ), + m_antipadClearance( aPCB_FRAME, m_antipadLabel, m_antipadCtrl, m_antipadUnits ), + m_spokeWidth( aPCB_FRAME, m_spokeWidthLabel, m_spokeWidthCtrl, m_spokeWidthUnits ), + m_gridStyleRotation( aPCB_FRAME, m_staticTextGrindOrient, m_tcGridStyleOrientation, + m_staticTextRotUnits ), + m_gridStyleThickness( aPCB_FRAME, m_staticTextStyleThickness, m_tcGridStyleThickness, + m_GridStyleThicknessUnits ), + m_gridStyleGap( aPCB_FRAME, m_staticTextGridGap, m_tcGridStyleGap, m_GridStyleGapUnits ), + m_islandThreshold( aPCB_FRAME, m_islandThresholdLabel, m_tcIslandThreshold, + m_islandThresholdUnits ), + m_isTeardrop() +{ + m_cbRemoveIslands->Bind( wxEVT_CHOICE, + [&]( wxCommandEvent& ) + { + // Area mode is index 2 + m_islandThreshold.Enable( m_cbRemoveIslands->GetSelection() == 2 ); + } ); +} + + +void PANEL_ZONE_PROPERTIES::ActivateSelectedZone( ZONE* aZone ) +{ + if( m_settings ) + TransferZoneSettingsFromWindow(); + + m_settings = m_ZoneContainer.GetZoneSettings( aZone ); + m_isTeardrop = m_settings->m_TeardropType != TEARDROP_TYPE::TD_NONE; + + TransferZoneSettingsToWindow(); +} + +void PANEL_ZONE_PROPERTIES::OnUserConfirmChange() +{ + TransferZoneSettingsFromWindow(); +} + + +bool PANEL_ZONE_PROPERTIES::TransferZoneSettingsToWindow() +{ + if( !m_settings ) + return false; + m_cbLocked->SetValue( m_settings->m_Locked ); + m_cornerSmoothingChoice->SetSelection( m_settings->GetCornerSmoothingType() ); + m_cornerRadius.SetValue( m_settings->GetCornerRadius() ); + + if( m_isTeardrop ) // outlines are never smoothed: they have already the right shape + { + m_cornerSmoothingChoice->SetSelection( 0 ); + m_cornerSmoothingChoice->Enable( false ); + m_cornerRadius.SetValue( 0 ); + m_cornerRadius.Enable( false ); + } + + switch( m_settings->m_ZoneBorderDisplayStyle ) + { + case ZONE_BORDER_DISPLAY_STYLE::NO_HATCH: m_OutlineDisplayCtrl->SetSelection( 0 ); break; + case ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE: m_OutlineDisplayCtrl->SetSelection( 1 ); break; + case ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_FULL: m_OutlineDisplayCtrl->SetSelection( 2 ); break; + case ZONE_BORDER_DISPLAY_STYLE::INVISIBLE_BORDER: break; + } + + m_outlineHatchPitch.SetValue( m_settings->m_BorderHatchPitch ); + + m_clearance.SetValue( m_settings->m_ZoneClearance ); + m_minThickness.SetValue( m_settings->m_ZoneMinThickness ); + + switch( m_settings->GetPadConnection() ) + { + default: + case ZONE_CONNECTION::THERMAL: m_PadInZoneOpt->SetSelection( 1 ); break; + case ZONE_CONNECTION::THT_THERMAL: m_PadInZoneOpt->SetSelection( 2 ); break; + case ZONE_CONNECTION::NONE: m_PadInZoneOpt->SetSelection( 3 ); break; + case ZONE_CONNECTION::FULL: m_PadInZoneOpt->SetSelection( 0 ); break; + } + + if( m_isTeardrop ) + { + m_PadInZoneOpt->SetSelection( 0 ); + m_PadInZoneOpt->Enable( false ); + } + + // Do not enable/disable antipad clearance and spoke width. They might be needed if + // a footprint or pad overrides the zone to specify a thermal connection. + m_antipadClearance.SetValue( m_settings->m_ThermalReliefGap ); + m_spokeWidth.SetValue( m_settings->m_ThermalReliefSpokeWidth ); + + m_islandThreshold.SetDataType( EDA_DATA_TYPE::AREA ); + m_islandThreshold.SetDoubleValue( static_cast( m_settings->GetMinIslandArea() ) ); + + m_cbRemoveIslands->SetSelection( static_cast( m_settings->GetIslandRemovalMode() ) ); + + m_islandThreshold.Enable( m_settings->GetIslandRemovalMode() == ISLAND_REMOVAL_MODE::AREA ); + + + if( !m_isTeardrop && m_settings->m_FillMode == ZONE_FILL_MODE::HATCH_PATTERN ) + m_GridStyleCtrl->SetSelection( 1 ); + else + m_GridStyleCtrl->SetSelection( 0 ); + + m_GridStyleCtrl->Enable( !m_isTeardrop ); + + m_gridStyleRotation.SetUnits( EDA_UNITS::DEGREES ); + m_gridStyleRotation.SetAngleValue( m_settings->m_HatchOrientation ); + m_gridStyleThickness.SetValue( m_settings->m_HatchThickness ); + m_gridStyleGap.SetValue( m_settings->m_HatchGap ); + + m_spinCtrlSmoothLevel->SetValue( m_settings->m_HatchSmoothingLevel ); + m_spinCtrlSmoothValue->SetValue( m_settings->m_HatchSmoothingValue ); + + m_tcZoneName->SetValue( m_settings->m_Name ); + + + // Enable/Disable some widgets + wxCommandEvent aEvent; + OnStyleSelection( aEvent ); + Fit(); + + return true; +} + + +void PANEL_ZONE_PROPERTIES::OnUpdateUI( wxUpdateUIEvent& ) +{ + if( m_cornerSmoothingType != m_cornerSmoothingChoice->GetSelection() ) + { + m_cornerSmoothingType = m_cornerSmoothingChoice->GetSelection(); + + if( m_cornerSmoothingChoice->GetSelection() == ZONE_SETTINGS::SMOOTHING_CHAMFER ) + m_cornerRadiusLabel->SetLabel( _( "Chamfer distance:" ) ); + else + m_cornerRadiusLabel->SetLabel( _( "Fillet radius:" ) ); + } + + m_cornerRadiusCtrl->Enable( m_cornerSmoothingType > ZONE_SETTINGS::SMOOTHING_NONE ); +} + + +void PANEL_ZONE_PROPERTIES::OnRemoveIslandsSelection( wxCommandEvent& aEvent ) +{ + m_islandThreshold.Enable( m_cbRemoveIslands->GetSelection() == 2 ); +} + +void PANEL_ZONE_PROPERTIES::OnZoneNameChanged( wxCommandEvent& aEvent ) +{ + wxCommandEvent* evt = new wxCommandEvent( EVT_ZONE_NAME_UPDATE ); + evt->SetString( m_tcZoneName->GetValue() ); + wxQueueEvent( m_parent, evt ); +} + + +bool PANEL_ZONE_PROPERTIES::TransferZoneSettingsFromWindow() +{ + if( !m_settings ) + return false; + if( m_GridStyleCtrl->GetSelection() > 0 ) + m_settings->m_FillMode = ZONE_FILL_MODE::HATCH_PATTERN; + else + m_settings->m_FillMode = ZONE_FILL_MODE::POLYGONS; + + if( !AcceptOptions() ) + return false; + m_settings->m_HatchOrientation = m_gridStyleRotation.GetAngleValue(); + m_settings->m_HatchThickness = m_gridStyleThickness.GetValue(); + m_settings->m_HatchGap = m_gridStyleGap.GetValue(); + m_settings->m_HatchSmoothingLevel = m_spinCtrlSmoothLevel->GetValue(); + m_settings->m_HatchSmoothingValue = m_spinCtrlSmoothValue->GetValue(); + + return true; +} + + +bool PANEL_ZONE_PROPERTIES::AcceptOptions( bool aUseExportableSetupOnly ) +{ + if( !m_clearance.Validate( 0, pcbIUScale.mmToIU( ZONE_CLEARANCE_MAX_VALUE_MM ) ) ) + return false; + + if( !m_minThickness.Validate( pcbIUScale.mmToIU( ZONE_THICKNESS_MIN_VALUE_MM ), INT_MAX ) ) + return false; + + if( !m_cornerRadius.Validate( 0, INT_MAX ) ) + return false; + + if( !m_spokeWidth.Validate( 0, INT_MAX ) ) + return false; + + m_gridStyleRotation.SetValue( NormalizeAngle180( m_gridStyleRotation.GetValue() ) ); + + if( m_settings->m_FillMode == ZONE_FILL_MODE::HATCH_PATTERN ) + { + int minThickness = m_minThickness.GetValue(); + + if( !m_gridStyleThickness.Validate( minThickness, INT_MAX ) ) + return false; + + if( !m_gridStyleGap.Validate( minThickness, INT_MAX ) ) + return false; + } + + switch( m_PadInZoneOpt->GetSelection() ) + { + case 3: m_settings->SetPadConnection( ZONE_CONNECTION::NONE ); break; + case 2: m_settings->SetPadConnection( ZONE_CONNECTION::THT_THERMAL ); break; + case 1: m_settings->SetPadConnection( ZONE_CONNECTION::THERMAL ); break; + case 0: m_settings->SetPadConnection( ZONE_CONNECTION::FULL ); break; + } + + switch( m_OutlineDisplayCtrl->GetSelection() ) + { + case 0: m_settings->m_ZoneBorderDisplayStyle = ZONE_BORDER_DISPLAY_STYLE::NO_HATCH; break; + case 1: m_settings->m_ZoneBorderDisplayStyle = ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_EDGE; break; + case 2: m_settings->m_ZoneBorderDisplayStyle = ZONE_BORDER_DISPLAY_STYLE::DIAGONAL_FULL; break; + } + + if( !m_outlineHatchPitch.Validate( pcbIUScale.mmToIU( ZONE_BORDER_HATCH_MINDIST_MM ), + pcbIUScale.mmToIU( ZONE_BORDER_HATCH_MAXDIST_MM ) ) ) + return false; + + m_settings->m_BorderHatchPitch = m_outlineHatchPitch.GetValue(); + + m_settings->m_ZoneClearance = m_clearance.GetValue(); + m_settings->m_ZoneMinThickness = m_minThickness.GetValue(); + + m_settings->SetCornerSmoothingType( m_cornerSmoothingChoice->GetSelection() ); + + m_settings->SetCornerRadius( m_settings->GetCornerSmoothingType() + == ZONE_SETTINGS::SMOOTHING_NONE + ? 0 + : m_cornerRadius.GetValue() ); + + m_settings->m_Locked = m_cbLocked->GetValue(); + + m_settings->m_ThermalReliefGap = m_antipadClearance.GetValue(); + m_settings->m_ThermalReliefSpokeWidth = m_spokeWidth.GetValue(); + + if( m_settings->m_ThermalReliefSpokeWidth < m_settings->m_ZoneMinThickness ) + { + DisplayError( this, _( "Thermal spoke width cannot be smaller than the minimum width." ) ); + return false; + } + + m_settings->SetIslandRemovalMode( (ISLAND_REMOVAL_MODE) m_cbRemoveIslands->GetSelection() ); + m_settings->SetMinIslandArea( m_islandThreshold.GetValue() ); + + // If we use only exportable to others zones parameters, exit here: + if( aUseExportableSetupOnly ) + return true; + + m_settings->m_Name = m_tcZoneName->GetValue(); + + return true; +} + + +void PANEL_ZONE_PROPERTIES::OnStyleSelection( wxCommandEvent& aEvent ) +{ + bool enable = m_GridStyleCtrl->GetSelection() >= 1; + m_tcGridStyleThickness->Enable( enable ); + m_tcGridStyleGap->Enable( enable ); + m_tcGridStyleOrientation->Enable( enable ); + m_spinCtrlSmoothLevel->Enable( enable ); + m_spinCtrlSmoothValue->Enable( enable ); +} diff --git a/pcbnew/zone_manager/panel_zone_properties.h b/pcbnew/zone_manager/panel_zone_properties.h new file mode 100644 index 0000000000..fb80ed0e6f --- /dev/null +++ b/pcbnew/zone_manager/panel_zone_properties.h @@ -0,0 +1,106 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck + * Copyright (C) 1992-2022 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 PANEL_ZONE_PROPERTIES_H +#define PANEL_ZONE_PROPERTIES_H + + +#include "widgets/unit_binder.h" +#include "zone_manager/panel_zone_properties_base.h" +#include "zone_management_base.h" + +#include "zone_manager/zone_selection_change_notifier.h" +#include +#include + +wxDECLARE_EVENT( EVT_ZONE_NAME_UPDATE, wxCommandEvent ); + + +class PCB_BASE_FRAME; +class ZONES_CONTAINER; +class PANEL_ZONE_PROPERTIES : public PANEL_ZONE_PROPERTIES_BASE, + public ZONE_SELECTION_CHANGE_NOTIFIER, + public ZONE_MANAGEMENT_BASE +{ +public: + PANEL_ZONE_PROPERTIES( wxWindow* aParent, PCB_BASE_FRAME* aPcb, + ZONES_CONTAINER& aZoneContainer ); + + + void ActivateSelectedZone( ZONE* new_zone ) override; + + void OnUserConfirmChange() override; + + std::shared_ptr GetZoneSettings() const { return m_settings; } + + +private: + static constexpr int INVALID_NET_CODE{ 0 }; + + static constexpr int DEFAULT_SORT_CONFIG{ -1 }; + static constexpr int NO_PERSISTENT_SORT_MODE{ 0 }; + static constexpr int HIDE_ANONYMOUS_NETS{ 1 << 0 }; + static constexpr int SORT_BY_PAD_COUNT{ 1 << 1 }; + + bool TransferZoneSettingsToWindow(); + bool TransferZoneSettingsFromWindow(); + + /** + * @param aUseExportableSetupOnly is true to use exportable parameters only (used to + * export this setup to other zones). + * @return bool - false if incorrect options, true if ok. + */ + bool AcceptOptions( bool aUseExportableSetupOnly = false ); + + void OnStyleSelection( wxCommandEvent& event ) override; + void OnUpdateUI( wxUpdateUIEvent& ) override; + void OnRemoveIslandsSelection( wxCommandEvent& event ) override; + void OnZoneNameChanged( wxCommandEvent& event ) override; + + +private: + ZONES_CONTAINER& m_ZoneContainer; + PCB_BASE_FRAME* m_PCB_Frame; + + std::shared_ptr m_settings; + + int m_cornerSmoothingType; + UNIT_BINDER m_outlineHatchPitch; + + UNIT_BINDER m_cornerRadius; + UNIT_BINDER m_clearance; + UNIT_BINDER m_minThickness; + UNIT_BINDER m_antipadClearance; + UNIT_BINDER m_spokeWidth; + + UNIT_BINDER m_gridStyleRotation; + UNIT_BINDER m_gridStyleThickness; + UNIT_BINDER m_gridStyleGap; + UNIT_BINDER m_islandThreshold; + bool m_isTeardrop; +}; + + +#endif \ No newline at end of file diff --git a/pcbnew/zone_manager/panel_zone_properties_base.cpp b/pcbnew/zone_manager/panel_zone_properties_base.cpp new file mode 100644 index 0000000000..40d6779bb4 --- /dev/null +++ b/pcbnew/zone_manager/panel_zone_properties_base.cpp @@ -0,0 +1,485 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf) +// http://www.wxformbuilder.org/ +// +// PLEASE DO *NOT* EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "panel_zone_properties_base.h" + +/////////////////////////////////////////////////////////////////////////// + +PANEL_ZONE_PROPERTIES_BASE::PANEL_ZONE_PROPERTIES_BASE( wxWindow* parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, + long style, const wxString& name ) : + wxPanel( parent, id, pos, size, style, name ) +{ + wxBoxSizer* bSizerMiddle; + bSizerMiddle = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bLeftColumn; + bLeftColumn = new wxBoxSizer( wxVERTICAL ); + + wxStaticBoxSizer* sbGeneral; + sbGeneral = + new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _( "General" ) ), wxHORIZONTAL ); + + wxFlexGridSizer* fgSizer1; + fgSizer1 = new wxFlexGridSizer( 0, 2, 0, 0 ); + fgSizer1->AddGrowableCol( 1 ); + fgSizer1->SetFlexibleDirection( wxBOTH ); + fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + m_zoneNameLabel = new wxStaticText( sbGeneral->GetStaticBox(), wxID_ANY, _( "Zone name:" ), + wxDefaultPosition, wxDefaultSize, 0 ); + m_zoneNameLabel->Wrap( -1 ); + m_zoneNameLabel->SetToolTip( _( "A unique name for this zone to identify it for DRC" ) ); + + fgSizer1->Add( m_zoneNameLabel, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 5 ); + + m_tcZoneName = new wxTextCtrl( sbGeneral->GetStaticBox(), EDIT_ZONE_NAME, wxEmptyString, + wxDefaultPosition, wxDefaultSize, 0 ); + fgSizer1->Add( m_tcZoneName, 0, + wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxRIGHT | wxLEFT | wxEXPAND, 5 ); + + + sbGeneral->Add( fgSizer1, 1, wxEXPAND | wxBOTTOM, 5 ); + + + bLeftColumn->Add( sbGeneral, 0, wxEXPAND | wxTOP | wxRIGHT | wxLEFT, 10 ); + + wxStaticBoxSizer* m_ExportableSetupSizer; + m_ExportableSetupSizer = + new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _( "Shape" ) ), wxHORIZONTAL ); + + wxGridBagSizer* gbSizer1; + gbSizer1 = new wxGridBagSizer( 5, 5 ); + gbSizer1->SetFlexibleDirection( wxBOTH ); + gbSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + m_cbLocked = new wxCheckBox( m_ExportableSetupSizer->GetStaticBox(), wxID_ANY, _( "Locked" ), + wxDefaultPosition, wxDefaultSize, 0 ); + gbSizer1->Add( m_cbLocked, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxBOTTOM | wxRIGHT, 5 ); + + m_staticTextStyle = + new wxStaticText( m_ExportableSetupSizer->GetStaticBox(), wxID_ANY, + _( "Outline display:" ), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextStyle->Wrap( -1 ); + gbSizer1->Add( m_staticTextStyle, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 5 ); + + wxString m_OutlineDisplayCtrlChoices[] = { _( "Line" ), _( "Hatched" ), _( "Fully hatched" ) }; + int m_OutlineDisplayCtrlNChoices = sizeof( m_OutlineDisplayCtrlChoices ) / sizeof( wxString ); + m_OutlineDisplayCtrl = new wxChoice( + m_ExportableSetupSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, + m_OutlineDisplayCtrlNChoices, m_OutlineDisplayCtrlChoices, 0 ); + m_OutlineDisplayCtrl->SetSelection( 0 ); + gbSizer1->Add( m_OutlineDisplayCtrl, wxGBPosition( 1, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 ); + + m_stBorderHatchPitchText = + new wxStaticText( m_ExportableSetupSizer->GetStaticBox(), wxID_ANY, + _( "Outline hatch pitch:" ), wxDefaultPosition, wxDefaultSize, 0 ); + m_stBorderHatchPitchText->Wrap( -1 ); + gbSizer1->Add( m_stBorderHatchPitchText, wxGBPosition( 2, 0 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxLEFT, 5 ); + + m_outlineHatchPitchCtrl = + new wxTextCtrl( m_ExportableSetupSizer->GetStaticBox(), ID_M_CORNERSMOOTHINGCTRL, + wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + gbSizer1->Add( m_outlineHatchPitchCtrl, wxGBPosition( 2, 1 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxEXPAND, 5 ); + + m_outlineHatchUnits = new wxStaticText( m_ExportableSetupSizer->GetStaticBox(), wxID_ANY, + _( "mm" ), wxDefaultPosition, wxDefaultSize, 0 ); + m_outlineHatchUnits->Wrap( -1 ); + gbSizer1->Add( m_outlineHatchUnits, wxGBPosition( 2, 2 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL, 5 ); + + m_staticline4 = new wxStaticLine( m_ExportableSetupSizer->GetStaticBox(), wxID_ANY, + wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + gbSizer1->Add( m_staticline4, wxGBPosition( 3, 0 ), wxGBSpan( 1, 3 ), wxEXPAND | wxALL, 5 ); + + m_staticTextSmoothing = + new wxStaticText( m_ExportableSetupSizer->GetStaticBox(), wxID_ANY, + _( "Corner smoothing:" ), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextSmoothing->Wrap( -1 ); + gbSizer1->Add( m_staticTextSmoothing, wxGBPosition( 4, 0 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxLEFT, 5 ); + + wxString m_cornerSmoothingChoiceChoices[] = { _( "None" ), _( "Chamfer" ), _( "Fillet" ) }; + int m_cornerSmoothingChoiceNChoices = + sizeof( m_cornerSmoothingChoiceChoices ) / sizeof( wxString ); + m_cornerSmoothingChoice = new wxChoice( + m_ExportableSetupSizer->GetStaticBox(), ID_CORNER_SMOOTHING, wxDefaultPosition, + wxDefaultSize, m_cornerSmoothingChoiceNChoices, m_cornerSmoothingChoiceChoices, 0 ); + m_cornerSmoothingChoice->SetSelection( 1 ); + gbSizer1->Add( m_cornerSmoothingChoice, wxGBPosition( 4, 1 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxEXPAND, 5 ); + + m_cornerRadiusLabel = + new wxStaticText( m_ExportableSetupSizer->GetStaticBox(), wxID_ANY, + _( "Chamfer distance:" ), wxDefaultPosition, wxDefaultSize, 0 ); + m_cornerRadiusLabel->Wrap( -1 ); + gbSizer1->Add( m_cornerRadiusLabel, wxGBPosition( 5, 0 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxLEFT, 5 ); + + m_cornerRadiusCtrl = + new wxTextCtrl( m_ExportableSetupSizer->GetStaticBox(), ID_M_CORNERSMOOTHINGCTRL, + wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + gbSizer1->Add( m_cornerRadiusCtrl, wxGBPosition( 5, 1 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxEXPAND, 5 ); + + m_cornerRadiusUnits = new wxStaticText( m_ExportableSetupSizer->GetStaticBox(), wxID_ANY, + _( "mm" ), wxDefaultPosition, wxDefaultSize, 0 ); + m_cornerRadiusUnits->Wrap( -1 ); + gbSizer1->Add( m_cornerRadiusUnits, wxGBPosition( 5, 2 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL, 5 ); + + + gbSizer1->AddGrowableCol( 0 ); + + m_ExportableSetupSizer->Add( gbSizer1, 1, wxEXPAND | wxBOTTOM | wxRIGHT, 5 ); + + + bLeftColumn->Add( m_ExportableSetupSizer, 1, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 10 ); + + + bSizerMiddle->Add( bLeftColumn, 1, wxEXPAND, 5 ); + + wxBoxSizer* bMiddleColumn; + bMiddleColumn = new wxBoxSizer( wxVERTICAL ); + + wxStaticBoxSizer* sbSizer5; + sbSizer5 = new wxStaticBoxSizer( + new wxStaticBox( this, wxID_ANY, _( "Electrical Properties" ) ), wxVERTICAL ); + + wxGridBagSizer* gbSizerSettings; + gbSizerSettings = new wxGridBagSizer( 0, 0 ); + gbSizerSettings->SetFlexibleDirection( wxBOTH ); + gbSizerSettings->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + m_clearanceLabel = new wxStaticText( sbSizer5->GetStaticBox(), wxID_ANY, _( "Clearance:" ), + wxDefaultPosition, wxDefaultSize, 0 ); + m_clearanceLabel->Wrap( -1 ); + m_clearanceLabel->SetToolTip( + _( "Copper clearance for this zone (set to 0 to use the netclass clearance)" ) ); + + gbSizerSettings->Add( m_clearanceLabel, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxLEFT, 5 ); + + m_clearanceCtrl = new wxTextCtrl( sbSizer5->GetStaticBox(), wxID_ANY, wxEmptyString, + wxDefaultPosition, wxDefaultSize, 0 ); + gbSizerSettings->Add( m_clearanceCtrl, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), + wxEXPAND | wxBOTTOM | wxRIGHT | wxLEFT, 5 ); + + m_clearanceUnits = new wxStaticText( sbSizer5->GetStaticBox(), wxID_ANY, _( "mm" ), + wxDefaultPosition, wxDefaultSize, 0 ); + m_clearanceUnits->Wrap( -1 ); + gbSizerSettings->Add( m_clearanceUnits, wxGBPosition( 0, 2 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxRIGHT, 5 ); + + m_minWidthLabel = new wxStaticText( sbSizer5->GetStaticBox(), wxID_ANY, _( "Minimum width:" ), + wxDefaultPosition, wxDefaultSize, 0 ); + m_minWidthLabel->Wrap( -1 ); + m_minWidthLabel->SetToolTip( _( "Minimum thickness of filled areas." ) ); + + gbSizerSettings->Add( m_minWidthLabel, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxLEFT, 5 ); + + m_minWidthCtrl = new wxTextCtrl( sbSizer5->GetStaticBox(), wxID_ANY, wxEmptyString, + wxDefaultPosition, wxDefaultSize, 0 ); + gbSizerSettings->Add( m_minWidthCtrl, wxGBPosition( 1, 1 ), wxGBSpan( 1, 1 ), + wxEXPAND | wxBOTTOM | wxRIGHT | wxLEFT, 5 ); + + m_minWidthUnits = new wxStaticText( sbSizer5->GetStaticBox(), wxID_ANY, _( "mm" ), + wxDefaultPosition, wxDefaultSize, 0 ); + m_minWidthUnits->Wrap( -1 ); + gbSizerSettings->Add( m_minWidthUnits, wxGBPosition( 1, 2 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxRIGHT, 5 ); + + m_staticline2 = new wxStaticLine( sbSizer5->GetStaticBox(), wxID_ANY, wxDefaultPosition, + wxDefaultSize, wxLI_HORIZONTAL ); + gbSizerSettings->Add( m_staticline2, wxGBPosition( 2, 0 ), wxGBSpan( 1, 3 ), + wxBOTTOM | wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 5 ); + + m_connectionLabel = + new wxStaticText( sbSizer5->GetStaticBox(), wxID_ANY, _( "Pad connections:" ), + wxDefaultPosition, wxDefaultSize, 0 ); + m_connectionLabel->Wrap( -1 ); + m_connectionLabel->SetToolTip( _( "Default pad connection type to zone.\nThis setting can be " + "overridden by local pad settings" ) ); + + gbSizerSettings->Add( m_connectionLabel, wxGBPosition( 3, 0 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxTOP | wxLEFT, 5 ); + + wxString m_PadInZoneOptChoices[] = { _( "Solid" ), _( "Thermal reliefs" ), + _( "Reliefs for PTH" ), _( "None" ) }; + int m_PadInZoneOptNChoices = sizeof( m_PadInZoneOptChoices ) / sizeof( wxString ); + m_PadInZoneOpt = + new wxChoice( sbSizer5->GetStaticBox(), ID_M_PADINZONEOPT, wxDefaultPosition, + wxDefaultSize, m_PadInZoneOptNChoices, m_PadInZoneOptChoices, 0 ); + m_PadInZoneOpt->SetSelection( 0 ); + gbSizerSettings->Add( m_PadInZoneOpt, wxGBPosition( 3, 1 ), wxGBSpan( 1, 1 ), + wxEXPAND | wxTOP | wxRIGHT | wxLEFT | wxALIGN_CENTER_VERTICAL, 5 ); + + m_antipadLabel = + new wxStaticText( sbSizer5->GetStaticBox(), wxID_ANY, _( "Thermal relief gap:" ), + wxDefaultPosition, wxDefaultSize, 0 ); + m_antipadLabel->Wrap( -1 ); + m_antipadLabel->SetToolTip( _( "The distance that will be kept clear between the filled area " + "of the zone and a pad connected by thermal relief spokes." ) ); + + gbSizerSettings->Add( m_antipadLabel, wxGBPosition( 4, 0 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxLEFT | wxTOP, 5 ); + + m_antipadCtrl = new wxTextCtrl( sbSizer5->GetStaticBox(), wxID_ANTIPAD_SIZE, wxEmptyString, + wxDefaultPosition, wxDefaultSize, 0 ); + m_antipadCtrl->SetToolTip( _( "Clearance between pads in the same net and filled areas." ) ); + + gbSizerSettings->Add( m_antipadCtrl, wxGBPosition( 4, 1 ), wxGBSpan( 1, 1 ), + wxEXPAND | wxTOP | wxRIGHT | wxLEFT, 5 ); + + m_antipadUnits = new wxStaticText( sbSizer5->GetStaticBox(), wxID_ANY, _( "mm" ), + wxDefaultPosition, wxDefaultSize, 0 ); + m_antipadUnits->Wrap( -1 ); + gbSizerSettings->Add( m_antipadUnits, wxGBPosition( 4, 2 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxTOP | wxRIGHT, 5 ); + + m_spokeWidthLabel = + new wxStaticText( sbSizer5->GetStaticBox(), wxID_ANY, _( "Thermal spoke width:" ), + wxDefaultPosition, wxDefaultSize, 0 ); + m_spokeWidthLabel->Wrap( -1 ); + gbSizerSettings->Add( m_spokeWidthLabel, wxGBPosition( 5, 0 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxLEFT | wxTOP, 5 ); + + m_spokeWidthCtrl = new wxTextCtrl( sbSizer5->GetStaticBox(), wxID_COPPER_BRIDGE_VALUE, + wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_spokeWidthCtrl->SetToolTip( _( "Width of copper in thermal reliefs." ) ); + + gbSizerSettings->Add( m_spokeWidthCtrl, wxGBPosition( 5, 1 ), wxGBSpan( 1, 1 ), + wxEXPAND | wxALL, 5 ); + + m_spokeWidthUnits = new wxStaticText( sbSizer5->GetStaticBox(), wxID_ANY, _( "mm" ), + wxDefaultPosition, wxDefaultSize, 0 ); + m_spokeWidthUnits->Wrap( -1 ); + gbSizerSettings->Add( m_spokeWidthUnits, wxGBPosition( 5, 2 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM | wxRIGHT, 5 ); + + + gbSizerSettings->AddGrowableCol( 1 ); + + sbSizer5->Add( gbSizerSettings, 0, wxEXPAND, 5 ); + + + bMiddleColumn->Add( sbSizer5, 1, wxEXPAND | wxRIGHT | wxTOP, 10 ); + + + bSizerMiddle->Add( bMiddleColumn, 1, wxEXPAND, 5 ); + + wxStaticBoxSizer* sbSizerZoneStyle; + sbSizerZoneStyle = + new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _( "Fill" ) ), wxVERTICAL ); + + wxGridBagSizer* gbSizer3; + gbSizer3 = new wxGridBagSizer( 0, 0 ); + gbSizer3->SetFlexibleDirection( wxBOTH ); + gbSizer3->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + gbSizer3->SetEmptyCellSize( wxSize( -1, 10 ) ); + + m_staticTextGridFillType = + new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, _( "Fill type:" ), + wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextGridFillType->Wrap( -1 ); + gbSizer3->Add( m_staticTextGridFillType, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxLEFT, 5 ); + + wxString m_GridStyleCtrlChoices[] = { _( "Solid fill" ), _( "Hatch pattern" ) }; + int m_GridStyleCtrlNChoices = sizeof( m_GridStyleCtrlChoices ) / sizeof( wxString ); + m_GridStyleCtrl = + new wxChoice( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, wxDefaultPosition, + wxDefaultSize, m_GridStyleCtrlNChoices, m_GridStyleCtrlChoices, 0 ); + m_GridStyleCtrl->SetSelection( 0 ); + gbSizer3->Add( m_GridStyleCtrl, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxEXPAND | wxRIGHT | wxLEFT, 5 ); + + m_staticTextGrindOrient = + new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, _( "Orientation:" ), + wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextGrindOrient->Wrap( -1 ); + gbSizer3->Add( m_staticTextGrindOrient, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxLEFT | wxTOP, 5 ); + + m_tcGridStyleOrientation = new wxTextCtrl( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, + wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + gbSizer3->Add( m_tcGridStyleOrientation, wxGBPosition( 1, 1 ), wxGBSpan( 1, 1 ), + wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 5 ); + + m_staticTextRotUnits = new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, _( "deg" ), + wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextRotUnits->Wrap( -1 ); + gbSizer3->Add( m_staticTextRotUnits, wxGBPosition( 1, 2 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM | wxRIGHT, 5 ); + + m_staticTextStyleThickness = + new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, _( "Hatch width:" ), + wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextStyleThickness->Wrap( -1 ); + gbSizer3->Add( m_staticTextStyleThickness, wxGBPosition( 2, 0 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxLEFT, 5 ); + + m_tcGridStyleThickness = new wxTextCtrl( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, + wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + gbSizer3->Add( m_tcGridStyleThickness, wxGBPosition( 2, 1 ), wxGBSpan( 1, 1 ), + wxEXPAND | wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxRIGHT | wxLEFT, 5 ); + + m_GridStyleThicknessUnits = new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, + _( "mm" ), wxDefaultPosition, wxDefaultSize, 0 ); + m_GridStyleThicknessUnits->Wrap( -1 ); + gbSizer3->Add( m_GridStyleThicknessUnits, wxGBPosition( 2, 2 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxRIGHT, 5 ); + + m_staticTextGridGap = + new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, _( "Hatch gap:" ), + wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextGridGap->Wrap( -1 ); + gbSizer3->Add( m_staticTextGridGap, wxGBPosition( 3, 0 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxLEFT, 5 ); + + m_tcGridStyleGap = new wxTextCtrl( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, wxEmptyString, + wxDefaultPosition, wxDefaultSize, 0 ); + gbSizer3->Add( m_tcGridStyleGap, wxGBPosition( 3, 1 ), wxGBSpan( 1, 1 ), + wxEXPAND | wxBOTTOM | wxRIGHT | wxLEFT | wxALIGN_CENTER_VERTICAL, 5 ); + + m_GridStyleGapUnits = new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, _( "mm" ), + wxDefaultPosition, wxDefaultSize, 0 ); + m_GridStyleGapUnits->Wrap( -1 ); + gbSizer3->Add( m_GridStyleGapUnits, wxGBPosition( 3, 2 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxRIGHT, 5 ); + + m_staticTextGridSmoothingLevel = + new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, _( "Smoothing effort:" ), + wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextGridSmoothingLevel->Wrap( -1 ); + m_staticTextGridSmoothingLevel->SetToolTip( + _( "Value of smoothing effort\n0 = no smoothing\n1 = chamfer\n2 = round corners\n3 = " + "round corners (finer shape)" ) ); + + gbSizer3->Add( m_staticTextGridSmoothingLevel, wxGBPosition( 4, 0 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxLEFT, 5 ); + + m_spinCtrlSmoothLevel = + new wxSpinCtrl( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, wxEmptyString, + wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 3, 0 ); + gbSizer3->Add( m_spinCtrlSmoothLevel, wxGBPosition( 4, 1 ), wxGBSpan( 1, 1 ), + wxBOTTOM | wxRIGHT | wxLEFT | wxALIGN_CENTER_VERTICAL | wxEXPAND, 5 ); + + m_staticTextGridSmootingVal = + new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, _( "Smoothing amount:" ), + wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextGridSmootingVal->Wrap( -1 ); + m_staticTextGridSmootingVal->SetToolTip( + _( "Ratio between smoothed corners size and the gap between lines\n0 = no " + "smoothing\n1.0 = max radius/chamfer size (half gap value)" ) ); + + gbSizer3->Add( m_staticTextGridSmootingVal, wxGBPosition( 5, 0 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxLEFT, 5 ); + + m_spinCtrlSmoothValue = new wxSpinCtrlDouble( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, + wxEmptyString, wxDefaultPosition, wxDefaultSize, + wxSP_ARROW_KEYS, 0, 1, 0.1, 0.1 ); + m_spinCtrlSmoothValue->SetDigits( 2 ); + gbSizer3->Add( m_spinCtrlSmoothValue, wxGBPosition( 5, 1 ), wxGBSpan( 1, 1 ), + wxBOTTOM | wxRIGHT | wxLEFT | wxALIGN_CENTER_VERTICAL | wxEXPAND, 5 ); + + m_staticline5 = new wxStaticLine( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, wxDefaultPosition, + wxDefaultSize, wxLI_HORIZONTAL ); + gbSizer3->Add( m_staticline5, wxGBPosition( 6, 0 ), wxGBSpan( 1, 3 ), + wxBOTTOM | wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 5 ); + + m_staticText40 = + new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, _( "Remove islands:" ), + wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText40->Wrap( -1 ); + m_staticText40->SetToolTip( _( "Choose what to do with unconnected copper islands" ) ); + + gbSizer3->Add( m_staticText40, wxGBPosition( 7, 0 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxLEFT | wxTOP, 5 ); + + wxString m_cbRemoveIslandsChoices[] = { _( "Always" ), _( "Never" ), _( "Below area limit" ) }; + int m_cbRemoveIslandsNChoices = sizeof( m_cbRemoveIslandsChoices ) / sizeof( wxString ); + m_cbRemoveIslands = + new wxChoice( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, wxDefaultPosition, + wxDefaultSize, m_cbRemoveIslandsNChoices, m_cbRemoveIslandsChoices, 0 ); + m_cbRemoveIslands->SetSelection( 0 ); + gbSizer3->Add( m_cbRemoveIslands, wxGBPosition( 7, 1 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxALL, 5 ); + + m_islandThresholdLabel = + new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, + _( "Minimum island size:" ), wxDefaultPosition, wxDefaultSize, 0 ); + m_islandThresholdLabel->Wrap( -1 ); + m_islandThresholdLabel->Enable( false ); + m_islandThresholdLabel->SetToolTip( _( "Isolated islands smaller than this will be removed" ) ); + + gbSizer3->Add( m_islandThresholdLabel, wxGBPosition( 8, 0 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxLEFT, 5 ); + + m_tcIslandThreshold = new wxTextCtrl( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, wxEmptyString, + wxDefaultPosition, wxDefaultSize, 0 ); + m_tcIslandThreshold->Enable( false ); + + gbSizer3->Add( m_tcIslandThreshold, wxGBPosition( 8, 1 ), wxGBSpan( 1, 1 ), + wxEXPAND | wxBOTTOM | wxRIGHT | wxLEFT | wxALIGN_CENTER_VERTICAL, 5 ); + + m_islandThresholdUnits = new wxStaticText( sbSizerZoneStyle->GetStaticBox(), wxID_ANY, + _( "mm" ), wxDefaultPosition, wxDefaultSize, 0 ); + m_islandThresholdUnits->Wrap( -1 ); + m_islandThresholdUnits->Enable( false ); + + gbSizer3->Add( m_islandThresholdUnits, wxGBPosition( 8, 2 ), wxGBSpan( 1, 1 ), + wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxRIGHT, 5 ); + + + gbSizer3->AddGrowableCol( 0 ); + + sbSizerZoneStyle->Add( gbSizer3, 1, wxEXPAND | wxBOTTOM, 5 ); + + + bSizerMiddle->Add( sbSizerZoneStyle, 1, wxEXPAND | wxTOP | wxRIGHT, 10 ); + + + this->SetSizer( bSizerMiddle ); + this->Layout(); + bSizerMiddle->Fit( this ); + + // Connect Events + this->Connect( wxEVT_UPDATE_UI, + wxUpdateUIEventHandler( PANEL_ZONE_PROPERTIES_BASE::OnUpdateUI ) ); + m_tcZoneName->Connect( wxEVT_COMMAND_TEXT_UPDATED, + wxCommandEventHandler( PANEL_ZONE_PROPERTIES_BASE::OnZoneNameChanged ), + NULL, this ); + m_GridStyleCtrl->Connect( wxEVT_COMMAND_CHOICE_SELECTED, + wxCommandEventHandler( PANEL_ZONE_PROPERTIES_BASE::OnStyleSelection ), + NULL, this ); + m_cbRemoveIslands->Connect( + wxEVT_COMMAND_CHOICE_SELECTED, + wxCommandEventHandler( PANEL_ZONE_PROPERTIES_BASE::OnRemoveIslandsSelection ), NULL, + this ); +} + +PANEL_ZONE_PROPERTIES_BASE::~PANEL_ZONE_PROPERTIES_BASE() +{ + // Disconnect Events + this->Disconnect( wxEVT_UPDATE_UI, + wxUpdateUIEventHandler( PANEL_ZONE_PROPERTIES_BASE::OnUpdateUI ) ); + m_tcZoneName->Disconnect( + wxEVT_COMMAND_TEXT_UPDATED, + wxCommandEventHandler( PANEL_ZONE_PROPERTIES_BASE::OnZoneNameChanged ), NULL, this ); + m_GridStyleCtrl->Disconnect( + wxEVT_COMMAND_CHOICE_SELECTED, + wxCommandEventHandler( PANEL_ZONE_PROPERTIES_BASE::OnStyleSelection ), NULL, this ); + m_cbRemoveIslands->Disconnect( + wxEVT_COMMAND_CHOICE_SELECTED, + wxCommandEventHandler( PANEL_ZONE_PROPERTIES_BASE::OnRemoveIslandsSelection ), NULL, + this ); +} diff --git a/pcbnew/zone_manager/panel_zone_properties_base.fbp b/pcbnew/zone_manager/panel_zone_properties_base.fbp new file mode 100644 index 0000000000..3f78f9a49f --- /dev/null +++ b/pcbnew/zone_manager/panel_zone_properties_base.fbp @@ -0,0 +1,3505 @@ + + + + + + C++ + 1 + source_name + 0 + 0 + res + UTF-8 + connect + panel_zone_properties_base + 1000 + none + + + 1 + panel_zone_properties_base + + . + + 1 + 1 + 1 + 1 + UI + 0 + 1 + 0 + + 0 + wxAUI_MGR_DEFAULT + + + 1 + 0 + 1 + impl_virtual + + + 0 + wxID_ANY + + + PANEL_ZONE_PROPERTIES_BASE + + -1,-1 + ; ; forward_declare + + 0 + + + wxTAB_TRAVERSAL + OnUpdateUI + + + bSizerMiddle + wxHORIZONTAL + none + + 5 + wxEXPAND + 0 + + + bLeftColumn + wxVERTICAL + none + + 10 + wxEXPAND|wxTOP|wxRIGHT|wxLEFT + 0 + + wxID_ANY + General + + sbGeneral + wxHORIZONTAL + 1 + none + + 5 + wxEXPAND|wxBOTTOM + 1 + + 2 + wxBOTH + 1 + + 0 + + fgSizer1 + wxFLEX_GROWMODE_SPECIFIED + none + 0 + 0 + + 5 + wxALIGN_CENTER_VERTICAL|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Zone name: + 0 + + 0 + + + 0 + + 1 + m_zoneNameLabel + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + A unique name for this zone to identify it for DRC + + + + -1 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + EDIT_ZONE_NAME + + 0 + + + + 0 + + 1 + m_tcZoneName + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + OnZoneNameChanged + + + + + + + + 10 + wxEXPAND|wxLEFT|wxRIGHT|wxTOP + 1 + + wxID_ANY + Shape + + m_ExportableSetupSizer + wxHORIZONTAL + 1 + none + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT + 1 + + -1,-1 + wxBOTH + 0 + + 5 + + gbSizer1 + wxFLEX_GROWMODE_SPECIFIED + none + 5 + + 5 + 1 + 0 + wxBOTTOM|wxRIGHT + 0 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Locked + + 0 + + + 0 + + 1 + m_cbLocked + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT + 1 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Outline display: + 0 + + 0 + + + 0 + + 1 + m_staticTextStyle + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + 5 + 1 + 1 + wxALL + 1 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + "Line" "Hatched" "Fully hatched" + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_OutlineDisplayCtrl + 1 + + + protected + 1 + + Resizable + 0 + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxLEFT + 2 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Outline hatch pitch: + 0 + + 0 + + + 0 + + 1 + m_stBorderHatchPitchText + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + 5 + 1 + 1 + wxALIGN_CENTER_VERTICAL|wxEXPAND + 2 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + ID_M_CORNERSMOOTHINGCTRL + + 0 + + 0 + + 0 + -1,-1 + 1 + m_outlineHatchPitchCtrl + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + 1 + 2 + wxALIGN_CENTER_VERTICAL + 2 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + mm + 0 + + 0 + + + 0 + + 1 + m_outlineHatchUnits + 1 + + + protected + 1 + + Resizable + 1 + + + ; forward_declare + 0 + + + + + -1 + + + + 5 + 3 + 0 + wxEXPAND | wxALL + 3 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_staticline4 + 1 + + + protected + 1 + + Resizable + 1 + + wxLI_HORIZONTAL + ; ; forward_declare + 0 + + + + + + + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxLEFT + 4 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Corner smoothing: + 0 + + 0 + + + 0 + + 1 + m_staticTextSmoothing + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + 5 + 1 + 1 + wxALIGN_CENTER_VERTICAL|wxEXPAND + 4 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + "None" "Chamfer" "Fillet" + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + ID_CORNER_SMOOTHING + + 0 + + + 0 + + 1 + m_cornerSmoothingChoice + 1 + + + protected + 1 + + Resizable + 1 + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxLEFT + 5 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Chamfer distance: + 0 + + 0 + + + 0 + + 1 + m_cornerRadiusLabel + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + 5 + 1 + 1 + wxALIGN_CENTER_VERTICAL|wxEXPAND + 5 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + ID_M_CORNERSMOOTHINGCTRL + + 0 + + 0 + + 0 + -1,-1 + 1 + m_cornerRadiusCtrl + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + 1 + 2 + wxALIGN_CENTER_VERTICAL + 5 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + mm + 0 + + 0 + + + 0 + + 1 + m_cornerRadiusUnits + 1 + + + protected + 1 + + Resizable + 1 + + + ; forward_declare + 0 + + + + + -1 + + + + + + + + + + 5 + wxEXPAND + 1 + + + bMiddleColumn + wxVERTICAL + none + + 10 + wxEXPAND|wxRIGHT|wxTOP + 1 + + wxID_ANY + Electrical Properties + + sbSizer5 + wxVERTICAL + 1 + none + + 5 + wxEXPAND + 0 + + + wxBOTH + 1 + + 0 + + gbSizerSettings + wxFLEX_GROWMODE_SPECIFIED + none + 0 + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT + 0 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Clearance: + 0 + + 0 + + + 0 + + 1 + m_clearanceLabel + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Copper clearance for this zone (set to 0 to use the netclass clearance) + + + + -1 + + + + 5 + 1 + 1 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 0 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 0 + + 0 + -1,-1 + 1 + m_clearanceCtrl + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + 1 + 2 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT + 0 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + mm + 0 + + 0 + + + 0 + + 1 + m_clearanceUnits + 1 + + + protected + 1 + + Resizable + 1 + + + ; forward_declare + 0 + + + + + -1 + + + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT + 1 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Minimum width: + 0 + + 0 + + + 0 + + 1 + m_minWidthLabel + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Minimum thickness of filled areas. + + + + -1 + + + + 5 + 1 + 1 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 1 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 0 + + 0 + + 1 + m_minWidthCtrl + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + 1 + 2 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT + 1 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + mm + 0 + + 0 + + + 0 + + 1 + m_minWidthUnits + 1 + + + protected + 1 + + Resizable + 1 + + + ; forward_declare + 0 + + + + + -1 + + + + 5 + 3 + 0 + wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP + 2 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_staticline2 + 1 + + + protected + 1 + + Resizable + 1 + + wxLI_HORIZONTAL + ; ; forward_declare + 0 + + + + + + + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT + 3 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Pad connections: + 0 + + 0 + + + 0 + + 1 + m_connectionLabel + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Default pad connection type to zone. This setting can be overridden by local pad settings + + + + -1 + + + + 5 + 1 + 1 + wxEXPAND|wxTOP|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL + 3 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + "Solid" "Thermal reliefs" "Reliefs for PTH" "None" + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + ID_M_PADINZONEOPT + + 0 + + + 0 + + 1 + m_PadInZoneOpt + 1 + + + protected + 1 + + Resizable + 0 + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP + 4 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Thermal relief gap: + 0 + + 0 + + + 0 + + 1 + m_antipadLabel + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + The distance that will be kept clear between the filled area of the zone and a pad connected by thermal relief spokes. + + + + -1 + + + + 5 + 1 + 1 + wxEXPAND|wxTOP|wxRIGHT|wxLEFT + 4 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANTIPAD_SIZE + + 0 + + 0 + + 0 + + 1 + m_antipadCtrl + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Clearance between pads in the same net and filled areas. + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + 1 + 2 + wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT + 4 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + mm + 0 + + 0 + + + 0 + + 1 + m_antipadUnits + 1 + + + protected + 1 + + Resizable + 1 + + + ; forward_declare + 0 + + + + + -1 + + + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP + 5 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Thermal spoke width: + 0 + + 0 + + + 0 + + 1 + m_spokeWidthLabel + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + 5 + 1 + 1 + wxEXPAND|wxALL + 5 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_COPPER_BRIDGE_VALUE + + 0 + + 0 + + 0 + + 1 + m_spokeWidthCtrl + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Width of copper in thermal reliefs. + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + 1 + 2 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT + 5 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + mm + 0 + + 0 + + + 0 + + 1 + m_spokeWidthUnits + 1 + + + protected + 1 + + Resizable + 1 + + + ; forward_declare + 0 + + + + + -1 + + + + + + + + + + 10 + wxEXPAND|wxTOP|wxRIGHT + 0 + + wxID_ANY + Fill + + sbSizerZoneStyle + wxVERTICAL + 1 + none + + 5 + wxEXPAND|wxBOTTOM + 1 + + -1,10 + wxBOTH + 0 + + 0 + + gbSizer3 + wxFLEX_GROWMODE_SPECIFIED + none + 0 + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxLEFT + 0 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Fill type: + 0 + + 0 + + + 0 + + 1 + m_staticTextGridFillType + 1 + + + protected + 1 + + Resizable + 1 + + + ; forward_declare + 0 + + + + + -1 + + + + 5 + 1 + 1 + wxALIGN_CENTER_VERTICAL|wxEXPAND|wxRIGHT|wxLEFT + 0 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + "Solid fill" "Hatch pattern" + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_GridStyleCtrl + 1 + + + protected + 1 + + Resizable + 0 + 1 + + + ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnStyleSelection + + + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP + 1 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Orientation: + 0 + + 0 + + + 0 + + 1 + m_staticTextGrindOrient + 1 + + + protected + 1 + + Resizable + 1 + + + ; forward_declare + 0 + + + + + -1 + + + + 5 + 1 + 1 + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 1 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_tcGridStyleOrientation + 1 + + + protected + 1 + + Resizable + 1 + + + ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + 1 + 2 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT + 1 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + deg + 0 + + 0 + + + 0 + + 1 + m_staticTextRotUnits + 1 + + + protected + 1 + + Resizable + 1 + + + ; forward_declare + 0 + + + + + -1 + + + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT + 2 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Hatch width: + 0 + + 0 + + + 0 + + 1 + m_staticTextStyleThickness + 1 + + + protected + 1 + + Resizable + 1 + + + ; forward_declare + 0 + + + + + -1 + + + + 5 + 1 + 1 + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT + 2 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_tcGridStyleThickness + 1 + + + protected + 1 + + Resizable + 1 + + + ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + 1 + 2 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT + 2 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + mm + 0 + + 0 + + + 0 + + 1 + m_GridStyleThicknessUnits + 1 + + + protected + 1 + + Resizable + 1 + + + ; forward_declare + 0 + + + + + -1 + + + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT + 3 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Hatch gap: + 0 + + 0 + + + 0 + + 1 + m_staticTextGridGap + 1 + + + protected + 1 + + Resizable + 1 + + + ; forward_declare + 0 + + + + + -1 + + + + 5 + 1 + 1 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL + 3 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_tcGridStyleGap + 1 + + + protected + 1 + + Resizable + 1 + + + ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + 1 + 2 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT + 3 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + mm + 0 + + 0 + + + 0 + + 1 + m_GridStyleGapUnits + 1 + + + protected + 1 + + Resizable + 1 + + + ; forward_declare + 0 + + + + + -1 + + + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT + 4 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Smoothing effort: + 0 + + 0 + + + 0 + + 1 + m_staticTextGridSmoothingLevel + 1 + + + protected + 1 + + Resizable + 1 + + + ; forward_declare + 0 + Value of smoothing effort 0 = no smoothing 1 = chamfer 2 = round corners 3 = round corners (finer shape) + + + + -1 + + + + 5 + 1 + 1 + wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL|wxEXPAND + 4 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + 0 + 3 + + 0 + + 0 + + 0 + + 1 + m_spinCtrlSmoothLevel + 1 + + + protected + 1 + + Resizable + 1 + + wxSP_ARROW_KEYS + ; forward_declare + 0 + + + + + + + + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT + 5 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Smoothing amount: + 0 + + 0 + + + 0 + + 1 + m_staticTextGridSmootingVal + 1 + + + protected + 1 + + Resizable + 1 + + + ; forward_declare + 0 + Ratio between smoothed corners size and the gap between lines 0 = no smoothing 1.0 = max radius/chamfer size (half gap value) + + + + -1 + + + + 5 + 1 + 1 + wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL|wxEXPAND + 5 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 2 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + 0.1 + 0.1 + 1 + + 0 + + 0 + + 0 + + 1 + m_spinCtrlSmoothValue + 1 + + + protected + 1 + + Resizable + 1 + + wxSP_ARROW_KEYS + ; forward_declare + 0 + + + + + + + + + 5 + 3 + 0 + wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP + 6 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_staticline5 + 1 + + + protected + 1 + + Resizable + 1 + + wxLI_HORIZONTAL + ; ; forward_declare + 0 + + + + + + + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP + 7 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Remove islands: + 0 + + 0 + + + 0 + + 1 + m_staticText40 + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + Choose what to do with unconnected copper islands + + + + -1 + + + + 5 + 1 + 1 + wxALIGN_CENTER_VERTICAL|wxALL + 7 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + "Always" "Never" "Below area limit" + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_cbRemoveIslands + 1 + + + protected + 1 + + Resizable + 0 + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnRemoveIslandsSelection + + + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT + 8 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 0 + + 1 + + 0 + 0 + wxID_ANY + Minimum island size: + 0 + + 0 + + + 0 + + 1 + m_islandThresholdLabel + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + Isolated islands smaller than this will be removed + + + + -1 + + + + 5 + 1 + 1 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL + 8 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 0 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_tcIslandThreshold + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + 1 + 2 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT + 8 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 0 + + 1 + + 0 + 0 + wxID_ANY + mm + 0 + + 0 + + + 0 + + 1 + m_islandThresholdUnits + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + + + + + + + diff --git a/pcbnew/zone_manager/panel_zone_properties_base.h b/pcbnew/zone_manager/panel_zone_properties_base.h new file mode 100644 index 0000000000..fdf640ea68 --- /dev/null +++ b/pcbnew/zone_manager/panel_zone_properties_base.h @@ -0,0 +1,113 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf) +// http://www.wxformbuilder.org/ +// +// PLEASE DO *NOT* EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +/// Class PANEL_ZONE_PROPERTIES_BASE +/////////////////////////////////////////////////////////////////////////////// +class PANEL_ZONE_PROPERTIES_BASE : public wxPanel +{ +private: +protected: + enum + { + EDIT_ZONE_NAME = 1000, + ID_M_CORNERSMOOTHINGCTRL, + ID_CORNER_SMOOTHING, + ID_M_PADINZONEOPT, + wxID_ANTIPAD_SIZE, + wxID_COPPER_BRIDGE_VALUE + }; + + wxStaticText* m_zoneNameLabel; + wxTextCtrl* m_tcZoneName; + wxCheckBox* m_cbLocked; + wxStaticText* m_staticTextStyle; + wxChoice* m_OutlineDisplayCtrl; + wxStaticText* m_stBorderHatchPitchText; + wxTextCtrl* m_outlineHatchPitchCtrl; + wxStaticText* m_outlineHatchUnits; + wxStaticLine* m_staticline4; + wxStaticText* m_staticTextSmoothing; + wxChoice* m_cornerSmoothingChoice; + wxStaticText* m_cornerRadiusLabel; + wxTextCtrl* m_cornerRadiusCtrl; + wxStaticText* m_cornerRadiusUnits; + wxStaticText* m_clearanceLabel; + wxTextCtrl* m_clearanceCtrl; + wxStaticText* m_clearanceUnits; + wxStaticText* m_minWidthLabel; + wxTextCtrl* m_minWidthCtrl; + wxStaticText* m_minWidthUnits; + wxStaticLine* m_staticline2; + wxStaticText* m_connectionLabel; + wxChoice* m_PadInZoneOpt; + wxStaticText* m_antipadLabel; + wxTextCtrl* m_antipadCtrl; + wxStaticText* m_antipadUnits; + wxStaticText* m_spokeWidthLabel; + wxTextCtrl* m_spokeWidthCtrl; + wxStaticText* m_spokeWidthUnits; + wxStaticText* m_staticTextGridFillType; + wxChoice* m_GridStyleCtrl; + wxStaticText* m_staticTextGrindOrient; + wxTextCtrl* m_tcGridStyleOrientation; + wxStaticText* m_staticTextRotUnits; + wxStaticText* m_staticTextStyleThickness; + wxTextCtrl* m_tcGridStyleThickness; + wxStaticText* m_GridStyleThicknessUnits; + wxStaticText* m_staticTextGridGap; + wxTextCtrl* m_tcGridStyleGap; + wxStaticText* m_GridStyleGapUnits; + wxStaticText* m_staticTextGridSmoothingLevel; + wxSpinCtrl* m_spinCtrlSmoothLevel; + wxStaticText* m_staticTextGridSmootingVal; + wxSpinCtrlDouble* m_spinCtrlSmoothValue; + wxStaticLine* m_staticline5; + wxStaticText* m_staticText40; + wxChoice* m_cbRemoveIslands; + wxStaticText* m_islandThresholdLabel; + wxTextCtrl* m_tcIslandThreshold; + wxStaticText* m_islandThresholdUnits; + + // Virtual event handlers, override them in your derived class + virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); } + virtual void OnZoneNameChanged( wxCommandEvent& event ) { event.Skip(); } + virtual void OnStyleSelection( wxCommandEvent& event ) { event.Skip(); } + virtual void OnRemoveIslandsSelection( wxCommandEvent& event ) { event.Skip(); } + + +public: + PANEL_ZONE_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxSize( -1, -1 ), long style = wxTAB_TRAVERSAL, + const wxString& name = wxEmptyString ); + + ~PANEL_ZONE_PROPERTIES_BASE(); +}; diff --git a/pcbnew/zone_manager/zone_management_base.h b/pcbnew/zone_manager/zone_management_base.h new file mode 100644 index 0000000000..0714002cb1 --- /dev/null +++ b/pcbnew/zone_manager/zone_management_base.h @@ -0,0 +1,42 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 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 ZONE_MANAGEMENT_BASE_H +#define ZONE_MANAGEMENT_BASE_H + +/** + * @brief Classes need post progress after user click OK + * + */ +class ZONE_MANAGEMENT_BASE +{ +public: + virtual ~ZONE_MANAGEMENT_BASE() = default; + + virtual void OnUserConfirmChange() = 0; + +private: +}; + +#endif \ No newline at end of file diff --git a/pcbnew/zone_manager/zone_manager_preference.cpp b/pcbnew/zone_manager/zone_manager_preference.cpp new file mode 100644 index 0000000000..b3cc483c8b --- /dev/null +++ b/pcbnew/zone_manager/zone_manager_preference.cpp @@ -0,0 +1,55 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 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 "zone_manager_preference.h" +#include + + +//NOTE - Is recording in the setting file needed ? +static bool RepourOnClose = false; + +bool ZONE_MANAGER_PREFERENCE::GetRepourOnClose() +{ + return RepourOnClose; +} + +wxColour ZONE_MANAGER_PREFERENCE::GetCanvasBackgroundColor() +{ + if( KIPLATFORM::UI::IsDarkTheme() ) + return wxColour( 0, 0, 0, 30 ); + + return wxColour( 238, 243, 243 ); +} + +wxColour ZONE_MANAGER_PREFERENCE::GetBoundBoundingFillColor() +{ + if( KIPLATFORM::UI::IsDarkTheme() ) + return wxColour( 238, 243, 243, 60 ); + + return wxColour( 84, 84, 84, 40 ); +} +void ZONE_MANAGER_PREFERENCE::SetRepourOnClose( bool aRepour ) +{ + RepourOnClose = aRepour; +} diff --git a/pcbnew/zone_manager/zone_manager_preference.h b/pcbnew/zone_manager/zone_manager_preference.h new file mode 100644 index 0000000000..6a4aa5eeba --- /dev/null +++ b/pcbnew/zone_manager/zone_manager_preference.h @@ -0,0 +1,53 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 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 ZONE_MANAGER_PREFERENCE_H +#define ZONE_MANAGER_PREFERENCE_H + +#include +#include +class ZONE_MANAGER_PREFERENCE +{ +public: + enum LAYER_ICON_SIZE + { + WIDTH = 16, + HEIGHT = 16, + + }; + + static wxColour GetCanvasBackgroundColor(); + + static wxColour GetBoundBoundingFillColor(); + + /** + * @brief Should all the zones be re-poured on dialog close + * + */ + static void SetRepourOnClose( bool aRepour ); + + static bool GetRepourOnClose(); +}; + +#endif \ No newline at end of file diff --git a/pcbnew/zone_manager/zone_painter.cpp b/pcbnew/zone_manager/zone_painter.cpp new file mode 100644 index 0000000000..2e124d479b --- /dev/null +++ b/pcbnew/zone_manager/zone_painter.cpp @@ -0,0 +1,68 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 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 "zone_painter.h" +#include "board_edges_bounding_item.h" +#include "zone_manager_preference.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool ZONE_PAINTER::Draw( const KIGFX::VIEW_ITEM* aItem, int aLayer ) +{ + const BOARD_EDGES_BOUNDING_ITEM* item = dynamic_cast( aItem ); + + if( item ) + { + draw( item, aLayer ); + return true; + } + + return KIGFX::PCB_PAINTER::Draw( aItem, aLayer ); +} + +void ZONE_PAINTER::draw( const BOARD_EDGES_BOUNDING_ITEM* aBox, int aLayer ) +{ + m_gal->Save(); + m_gal->SetFillColor( ZONE_MANAGER_PREFERENCE::GetBoundBoundingFillColor() ); + m_gal->SetLineWidth( 0 ); + m_gal->SetIsFill( true ); + m_gal->SetIsStroke( false ); + m_gal->DrawRectangle( aBox->ViewBBox() ); + m_gal->Restore(); +} diff --git a/pcbnew/zone_manager/zone_painter.h b/pcbnew/zone_manager/zone_painter.h new file mode 100644 index 0000000000..b3d2ea8837 --- /dev/null +++ b/pcbnew/zone_manager/zone_painter.h @@ -0,0 +1,43 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 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 ZONE_PAINTER_H +#define ZONE_PAINTER_H + +#include + + +class BOARD_EDGES_BOUNDING_ITEM; +class ZONE_PAINTER : public KIGFX::PCB_PAINTER +{ +public: + using KIGFX::PCB_PAINTER::PCB_PAINTER; + + + bool Draw( const KIGFX::VIEW_ITEM* aItem, int aLayer ) override; + + void draw( const BOARD_EDGES_BOUNDING_ITEM* aBox, int aLayer ); +}; + +#endif \ No newline at end of file diff --git a/pcbnew/zone_manager/zone_priority_container.h b/pcbnew/zone_manager/zone_priority_container.h new file mode 100644 index 0000000000..2aabfe0f0f --- /dev/null +++ b/pcbnew/zone_manager/zone_priority_container.h @@ -0,0 +1,72 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 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 ZONE_PRIORITY_CONTAINER_H +#define ZONE_PRIORITY_CONTAINER_H + +#include +#include +#include +#include "zone_management_base.h" +/** + * @brief Workaround to keep the original priorities if user didn't change any + * + */ +class ZONE_PRIORITY_CONTAINER : public ZONE_MANAGEMENT_BASE +{ + friend class MODEL_ZONES_OVERVIEW_TABLE; + +public: + ZONE_PRIORITY_CONTAINER( std::shared_ptr aZone, unsigned aInitialIndex ) : + m_zone( std::move( aZone ) ), m_initialPriority( aInitialIndex ), + m_currentPriority( aInitialIndex ) + { + } + ZONE_PRIORITY_CONTAINER() = delete; + + ~ZONE_PRIORITY_CONTAINER() override = default; + + bool PriorityChanged() const { return m_initialPriority != m_currentPriority; } + + void SetCurrentPriority( unsigned aPriority ) { m_currentPriority = aPriority; } + + unsigned GetCurrentPriority() const { return m_currentPriority; } + + unsigned GetInitialPriority() const { return m_initialPriority; } + + void OnUserConfirmChange() override { m_zone->SetAssignedPriority( m_currentPriority ); } + + ZONE const& GetZone() const { return *m_zone; } + + ZONE& GetZone() { return *m_zone; } + + +private: + std::shared_ptr m_zone; + const unsigned m_initialPriority; + unsigned m_currentPriority; +}; + +#endif \ No newline at end of file diff --git a/pcbnew/zone_manager/zone_selection_change_notifier.h b/pcbnew/zone_manager/zone_selection_change_notifier.h new file mode 100644 index 0000000000..d6f9807416 --- /dev/null +++ b/pcbnew/zone_manager/zone_selection_change_notifier.h @@ -0,0 +1,64 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 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 ZONE_SELECTION_CHANGE_NOTIFIER_H +#define ZONE_SELECTION_CHANGE_NOTIFIER_H + +class ZONE; + +/** + * @brief Subscriber who is interested in the zone selection change + * + */ +class ZONE_SELECTION_CHANGE_NOTIFIER +{ +public: + virtual ~ZONE_SELECTION_CHANGE_NOTIFIER() = default; + + ZONE* GetZone() const { return m_zone; } + /** + * @brief Inform the subscriber about the zone selection change + * + * @param aZone The current zone selection from the publisher + */ + void OnZoneSelectionChanged( ZONE* aZone ) + { + if( m_zone == aZone ) + return; + m_zone = aZone; + ActivateSelectedZone( m_zone ); + } + + ZONE* GetSelectedZone() const { return m_zone; } + +protected: + virtual void ActivateSelectedZone( ZONE* new_zone ) = 0; + + +private: + ZONE* m_zone{}; +}; + +#endif \ No newline at end of file diff --git a/pcbnew/zone_manager/zones_container.cpp b/pcbnew/zone_manager/zones_container.cpp new file mode 100644 index 0000000000..010aec3f9c --- /dev/null +++ b/pcbnew/zone_manager/zones_container.cpp @@ -0,0 +1,124 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 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 "zones_container.h" +#include "zone_priority_container.h" + +#include +#include +#include +#include + + +ZONES_CONTAINER::ZONES_CONTAINER( BOARD* aBoard ) : m_originalZoneList( aBoard->Zones() ) +{ + std::vector> clonedZones; + + for( ZONE* zone : aBoard->Zones() ) + { + if( ( !zone->GetIsRuleArea() ) && IsCopperLayer( zone->GetFirstLayer() ) + && ( !zone->IsTeardropArea() ) ) + { + std::shared_ptr zone_clone = + std::shared_ptr( static_cast( zone->Clone() ) ); + m_zonesColoneMap.try_emplace( zone, zone_clone ); + m_clonedZoneList.push_back( zone_clone.get() ); + clonedZones.push_back( std::move( zone_clone ) ); + } + } + + std::sort( clonedZones.begin(), clonedZones.end(), + []( std::shared_ptr const& l, std::shared_ptr const& r + + ) + { + return l->GetAssignedPriority() > r->GetAssignedPriority(); + } ); + + unsigned currentPriority = clonedZones.size() - 1; + + for( const std::shared_ptr& zone : clonedZones ) + { + m_zonesPriorityContainer.push_back( + std::make_shared( zone, currentPriority ) ); + --currentPriority; + } +} + +ZONES_CONTAINER::~ZONES_CONTAINER() = default; + +std::shared_ptr ZONES_CONTAINER::GetZoneSettings( ZONE* aZone ) +{ + if( auto ll = m_zoneSettings.find( aZone ); ll != m_zoneSettings.end() ) + return ll->second; + + std::shared_ptr zoneSetting = std::make_shared(); + *zoneSetting << *aZone; + m_zoneSettings.try_emplace( aZone, zoneSetting ); + return zoneSetting; +} + +void ZONES_CONTAINER::OnUserConfirmChange() +{ + FlushZoneSettingsChange(); + FlushPriorityChange(); + + for( auto& [c, v] : m_zonesColoneMap ) + { + *c = *v; + } +} + +void ZONES_CONTAINER::FlushZoneSettingsChange() +{ + for( const std::shared_ptr& zone : m_zonesPriorityContainer ) + { + if( auto ll = m_zoneSettings.find( &zone->GetZone() ); ll != m_zoneSettings.end() ) + ll->second->ExportSetting( zone->GetZone() ); + } +} + +bool ZONES_CONTAINER::FlushPriorityChange() +{ + bool priorityChanged = false; + + for( const std::shared_ptr& c : m_zonesPriorityContainer ) + { + if( c->PriorityChanged() ) + { + priorityChanged = true; + break; + } + } + + if( priorityChanged ) + { + for( std::shared_ptr& c : m_zonesPriorityContainer ) + { + c->OnUserConfirmChange(); + } + } + + return priorityChanged; +} diff --git a/pcbnew/zone_manager/zones_container.h b/pcbnew/zone_manager/zones_container.h new file mode 100644 index 0000000000..396a3542dd --- /dev/null +++ b/pcbnew/zone_manager/zones_container.h @@ -0,0 +1,83 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 Ethan Chien + * Copyright (C) 2023 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 ZONES_CONTAINER_H +#define ZONES_CONTAINER_H +#include "board.h" +#include +#include +#include +#include +#include "zone_management_base.h" +#include "zone_settings.h" + +class ZONE_PRIORITY_CONTAINER; +class ZONES_CONTAINER : public ZONE_MANAGEMENT_BASE +{ +public: + ZONES_CONTAINER( BOARD* board ); + ~ZONES_CONTAINER() override; + + std::vector> GetZonesPriorityContainers() const + { + return m_zonesPriorityContainer; + } + + std::shared_ptr GetZoneSettings( ZONE* zone ); + /** + * @brief Adapter for the zone filler ,zones are actually managed the smart ptr + * + * @return std::vector + */ + std::vector& GetClonedZoneList() { return m_clonedZoneList; } + /** + * @brief Used for restoring the zones in the board after refilling + * + * @return std::vector& + */ + std::vector& GetOriginalZoneList() { return m_originalZoneList; } + /** + * @brief Flush the zone settings change to the cloned ones + * + */ + void FlushZoneSettingsChange(); + /** + * @brief Flush the priority change to the cloned ones + * + * @return true if priority changed + */ + bool FlushPriorityChange(); + + void OnUserConfirmChange() override; + +private: + std::unordered_map> m_zonesColoneMap; + std::unordered_map> m_zoneSettings; + std::vector> m_zonesPriorityContainer; + std::vector m_clonedZoneList; + std::vector m_originalZoneList; +}; + +#endif diff --git a/pcbnew/zones.h b/pcbnew/zones.h index b6eea7f8ca..8fc254f9ac 100644 --- a/pcbnew/zones.h +++ b/pcbnew/zones.h @@ -41,6 +41,7 @@ struct CONVERT_SETTINGS; #define ZONE_BORDER_HATCH_MAXDIST_MM 2.0 // Maximum for ZONE_SETTINGS::m_BorderHatchPitch +#define ZONE_MANAGER_REPOUR 1005 //Reported if repour option is checked while clicking OK /// How pads are covered by copper in zone enum class ZONE_CONNECTION { @@ -106,4 +107,14 @@ int InvokeCopperZonesEditor( PCB_BASE_FRAME* aCaller, ZONE_SETTINGS* aSettings, int InvokeRuleAreaEditor( PCB_BASE_FRAME* aCaller, ZONE_SETTINGS* aSettings, CONVERT_SETTINGS* aConvertSettings = nullptr ); +/** + * Function InvokeZonesManager + * invokes up a modal dialog window for zones manager. + * + * @param aCaller is the PCB_BASE_FRAME calling parent window for the modal dialog, + * and it gives access to the BOARD through PCB_BASE_FRAME::GetBoard(). + * @return int - tells if user aborted, or edited the zones + */ +int InvokeZonesManager( PCB_BASE_FRAME* aCall, ZONE_SETTINGS* aSettings ); + #endif // ZONES_H_