Browse Source
Push most of footprint chooser into PANEL_FOOTPRINT_CHOOSER.
Push most of footprint chooser into PANEL_FOOTPRINT_CHOOSER.
Create 2 wrappers for it: DIALOG_FOOTPRINT_CHOOSER and FOOTPRINT_CHOOSER_FRAME. The first now gets called from wxGrid editors, text button editors (such as Change Footprints), etc. Retire FOOTPRINT_VIEWER_FRAME_MODAL. FOOTPRINT_VIEWER_FRAME still exists, but has very few uses at this point.newinvert
31 changed files with 923 additions and 615 deletions
-
56common/eda_draw_frame.cpp
-
2common/kiway.cpp
-
5common/tool/common_tools.cpp
-
2common/widgets/grid_text_button_helpers.cpp
-
2eeschema/dialogs/dialog_field_properties.cpp
-
3eeschema/dialogs/dialog_symbol_fields_table.cpp
-
2eeschema/fields_grid_table.cpp
-
16include/eda_draw_frame.h
-
2include/frame_type.h
-
9include/pcb_base_frame.h
-
8pcbnew/CMakeLists.txt
-
265pcbnew/dialogs/dialog_choose_footprint.cpp
-
148pcbnew/dialogs/dialog_choose_footprint.h
-
4pcbnew/dialogs/dialog_exchange_footprints.cpp
-
73pcbnew/dialogs/dialog_footprint_chooser.cpp
-
53pcbnew/dialogs/dialog_footprint_chooser.h
-
2pcbnew/footprint.cpp
-
239pcbnew/footprint_chooser_frame.cpp
-
90pcbnew/footprint_chooser_frame.h
-
39pcbnew/footprint_viewer_frame.cpp
-
2pcbnew/footprint_viewer_frame.h
-
113pcbnew/load_select_footprint.cpp
-
5pcbnew/pcb_base_frame.cpp
-
2pcbnew/pcb_edit_frame.cpp
-
2pcbnew/pcb_painter.cpp
-
7pcbnew/pcbnew.cpp
-
2pcbnew/tools/board_editor_control.cpp
-
3pcbnew/tools/pcb_selection_tool.cpp
-
1pcbnew/tools/pcb_viewer_tools.cpp
-
282pcbnew/widgets/panel_footprint_chooser.cpp
-
99pcbnew/widgets/panel_footprint_chooser.h
@ -1,265 +0,0 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2014 Henner Zeller <h.zeller@acm.org> |
|||
* Copyright (C) 2016-2021 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 <dialog_choose_footprint.h>
|
|||
#include <algorithm>
|
|||
#include <wx/utils.h>
|
|||
#include <wx/button.h>
|
|||
#include <wx/panel.h>
|
|||
#include <wx/sizer.h>
|
|||
#include <wx/splitter.h>
|
|||
#include <wx/timer.h>
|
|||
#include <wx/wxhtml.h>
|
|||
#include <pcb_base_frame.h>
|
|||
#include <pcbnew_settings.h>
|
|||
#include <pgm_base.h>
|
|||
#include <fp_lib_table.h>
|
|||
#include <settings/settings_manager.h>
|
|||
#include <widgets/lib_tree.h>
|
|||
#include <widgets/footprint_preview_widget.h>
|
|||
#include <widgets/footprint_select_widget.h>
|
|||
#include <kiface_base.h>
|
|||
|
|||
|
|||
DIALOG_CHOOSE_FOOTPRINT::DIALOG_CHOOSE_FOOTPRINT( PCB_BASE_FRAME* aParent, |
|||
const wxString& aTitle, |
|||
wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER>& aAdapter ) |
|||
: DIALOG_SHIM( aParent, wxID_ANY, aTitle, wxDefaultPosition, wxDefaultSize, |
|||
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ), |
|||
m_browser_button( nullptr ), |
|||
m_hsplitter( nullptr ), |
|||
m_vsplitter( nullptr ), |
|||
m_parent( aParent ), |
|||
m_external_browser_requested( false ) |
|||
{ |
|||
auto sizer = new wxBoxSizer( wxVERTICAL ); |
|||
HTML_WINDOW* details = nullptr; |
|||
|
|||
m_vsplitter = new wxSplitterWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, |
|||
wxSP_LIVE_UPDATE ); |
|||
|
|||
m_hsplitter = new wxSplitterWindow( m_vsplitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, |
|||
wxSP_LIVE_UPDATE ); |
|||
|
|||
//Avoid the splitter window being assigned as the Parent to additional windows
|
|||
m_hsplitter->SetExtraStyle( wxWS_EX_TRANSIENT ); |
|||
|
|||
auto detailsPanel = new wxPanel( m_vsplitter ); |
|||
auto detailsSizer = new wxBoxSizer( wxVERTICAL ); |
|||
detailsPanel->SetSizer( detailsSizer ); |
|||
|
|||
details = new HTML_WINDOW( detailsPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, |
|||
wxHW_SCROLLBAR_AUTO ); |
|||
detailsSizer->Add( details, 1, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 5 ); |
|||
detailsPanel->Layout(); |
|||
detailsSizer->Fit( detailsPanel ); |
|||
|
|||
m_vsplitter->SetSashGravity( 0.5 ); |
|||
m_vsplitter->SetMinimumPaneSize( 20 ); |
|||
m_vsplitter->SplitHorizontally( m_hsplitter, detailsPanel ); |
|||
|
|||
sizer->Add( m_vsplitter, 1, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 5 ); |
|||
|
|||
m_tree = new LIB_TREE( m_hsplitter, wxT( "footprints" ), Prj().PcbFootprintLibs(), aAdapter, |
|||
LIB_TREE::FLAGS::ALL_WIDGETS, details ); |
|||
|
|||
m_hsplitter->SetSashGravity( 0.8 ); |
|||
m_hsplitter->SetMinimumPaneSize( 20 ); |
|||
m_hsplitter->SplitVertically( m_tree, ConstructRightPanel( m_hsplitter ) ); |
|||
|
|||
m_dbl_click_timer = new wxTimer( this ); |
|||
|
|||
auto buttonsSizer = new wxBoxSizer( wxHORIZONTAL ); |
|||
|
|||
m_browser_button = new wxButton( this, wxID_ANY, _( "Select with Browser" ) ); |
|||
buttonsSizer->Add( m_browser_button, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 ); |
|||
|
|||
auto sdbSizer = new wxStdDialogButtonSizer(); |
|||
auto okButton = new wxButton( this, wxID_OK ); |
|||
auto cancelButton = new wxButton( this, wxID_CANCEL ); |
|||
sdbSizer->AddButton( okButton ); |
|||
sdbSizer->AddButton( cancelButton ); |
|||
sdbSizer->Realize(); |
|||
|
|||
buttonsSizer->Add( sdbSizer, 1, wxALL, 5 ); |
|||
|
|||
sizer->Add( buttonsSizer, 0, wxEXPAND | wxLEFT, 5 ); |
|||
SetSizer( sizer ); |
|||
|
|||
aAdapter->FinishTreeInitialization(); |
|||
|
|||
SetupStandardButtons(); |
|||
|
|||
Bind( wxEVT_TIMER, &DIALOG_CHOOSE_FOOTPRINT::OnCloseTimer, this, m_dbl_click_timer->GetId() ); |
|||
Bind( SYMBOL_PRESELECTED, &DIALOG_CHOOSE_FOOTPRINT::OnComponentPreselected, this ); |
|||
Bind( SYMBOL_SELECTED, &DIALOG_CHOOSE_FOOTPRINT::OnComponentSelected, this ); |
|||
m_browser_button->Bind( wxEVT_COMMAND_BUTTON_CLICKED, &DIALOG_CHOOSE_FOOTPRINT::OnUseBrowser, |
|||
this ); |
|||
|
|||
Layout(); |
|||
|
|||
if( PCBNEW_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<PCBNEW_SETTINGS>() ) |
|||
{ |
|||
// We specify the width of the right window (m_symbol_view_panel), because specify
|
|||
// the width of the left window does not work as expected when SetSashGravity() is called
|
|||
if( cfg->m_FootprintChooser.sash_h < 0 ) |
|||
cfg->m_FootprintChooser.sash_h = horizPixelsFromDU( 220 ); |
|||
|
|||
m_hsplitter->SetSashPosition( cfg->m_FootprintChooser.sash_h ); |
|||
|
|||
if( cfg->m_FootprintChooser.sash_v < 0 ) |
|||
cfg->m_FootprintChooser.sash_v = horizPixelsFromDU( 230 ); |
|||
|
|||
if( m_vsplitter ) |
|||
m_vsplitter->SetSashPosition( cfg->m_FootprintChooser.sash_v ); |
|||
|
|||
int w = cfg->m_FootprintChooser.width < 0 ? |
|||
horizPixelsFromDU( 440 ) : cfg->m_FootprintChooser.width; |
|||
int h = cfg->m_FootprintChooser.height < 0 ? |
|||
horizPixelsFromDU( 340 ) : cfg->m_FootprintChooser.height; |
|||
SetSize( wxSize( w, h ) ); |
|||
|
|||
aAdapter->SetSortMode( (LIB_TREE_MODEL_ADAPTER::SORT_MODE) cfg->m_FootprintChooser.sort_mode ); |
|||
} |
|||
|
|||
SetInitialFocus( m_tree->GetFocusTarget() ); |
|||
} |
|||
|
|||
|
|||
DIALOG_CHOOSE_FOOTPRINT::~DIALOG_CHOOSE_FOOTPRINT() |
|||
{ |
|||
Unbind( wxEVT_TIMER, &DIALOG_CHOOSE_FOOTPRINT::OnCloseTimer, this ); |
|||
Unbind( SYMBOL_PRESELECTED, &DIALOG_CHOOSE_FOOTPRINT::OnComponentPreselected, this ); |
|||
Unbind( SYMBOL_SELECTED, &DIALOG_CHOOSE_FOOTPRINT::OnComponentSelected, this ); |
|||
m_browser_button->Unbind( wxEVT_COMMAND_BUTTON_CLICKED, |
|||
&DIALOG_CHOOSE_FOOTPRINT::OnUseBrowser, this ); |
|||
|
|||
// I am not sure the following two lines are necessary,
|
|||
// but they will not hurt anyone
|
|||
m_dbl_click_timer->Stop(); |
|||
delete m_dbl_click_timer; |
|||
|
|||
if( PCBNEW_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<PCBNEW_SETTINGS>() ) |
|||
{ |
|||
cfg->m_FootprintChooser.width = GetSize().x; |
|||
cfg->m_FootprintChooser.height = GetSize().y; |
|||
cfg->m_FootprintChooser.sash_h = m_hsplitter->GetSashPosition(); |
|||
|
|||
if( m_vsplitter ) |
|||
cfg->m_FootprintChooser.sash_v = m_vsplitter->GetSashPosition(); |
|||
|
|||
cfg->m_FootprintChooser.sort_mode = m_tree->GetSortMode(); |
|||
} |
|||
} |
|||
|
|||
|
|||
wxPanel* DIALOG_CHOOSE_FOOTPRINT::ConstructRightPanel( wxWindow* aParent ) |
|||
{ |
|||
auto panel = new wxPanel( aParent ); |
|||
auto sizer = new wxBoxSizer( wxVERTICAL ); |
|||
|
|||
m_preview_ctrl = new FOOTPRINT_PREVIEW_WIDGET( panel, Kiway() ); |
|||
m_preview_ctrl->SetUserUnits( GetUserUnits() ); |
|||
sizer->Add( m_preview_ctrl, 1, wxEXPAND | wxTOP | wxRIGHT, 5 ); |
|||
|
|||
panel->SetSizer( sizer ); |
|||
panel->Layout(); |
|||
sizer->Fit( panel ); |
|||
|
|||
return panel; |
|||
} |
|||
|
|||
|
|||
LIB_ID DIALOG_CHOOSE_FOOTPRINT::GetSelectedLibId() const |
|||
{ |
|||
return m_tree->GetSelectedLibId(); |
|||
} |
|||
|
|||
|
|||
void DIALOG_CHOOSE_FOOTPRINT::OnUseBrowser( wxCommandEvent& aEvent ) |
|||
{ |
|||
m_external_browser_requested = true; |
|||
EndQuasiModal( wxID_OK ); |
|||
} |
|||
|
|||
|
|||
void DIALOG_CHOOSE_FOOTPRINT::OnCloseTimer( wxTimerEvent& aEvent ) |
|||
{ |
|||
// Hack handler because of eaten MouseUp event. See
|
|||
// DIALOG_CHOOSE_FOOTPRINT::OnComponentSelected for the beginning
|
|||
// of this spaghetti noodle.
|
|||
|
|||
auto state = wxGetMouseState(); |
|||
|
|||
if( state.LeftIsDown() ) |
|||
{ |
|||
// Mouse hasn't been raised yet, so fire the timer again. Otherwise the
|
|||
// purpose of this timer is defeated.
|
|||
m_dbl_click_timer->StartOnce( DIALOG_CHOOSE_FOOTPRINT::DblClickDelay ); |
|||
} |
|||
else |
|||
{ |
|||
EndQuasiModal( wxID_OK ); |
|||
} |
|||
} |
|||
|
|||
|
|||
void DIALOG_CHOOSE_FOOTPRINT::OnComponentPreselected( wxCommandEvent& aEvent ) |
|||
{ |
|||
if( !m_preview_ctrl || !m_preview_ctrl->IsInitialized() ) |
|||
return; |
|||
|
|||
LIB_ID lib_id = m_tree->GetSelectedLibId(); |
|||
|
|||
if( !lib_id.IsValid() ) |
|||
{ |
|||
m_preview_ctrl->SetStatusText( _( "No footprint selected" ) ); |
|||
} |
|||
else |
|||
{ |
|||
m_preview_ctrl->ClearStatus(); |
|||
m_preview_ctrl->DisplayFootprint( lib_id ); |
|||
} |
|||
} |
|||
|
|||
|
|||
void DIALOG_CHOOSE_FOOTPRINT::OnComponentSelected( wxCommandEvent& aEvent ) |
|||
{ |
|||
if( m_tree->GetSelectedLibId().IsValid() ) |
|||
{ |
|||
// Got a selection. We can't just end the modal dialog here, because
|
|||
// wx leaks some events back to the parent window (in particular, the
|
|||
// MouseUp following a double click).
|
|||
//
|
|||
// NOW, here's where it gets really fun. wxTreeListCtrl eats MouseUp.
|
|||
// This isn't really feasible to bypass without a fully custom
|
|||
// wxDataViewCtrl implementation, and even then might not be fully
|
|||
// possible (docs are vague). To get around this, we use a one-shot
|
|||
// timer to schedule the dialog close.
|
|||
//
|
|||
// See DIALOG_CHOOSE_FOOTPRINT::OnCloseTimer for the other end of this
|
|||
// spaghetti noodle.
|
|||
m_dbl_click_timer->StartOnce( DIALOG_CHOOSE_FOOTPRINT::DblClickDelay ); |
|||
} |
|||
} |
|||
@ -1,148 +0,0 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2014 Henner Zeller <h.zeller@acm.org> |
|||
* Copyright (C) 2014-2018 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_CHOOSE_FOOTPRINT_H |
|||
#define DIALOG_CHOOSE_FOOTPRINT_H |
|||
|
|||
#include "dialog_shim.h" |
|||
#include <fp_tree_model_adapter.h> |
|||
#include <footprint_info.h> |
|||
#include <widgets/footprint_preview_widget.h> |
|||
|
|||
class wxStaticBitmap; |
|||
class wxTextCtrl; |
|||
class wxStdDialogButtonSizer; |
|||
class wxDataViewCtrl; |
|||
class wxHtmlLinkEvent; |
|||
class wxPanel; |
|||
class wxChoice; |
|||
class wxButton; |
|||
class wxTimer; |
|||
class wxSplitterWindow; |
|||
|
|||
class PCB_BASE_FRAME; |
|||
class LIB_TREE; |
|||
class FOOTPRINT; |
|||
|
|||
|
|||
/** |
|||
* Dialog class to select a footprint from the libraries. This is the master |
|||
* View class in a Model-View-Adapter (mediated MVC) architecture. The other |
|||
* pieces are in: |
|||
* |
|||
* - Adapter: CMP_TREE_MODEL_ADAPTER in common/cmp_tree_model_adapter.h |
|||
* - Model: CMP_TREE_NODE and descendants in common/cmp_tree_model.h |
|||
* |
|||
* Because everything is tied together in the adapter class, see that file |
|||
* for thorough documentation. A simple example usage follows: |
|||
* |
|||
* // Create the adapter class |
|||
* auto adapter( FP_TREE_MODEL_ADAPTER::Create( Prj().PcbFootprintLibs() ) ); |
|||
* |
|||
* // Perform any configuration of adapter properties here |
|||
* adapter->SetPreselectNode( "LIB_NICKNAME", "FP_NAME", 2 ); |
|||
* |
|||
* // Initialize model from #FP_LIB_TABLE |
|||
* libNicknames = libs->GetLogicalLibs(); |
|||
* |
|||
* for( auto nickname : libNicknames ) |
|||
* { |
|||
* adapter->AddLibrary( nickname ); |
|||
* } |
|||
* |
|||
* // Create and display dialog |
|||
* DIALOG_CHOOSE_FOOTPRINT dlg( this, title, adapter, 1 ); |
|||
* bool selected = ( dlg.ShowModal() != wxID_CANCEL ); |
|||
* |
|||
* // Receive part |
|||
* if( selected ) |
|||
* { |
|||
* int unit; |
|||
* #LIB_ID id = dlg.GetSelectedAlias( &unit ); |
|||
* do_something( id, unit ); |
|||
* } |
|||
* |
|||
*/ |
|||
class DIALOG_CHOOSE_FOOTPRINT : public DIALOG_SHIM |
|||
{ |
|||
public: |
|||
/** |
|||
* Create dialog to choose component. |
|||
* |
|||
* @param aParent a PCB_BASE_FRAME parent window. |
|||
* @param aAdapter FP_TREE_MODEL_ADAPTER::PTR. See CMP_TREE_MODEL_ADAPTER |
|||
* for documentation. |
|||
*/ |
|||
DIALOG_CHOOSE_FOOTPRINT( PCB_BASE_FRAME* aParent, const wxString& aTitle, |
|||
wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER>& aAdapter ); |
|||
|
|||
~DIALOG_CHOOSE_FOOTPRINT(); |
|||
|
|||
/** |
|||
* To be called after this dialog returns from ShowModal(). |
|||
* |
|||
* @return the #LIB_ID of the symbol that has been selected. |
|||
*/ |
|||
LIB_ID GetSelectedLibId() const; |
|||
|
|||
/** Function IsExternalBrowserSelected |
|||
* |
|||
* @return true, iff the user pressed the thumbnail view of the component to |
|||
* launch the component browser. |
|||
*/ |
|||
bool IsExternalBrowserSelected() const |
|||
{ |
|||
return m_external_browser_requested; |
|||
} |
|||
|
|||
protected: |
|||
static constexpr int DblClickDelay = 100; // milliseconds |
|||
|
|||
wxPanel* ConstructRightPanel( wxWindow* aParent ); |
|||
|
|||
void OnCloseTimer( wxTimerEvent& aEvent ); |
|||
void OnUseBrowser( wxCommandEvent& aEvent ); |
|||
|
|||
void OnComponentPreselected( wxCommandEvent& aEvent ); |
|||
|
|||
/** |
|||
* Handle the selection of an item. This is called when either the search |
|||
* box or the tree receive an Enter, or the tree receives a double click. |
|||
* If the item selected is a category, it is expanded or collapsed; if it |
|||
* is a component, the component is picked. |
|||
*/ |
|||
void OnComponentSelected( wxCommandEvent& aEvent ); |
|||
|
|||
wxTimer* m_dbl_click_timer; |
|||
wxButton* m_browser_button; |
|||
wxSplitterWindow* m_hsplitter; |
|||
wxSplitterWindow* m_vsplitter; |
|||
|
|||
FOOTPRINT_PREVIEW_WIDGET* m_preview_ctrl; |
|||
LIB_TREE* m_tree; |
|||
|
|||
PCB_BASE_FRAME* m_parent; |
|||
bool m_external_browser_requested; |
|||
}; |
|||
|
|||
#endif /* DIALOG_CHOOSE_FOOTPRINT_H */ |
|||
@ -0,0 +1,73 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* 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 <dialog_footprint_chooser.h>
|
|||
#include <wx/sizer.h>
|
|||
#include <wx/button.h>
|
|||
#include <pcb_base_frame.h>
|
|||
#include <widgets/panel_footprint_chooser.h>
|
|||
|
|||
|
|||
DIALOG_FOOTPRINT_CHOOSER::DIALOG_FOOTPRINT_CHOOSER( PCB_BASE_FRAME* aParent, |
|||
const LIB_ID& aPreselect, |
|||
const wxArrayString& aFootprintHistoryList ) : |
|||
DIALOG_SHIM( aParent, wxID_ANY, _( "Choose Footprint" ), wxDefaultPosition, wxDefaultSize, |
|||
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ) |
|||
{ |
|||
wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL ); |
|||
m_chooserPanel = new PANEL_FOOTPRINT_CHOOSER( aParent, this, aFootprintHistoryList, |
|||
[this]() |
|||
{ |
|||
EndQuasiModal( wxID_OK ); |
|||
} ); |
|||
|
|||
sizer->Add( m_chooserPanel, 1, wxEXPAND, 5 ); |
|||
|
|||
if( aPreselect.IsValid() ) |
|||
m_chooserPanel->SetPreselect( aPreselect ); |
|||
|
|||
SetTitle( GetTitle() + wxString::Format( _( " (%d items loaded)" ), |
|||
m_chooserPanel->GetItemCount() ) ); |
|||
|
|||
wxStdDialogButtonSizer* sdbSizer = new wxStdDialogButtonSizer(); |
|||
wxButton* okButton = new wxButton( this, wxID_OK ); |
|||
wxButton* cancelButton = new wxButton( this, wxID_CANCEL ); |
|||
sdbSizer->AddButton( okButton ); |
|||
sdbSizer->AddButton( cancelButton ); |
|||
sdbSizer->Realize(); |
|||
|
|||
sizer->Add( sdbSizer, 0, wxEXPAND | wxALL, 5 ); |
|||
SetSizer( sizer ); |
|||
|
|||
SetInitialFocus( m_chooserPanel->GetFocusTarget() ); |
|||
SetupStandardButtons(); |
|||
|
|||
m_chooserPanel->FinishSetup(); |
|||
Layout(); |
|||
} |
|||
|
|||
|
|||
LIB_ID DIALOG_FOOTPRINT_CHOOSER::GetSelectedLibId() const |
|||
{ |
|||
return m_chooserPanel->GetSelectedLibId(); |
|||
} |
|||
@ -0,0 +1,53 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* 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_FOOTPRINT_CHOOSER_H |
|||
#define DIALOG_FOOTPRINT_CHOOSER_H |
|||
|
|||
#include <lib_id.h> |
|||
#include "dialog_shim.h" |
|||
|
|||
|
|||
class PCB_BASE_FRAME; |
|||
class PANEL_FOOTPRINT_CHOOSER; |
|||
|
|||
|
|||
class DIALOG_FOOTPRINT_CHOOSER : public DIALOG_SHIM |
|||
{ |
|||
public: |
|||
DIALOG_FOOTPRINT_CHOOSER( PCB_BASE_FRAME* aParent, const LIB_ID& aPreselect, |
|||
const wxArrayString& aFootprintHistoryList ); |
|||
|
|||
~DIALOG_FOOTPRINT_CHOOSER() {}; |
|||
|
|||
/** |
|||
* To be called after this dialog returns from ShowModal(). |
|||
* |
|||
* @return the #LIB_ID of the symbol that has been selected. |
|||
*/ |
|||
LIB_ID GetSelectedLibId() const; |
|||
|
|||
protected: |
|||
PANEL_FOOTPRINT_CHOOSER* m_chooserPanel; |
|||
}; |
|||
|
|||
#endif /* DIALOG_FOOTPRINT_CHOOSER_H */ |
|||
@ -0,0 +1,239 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* 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 <pgm_base.h>
|
|||
#include <kiway.h>
|
|||
#include <kiway_express.h>
|
|||
#include <wx/button.h>
|
|||
#include <kiplatform/ui.h>
|
|||
#include <widgets/panel_footprint_chooser.h>
|
|||
#include <settings/settings_manager.h>
|
|||
#include <footprint_editor_settings.h>
|
|||
#include <footprint_chooser_frame.h>
|
|||
|
|||
|
|||
static wxArrayString s_FootprintHistoryList; |
|||
static unsigned s_FootprintHistoryMaxCount = 8; |
|||
|
|||
static void AddFootprintToHistory( const wxString& aName ) |
|||
{ |
|||
// Remove duplicates
|
|||
for( int ii = s_FootprintHistoryList.GetCount() - 1; ii >= 0; --ii ) |
|||
{ |
|||
if( s_FootprintHistoryList[ ii ] == aName ) |
|||
s_FootprintHistoryList.RemoveAt((size_t) ii ); |
|||
} |
|||
|
|||
// Add the new name at the beginning of the history list
|
|||
s_FootprintHistoryList.Insert( aName, 0 ); |
|||
|
|||
// Remove extra names
|
|||
while( s_FootprintHistoryList.GetCount() >= s_FootprintHistoryMaxCount ) |
|||
s_FootprintHistoryList.RemoveAt( s_FootprintHistoryList.GetCount() - 1 ); |
|||
} |
|||
|
|||
|
|||
BEGIN_EVENT_TABLE( FOOTPRINT_CHOOSER_FRAME, PCB_BASE_FRAME ) |
|||
EVT_MENU( wxID_CLOSE, FOOTPRINT_CHOOSER_FRAME::CloseFootprintChooser ) |
|||
EVT_BUTTON( wxID_OK, FOOTPRINT_CHOOSER_FRAME::OnOK ) |
|||
EVT_BUTTON( wxID_CANCEL, FOOTPRINT_CHOOSER_FRAME::CloseFootprintChooser ) |
|||
EVT_PAINT( FOOTPRINT_CHOOSER_FRAME::OnPaint ) |
|||
END_EVENT_TABLE() |
|||
|
|||
|
|||
#define PARENT_STYLE ( wxRESIZE_BORDER | wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxCLIP_CHILDREN \
|
|||
| wxWANTS_CHARS | wxFRAME_NO_TASKBAR | wxFRAME_FLOAT_ON_PARENT ) |
|||
#define MODAL_STYLE ( wxRESIZE_BORDER | wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxCLIP_CHILDREN \
|
|||
| wxWANTS_CHARS | wxFRAME_NO_TASKBAR | wxSTAY_ON_TOP ) |
|||
|
|||
|
|||
FOOTPRINT_CHOOSER_FRAME::FOOTPRINT_CHOOSER_FRAME( KIWAY* aKiway, wxWindow* aParent ) : |
|||
PCB_BASE_FRAME( aKiway, aParent, FRAME_FOOTPRINT_CHOOSER, _( "Footprint Chooser" ), |
|||
wxDefaultPosition, wxDefaultSize, aParent ? PARENT_STYLE : MODAL_STYLE, |
|||
FOOTPRINT_CHOOSER_FRAME_NAME ), |
|||
m_comp( LIB_ID(), wxEmptyString, wxEmptyString, KIID_PATH(), {} ) |
|||
{ |
|||
SetModal( true ); |
|||
|
|||
wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL ); |
|||
m_chooserPanel = new PANEL_FOOTPRINT_CHOOSER( this, this, s_FootprintHistoryList, |
|||
[this]() |
|||
{ |
|||
wxCommandEvent dummy; |
|||
OnOK( dummy ); |
|||
} ); |
|||
|
|||
sizer->Add( m_chooserPanel, 1, wxEXPAND, 5 ); |
|||
|
|||
wxStdDialogButtonSizer* sdbSizer = new wxStdDialogButtonSizer(); |
|||
wxButton* okButton = new wxButton( this, wxID_OK ); |
|||
wxButton* cancelButton = new wxButton( this, wxID_CANCEL ); |
|||
sdbSizer->AddButton( okButton ); |
|||
sdbSizer->AddButton( cancelButton ); |
|||
sdbSizer->Realize(); |
|||
|
|||
sizer->Add( sdbSizer, 0, wxEXPAND | wxALL, 5 ); |
|||
SetSizer( sizer ); |
|||
|
|||
SetTitle( GetTitle() + wxString::Format( _( " (%d items loaded)" ), |
|||
m_chooserPanel->GetItemCount() ) ); |
|||
|
|||
Layout(); |
|||
m_chooserPanel->FinishSetup(); |
|||
} |
|||
|
|||
|
|||
void FOOTPRINT_CHOOSER_FRAME::doCloseWindow() |
|||
{ |
|||
// Only dismiss a modal frame once, so that the return values set by
|
|||
// the prior DismissModal() are not bashed for ShowModal().
|
|||
if( !IsDismissed() ) |
|||
DismissModal( false ); |
|||
|
|||
// window to be destroyed by the caller of KIWAY_PLAYER::ShowModal()
|
|||
} |
|||
|
|||
|
|||
WINDOW_SETTINGS* FOOTPRINT_CHOOSER_FRAME::GetWindowSettings( APP_SETTINGS_BASE* aCfg ) |
|||
{ |
|||
PCBNEW_SETTINGS* cfg = dynamic_cast<PCBNEW_SETTINGS*>( aCfg ); |
|||
wxCHECK_MSG( cfg, nullptr, wxT( "config not existing" ) ); |
|||
|
|||
return &cfg->m_FootprintViewer; |
|||
} |
|||
|
|||
|
|||
COLOR_SETTINGS* FOOTPRINT_CHOOSER_FRAME::GetColorSettings( bool aForceRefresh ) const |
|||
{ |
|||
auto* settings = Pgm().GetSettingsManager().GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>(); |
|||
|
|||
if( settings ) |
|||
return Pgm().GetSettingsManager().GetColorSettings( settings->m_ColorTheme ); |
|||
else |
|||
return Pgm().GetSettingsManager().GetColorSettings(); |
|||
} |
|||
|
|||
|
|||
void FOOTPRINT_CHOOSER_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail ) |
|||
{ |
|||
// JEY TODO: don't delete this just yet. We can use it to pass in symbol info so that we
|
|||
// can filter on footprint filters, symbol pin count, etc.
|
|||
|
|||
const std::string& payload = mail.GetPayload(); |
|||
|
|||
switch( mail.Command() ) |
|||
{ |
|||
case MAIL_SYMBOL_NETLIST: |
|||
{ |
|||
/*
|
|||
* Symbol netlist format: |
|||
* library:footprint |
|||
* reference |
|||
* value |
|||
* pinName,netName,pinFunction,pinType |
|||
* pinName,netName,pinFunction,pinType |
|||
* ... |
|||
*/ |
|||
std::vector<std::string> strings = split( payload, "\r" ); |
|||
LIB_ID libid; |
|||
|
|||
if( strings.size() >= 3 ) |
|||
{ |
|||
libid.Parse( strings[0] ); |
|||
|
|||
m_comp.SetFPID( libid ); |
|||
m_comp.SetReference( strings[1] ); |
|||
m_comp.SetValue( strings[2] ); |
|||
|
|||
m_comp.ClearNets(); |
|||
|
|||
for( size_t ii = 3; ii < strings.size(); ++ii ) |
|||
{ |
|||
std::vector<std::string> pinData = split( strings[ii], "," ); |
|||
m_comp.AddNet( pinData[0], pinData[1], pinData[2], pinData[3] ); |
|||
} |
|||
} |
|||
|
|||
break; |
|||
} |
|||
|
|||
default: |
|||
break; |
|||
} |
|||
} |
|||
|
|||
|
|||
bool FOOTPRINT_CHOOSER_FRAME::ShowModal( wxString* aFootprint, wxWindow* aParent ) |
|||
{ |
|||
if( aFootprint && !aFootprint->IsEmpty() ) |
|||
{ |
|||
LIB_ID fpid; |
|||
|
|||
fpid.Parse( *aFootprint, true ); |
|||
|
|||
if( fpid.IsValid() ) |
|||
m_chooserPanel->SetPreselect( fpid ); |
|||
} |
|||
|
|||
return KIWAY_PLAYER::ShowModal( aFootprint, aParent ); |
|||
} |
|||
|
|||
|
|||
void FOOTPRINT_CHOOSER_FRAME::OnPaint( wxPaintEvent& aEvent ) |
|||
{ |
|||
if( m_firstPaintEvent ) |
|||
{ |
|||
KIPLATFORM::UI::FixupCancelButtonCmdKeyCollision( this ); |
|||
KIPLATFORM::UI::ForceFocus( m_chooserPanel->GetFocusTarget() ); |
|||
|
|||
m_firstPaintEvent = false; |
|||
} |
|||
|
|||
aEvent.Skip(); |
|||
} |
|||
|
|||
|
|||
void FOOTPRINT_CHOOSER_FRAME::OnOK( wxCommandEvent& aEvent ) |
|||
{ |
|||
LIB_ID fpID = m_chooserPanel->GetSelectedLibId(); |
|||
|
|||
if( fpID.IsValid() ) |
|||
{ |
|||
wxString footprint = fpID.Format(); |
|||
|
|||
AddFootprintToHistory( footprint ); |
|||
DismissModal( true, footprint ); |
|||
} |
|||
else |
|||
{ |
|||
DismissModal( false ); |
|||
} |
|||
} |
|||
|
|||
|
|||
void FOOTPRINT_CHOOSER_FRAME::CloseFootprintChooser( wxCommandEvent& aEvent ) |
|||
{ |
|||
Close( false ); |
|||
} |
|||
|
|||
|
|||
@ -0,0 +1,90 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* 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 FOOTPRINT_CHOOSER_FRAME_H |
|||
#define FOOTPRINT_CHOOSER_FRAME_H |
|||
|
|||
|
|||
#include <wx/gdicmn.h> |
|||
#include <pcb_base_frame.h> |
|||
#include <pcbnew_settings.h> |
|||
#include <netlist_reader/pcb_netlist.h> |
|||
|
|||
class PANEL_FOOTPRINT_CHOOSER; |
|||
|
|||
namespace PCB { struct IFACE; } |
|||
|
|||
|
|||
class FOOTPRINT_CHOOSER_FRAME : public PCB_BASE_FRAME |
|||
{ |
|||
public: |
|||
~FOOTPRINT_CHOOSER_FRAME() {}; |
|||
|
|||
///< @copydoc PCB_BASE_FRAME::GetModel() |
|||
BOARD_ITEM_CONTAINER* GetModel() const override { return nullptr; } |
|||
|
|||
/** |
|||
* @param aFootprint an optional FPID string to initialize the viewer with and to |
|||
* return a selected footprint through. |
|||
*/ |
|||
bool ShowModal( wxString* aFootprint, wxWindow* aParent ) override; |
|||
|
|||
void KiwayMailIn( KIWAY_EXPRESS& mail ) override; |
|||
|
|||
protected: |
|||
FOOTPRINT_CHOOSER_FRAME( KIWAY* aKiway, wxWindow* aParent ); |
|||
|
|||
void doReCreateMenuBar() override {} |
|||
|
|||
private: |
|||
void OnPaint( wxPaintEvent& aEvent ); |
|||
void OnOK( wxCommandEvent& aEvent ); |
|||
|
|||
void doCloseWindow() override; |
|||
void CloseFootprintChooser( wxCommandEvent& aEvent ); |
|||
|
|||
WINDOW_SETTINGS* GetWindowSettings( APP_SETTINGS_BASE* aCfg ) override; |
|||
COLOR_SETTINGS* GetColorSettings( bool aForceRefresh ) const override; |
|||
|
|||
// Required pure-virtual methods |
|||
void ReCreateHToolbar() override {}; |
|||
void ReCreateVToolbar() override {}; |
|||
void SaveCopyInUndoList( EDA_ITEM*, UNDO_REDO ) override {} |
|||
void SaveCopyInUndoList( const PICKED_ITEMS_LIST&, UNDO_REDO ) override {} |
|||
void AppendCopyToUndoList( const PICKED_ITEMS_LIST&, UNDO_REDO ) override {} |
|||
|
|||
DECLARE_EVENT_TABLE() |
|||
|
|||
friend struct PCB::IFACE; // constructor called from here only |
|||
|
|||
private: |
|||
PANEL_FOOTPRINT_CHOOSER* m_chooserPanel; |
|||
COMPONENT m_comp; |
|||
|
|||
// On MacOS (at least) SetFocus() calls made in the constructor will fail because a |
|||
// window that isn't yet visible will return false to AcceptsFocus(). So we must delay |
|||
// the initial-focus SetFocus() call to the first paint event. |
|||
bool m_firstPaintEvent; |
|||
}; |
|||
|
|||
#endif // FOOTPRINT_CHOOSER_FRAME_H |
|||
@ -0,0 +1,282 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2014 Henner Zeller <h.zeller@acm.org> |
|||
* Copyright (C) 2016-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 <widgets/panel_footprint_chooser.h>
|
|||
#include <wx/button.h>
|
|||
#include <wx/panel.h>
|
|||
#include <wx/sizer.h>
|
|||
#include <wx/splitter.h>
|
|||
#include <wx/timer.h>
|
|||
#include <wx/wxhtml.h>
|
|||
#include <pcb_base_frame.h>
|
|||
#include <pcbnew_settings.h>
|
|||
#include <pgm_base.h>
|
|||
#include <fp_lib_table.h>
|
|||
#include <settings/settings_manager.h>
|
|||
#include <widgets/lib_tree.h>
|
|||
#include <widgets/footprint_preview_widget.h>
|
|||
#include <widgets/wx_progress_reporters.h>
|
|||
#include <footprint_info_impl.h>
|
|||
|
|||
|
|||
PANEL_FOOTPRINT_CHOOSER::PANEL_FOOTPRINT_CHOOSER( PCB_BASE_FRAME* aFrame, wxTopLevelWindow* aParent, |
|||
const wxArrayString& aFootprintHistoryList, |
|||
std::function<void()> aCloseHandler ) : |
|||
wxPanel( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize ), |
|||
m_hsplitter( nullptr ), |
|||
m_vsplitter( nullptr ), |
|||
m_frame( aFrame ), |
|||
m_closeHandler( std::move( aCloseHandler ) ) |
|||
{ |
|||
FP_LIB_TABLE* fpTable = aFrame->Prj().PcbFootprintLibs(); |
|||
|
|||
// Load footprint files:
|
|||
WX_PROGRESS_REPORTER* progressReporter = new WX_PROGRESS_REPORTER( aParent, |
|||
_( "Loading Footprint Libraries" ), 3 ); |
|||
GFootprintList.ReadFootprintFiles( fpTable, nullptr, progressReporter ); |
|||
|
|||
// Force immediate deletion of the WX_PROGRESS_REPORTER. Do not use Destroy(), or use
|
|||
// Destroy() followed by wxSafeYield() because on Windows, APP_PROGRESS_DIALOG and
|
|||
// WX_PROGRESS_REPORTER have some side effects on the event loop manager. For instance, a
|
|||
// subsequent call to ShowModal() or ShowQuasiModal() for a dialog following the use of a
|
|||
// WX_PROGRESS_REPORTER results in incorrect modal or quasi modal behavior.
|
|||
delete progressReporter; |
|||
|
|||
if( GFootprintList.GetErrorCount() ) |
|||
GFootprintList.DisplayErrors( aParent ); |
|||
|
|||
m_adapter = FP_TREE_MODEL_ADAPTER::Create( aFrame, fpTable ); |
|||
FP_TREE_MODEL_ADAPTER* adapter = static_cast<FP_TREE_MODEL_ADAPTER*>( m_adapter.get() ); |
|||
|
|||
std::vector<LIB_TREE_ITEM*> historyInfos; |
|||
|
|||
for( const wxString& item : aFootprintHistoryList ) |
|||
{ |
|||
LIB_TREE_ITEM* fp_info = GFootprintList.GetFootprintInfo( item ); |
|||
|
|||
// this can be null, for example, if the footprint has been deleted from a library.
|
|||
if( fp_info != nullptr ) |
|||
historyInfos.push_back( fp_info ); |
|||
} |
|||
|
|||
adapter->DoAddLibrary( wxT( "-- " ) + _( "Recently Used" ) + wxT( " --" ), wxEmptyString, |
|||
historyInfos, false, true ); |
|||
|
|||
if( historyInfos.size() ) |
|||
adapter->SetPreselectNode( historyInfos[0]->GetLibId(), 0 ); |
|||
|
|||
adapter->AddLibraries( aFrame ); |
|||
|
|||
wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL ); |
|||
HTML_WINDOW* details = nullptr; |
|||
|
|||
m_vsplitter = new wxSplitterWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, |
|||
wxSP_LIVE_UPDATE | wxSP_3DSASH ); |
|||
|
|||
m_hsplitter = new wxSplitterWindow( m_vsplitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, |
|||
wxSP_LIVE_UPDATE | wxSP_3DSASH ); |
|||
|
|||
//Avoid the splitter window being assigned as the Parent to additional windows
|
|||
m_hsplitter->SetExtraStyle( wxWS_EX_TRANSIENT ); |
|||
|
|||
auto detailsPanel = new wxPanel( m_vsplitter ); |
|||
auto detailsSizer = new wxBoxSizer( wxVERTICAL ); |
|||
detailsPanel->SetSizer( detailsSizer ); |
|||
|
|||
details = new HTML_WINDOW( detailsPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, |
|||
wxHW_SCROLLBAR_AUTO ); |
|||
detailsSizer->Add( details, 1, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 5 ); |
|||
detailsPanel->Layout(); |
|||
detailsSizer->Fit( detailsPanel ); |
|||
|
|||
m_vsplitter->SetSashGravity( 0.5 ); |
|||
m_vsplitter->SetMinimumPaneSize( 20 ); |
|||
m_vsplitter->SplitHorizontally( m_hsplitter, detailsPanel ); |
|||
|
|||
sizer->Add( m_vsplitter, 1, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 5 ); |
|||
|
|||
m_tree = new LIB_TREE( m_hsplitter, wxT( "footprints" ), fpTable, m_adapter, |
|||
LIB_TREE::FLAGS::ALL_WIDGETS, details ); |
|||
|
|||
m_hsplitter->SetSashGravity( 0.8 ); |
|||
m_hsplitter->SetMinimumPaneSize( 20 ); |
|||
|
|||
wxPanel* rightPanel = new wxPanel( m_hsplitter ); |
|||
wxBoxSizer* rightPanelSizer = new wxBoxSizer( wxVERTICAL ); |
|||
|
|||
m_preview_ctrl = new FOOTPRINT_PREVIEW_WIDGET( rightPanel, m_frame->Kiway() ); |
|||
m_preview_ctrl->SetUserUnits( m_frame->GetUserUnits() ); |
|||
rightPanelSizer->Add( m_preview_ctrl, 1, wxEXPAND | wxTOP | wxRIGHT, 5 ); |
|||
|
|||
rightPanel->SetSizer( rightPanelSizer ); |
|||
rightPanel->Layout(); |
|||
rightPanelSizer->Fit( rightPanel ); |
|||
|
|||
m_hsplitter->SplitVertically( m_tree, rightPanel ); |
|||
|
|||
m_dbl_click_timer = new wxTimer( this ); |
|||
|
|||
SetSizer( sizer ); |
|||
|
|||
m_adapter->FinishTreeInitialization(); |
|||
|
|||
Bind( wxEVT_TIMER, &PANEL_FOOTPRINT_CHOOSER::onCloseTimer, this, m_dbl_click_timer->GetId() ); |
|||
Bind( SYMBOL_PRESELECTED, &PANEL_FOOTPRINT_CHOOSER::onComponentPreselected, this ); |
|||
Bind( SYMBOL_SELECTED, &PANEL_FOOTPRINT_CHOOSER::onComponentSelected, this ); |
|||
|
|||
Layout(); |
|||
} |
|||
|
|||
|
|||
PANEL_FOOTPRINT_CHOOSER::~PANEL_FOOTPRINT_CHOOSER() |
|||
{ |
|||
Unbind( wxEVT_TIMER, &PANEL_FOOTPRINT_CHOOSER::onCloseTimer, this ); |
|||
Unbind( SYMBOL_PRESELECTED, &PANEL_FOOTPRINT_CHOOSER::onComponentPreselected, this ); |
|||
Unbind( SYMBOL_SELECTED, &PANEL_FOOTPRINT_CHOOSER::onComponentSelected, this ); |
|||
|
|||
// I am not sure the following two lines are necessary, but they will not hurt anyone
|
|||
m_dbl_click_timer->Stop(); |
|||
delete m_dbl_click_timer; |
|||
|
|||
if( PCBNEW_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<PCBNEW_SETTINGS>() ) |
|||
{ |
|||
// Save any changes to column widths, etc.
|
|||
m_adapter->SaveSettings(); |
|||
|
|||
cfg->m_FootprintChooser.width = GetParent()->GetSize().x; |
|||
cfg->m_FootprintChooser.height = GetParent()->GetSize().y; |
|||
cfg->m_FootprintChooser.sash_h = m_hsplitter->GetSashPosition(); |
|||
|
|||
if( m_vsplitter ) |
|||
cfg->m_FootprintChooser.sash_v = m_vsplitter->GetSashPosition(); |
|||
|
|||
cfg->m_FootprintChooser.sort_mode = m_tree->GetSortMode(); |
|||
} |
|||
} |
|||
|
|||
|
|||
void PANEL_FOOTPRINT_CHOOSER::FinishSetup() |
|||
{ |
|||
if( PCBNEW_SETTINGS* settings = Pgm().GetSettingsManager().GetAppSettings<PCBNEW_SETTINGS>() ) |
|||
{ |
|||
auto horizPixelsFromDU = |
|||
[&]( int x ) -> int |
|||
{ |
|||
wxSize sz( x, 0 ); |
|||
return GetParent()->ConvertDialogToPixels( sz ).x; |
|||
}; |
|||
|
|||
PCBNEW_SETTINGS::FOOTPRINT_CHOOSER& cfg = settings->m_FootprintChooser; |
|||
|
|||
int w = cfg.width < 0 ? horizPixelsFromDU( 440 ) : cfg.width; |
|||
int h = cfg.height < 0 ? horizPixelsFromDU( 340 ) : cfg.height; |
|||
|
|||
GetParent()->SetSize( wxSize( w, h ) ); |
|||
GetParent()->Layout(); |
|||
|
|||
// We specify the width of the right window (m_symbol_view_panel), because specify
|
|||
// the width of the left window does not work as expected when SetSashGravity() is called
|
|||
if( cfg.sash_h < 0 ) |
|||
cfg.sash_h = horizPixelsFromDU( 220 ); |
|||
|
|||
m_hsplitter->SetSashPosition( cfg.sash_h ); |
|||
|
|||
if( cfg.sash_v < 0 ) |
|||
cfg.sash_v = horizPixelsFromDU( 230 ); |
|||
|
|||
if( m_vsplitter ) |
|||
m_vsplitter->SetSashPosition( cfg.sash_v ); |
|||
|
|||
m_adapter->SetSortMode( (LIB_TREE_MODEL_ADAPTER::SORT_MODE) cfg.sort_mode ); |
|||
} |
|||
} |
|||
|
|||
|
|||
void PANEL_FOOTPRINT_CHOOSER::SetPreselect( const LIB_ID& aPreselect ) |
|||
{ |
|||
m_adapter->SetPreselectNode( aPreselect, 0 ); |
|||
} |
|||
|
|||
|
|||
LIB_ID PANEL_FOOTPRINT_CHOOSER::GetSelectedLibId() const |
|||
{ |
|||
return m_tree->GetSelectedLibId(); |
|||
} |
|||
|
|||
|
|||
void PANEL_FOOTPRINT_CHOOSER::onCloseTimer( wxTimerEvent& aEvent ) |
|||
{ |
|||
// Hack because of eaten MouseUp event. See PANEL_FOOTPRINT_CHOOSER::onComponentSelected
|
|||
// for the beginning of this spaghetti noodle.
|
|||
|
|||
auto state = wxGetMouseState(); |
|||
|
|||
if( state.LeftIsDown() ) |
|||
{ |
|||
// Mouse hasn't been raised yet, so fire the timer again. Otherwise the
|
|||
// purpose of this timer is defeated.
|
|||
m_dbl_click_timer->StartOnce( PANEL_FOOTPRINT_CHOOSER::DblClickDelay ); |
|||
} |
|||
else |
|||
{ |
|||
m_closeHandler(); |
|||
} |
|||
} |
|||
|
|||
|
|||
void PANEL_FOOTPRINT_CHOOSER::onComponentPreselected( wxCommandEvent& aEvent ) |
|||
{ |
|||
if( !m_preview_ctrl || !m_preview_ctrl->IsInitialized() ) |
|||
return; |
|||
|
|||
LIB_ID lib_id = m_tree->GetSelectedLibId(); |
|||
|
|||
if( !lib_id.IsValid() ) |
|||
{ |
|||
m_preview_ctrl->SetStatusText( _( "No footprint selected" ) ); |
|||
} |
|||
else |
|||
{ |
|||
m_preview_ctrl->ClearStatus(); |
|||
m_preview_ctrl->DisplayFootprint( lib_id ); |
|||
} |
|||
} |
|||
|
|||
|
|||
void PANEL_FOOTPRINT_CHOOSER::onComponentSelected( wxCommandEvent& aEvent ) |
|||
{ |
|||
if( m_tree->GetSelectedLibId().IsValid() ) |
|||
{ |
|||
// Got a selection. We can't just end the modal dialog here, because wx leaks some
|
|||
// events back to the parent window (in particular, the MouseUp following a double click).
|
|||
//
|
|||
// NOW, here's where it gets really fun. wxTreeListCtrl eats MouseUp. This isn't really
|
|||
// feasible to bypass without a fully custom wxDataViewCtrl implementation, and even then
|
|||
// might not be fully possible (docs are vague). To get around this, we use a one-shot
|
|||
// timer to schedule the dialog close.
|
|||
//
|
|||
// See PANEL_FOOTPRINT_CHOOSER::onCloseTimer for the other end of this spaghetti noodle.
|
|||
m_dbl_click_timer->StartOnce( PANEL_FOOTPRINT_CHOOSER::DblClickDelay ); |
|||
} |
|||
} |
|||
@ -0,0 +1,99 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2014-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_FOOTPRINT_CHOOSER_H |
|||
#define PANEL_FOOTPRINT_CHOOSER_H |
|||
|
|||
#include "dialog_shim.h" |
|||
#include <widgets/lib_tree.h> |
|||
#include <fp_tree_model_adapter.h> |
|||
#include <footprint_info.h> |
|||
#include <widgets/footprint_preview_widget.h> |
|||
|
|||
class wxTimer; |
|||
class wxSplitterWindow; |
|||
|
|||
class PCB_BASE_FRAME; |
|||
|
|||
|
|||
class PANEL_FOOTPRINT_CHOOSER : public wxPanel |
|||
{ |
|||
public: |
|||
/** |
|||
* Create dialog to choose component. |
|||
* |
|||
* @param aFrame the parent frame (FRAME_PCB_EDIT_FRAME or FOOTPRINT_CHOOSER_FRAME) |
|||
* @param aParent the parent window (DIALOG_SHIM or FOOTPRINT_CHOOSER_FRAME) |
|||
* @param aCloseHandler a handler to be called on double-click of a footprint |
|||
*/ |
|||
PANEL_FOOTPRINT_CHOOSER( PCB_BASE_FRAME* aFrame, wxTopLevelWindow* aParent, |
|||
const wxArrayString& aFootprintHistoryList, |
|||
std::function<void()> aCloseHandler ); |
|||
|
|||
~PANEL_FOOTPRINT_CHOOSER(); |
|||
|
|||
void FinishSetup(); |
|||
|
|||
void SetPreselect( const LIB_ID& aPreselect ); |
|||
|
|||
/** |
|||
* To be called after this dialog returns from ShowModal(). |
|||
* |
|||
* @return the #LIB_ID of the symbol that has been selected. |
|||
*/ |
|||
LIB_ID GetSelectedLibId() const; |
|||
|
|||
int GetItemCount() const { return m_adapter->GetItemCount(); } |
|||
|
|||
wxWindow* GetFocusTarget() const { return m_tree->GetFocusTarget(); } |
|||
|
|||
|
|||
protected: |
|||
static constexpr int DblClickDelay = 100; // milliseconds |
|||
|
|||
void onCloseTimer( wxTimerEvent& aEvent ); |
|||
|
|||
void onComponentPreselected( wxCommandEvent& aEvent ); |
|||
|
|||
/** |
|||
* Handle the selection of an item. This is called when either the search |
|||
* box or the tree receive an Enter, or the tree receives a double click. |
|||
* If the item selected is a category, it is expanded or collapsed; if it |
|||
* is a component, the component is picked. |
|||
*/ |
|||
void onComponentSelected( wxCommandEvent& aEvent ); |
|||
|
|||
protected: |
|||
wxTimer* m_dbl_click_timer; |
|||
wxSplitterWindow* m_hsplitter; |
|||
wxSplitterWindow* m_vsplitter; |
|||
|
|||
wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER> m_adapter; |
|||
|
|||
FOOTPRINT_PREVIEW_WIDGET* m_preview_ctrl; |
|||
LIB_TREE* m_tree; |
|||
|
|||
PCB_BASE_FRAME* m_frame; |
|||
std::function<void()> m_closeHandler; |
|||
}; |
|||
|
|||
#endif /* PANEL_FOOTPRINT_CHOOSER_H */ |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue