pcbnew: Update zone manager

Update zone manager to improve usability. Filter zones based on layers,
provide move to top/move to bottom actions, global arrow key navigation,
zoom preservation across zone switches, right-click zoom-to-fit on the
preview canvas, and pixel-aligned icons for top/bottom move buttons.
This commit is contained in:
Seth Hillbrand
2026-03-01 22:07:19 -08:00
parent f07f1083ac
commit 314429373c
26 changed files with 963 additions and 18 deletions
+8
View File
@@ -80,6 +80,7 @@ void BuildBitmapInfo( std::unordered_map<BITMAPS, std::vector<BITMAP_INFO>>& aBi
aBitmapInfoCache[BITMAPS::pintype_openemit].emplace_back( BITMAPS::pintype_openemit, wxT( "pintype_openemit_16.png" ), 16, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::pintype_nic].emplace_back( BITMAPS::pintype_nic, wxT( "pintype_nic_16.png" ), 16, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::pintype_noconnect].emplace_back( BITMAPS::pintype_noconnect, wxT( "pintype_noconnect_16.png" ), 16, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::small_bottom].emplace_back( BITMAPS::small_bottom, wxT( "small_bottom_16.png" ), 16, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::small_down].emplace_back( BITMAPS::small_down, wxT( "small_down_16.png" ), 16, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::small_edit].emplace_back( BITMAPS::small_edit, wxT( "small_edit_16.png" ), 16, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::small_folder].emplace_back( BITMAPS::small_folder, wxT( "small_folder_16.png" ), 16, wxT( "light" ) );
@@ -88,6 +89,7 @@ void BuildBitmapInfo( std::unordered_map<BITMAPS, std::vector<BITMAP_INFO>>& aBi
aBitmapInfoCache[BITMAPS::small_plus].emplace_back( BITMAPS::small_plus, wxT( "small_plus_16.png" ), 16, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::small_refresh].emplace_back( BITMAPS::small_refresh, wxT( "small_refresh_16.png" ), 16, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::small_sort_desc].emplace_back( BITMAPS::small_sort_desc, wxT( "small_sort_desc_16.png" ), 16, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::small_top].emplace_back( BITMAPS::small_top, wxT( "small_top_16.png" ), 16, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::small_trash].emplace_back( BITMAPS::small_trash, wxT( "small_trash_16.png" ), 16, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::small_up].emplace_back( BITMAPS::small_up, wxT( "small_up_16.png" ), 16, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::small_warning].emplace_back( BITMAPS::small_warning, wxT( "small_warning_16.png" ), 16, wxT( "light" ) );
@@ -165,6 +167,7 @@ void BuildBitmapInfo( std::unordered_map<BITMAPS, std::vector<BITMAP_INFO>>& aBi
aBitmapInfoCache[BITMAPS::pintype_openemit].emplace_back( BITMAPS::pintype_openemit, wxT( "pintype_openemit_dark_16.png" ), 16, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::pintype_nic].emplace_back( BITMAPS::pintype_nic, wxT( "pintype_nic_dark_16.png" ), 16, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::pintype_noconnect].emplace_back( BITMAPS::pintype_noconnect, wxT( "pintype_noconnect_dark_16.png" ), 16, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::small_bottom].emplace_back( BITMAPS::small_bottom, wxT( "small_bottom_dark_16.png" ), 16, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::small_down].emplace_back( BITMAPS::small_down, wxT( "small_down_dark_16.png" ), 16, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::small_edit].emplace_back( BITMAPS::small_edit, wxT( "small_edit_dark_16.png" ), 16, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::small_folder].emplace_back( BITMAPS::small_folder, wxT( "small_folder_dark_16.png" ), 16, wxT( "dark" ) );
@@ -173,6 +176,7 @@ void BuildBitmapInfo( std::unordered_map<BITMAPS, std::vector<BITMAP_INFO>>& aBi
aBitmapInfoCache[BITMAPS::small_plus].emplace_back( BITMAPS::small_plus, wxT( "small_plus_dark_16.png" ), 16, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::small_refresh].emplace_back( BITMAPS::small_refresh, wxT( "small_refresh_dark_16.png" ), 16, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::small_sort_desc].emplace_back( BITMAPS::small_sort_desc, wxT( "small_sort_desc_dark_16.png" ), 16, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::small_top].emplace_back( BITMAPS::small_top, wxT( "small_top_dark_16.png" ), 16, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::small_trash].emplace_back( BITMAPS::small_trash, wxT( "small_trash_dark_16.png" ), 16, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::small_up].emplace_back( BITMAPS::small_up, wxT( "small_up_dark_16.png" ), 16, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::small_warning].emplace_back( BITMAPS::small_warning, wxT( "small_warning_dark_16.png" ), 16, wxT( "dark" ) );
@@ -250,6 +254,7 @@ void BuildBitmapInfo( std::unordered_map<BITMAPS, std::vector<BITMAP_INFO>>& aBi
aBitmapInfoCache[BITMAPS::pintype_openemit].emplace_back( BITMAPS::pintype_openemit, wxT( "pintype_openemit_32.png" ), 32, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::pintype_nic].emplace_back( BITMAPS::pintype_nic, wxT( "pintype_nic_32.png" ), 32, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::pintype_noconnect].emplace_back( BITMAPS::pintype_noconnect, wxT( "pintype_noconnect_32.png" ), 32, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::small_bottom].emplace_back( BITMAPS::small_bottom, wxT( "small_bottom_32.png" ), 32, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::small_down].emplace_back( BITMAPS::small_down, wxT( "small_down_32.png" ), 32, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::small_edit].emplace_back( BITMAPS::small_edit, wxT( "small_edit_32.png" ), 32, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::small_folder].emplace_back( BITMAPS::small_folder, wxT( "small_folder_32.png" ), 32, wxT( "light" ) );
@@ -258,6 +263,7 @@ void BuildBitmapInfo( std::unordered_map<BITMAPS, std::vector<BITMAP_INFO>>& aBi
aBitmapInfoCache[BITMAPS::small_plus].emplace_back( BITMAPS::small_plus, wxT( "small_plus_32.png" ), 32, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::small_refresh].emplace_back( BITMAPS::small_refresh, wxT( "small_refresh_32.png" ), 32, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::small_sort_desc].emplace_back( BITMAPS::small_sort_desc, wxT( "small_sort_desc_32.png" ), 32, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::small_top].emplace_back( BITMAPS::small_top, wxT( "small_top_32.png" ), 32, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::small_trash].emplace_back( BITMAPS::small_trash, wxT( "small_trash_32.png" ), 32, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::small_up].emplace_back( BITMAPS::small_up, wxT( "small_up_32.png" ), 32, wxT( "light" ) );
aBitmapInfoCache[BITMAPS::small_warning].emplace_back( BITMAPS::small_warning, wxT( "small_warning_32.png" ), 32, wxT( "light" ) );
@@ -335,6 +341,7 @@ void BuildBitmapInfo( std::unordered_map<BITMAPS, std::vector<BITMAP_INFO>>& aBi
aBitmapInfoCache[BITMAPS::pintype_openemit].emplace_back( BITMAPS::pintype_openemit, wxT( "pintype_openemit_dark_32.png" ), 32, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::pintype_nic].emplace_back( BITMAPS::pintype_nic, wxT( "pintype_nic_dark_32.png" ), 32, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::pintype_noconnect].emplace_back( BITMAPS::pintype_noconnect, wxT( "pintype_noconnect_dark_32.png" ), 32, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::small_bottom].emplace_back( BITMAPS::small_bottom, wxT( "small_bottom_dark_32.png" ), 32, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::small_down].emplace_back( BITMAPS::small_down, wxT( "small_down_dark_32.png" ), 32, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::small_edit].emplace_back( BITMAPS::small_edit, wxT( "small_edit_dark_32.png" ), 32, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::small_folder].emplace_back( BITMAPS::small_folder, wxT( "small_folder_dark_32.png" ), 32, wxT( "dark" ) );
@@ -343,6 +350,7 @@ void BuildBitmapInfo( std::unordered_map<BITMAPS, std::vector<BITMAP_INFO>>& aBi
aBitmapInfoCache[BITMAPS::small_plus].emplace_back( BITMAPS::small_plus, wxT( "small_plus_dark_32.png" ), 32, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::small_refresh].emplace_back( BITMAPS::small_refresh, wxT( "small_refresh_dark_32.png" ), 32, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::small_sort_desc].emplace_back( BITMAPS::small_sort_desc, wxT( "small_sort_desc_dark_32.png" ), 32, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::small_top].emplace_back( BITMAPS::small_top, wxT( "small_top_dark_32.png" ), 32, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::small_trash].emplace_back( BITMAPS::small_trash, wxT( "small_trash_dark_32.png" ), 32, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::small_up].emplace_back( BITMAPS::small_up, wxT( "small_up_dark_32.png" ), 32, wxT( "dark" ) );
aBitmapInfoCache[BITMAPS::small_warning].emplace_back( BITMAPS::small_warning, wxT( "small_warning_dark_32.png" ), 32, wxT( "dark" ) );
+2
View File
@@ -573,6 +573,7 @@ enum class BITMAPS : unsigned int
sim_tune,
simulator,
slice_line,
small_bottom,
small_down,
small_edit,
small_folder,
@@ -581,6 +582,7 @@ enum class BITMAPS : unsigned int
small_plus,
small_refresh,
small_sort_desc,
small_top,
small_trash,
small_up,
small_warning,
+94 -4
View File
@@ -59,8 +59,10 @@ DIALOG_ZONE_MANAGER::DIALOG_ZONE_MANAGER( PCB_BASE_FRAME* aParent ) :
m_sizerZoneOP->InsertSpacer( m_sizerZoneOP->GetItemCount(), 5 );
#endif
m_btnMoveTop->SetBitmap( KiBitmapBundle( BITMAPS::small_top ) );
m_btnMoveUp->SetBitmap( KiBitmapBundle( BITMAPS::small_up ) );
m_btnMoveDown->SetBitmap( KiBitmapBundle( BITMAPS::small_down ) );
m_btnMoveBottom->SetBitmap( KiBitmapBundle( BITMAPS::small_bottom ) );
m_panelZoneProperties = new PANEL_ZONE_PROPERTIES( m_zonePanel, aParent, m_zoneSettingsBag );
m_sizerProperties->Add( m_panelZoneProperties, 0, wxEXPAND, 5 );
@@ -95,6 +97,7 @@ DIALOG_ZONE_MANAGER::DIALOG_ZONE_MANAGER( PCB_BASE_FRAME* aParent ) :
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_CHAR_HOOK, &DIALOG_ZONE_MANAGER::OnDialogCharHook, this );
Bind( wxEVT_BOOKCTRL_PAGE_CHANGED,
[this]( wxNotebookEvent& aEvent )
{
@@ -113,6 +116,24 @@ DIALOG_ZONE_MANAGER::~DIALOG_ZONE_MANAGER() = default;
bool DIALOG_ZONE_MANAGER::TransferDataToWindow()
{
m_layerFilter->Clear();
m_layerFilter->Append( _( "All Layers" ) );
LSET usedLayers;
BOARD* board = m_pcbFrame->GetBoard();
for( ZONE* zone : m_zoneSettingsBag.GetClonedZoneList() )
usedLayers |= zone->GetLayerSet();
for( PCB_LAYER_ID layer : usedLayers.Seq() )
{
m_layerFilter->Append( board->GetLayerName( layer ),
reinterpret_cast<void*>( static_cast<intptr_t>( layer ) ) );
}
m_modelZonesOverview->SetLayerFilter( UNDEFINED_LAYER );
m_layerFilter->SetSelection( 0 );
m_modelZonesOverview->ApplyFilter( m_filterCtrl->GetValue(), m_viewZonesOverview->GetSelection() );
if( m_modelZonesOverview->GetCount() )
@@ -131,6 +152,7 @@ void DIALOG_ZONE_MANAGER::PostProcessZoneViewSelChange( wxDataViewItem const& aI
{
m_viewZonesOverview->Select( aItem );
m_viewZonesOverview->EnsureVisible( aItem );
SelectZoneTableItem( aItem );
}
else
{
@@ -158,9 +180,44 @@ void DIALOG_ZONE_MANAGER::PostProcessZoneViewSelChange( wxDataViewItem const& aI
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::OnDialogCharHook( wxKeyEvent& aEvent )
{
if( aEvent.GetKeyCode() == WXK_UP )
{
NavigateZoneSelection( -1 );
}
else if( aEvent.GetKeyCode() == WXK_DOWN )
{
NavigateZoneSelection( 1 );
}
else
{
aEvent.Skip();
}
}
void DIALOG_ZONE_MANAGER::NavigateZoneSelection( int aDirection )
{
unsigned count = m_modelZonesOverview->GetCount();
if( count == 0 )
return;
wxDataViewItem current = m_viewZonesOverview->GetSelection();
unsigned currentRow = 0;
if( current.IsOk() )
currentRow = m_modelZonesOverview->GetRow( current );
int newRow = (int) currentRow + aDirection;
newRow = std::max( 0, std::min( newRow, (int) count - 1 ) );
if( !current.IsOk() || (unsigned) newRow != currentRow )
PostProcessZoneViewSelChange( m_modelZonesOverview->GetItem( (unsigned) newRow ) );
}
@@ -309,6 +366,12 @@ void DIALOG_ZONE_MANAGER::OnDrop( wxDataViewEvent& aEvent )
#endif // wxUSE_DRAG_AND_DROP
void DIALOG_ZONE_MANAGER::OnMoveTopClick( wxCommandEvent& aEvent )
{
MoveSelectedZonePriority( ZONE_INDEX_MOVEMENT::MOVE_TO_TOP );
}
void DIALOG_ZONE_MANAGER::OnMoveUpClick( wxCommandEvent& aEvent )
{
MoveSelectedZonePriority( ZONE_INDEX_MOVEMENT::MOVE_UP );
@@ -321,6 +384,12 @@ void DIALOG_ZONE_MANAGER::OnMoveDownClick( wxCommandEvent& aEvent )
}
void DIALOG_ZONE_MANAGER::OnMoveBottomClick( wxCommandEvent& aEvent )
{
MoveSelectedZonePriority( ZONE_INDEX_MOVEMENT::MOVE_TO_BOTTOM );
}
void DIALOG_ZONE_MANAGER::OnFilterCtrlCancel( wxCommandEvent& aEvent )
{
PostProcessZoneViewSelChange( m_modelZonesOverview->ClearFilter( m_viewZonesOverview->GetSelection() ) );
@@ -352,6 +421,27 @@ void DIALOG_ZONE_MANAGER::OnFilterCtrlEnter( wxCommandEvent& aEvent )
}
void DIALOG_ZONE_MANAGER::OnLayerFilterChanged( wxCommandEvent& aEvent )
{
int sel = m_layerFilter->GetSelection();
if( sel <= 0 )
{
m_modelZonesOverview->SetLayerFilter( UNDEFINED_LAYER );
}
else
{
void* data = m_layerFilter->GetClientData( sel );
PCB_LAYER_ID layer = static_cast<PCB_LAYER_ID>( reinterpret_cast<intptr_t>( data ) );
m_modelZonesOverview->SetLayerFilter( layer );
}
PostProcessZoneViewSelChange(
m_modelZonesOverview->ApplyFilter( m_filterCtrl->GetValue(),
m_viewZonesOverview->GetSelection() ) );
}
void DIALOG_ZONE_MANAGER::OnUpdateDisplayedZonesClick( wxCommandEvent& aEvent )
{
if( m_isFillingZones )
@@ -418,8 +508,8 @@ void DIALOG_ZONE_MANAGER::OnZonesTableRowCountChange( wxCommandEvent& aEvent )
{
unsigned count = aEvent.GetInt();
for( STD_BITMAP_BUTTON* btn : { m_btnMoveDown, m_btnMoveUp } )
btn->Enable( count == m_zoneSettingsBag.GetClonedZoneList().size() );
for( STD_BITMAP_BUTTON* btn : { m_btnMoveTop, m_btnMoveUp, m_btnMoveDown, m_btnMoveBottom } )
btn->Enable( count > 1 );
}
@@ -85,12 +85,15 @@ protected:
void MoveSelectedZonePriority( ZONE_INDEX_MOVEMENT aMove );
void OnMoveTopClick( wxCommandEvent& aEvent ) override;
void OnMoveUpClick( wxCommandEvent& aEvent ) override;
void OnMoveDownClick( wxCommandEvent& aEvent ) override;
void OnMoveBottomClick( wxCommandEvent& aEvent ) override;
void OnFilterCtrlCancel( wxCommandEvent& aEvent ) override;
void OnFilterCtrlSearch( wxCommandEvent& aEvent ) override;
void OnFilterCtrlTextChange( wxCommandEvent& aEvent ) override;
void OnFilterCtrlEnter( wxCommandEvent& aEvent ) override;
void OnLayerFilterChanged( wxCommandEvent& aEvent ) override;
void OnUpdateDisplayedZonesClick( wxCommandEvent& aEvent ) override;
void PostProcessZoneViewSelChange( wxDataViewItem const& aItem );
@@ -102,6 +105,8 @@ private:
void GenericProcessChar( wxKeyEvent& event );
void OnIdle( wxIdleEvent& aEvent );
void NavigateZoneSelection( int aDirection );
void OnDialogCharHook( wxKeyEvent& aEvent );
private:
PCB_BASE_FRAME* m_pcbFrame;
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a-dirty)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -54,6 +54,21 @@ DIALOG_ZONE_MANAGER_BASE::DIALOG_ZONE_MANAGER_BASE( wxWindow* parent, wxWindowID
m_leftColumn->Add( searchSizer, 0, wxBOTTOM|wxEXPAND|wxTOP, 5 );
wxBoxSizer* layerFilterSizer;
layerFilterSizer = new wxBoxSizer( wxHORIZONTAL );
m_layerFilterLabel = new wxStaticText( m_listPanel, wxID_ANY, _("Layer:"), wxDefaultPosition, wxDefaultSize, 0 );
m_layerFilterLabel->Wrap( -1 );
layerFilterSizer->Add( m_layerFilterLabel, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
wxArrayString m_layerFilterChoices;
m_layerFilter = new wxChoice( m_listPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_layerFilterChoices, 0 );
m_layerFilter->SetSelection( 0 );
layerFilterSizer->Add( m_layerFilter, 1, wxALIGN_CENTER_VERTICAL, 0 );
m_leftColumn->Add( layerFilterSizer, 0, wxBOTTOM|wxEXPAND|wxTOP, 5 );
m_viewZonesOverview = new wxDataViewCtrl( m_listPanel, wxID_ANY, wxDefaultPosition, wxSize( -1,240 ), wxDV_HORIZ_RULES|wxDV_SINGLE|wxDV_VERT_RULES );
m_viewZonesOverview->SetMinSize( wxSize( -1,240 ) );
@@ -61,6 +76,11 @@ DIALOG_ZONE_MANAGER_BASE::DIALOG_ZONE_MANAGER_BASE( wxWindow* parent, wxWindowID
m_sizerZoneOP = new wxBoxSizer( wxHORIZONTAL );
m_btnMoveTop = new STD_BITMAP_BUTTON( m_listPanel, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_btnMoveTop->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_btnMoveTop, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_btnMoveUp = new STD_BITMAP_BUTTON( m_listPanel, wxID_ANY, 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.") );
@@ -71,6 +91,11 @@ DIALOG_ZONE_MANAGER_BASE::DIALOG_ZONE_MANAGER_BASE( wxWindow* parent, wxWindowID
m_sizerZoneOP->Add( m_btnMoveDown, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_btnMoveBottom = new STD_BITMAP_BUTTON( m_listPanel, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_btnMoveBottom->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_btnMoveBottom, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_leftColumn->Add( m_sizerZoneOP, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
@@ -151,12 +176,15 @@ DIALOG_ZONE_MANAGER_BASE::DIALOG_ZONE_MANAGER_BASE( wxWindow* parent, wxWindowID
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_layerFilter->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnLayerFilterChanged ), NULL, this );
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_btnMoveTop->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnMoveTopClick ), NULL, this );
m_btnMoveUp->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnMoveUpClick ), NULL, this );
m_btnMoveDown->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnMoveDownClick ), NULL, this );
m_btnMoveBottom->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnMoveBottomClick ), NULL, this );
m_updateDisplayedZones->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnUpdateDisplayedZonesClick ), NULL, this );
m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnOk ), NULL, this );
}
@@ -169,12 +197,15 @@ DIALOG_ZONE_MANAGER_BASE::~DIALOG_ZONE_MANAGER_BASE()
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_layerFilter->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnLayerFilterChanged ), NULL, this );
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_btnMoveTop->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnMoveTopClick ), NULL, this );
m_btnMoveUp->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnMoveUpClick ), NULL, this );
m_btnMoveDown->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnMoveDownClick ), NULL, this );
m_btnMoveBottom->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnMoveBottomClick ), NULL, this );
m_updateDisplayedZones->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnUpdateDisplayedZonesClick ), NULL, this );
m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_ZONE_MANAGER_BASE::OnOk ), NULL, this );
@@ -424,6 +424,148 @@
</object>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxEXPAND|wxTOP</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">layerFilterSizer</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
<property name="proportion">0</property>
<object class="wxStaticText" 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">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</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="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">Layer:</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_layerFilterLabel</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>
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">0</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">1</property>
<object class="wxChoice" 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">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</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="choices"></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_layerFilter</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="selection">0</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="OnChoice">OnLayerFilterChanged</event>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
@@ -465,6 +607,81 @@
<property name="name">m_sizerZoneOP</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">protected</property>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
<property name="proportion">0</property>
<object class="wxBitmapButton" 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">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="auth_needed">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></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="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></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="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Move Top</property>
<property name="margins"></property>
<property name="markup">0</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_btnMoveTop</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="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; 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="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="OnButtonClick">OnMoveTopClick</event>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
@@ -615,6 +832,81 @@
<event name="OnButtonClick">OnMoveDownClick</event>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
<property name="proportion">0</property>
<object class="wxBitmapButton" 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">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="auth_needed">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></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="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></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="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Move Bottom</property>
<property name="margins"></property>
<property name="markup">0</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_btnMoveBottom</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="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; 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="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="OnButtonClick">OnMoveBottomClick</event>
</object>
</object>
</object>
</object>
</object>
+10 -1
View File
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a-dirty)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -21,6 +21,8 @@ class STD_BITMAP_BUTTON;
#include <wx/settings.h>
#include <wx/checkbox.h>
#include <wx/sizer.h>
#include <wx/stattext.h>
#include <wx/choice.h>
#include <wx/dataview.h>
#include <wx/bmpbuttn.h>
#include <wx/bitmap.h>
@@ -49,10 +51,14 @@ class DIALOG_ZONE_MANAGER_BASE : public DIALOG_SHIM
wxSearchCtrl* m_filterCtrl;
wxCheckBox* m_checkName;
wxCheckBox* m_checkNet;
wxStaticText* m_layerFilterLabel;
wxChoice* m_layerFilter;
wxDataViewCtrl* m_viewZonesOverview;
wxBoxSizer* m_sizerZoneOP;
STD_BITMAP_BUTTON* m_btnMoveTop;
STD_BITMAP_BUTTON* m_btnMoveUp;
STD_BITMAP_BUTTON* m_btnMoveDown;
STD_BITMAP_BUTTON* m_btnMoveBottom;
wxPanel* m_zonePanel;
wxBoxSizer* m_rightColumn;
wxBoxSizer* m_sizerProperties;
@@ -71,12 +77,15 @@ class DIALOG_ZONE_MANAGER_BASE : public DIALOG_SHIM
virtual void OnFilterCtrlSearch( wxCommandEvent& event ) { event.Skip(); }
virtual void OnFilterCtrlTextChange( wxCommandEvent& event ) { event.Skip(); }
virtual void OnFilterCtrlEnter( wxCommandEvent& event ) { event.Skip(); }
virtual void OnLayerFilterChanged( wxCommandEvent& event ) { event.Skip(); }
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 OnMoveTopClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnMoveUpClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnMoveDownClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnMoveBottomClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnUpdateDisplayedZonesClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnOk( wxCommandEvent& event ) { event.Skip(); }
+52 -2
View File
@@ -98,7 +98,8 @@ MODEL_ZONES_OVERVIEW::MODEL_ZONES_OVERVIEW( wxWindow* aParent, PCB_BASE_FRAME* a
m_frame( aFrame ),
m_zoneSettingsBag( aZoneSettingsBag ),
m_sortByName( true ),
m_sortByNet( true )
m_sortByNet( true ),
m_layerFilter( UNDEFINED_LAYER )
{
m_filteredZones = m_zoneSettingsBag.GetClonedZoneList();
Reset( m_filteredZones.size() );
@@ -153,6 +154,12 @@ void MODEL_ZONES_OVERVIEW::EnableFitterByNet( bool aEnable )
}
void MODEL_ZONES_OVERVIEW::SetLayerFilter( PCB_LAYER_ID aLayer )
{
m_layerFilter = aLayer;
}
bool MODEL_ZONES_OVERVIEW::SetValueByRow( const wxVariant& aVariant, unsigned aRow, unsigned aCol )
{
return {};
@@ -209,6 +216,39 @@ std::optional<unsigned> MODEL_ZONES_OVERVIEW::MoveZoneIndex( unsigned aIndex, ZO
return SwapZonePriority( aIndex, aIndex + 1 );
break;
case ZONE_INDEX_MOVEMENT::MOVE_TO_TOP:
if( aIndex >= 1 && GetCount() > 1 )
{
unsigned cur = aIndex;
while( cur > 0 )
{
SwapZonePriority( cur, cur - 1 );
--cur;
}
return 0u;
}
break;
case ZONE_INDEX_MOVEMENT::MOVE_TO_BOTTOM:
if( aIndex + 1 < GetCount() )
{
unsigned cur = aIndex;
const unsigned last = GetCount() - 1;
while( cur < last )
{
SwapZonePriority( cur, cur + 1 );
++cur;
}
return last;
}
break;
}
return std::optional<unsigned>{};
@@ -251,6 +291,9 @@ wxDataViewItem MODEL_ZONES_OVERVIEW::ApplyFilter( wxString const& aFilterText, w
for( ZONE* zone : m_zoneSettingsBag.GetClonedZoneList() )
{
if( m_layerFilter != UNDEFINED_LAYER && !zone->GetLayerSet().Contains( m_layerFilter ) )
continue;
if( ( m_sortByName && zone->GetZoneName().Lower().Contains( lowerFilterText ) )
|| ( m_sortByNet && zone->GetNetname().Lower().Contains( lowerFilterText ) ) )
{
@@ -271,7 +314,14 @@ wxDataViewItem MODEL_ZONES_OVERVIEW::ClearFilter( wxDataViewItem aSelection )
return {};
ZONE* zone = GetZone( aSelection );
m_filteredZones = m_zoneSettingsBag.GetClonedZoneList();
m_filteredZones.clear();
for( ZONE* z : m_zoneSettingsBag.GetClonedZoneList() )
{
if( m_layerFilter == UNDEFINED_LAYER || z->GetLayerSet().Contains( m_layerFilter ) )
m_filteredZones.push_back( z );
}
SortFilteredZones();
Reset( GetCount() );
OnRowCountChange();
+6 -1
View File
@@ -48,7 +48,9 @@ wxDECLARE_EVENT( EVT_ZONES_OVERVIEW_COUNT_CHANGE, wxCommandEvent );
enum class ZONE_INDEX_MOVEMENT
{
MOVE_UP,
MOVE_DOWN
MOVE_DOWN,
MOVE_TO_TOP,
MOVE_TO_BOTTOM
};
@@ -83,6 +85,8 @@ public:
void EnableFitterByNet( bool aEnable );
void SetLayerFilter( PCB_LAYER_ID aLayer );
void GetValueByRow( wxVariant& aVariant, unsigned aRow, unsigned aCol ) const override;
bool SetValueByRow( const wxVariant& aVariant, unsigned aRow, unsigned aCol ) override;
@@ -137,4 +141,5 @@ private:
std::vector<ZONE*> m_filteredZones;
bool m_sortByName;
bool m_sortByNet;
PCB_LAYER_ID m_layerFilter;
};
+39 -2
View File
@@ -24,6 +24,8 @@
#include "zone_preview_canvas.h"
#include <wx/gdicmn.h>
#include <wx/intl.h>
#include <wx/menu.h>
#include <wx/string.h>
#include <base_screen.h>
@@ -104,7 +106,9 @@ ZONE_PREVIEW_CANVAS::ZONE_PREVIEW_CANVAS( BOARD* aPcb, ZONE* aZone, PCB_LAYER_ID
const wxPoint& aPosition, const wxSize& aSize, GAL_TYPE aGalType ) :
PCB_DRAW_PANEL_GAL( aParentWindow, aWindowId, aPosition, wxDefaultSize, aOptions, aGalType ),
m_pcb( aPcb ),
m_pcb_bounding_box( std::make_unique<BOARD_EDGES_BOUNDING_ITEM>( aPcb->GetBoardEdgesBoundingBox() ) )
m_layer( aLayer ),
m_pcb_bounding_box( std::make_unique<BOARD_EDGES_BOUNDING_ITEM>( aPcb->GetBoardEdgesBoundingBox() ) ),
m_zoomLocked( false )
{
m_view->UseDrawPriority( true );
m_painter = std::make_unique<ZONE_PAINTER>( m_gal, FRAME_FOOTPRINT_PREVIEW );
@@ -126,10 +130,28 @@ ZONE_PREVIEW_CANVAS::ZONE_PREVIEW_CANVAS( BOARD* aPcb, ZONE* aZone, PCB_LAYER_ID
Bind( wxEVT_SIZE,
[this]( wxSizeEvent& aEvent )
{
ZoomFitScreen();
if( !m_zoomLocked )
ZoomFitScreen();
aEvent.Skip();
} );
Bind( wxEVT_RIGHT_UP,
[this]( wxMouseEvent& aEvent )
{
wxMenu menu;
menu.Append( wxID_ANY, _( "Zoom to Fit" ) );
menu.Bind( wxEVT_COMMAND_MENU_SELECTED,
[this]( wxCommandEvent& )
{
UnlockZoom();
ZoomFitScreen();
} );
PopupMenu( &menu );
} );
StartDrawing();
RequestRefresh();
}
@@ -192,3 +214,18 @@ void ZONE_PREVIEW_CANVAS::ZoomFitScreen()
m_view->SetCenter( bBox.Centre() );
RequestRefresh();
}
void ZONE_PREVIEW_CANVAS::LockZoom( double aScale, const VECTOR2D& aCenter )
{
m_zoomLocked = true;
m_view->SetScale( aScale );
m_view->SetCenter( aCenter );
RequestRefresh();
}
void ZONE_PREVIEW_CANVAS::UnlockZoom()
{
m_zoomLocked = false;
}
@@ -26,6 +26,7 @@
#pragma once
#include <board_item.h>
#include <math/vector2d.h>
#include <wx/gdicmn.h>
#include <zone.h>
#include <memory>
@@ -50,8 +51,12 @@ public:
const BOX2I GetDocumentExtents( bool aIncludeAllVisible = true ) const;
void LockZoom( double aScale, const VECTOR2D& aCenter );
void UnlockZoom();
private:
BOARD* m_pcb;
int m_layer;
std::unique_ptr<BOARD_EDGES_BOUNDING_ITEM> m_pcb_bounding_box;
bool m_zoomLocked;
};
+28 -6
View File
@@ -33,6 +33,7 @@
#include <board.h>
#include <zone.h>
#include <gal/color4d.h>
#include <view/view.h>
#include <widgets/color_swatch.h>
#include <settings/color_settings.h>
#include <zone_manager/zone_preview_canvas.h>
@@ -75,7 +76,10 @@ private:
ZONE_PREVIEW_NOTEBOOK::ZONE_PREVIEW_NOTEBOOK( wxWindow* aParent, PCB_BASE_FRAME* aPcbFrame ) :
wxNotebook( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize ),
m_pcbFrame( aPcbFrame )
m_pcbFrame( aPcbFrame ),
m_hasSavedZoom( false ),
m_savedScale( 1.0 ),
m_savedCenter( 0, 0 )
{
Bind( wxEVT_BOOKCTRL_PAGE_CHANGED, &ZONE_PREVIEW_NOTEBOOK::OnPageChanged, this );
@@ -108,7 +112,20 @@ void ZONE_PREVIEW_NOTEBOOK::OnZoneSelectionChanged( ZONE* aZone )
int preferredLayer = UNDEFINED_LAYER;
if( GetSelection() >= 0 && GetSelection() < (int) GetPageCount() )
preferredLayer = static_cast<ZONE_PREVIEW_NOTEBOOK_PAGE*>( GetCurrentPage() )->GetLayer();
{
ZONE_PREVIEW_NOTEBOOK_PAGE* curPage =
static_cast<ZONE_PREVIEW_NOTEBOOK_PAGE*>( GetCurrentPage() );
preferredLayer = curPage->GetLayer();
KIGFX::VIEW* view = curPage->GetCanvas()->GetView();
if( view )
{
m_savedScale = view->GetScale();
m_savedCenter = view->GetCenter();
m_hasSavedZoom = true;
}
}
while( GetPageCount() )
RemovePage( 0 );
@@ -122,13 +139,18 @@ void ZONE_PREVIEW_NOTEBOOK::OnZoneSelectionChanged( ZONE* aZone )
{
BOARD* board = m_pcbFrame->GetBoard();
wxString layerName = board->GetLayerName( layer );
ZONE_PREVIEW_NOTEBOOK_PAGE* page = new ZONE_PREVIEW_NOTEBOOK_PAGE( this, board, aZone, layer,
m_pcbFrame->GetGalDisplayOptions(),
m_pcbFrame->GetCanvas()->GetBackend() );
ZONE_PREVIEW_NOTEBOOK_PAGE* page =
new ZONE_PREVIEW_NOTEBOOK_PAGE( this, board, aZone, layer,
m_pcbFrame->GetGalDisplayOptions(),
m_pcbFrame->GetCanvas()->GetBackend() );
AddPage( page, layerName, false, layer );
page->Layout();
page->GetCanvas()->ZoomFitScreen();
if( m_hasSavedZoom )
page->GetCanvas()->LockZoom( m_savedScale, m_savedCenter );
else
page->GetCanvas()->ZoomFitScreen();
if( layer == preferredLayer )
preferredPage = page;
+4 -1
View File
@@ -24,7 +24,7 @@
#pragma once
#include <unordered_map>
#include <math/vector2d.h>
#include <wx/window.h>
#include <wx/panel.h>
#include <wx/notebook.h>
@@ -47,4 +47,7 @@ public:
private:
PCB_BASE_FRAME* m_pcbFrame;
bool m_hasSavedZoom;
double m_savedScale;
VECTOR2D m_savedCenter;
};
+2
View File
@@ -121,6 +121,7 @@ set( BMAPS_SMALL
pintype_openemit
pintype_nic
pintype_noconnect
small_bottom
small_down
small_edit
small_folder
@@ -129,6 +130,7 @@ set( BMAPS_SMALL
small_plus
small_refresh
small_sort_desc
small_top
small_trash
small_up
small_warning
Binary file not shown.

After

Width:  |  Height:  |  Size: 490 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 763 B

@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="Слой_1"
data-name="Слой 1"
viewBox="0 0 16 16"
version="1.1"
sodipodi:docname="small_bottom.svg"
inkscape:version="1.0.1 (c497b03c, 2020-09-10)"
width="16"
height="16">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1609"
inkscape:window-height="995"
id="namedview30"
showgrid="true"
inkscape:zoom="36.325579"
inkscape:cx="9.5840332"
inkscape:cy="13"
inkscape:window-x="2021"
inkscape:window-y="23"
inkscape:window-maximized="0"
inkscape:document-rotation="0"
inkscape:current-layer="Слой_1">
<inkscape:grid
type="xygrid"
id="grid_kicad"
spacingx="0.5"
spacingy="0.5"
color="#9999ff"
opacity="0.13"
empspacing="2" />
</sodipodi:namedview>
<metadata
id="metadata43">
<rdf:RDF>
<cc:Work
rdf:about="">
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>small_bottom</dc:title>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<defs
id="defs160009">
<style
id="style160007">.cls-1{fill:none;stroke:#DED3DD;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px;}</style>
</defs>
<title
id="title160011">small_bottom</title>
<line
class="cls-1"
x1="8"
y1="2"
x2="8"
y2="11"
id="line160013" />
<path
id="polyline160015"
style="fill:none;stroke:#DED3DD;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
d="M 13,6.5 8,11 3,6.5"
class="cls-1"
sodipodi:nodetypes="ccc" />
<line
id="line_cap"
x1="3"
y1="15"
x2="13"
y2="15"
style="fill:none;stroke:#DED3DD;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Capa_1"
x="0px"
y="0px"
viewBox="0 0 16 16"
xml:space="preserve"
sodipodi:docname="small_top.svg"
inkscape:version="1.0.1 (c497b03c, 2020-09-10)"
width="16"
height="16">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1035"
id="namedview39"
showgrid="true"
inkscape:zoom="35.42559"
inkscape:cx="5.1591685"
inkscape:cy="5.7120265"
inkscape:window-x="0"
inkscape:window-y="23"
inkscape:window-maximized="1"
inkscape:current-layer="Capa_1"
showguides="false"
inkscape:document-rotation="0"><inkscape:grid
type="xygrid"
id="grid1426" /></sodipodi:namedview>
<metadata
id="metadata43">
<rdf:RDF>
<cc:Work
rdf:about="">
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/"><cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" /><cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" /><cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" /><cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" /><cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /><cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" /></cc:License></rdf:RDF>
</metadata>
<defs
id="defs41" />
<line
id="line_cap"
x1="3"
y1="1"
x2="13"
y2="1"
style="fill:none;stroke:#DED3DD;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
<path
id="polyline160015"
style="fill:none;stroke:#DED3DD;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
d="M 3,9.5 8,5 13,9.5"
class="cls-1"
sodipodi:nodetypes="ccc" /><line
class="cls-1"
x1="8"
y1="5"
x2="8"
y2="14"
id="line160013"
style="fill:none;stroke:#DED3DD;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="Слой_1"
data-name="Слой 1"
viewBox="0 0 16 16"
version="1.1"
sodipodi:docname="small_bottom.svg"
inkscape:version="1.0.1 (c497b03c, 2020-09-10)"
width="16"
height="16">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1609"
inkscape:window-height="995"
id="namedview30"
showgrid="true"
inkscape:zoom="36.325579"
inkscape:cx="9.5840332"
inkscape:cy="13"
inkscape:window-x="2021"
inkscape:window-y="23"
inkscape:window-maximized="0"
inkscape:document-rotation="0"
inkscape:current-layer="Слой_1">
<inkscape:grid
type="xygrid"
id="grid_kicad"
spacingx="0.5"
spacingy="0.5"
color="#9999ff"
opacity="0.13"
empspacing="2" />
</sodipodi:namedview>
<metadata
id="metadata43">
<rdf:RDF>
<cc:Work
rdf:about="">
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>small_bottom</dc:title>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<defs
id="defs160009">
<style
id="style160007">.cls-1{fill:none;stroke:#545454;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px;}</style>
</defs>
<title
id="title160011">small_bottom</title>
<line
class="cls-1"
x1="8"
y1="2"
x2="8"
y2="11"
id="line160013" />
<path
id="polyline160015"
style="fill:none;stroke:#545454;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
d="M 13,6.5 8,11 3,6.5"
class="cls-1"
sodipodi:nodetypes="ccc" />
<line
id="line_cap"
x1="3"
y1="15"
x2="13"
y2="15"
style="fill:none;stroke:#545454;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Capa_1"
x="0px"
y="0px"
viewBox="0 0 16 16"
xml:space="preserve"
sodipodi:docname="small_top.svg"
inkscape:version="1.0.1 (c497b03c, 2020-09-10)"
width="16"
height="16">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1035"
id="namedview39"
showgrid="true"
inkscape:zoom="35.42559"
inkscape:cx="5.1591685"
inkscape:cy="5.7120265"
inkscape:window-x="0"
inkscape:window-y="23"
inkscape:window-maximized="1"
inkscape:current-layer="Capa_1"
showguides="false"
inkscape:document-rotation="0"><inkscape:grid
type="xygrid"
id="grid1426" /></sodipodi:namedview>
<metadata
id="metadata43">
<rdf:RDF>
<cc:Work
rdf:about="">
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/"><cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" /><cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" /><cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" /><cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" /><cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /><cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" /></cc:License></rdf:RDF>
</metadata>
<defs
id="defs41" />
<line
id="line_cap"
x1="3"
y1="1"
x2="13"
y2="1"
style="fill:none;stroke:#545454;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
<path
id="polyline160015"
style="fill:none;stroke:#545454;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
d="M 3,9.5 8,5 13,9.5"
class="cls-1"
sodipodi:nodetypes="ccc" /><line
class="cls-1"
x1="8"
y1="5"
x2="8"
y2="14"
id="line160013"
style="fill:none;stroke:#545454;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB