ADDED: zone manager

Fixes https://gitlab.com/kicad/code/kicad/-/issues/9636
This commit is contained in:
Ethan Chien 2024-02-24 15:10:50 +00:00 committed by Jon Evans
parent b7b64d959f
commit d72491a4a5
34 changed files with 7734 additions and 0 deletions

View File

@ -271,6 +271,20 @@ set( PCBNEW_NETLIST_SRCS
netlist_reader/netlist.cpp 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 set( PCBNEW_CLASS_SRCS
${PCBNEW_DIALOGS} ${PCBNEW_DIALOGS}
${PCBNEW_EXPORTERS} ${PCBNEW_EXPORTERS}
@ -278,6 +292,7 @@ set( PCBNEW_CLASS_SRCS
${PCBNEW_DRC_SRCS} ${PCBNEW_DRC_SRCS}
${PCBNEW_IMPORT_GFX} ${PCBNEW_IMPORT_GFX}
${PCBNEW_NETLIST_SRCS} ${PCBNEW_NETLIST_SRCS}
${ZONE_MANAGER_SRCS}
${PCBNEW_BRDSTACKUP_MGR} ${PCBNEW_BRDSTACKUP_MGR}
autorouter/spread_footprints.cpp autorouter/spread_footprints.cpp

View File

@ -401,6 +401,10 @@ void PCB_EDIT_FRAME::doReCreateMenuBar()
toolsMenu->Add( ACTIONS::showFootprintEditor ); toolsMenu->Add( ACTIONS::showFootprintEditor );
toolsMenu->Add( PCB_ACTIONS::updateFootprints ); toolsMenu->Add( PCB_ACTIONS::updateFootprints );
//Zones management
toolsMenu->AppendSeparator();
toolsMenu->Add( PCB_ACTIONS::zonesManager );
if( ADVANCED_CFG::GetCfg().m_EnableGenerators ) if( ADVANCED_CFG::GetCfg().m_EnableGenerators )
{ {
toolsMenu->AppendSeparator(); toolsMenu->AppendSeparator();

View File

@ -24,6 +24,7 @@
#include <footprint.h> #include <footprint.h>
#include <pcb_track.h> #include <pcb_track.h>
#include <zone.h> #include <zone.h>
#include <zones.h>
#include <tool/tool_manager.h> #include <tool/tool_manager.h>
#include <tools/pcb_actions.h> #include <tools/pcb_actions.h>
#include <tools/edit_tool.h> #include <tools/edit_tool.h>
@ -34,6 +35,9 @@
#include <tools/global_edit_tool.h> #include <tools/global_edit_tool.h>
#include <board_commit.h> #include <board_commit.h>
#include <dialogs/dialog_cleanup_graphics.h> #include <dialogs/dialog_cleanup_graphics.h>
#include <tools/pcb_actions.h>
#include <board_design_settings.h>
GLOBAL_EDIT_TOOL::GLOBAL_EDIT_TOOL() : GLOBAL_EDIT_TOOL::GLOBAL_EDIT_TOOL() :
PCB_TOOL_BASE( "pcbnew.GlobalEdit" ), PCB_TOOL_BASE( "pcbnew.GlobalEdit" ),
@ -211,6 +215,55 @@ int GLOBAL_EDIT_TOOL::RemoveUnusedPads( const TOOL_EVENT& aEvent )
return 0; return 0;
} }
int GLOBAL_EDIT_TOOL::ZonesManager( const TOOL_EVENT& aEvent )
{
PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>();
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() 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::CleanupTracksAndVias, PCB_ACTIONS::cleanupTracksAndVias.MakeEvent() );
Go( &GLOBAL_EDIT_TOOL::CleanupGraphics, PCB_ACTIONS::cleanupGraphics.MakeEvent() ); Go( &GLOBAL_EDIT_TOOL::CleanupGraphics, PCB_ACTIONS::cleanupGraphics.MakeEvent() );
Go( &GLOBAL_EDIT_TOOL::RemoveUnusedPads, PCB_ACTIONS::removeUnusedPads.MakeEvent() ); Go( &GLOBAL_EDIT_TOOL::RemoveUnusedPads, PCB_ACTIONS::removeUnusedPads.MakeEvent() );
Go( &GLOBAL_EDIT_TOOL::ZonesManager, PCB_ACTIONS::zonesManager.MakeEvent() );
} }

View File

@ -63,6 +63,7 @@ public:
int CleanupTracksAndVias( const TOOL_EVENT& aEvent ); int CleanupTracksAndVias( const TOOL_EVENT& aEvent );
int CleanupGraphics( const TOOL_EVENT& aEvent ); int CleanupGraphics( const TOOL_EVENT& aEvent );
int RemoveUnusedPads( const TOOL_EVENT& aEvent ); int RemoveUnusedPads( const TOOL_EVENT& aEvent );
int ZonesManager( const TOOL_EVENT& aEvent );
private: private:
bool swapBoardItem( BOARD_ITEM* aItem, PCB_LAYER_ID* aLayerMap ); bool swapBoardItem( BOARD_ITEM* aItem, PCB_LAYER_ID* aLayerMap );

View File

@ -1335,6 +1335,11 @@ TOOL_ACTION PCB_ACTIONS::showLayersManager( TOOL_ACTION_ARGS()
.Tooltip( _( "Show/hide the appearance manager" ) ) .Tooltip( _( "Show/hide the appearance manager" ) )
.Icon( BITMAPS::layers_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() TOOL_ACTION PCB_ACTIONS::flipBoard( TOOL_ACTION_ARGS()
.Name( "pcbnew.Control.flipBoard" ) .Name( "pcbnew.Control.flipBoard" )
.Scope( AS_GLOBAL ) .Scope( AS_GLOBAL )

View File

@ -437,6 +437,7 @@ public:
static TOOL_ACTION showLayersManager; static TOOL_ACTION showLayersManager;
static TOOL_ACTION showPythonConsole; static TOOL_ACTION showPythonConsole;
static TOOL_ACTION zonesManager;
// Module editor tools // Module editor tools

View File

@ -0,0 +1,47 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Ethan Chien <liangtie.qian@gmail.com>
* 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;
}

View File

@ -0,0 +1,44 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Ethan Chien <liangtie.qian@gmail.com>
* 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 <view/view_item.h>
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

View File

@ -0,0 +1,454 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Ethan Chien <liangtie.qian@gmail.com>
* 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 <memory>
#include <optional>
#include <wx/dataview.h>
#include <wx/debug.h>
#include <wx/event.h>
#include <wx/gdicmn.h>
#include <wx/radiobut.h>
#include <kiface_base.h>
#include <confirm.h>
#include <pcb_edit_frame.h>
#include <pcbnew_settings.h>
#include <wx/string.h>
#include <zones.h>
#include <board_commit.h>
#include <widgets/unit_binder.h>
#include <zone.h>
#include <pad.h>
#include <board.h>
#include <trigo.h>
#include <bitmaps.h>
#include <eda_pattern_match.h>
#include <string_utils.h>
#include <bitmaps.h>
#include <zone_filler.h>
#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<ZONES_CONTAINER>( 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<ZONE_SELECTION_CHANGE_NOTIFIER*>{ 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<ZONE_MANAGEMENT_BASE*>{ m_panelZoneProperties, m_zonesContainer.get() } )
{
zone_management->OnUserConfirmChange();
}
if( m_zoneInfo )
{
if( std::shared_ptr<ZONE_SETTINGS> 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<unsigned> 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<BOARD_COMMIT>( m_pcbFrame );
m_filler = std::make_unique<ZONE_FILLER>( board, m_commit.get() );
auto reporter = std::make_unique<WX_PROGRESS_REPORTER>( 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<unsigned> 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();
}

View File

@ -0,0 +1,143 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Ethan Chien <liangtie.qian@gmail.com>
* 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 <memory>
#include <optional>
#include <wx/dataview.h>
#include <wx/event.h>
#include <wx/radiobut.h>
#include <kiface_base.h>
#include <confirm.h>
#include <pcb_edit_frame.h>
#include <pcbnew_settings.h>
#include <zones.h>
#include <widgets/unit_binder.h>
#include <zone.h>
#include <pad.h>
#include <board.h>
#include <trigo.h>
#include <eda_pattern_match.h>
#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<ZONES_CONTAINER> m_zonesContainer;
PANEL_ZONE_PROPERTIES* m_panelZoneProperties;
wxObjectDataPtr<MODEL_ZONES_OVERVIEW_TABLE> m_modelZoneOverviewTable;
PANE_ZONE_VIEWER* m_zoneViewer;
std::optional<unsigned> m_priorityDragIndex;
std::unique_ptr<ZONE_FILLER> m_filler;
std::unique_ptr<COMMIT> m_commit;
bool m_needZoomGAL;
};
#endif

View File

@ -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 );
}

View File

@ -0,0 +1,611 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="17"/>
<object class="Project" expanded="true">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
<property name="disconnect_events">1</property>
<property name="disconnect_mode">source_name</property>
<property name="disconnect_php_events">0</property>
<property name="disconnect_python_events">0</property>
<property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property>
<property name="event_generation">connect</property>
<property name="file">dialog_zone_manager_base</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="image_path_wrapper_function_name"></property>
<property name="indent_with_spaces"></property>
<property name="internationalize">1</property>
<property name="name">dialog_zone_manager_base</property>
<property name="namespace"></property>
<property name="path">.</property>
<property name="precompiled_header"></property>
<property name="relative_path">1</property>
<property name="skip_lua_events">1</property>
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_array_enum">0</property>
<property name="use_enum">1</property>
<property name="use_microsoft_bom">0</property>
<object class="Dialog" expanded="true">
<property name="aui_managed">0</property>
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
<property name="bg"></property>
<property name="center"></property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="event_handler">impl_virtual</property>
<property name="extra_style"></property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">ID_DIALOG_COPPER_ZONE_BASE</property>
<property name="maximum_size"></property>
<property name="minimum_size">-1,-1</property>
<property name="name">DIALOG_ZONE_MANAGER_BASE</property>
<property name="pos"></property>
<property name="size">-1,-1</property>
<property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
<property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
<property name="title">Zone Manager</property>
<property name="tooltip"></property>
<property name="two_step_creation">0</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size">-1,-1</property>
<property name="name">m_MainBoxSizer</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">protected</property>
<object class="sizeritem" expanded="true">
<property name="border">0</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">bSizer12</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">m_sizerTop</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">protected</property>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">bSizer7</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="false">
<property name="border">0</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxDataViewCtrl" expanded="false">
<property name="bg"></property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">VIEW_ZONE_TABLE</property>
<property name="maximum_size"></property>
<property name="minimum_size">-1,240</property>
<property name="name">m_viewZonesOverview</property>
<property name="permission">protected</property>
<property name="pos"></property>
<property name="size">-1,240</property>
<property name="style">wxDV_HORIZ_RULES|wxDV_ROW_LINES|wxDV_SINGLE|wxDV_VERT_RULES</property>
<property name="subclass">; ; forward_declare</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar">OnTableChar</event>
<event name="OnCharHook">OnTableCharHook</event>
<event name="OnDataViewCtrlSelectionChanged">OnDataViewCtrlSelectionChanged</event>
<event name="OnLeftUp">OnViewZonesOverviewOnLeftUp</event>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxTOP</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">m_sizerZoneOP</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">protected</property>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxRIGHT</property>
<property name="proportion">0</property>
<object class="CustomControl" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="class">STD_BITMAP_BUTTON</property>
<property name="close_button">1</property>
<property name="construction">m_btnMoveUp = new STD_BITMAP_BUTTON( this, BTN_MOVE_UP, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="declaration"></property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">BTN_MOVE_UP</property>
<property name="include">#include &quot;widgets/std_bitmap_button.h&quot;</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_btnMoveUp</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="settings"></property>
<property name="show">1</property>
<property name="size"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip">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.</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag"></property>
<property name="proportion">0</property>
<object class="CustomControl" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="class">STD_BITMAP_BUTTON</property>
<property name="close_button">1</property>
<property name="construction">m_btnMoveDown = new STD_BITMAP_BUTTON( this, BTN_MOVE_DOWN, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="declaration"></property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">BTN_MOVE_DOWN</property>
<property name="include">#include &quot;widgets/std_bitmap_button.h&quot;</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_btnMoveDown</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="settings"></property>
<property name="show">1</property>
<property name="size"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip">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.</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">10</property>
<property name="flag">wxEXPAND|wxLEFT|wxRIGHT</property>
<property name="proportion">0</property>
<object class="spacer" expanded="false">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxLEFT|wxTOP</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="false">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">1</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">CHECK_NAME</property>
<property name="label">Name</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_checkName</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="false">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">1</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">CHECK_NET</property>
<property name="label">Net</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_checkNet</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">0</property>
<property name="flag">wxALL</property>
<property name="proportion">1</property>
<object class="wxSearchCtrl" expanded="false">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="cancel_button">1</property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_filterCtrl</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="search_button">1</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxTE_PROCESS_ENTER</property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="value"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnCancelButton">OnFilterCtrlCancel</event>
<event name="OnSearchButton">OnFilterCtrlSearch</event>
<event name="OnText">OnFilterCtrlTextChange</event>
<event name="OnTextEnter">OnFilterCtrlEnter</event>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxStaticBoxSizer" expanded="false">
<property name="id">wxID_ANY</property>
<property name="label">Properties</property>
<property name="minimum_size"></property>
<property name="name">m_sizerProperties</property>
<property name="orient">wxVERTICAL</property>
<property name="parent">1</property>
<property name="permission">protected</property>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">bSizer61</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="true">
<property name="border">15</property>
<property name="flag">wxEXPAND|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">bSizer71</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="true">
<property name="border">10</property>
<property name="flag">wxLEFT|wxTOP</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Repour</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_checkRepour</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnCheckBox">OnRepourCheck</event>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="spacer" expanded="true">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxStdDialogButtonSizer" expanded="false">
<property name="Apply">1</property>
<property name="Cancel">1</property>
<property name="ContextHelp">0</property>
<property name="Help">0</property>
<property name="No">0</property>
<property name="OK">1</property>
<property name="Save">0</property>
<property name="Yes">0</property>
<property name="minimum_size"></property>
<property name="name">m_sdbSizer</property>
<property name="permission">protected</property>
<event name="OnApplyButtonClick">OnButtonApplyClick</event>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</wxFormBuilder_Project>

View File

@ -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 <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
#include "dialog_shim.h"
#include <wx/dataview.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/string.h>
#include "widgets/std_bitmap_button.h"
#include <wx/checkbox.h>
#include <wx/srchctrl.h>
#include <wx/sizer.h>
#include <wx/statbox.h>
#include <wx/button.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// 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();
};

View File

@ -0,0 +1,275 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Ethan Chien <liangtie.qian@gmail.com>
* 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.h>
#include <netinfo.h>
#include <vector>
#include <wx/string.h>
#include <settings/color_settings.h>
#include <wx/dcmemory.h>
#include <pcb_edit_frame.h>
#include <wx/variant.h>
#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<ZONE_PRIORITY_CONTAINER> const& l,
std::shared_ptr<ZONE_PRIORITY_CONTAINER> 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<PCB_LAYER_ID> 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<int>( 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<size_t>( 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<unsigned> 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<unsigned>{};
}
case ZONE_INDEX_MOVEMENT::MOVE_DOWN:
{
return aIndex + 1 < GetCount() ? SwapZonePriority( aIndex, aIndex + 1 )
: std::optional<unsigned>{};
}
}
return {};
}
std::optional<unsigned> 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 );
}

View File

@ -0,0 +1,154 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Ethan Chien <liangtie.qian@gmail.com>
* 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 <memory>
#include <utility>
#include <vector>
#include <wx/dataview.h>
#include <wx/event.h>
#include <wx/string.h>
#include <board.h>
#include <zone.h>
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<std::shared_ptr<ZONE_PRIORITY_CONTAINER>>;
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<int, wxString> GetColumnNames()
{
//NOTE - Build the column name dynamicly in case the display language changed
const std::map<int, wxString> ColNames = std::map<int, wxString>{
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<unsigned> the new index for selected one if success
*/
std::optional<unsigned> MoveZoneIndex( unsigned aIndex, ZONE_INDEX_MOVEMENT aMovement );
/**
* @brief Swap two zone while drag && drop
*
* @return std::optional<unsigned> the new index for the dragged one if success
*/
std::optional<unsigned> 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

View File

@ -0,0 +1,191 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Ethan Chien <liangtie.qian@gmail.com>
* 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 <wx/artprov.h>
#include <wx/dataview.h>
#include <wx/colour.h>
#include <wx/debug.h>
#include <wx/event.h>
#include <wx/imaglist.h>
#include <wx/panel.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
#include <wx/dataview.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/string.h>
#include <wx/sizer.h>
#include <wx/statbox.h>
#include <wx/button.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/dialog.h>
#include <wx/graphics.h>
#include <wx/dcbuffer.h>
#include <board.h>
#include <gal/color4d.h>
#include "panel_zone_gal.h"
#include <wx/dataview.h>
#include "settings/color_settings.h"
#include "zone_manager_preference.h"
#include "zone_manager/panel_zone_gal.h"
#include <pcb_edit_frame.h>
#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<PANEL_ZONE_GAL_CONTAINER*>( 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<PCB_LAYER_ID>( 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<PANEL_ZONE_GAL_CONTAINER*>( GetPage( idx ) );
container->ResetZoneGAL( m_zoneGAL );
m_zoneGAL->OnLayerSelected( container->GetLayer() );
SetSelection( idx );
aEvent.Skip();
}

View File

@ -0,0 +1,58 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Ethan Chien <liangtie.qian@gmail.com>
* 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 <unordered_map>
#include <wx/window.h>
#include <wx/panel.h>
#include <wx/notebook.h>
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<int, PANEL_ZONE_GAL_CONTAINER*> m_zoneContainers;
PANEL_ZONE_GAL* m_zoneGAL{};
};
#endif

View File

@ -0,0 +1,179 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Ethan Chien <liangtie.qian@gmail.com>
* 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 <pcb_track.h>
#include <pcb_marker.h>
#include <wx/event.h>
#include <wx/gdicmn.h>
#include <wx/string.h>
#include <base_screen.h>
#include <base_units.h>
#include <bitmaps.h>
#include <class_draw_panel_gal.h>
#include <dialogs/dialog_configure_paths.h>
#include <eda_draw_frame.h>
#include <gal/graphics_abstraction_layer.h>
#include <id.h>
#include <kiface_base.h>
#include <settings/app_settings.h>
#include <tool/actions.h>
#include <tool/common_tools.h>
#include <tool/tool_manager.h>
#include <view/view.h>
#include <view/view_controls.h>
#include <board.h>
#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<BOARD_EDGES_BOUNDING_ITEM>( aPcb->GetBoardEdgesBoundingBox() ) ),
m_zone( nullptr )
{
m_view->UseDrawPriority( true );
m_painter = std::make_unique<ZONE_PAINTER>( 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<double>( clientSize.x ), static_cast<double>( 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();
}

View File

@ -0,0 +1,75 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Ethan Chien <liangtie.qian@gmail.com>
* 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 <board_item.h>
#include <wx/gdicmn.h>
#include <zone.h>
#include <memory>
#include <wx/string.h>
#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<BOARD_EDGES_BOUNDING_ITEM> m_pcb_bounding_box;
ZONE* m_zone;
};
#endif

View File

@ -0,0 +1,320 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Ethan Chien <liangtie.qian@gmail.com>
* Copyright (C) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* 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 <wx/radiobut.h>
#include <kiface_base.h>
#include <confirm.h>
#include <pcb_edit_frame.h>
#include <pcbnew_settings.h>
#include <wx/string.h>
#include <zones.h>
#include <widgets/unit_binder.h>
#include <zone.h>
#include <pad.h>
#include <board.h>
#include <trigo.h>
#include <eda_pattern_match.h>
#include <dialog_copper_zones_base.h>
#include <string_utils.h>
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<double>( m_settings->GetMinIslandArea() ) );
m_cbRemoveIslands->SetSelection( static_cast<int>( 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 );
}

View File

@ -0,0 +1,106 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Ethan Chien <liangtie.qian@gmail.com>
* Copyright (C) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* 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 <memory>
#include <zone_settings.h>
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<ZONE_SETTINGS> 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<ZONE_SETTINGS> 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

View File

@ -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 );
}

File diff suppressed because it is too large Load Diff

View File

@ -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 <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
#include <wx/string.h>
#include <wx/stattext.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/textctrl.h>
#include <wx/sizer.h>
#include <wx/statbox.h>
#include <wx/checkbox.h>
#include <wx/choice.h>
#include <wx/statline.h>
#include <wx/gbsizer.h>
#include <wx/spinctrl.h>
#include <wx/panel.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// 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();
};

View File

@ -0,0 +1,42 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Ethan Chien <liangtie.qian@gmail.com>
* 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

View File

@ -0,0 +1,55 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Ethan Chien <liangtie.qian@gmail.com>
* 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 <kiplatform/ui.h>
//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;
}

View File

@ -0,0 +1,53 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Ethan Chien <liangtie.qian@gmail.com>
* 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 <wx/colour.h>
#include <wx/colour.h>
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

View File

@ -0,0 +1,68 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Ethan Chien <liangtie.qian@gmail.com>
* 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 <layer_ids.h>
#include <convert_basic_shapes_to_polygon.h>
#include <gal/graphics_abstraction_layer.h>
#include <callback_gal.h>
#include <geometry/geometry_utils.h>
#include <geometry/shape_line_chain.h>
#include <geometry/shape_rect.h>
#include <geometry/shape_segment.h>
#include <geometry/shape_simple.h>
#include <geometry/shape_circle.h>
#include <bezier_curves.h>
#include <kiface_base.h>
#include <gr_text.h>
#include <pgm_base.h>
#include <wx/gdicmn.h>
#include <board_item.h>
#include <zone.h>
bool ZONE_PAINTER::Draw( const KIGFX::VIEW_ITEM* aItem, int aLayer )
{
const BOARD_EDGES_BOUNDING_ITEM* item = dynamic_cast<const BOARD_EDGES_BOUNDING_ITEM*>( 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();
}

View File

@ -0,0 +1,43 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Ethan Chien <liangtie.qian@gmail.com>
* 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 <pcb_painter.h>
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

View File

@ -0,0 +1,72 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Ethan Chien <liangtie.qian@gmail.com>
* 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 <memory>
#include <utility>
#include <zone.h>
#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<ZONE> 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<ZONE> m_zone;
const unsigned m_initialPriority;
unsigned m_currentPriority;
};
#endif

View File

@ -0,0 +1,64 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Ethan Chien <liangtie.qian@gmail.com>
* 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

View File

@ -0,0 +1,124 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Ethan Chien <liangtie.qian@gmail.com>
* 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 <teardrop/teardrop_types.h>
#include <zone.h>
#include <memory>
#include <algorithm>
ZONES_CONTAINER::ZONES_CONTAINER( BOARD* aBoard ) : m_originalZoneList( aBoard->Zones() )
{
std::vector<std::shared_ptr<ZONE>> clonedZones;
for( ZONE* zone : aBoard->Zones() )
{
if( ( !zone->GetIsRuleArea() ) && IsCopperLayer( zone->GetFirstLayer() )
&& ( !zone->IsTeardropArea() ) )
{
std::shared_ptr<ZONE> zone_clone =
std::shared_ptr<ZONE>( static_cast<ZONE*>( 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<ZONE> const& l, std::shared_ptr<ZONE> const& r
)
{
return l->GetAssignedPriority() > r->GetAssignedPriority();
} );
unsigned currentPriority = clonedZones.size() - 1;
for( const std::shared_ptr<ZONE>& zone : clonedZones )
{
m_zonesPriorityContainer.push_back(
std::make_shared<ZONE_PRIORITY_CONTAINER>( zone, currentPriority ) );
--currentPriority;
}
}
ZONES_CONTAINER::~ZONES_CONTAINER() = default;
std::shared_ptr<ZONE_SETTINGS> ZONES_CONTAINER::GetZoneSettings( ZONE* aZone )
{
if( auto ll = m_zoneSettings.find( aZone ); ll != m_zoneSettings.end() )
return ll->second;
std::shared_ptr<ZONE_SETTINGS> zoneSetting = std::make_shared<ZONE_SETTINGS>();
*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_PRIORITY_CONTAINER>& 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<ZONE_PRIORITY_CONTAINER>& c : m_zonesPriorityContainer )
{
if( c->PriorityChanged() )
{
priorityChanged = true;
break;
}
}
if( priorityChanged )
{
for( std::shared_ptr<ZONE_PRIORITY_CONTAINER>& c : m_zonesPriorityContainer )
{
c->OnUserConfirmChange();
}
}
return priorityChanged;
}

View File

@ -0,0 +1,83 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Ethan Chien <liangtie.qian@gmail.com>
* 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 <memory>
#include <unordered_map>
#include <vector>
#include <zone.h>
#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<std::shared_ptr<ZONE_PRIORITY_CONTAINER>> GetZonesPriorityContainers() const
{
return m_zonesPriorityContainer;
}
std::shared_ptr<ZONE_SETTINGS> GetZoneSettings( ZONE* zone );
/**
* @brief Adapter for the zone filler ,zones are actually managed the smart ptr
*
* @return std::vector<ZONE*>
*/
std::vector<ZONE*>& GetClonedZoneList() { return m_clonedZoneList; }
/**
* @brief Used for restoring the zones in the board after refilling
*
* @return std::vector<ZONE*>&
*/
std::vector<ZONE*>& 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<ZONE*, std::shared_ptr<ZONE>> m_zonesColoneMap;
std::unordered_map<ZONE*, std::shared_ptr<ZONE_SETTINGS>> m_zoneSettings;
std::vector<std::shared_ptr<ZONE_PRIORITY_CONTAINER>> m_zonesPriorityContainer;
std::vector<ZONE*> m_clonedZoneList;
std::vector<ZONE*> m_originalZoneList;
};
#endif

View File

@ -41,6 +41,7 @@ struct CONVERT_SETTINGS;
#define ZONE_BORDER_HATCH_MAXDIST_MM 2.0 // Maximum for ZONE_SETTINGS::m_BorderHatchPitch #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 /// How pads are covered by copper in zone
enum class ZONE_CONNECTION 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, int InvokeRuleAreaEditor( PCB_BASE_FRAME* aCaller, ZONE_SETTINGS* aSettings,
CONVERT_SETTINGS* aConvertSettings = nullptr ); 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_ #endif // ZONES_H_