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.
This commit is contained in:
parent
4e77c9089e
commit
1047130046
|
@ -122,45 +122,51 @@ EDA_DRAW_FRAME::EDA_DRAW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrame
|
|||
|
||||
m_auimgr.SetFlags( wxAUI_MGR_DEFAULT );
|
||||
|
||||
CreateStatusBar( 8 )->SetDoubleBuffered( true );
|
||||
if( ( aStyle & wxFRAME_NO_TASKBAR ) == 0 )
|
||||
{
|
||||
CreateStatusBar( 8 )->SetDoubleBuffered( true );
|
||||
|
||||
// set the size of the status bar subwindows:
|
||||
|
||||
wxWindow* stsbar = GetStatusBar();
|
||||
int spacer = KIUI::GetTextSize( wxT( "M" ), stsbar ).x * 2;
|
||||
wxWindow* stsbar = GetStatusBar();
|
||||
int spacer = KIUI::GetTextSize( wxT( "M" ), stsbar ).x * 2;
|
||||
|
||||
int dims[] = {
|
||||
int dims[] =
|
||||
{
|
||||
// remainder of status bar on far left is set to a default or whatever is left over.
|
||||
-1,
|
||||
|
||||
// remainder of status bar on far left is set to a default or whatever is left over.
|
||||
-1,
|
||||
// When using GetTextSize() remember the width of character '1' is not the same
|
||||
// as the width of '0' unless the font is fixed width, and it usually won't be.
|
||||
|
||||
// When using GetTextSize() remember the width of character '1' is not the same
|
||||
// as the width of '0' unless the font is fixed width, and it usually won't be.
|
||||
// zoom:
|
||||
KIUI::GetTextSize( wxT( "Z 762000" ), stsbar ).x,
|
||||
|
||||
// zoom:
|
||||
KIUI::GetTextSize( wxT( "Z 762000" ), stsbar ).x + spacer,
|
||||
// cursor coords
|
||||
KIUI::GetTextSize( wxT( "X 1234.1234 Y 1234.1234" ), stsbar ).x,
|
||||
|
||||
// cursor coords
|
||||
KIUI::GetTextSize( wxT( "X 1234.1234 Y 1234.1234" ), stsbar ).x + spacer,
|
||||
// delta distances
|
||||
KIUI::GetTextSize( wxT( "dx 1234.1234 dy 1234.1234 dist 1234.1234" ), stsbar ).x,
|
||||
|
||||
// delta distances
|
||||
KIUI::GetTextSize( wxT( "dx 1234.1234 dy 1234.1234 dist 1234.1234" ), stsbar ).x + spacer,
|
||||
// grid size
|
||||
KIUI::GetTextSize( wxT( "grid X 1234.1234 Y 1234.1234" ), stsbar ).x,
|
||||
|
||||
// grid size
|
||||
KIUI::GetTextSize( wxT( "grid X 1234.1234 Y 1234.1234" ), stsbar ).x + spacer,
|
||||
// units display, Inches is bigger than mm
|
||||
KIUI::GetTextSize( _( "Inches" ), stsbar ).x,
|
||||
|
||||
// units display, Inches is bigger than mm
|
||||
KIUI::GetTextSize( _( "Inches" ), stsbar ).x + spacer,
|
||||
// Size for the "Current Tool" panel; longest string from SetTool()
|
||||
KIUI::GetTextSize( wxT( "Add layer alignment target" ), stsbar ).x,
|
||||
|
||||
// Size for the "Current Tool" panel; longest string from SetTool()
|
||||
KIUI::GetTextSize( wxT( "Add layer alignment target" ), stsbar ).x + spacer,
|
||||
// constraint mode
|
||||
KIUI::GetTextSize( _( "Constrain to H, V, 45" ), stsbar ).x
|
||||
};
|
||||
|
||||
// constraint mode
|
||||
KIUI::GetTextSize( _( "Constrain to H, V, 45" ), stsbar ).x + spacer
|
||||
};
|
||||
for( size_t ii = 1; ii < arrayDim( dims ); ii++ )
|
||||
dims[ii] += spacer;
|
||||
|
||||
SetStatusWidths( arrayDim( dims ), dims );
|
||||
stsbar->SetFont( KIUI::GetStatusFont( this ) );
|
||||
SetStatusWidths( arrayDim( dims ), dims );
|
||||
stsbar->SetFont( KIUI::GetStatusFont( this ) );
|
||||
}
|
||||
|
||||
// Create child subwindows.
|
||||
GetClientSize( &m_frameSize.x, &m_frameSize.y );
|
||||
|
|
|
@ -381,7 +381,7 @@ KIWAY::FACE_T KIWAY::KifaceType( FRAME_T aFrameType )
|
|||
case FRAME_PCB_EDITOR:
|
||||
case FRAME_FOOTPRINT_EDITOR:
|
||||
case FRAME_FOOTPRINT_VIEWER:
|
||||
case FRAME_FOOTPRINT_VIEWER_MODAL:
|
||||
case FRAME_FOOTPRINT_CHOOSER:
|
||||
case FRAME_FOOTPRINT_WIZARD:
|
||||
case FRAME_PCB_DISPLAY3D:
|
||||
return FACE_PCB;
|
||||
|
|
|
@ -354,8 +354,9 @@ int COMMON_TOOLS::doZoomFit( ZOOM_FIT_TYPE_T aFitType )
|
|||
{
|
||||
// Leave a bigger margin for library editors & viewers
|
||||
|
||||
if( frame->IsType( FRAME_FOOTPRINT_VIEWER ) || frame->IsType( FRAME_FOOTPRINT_VIEWER_MODAL )
|
||||
|| frame->IsType( FRAME_SCH_VIEWER ) || frame->IsType( FRAME_SCH_VIEWER_MODAL ) )
|
||||
if( frame->IsType( FRAME_FOOTPRINT_VIEWER )
|
||||
|| frame->IsType( FRAME_SCH_VIEWER )
|
||||
|| frame->IsType( FRAME_SCH_VIEWER_MODAL ) )
|
||||
{
|
||||
margin_scale_factor = 1.30;
|
||||
}
|
||||
|
|
|
@ -267,7 +267,7 @@ protected:
|
|||
if( fpid.IsEmpty() )
|
||||
fpid = m_preselect;
|
||||
|
||||
KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_FOOTPRINT_VIEWER_MODAL, true, m_dlg );
|
||||
KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_dlg );
|
||||
|
||||
if( !m_symbolNetlist.empty() )
|
||||
{
|
||||
|
|
|
@ -220,7 +220,7 @@ void DIALOG_FIELD_PROPERTIES::OnTextValueSelectButtonClick( wxCommandEvent& aEve
|
|||
else
|
||||
fpid = m_TextCtrl->GetValue();
|
||||
|
||||
if( KIWAY_PLAYER* frame = Kiway().Player( FRAME_FOOTPRINT_VIEWER_MODAL, true ) )
|
||||
if( KIWAY_PLAYER* frame = Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true ) )
|
||||
{
|
||||
if( frame->ShowModal( &fpid, this ) )
|
||||
{
|
||||
|
|
|
@ -110,8 +110,7 @@ protected:
|
|||
// pick a footprint using the footprint picker.
|
||||
wxString fpid = m_grid->GetCellValue( m_grid->GetGridCursorRow(),
|
||||
FOOTPRINT_FIELD );
|
||||
KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_FOOTPRINT_VIEWER_MODAL, true,
|
||||
m_dlg );
|
||||
KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_dlg );
|
||||
|
||||
if( frame->ShowModal( &fpid, m_dlg ) )
|
||||
m_grid->SetCellValue( m_grid->GetGridCursorRow(), FOOTPRINT_FIELD, fpid );
|
||||
|
|
|
@ -896,7 +896,7 @@ void FIELDS_GRID_TRICKS::doPopupSelection( wxCommandEvent& event )
|
|||
{
|
||||
// pick a footprint using the footprint picker.
|
||||
wxString fpid = m_grid->GetCellValue( FOOTPRINT_FIELD, FDC_VALUE );
|
||||
KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_FOOTPRINT_VIEWER_MODAL, true, m_dlg );
|
||||
KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_dlg );
|
||||
|
||||
if( frame->ShowModal( &fpid, m_dlg ) )
|
||||
m_grid->SetCellValue( FOOTPRINT_FIELD, FDC_VALUE, fpid );
|
||||
|
|
|
@ -56,14 +56,14 @@ namespace KIGFX
|
|||
using KIGFX::COLOR4D;
|
||||
using KIGFX::RENDER_SETTINGS;
|
||||
|
||||
#define LIB_EDIT_FRAME_NAME wxT( "LibeditFrame" )
|
||||
#define SCH_EDIT_FRAME_NAME wxT( "SchematicFrame" )
|
||||
#define PL_EDITOR_FRAME_NAME wxT( "PlEditorFrame" )
|
||||
#define FOOTPRINT_WIZARD_FRAME_NAME wxT( "FootprintWizard" )
|
||||
#define FOOTPRINT_EDIT_FRAME_NAME wxT( "ModEditFrame" )
|
||||
#define FOOTPRINT_VIEWER_FRAME_NAME wxT( "ModViewFrame" )
|
||||
#define FOOTPRINT_VIEWER_FRAME_NAME_MODAL wxT( "ModViewFrameModal" )
|
||||
#define PCB_EDIT_FRAME_NAME wxT( "PcbFrame" )
|
||||
#define LIB_EDIT_FRAME_NAME wxT( "LibeditFrame" )
|
||||
#define SCH_EDIT_FRAME_NAME wxT( "SchematicFrame" )
|
||||
#define PL_EDITOR_FRAME_NAME wxT( "PlEditorFrame" )
|
||||
#define FOOTPRINT_WIZARD_FRAME_NAME wxT( "FootprintWizard" )
|
||||
#define FOOTPRINT_CHOOSER_FRAME_NAME wxT( "FootprintChooserFrame" )
|
||||
#define FOOTPRINT_EDIT_FRAME_NAME wxT( "ModEditFrame" )
|
||||
#define FOOTPRINT_VIEWER_FRAME_NAME wxT( "ModViewFrame" )
|
||||
#define PCB_EDIT_FRAME_NAME wxT( "PcbFrame" )
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -39,8 +39,8 @@ enum FRAME_T
|
|||
|
||||
FRAME_PCB_EDITOR,
|
||||
FRAME_FOOTPRINT_EDITOR,
|
||||
FRAME_FOOTPRINT_CHOOSER,
|
||||
FRAME_FOOTPRINT_VIEWER,
|
||||
FRAME_FOOTPRINT_VIEWER_MODAL,
|
||||
FRAME_FOOTPRINT_WIZARD,
|
||||
FRAME_PCB_DISPLAY3D,
|
||||
FRAME_FOOTPRINT_PREVIEW,
|
||||
|
|
|
@ -290,7 +290,7 @@ public:
|
|||
*
|
||||
* @param aPreslect if valid, the #LIB_ID to select (otherwise the global history is used).
|
||||
*/
|
||||
FOOTPRINT* SelectFootprintFromLibTree( LIB_ID aPreselect = LIB_ID() );
|
||||
FOOTPRINT* SelectFootprintFromLibrary( LIB_ID aPreselect = LIB_ID() );
|
||||
|
||||
/**
|
||||
* Add the given footprint to the board.
|
||||
|
@ -299,13 +299,6 @@ public:
|
|||
*/
|
||||
virtual void AddFootprintToBoard( FOOTPRINT* aFootprint );
|
||||
|
||||
/**
|
||||
* Launch the footprint viewer to select the name of a footprint to load.
|
||||
*
|
||||
* @return the selected footprint name or an empty string if no selection was made.
|
||||
*/
|
||||
wxString SelectFootprintFromLibBrowser();
|
||||
|
||||
/**
|
||||
* Create the entire board ratsnest.
|
||||
*
|
||||
|
|
|
@ -37,7 +37,6 @@ set( PCBNEW_DIALOGS
|
|||
dialogs/dialog_board_statistics_base.cpp
|
||||
dialogs/dialog_board_reannotate.cpp
|
||||
dialogs/dialog_board_reannotate_base.cpp
|
||||
dialogs/dialog_choose_footprint.cpp
|
||||
dialogs/dialog_cleanup_graphics.cpp
|
||||
dialogs/dialog_cleanup_graphics_base.cpp
|
||||
dialogs/dialog_cleanup_tracks_and_vias.cpp
|
||||
|
@ -50,10 +49,11 @@ set( PCBNEW_DIALOGS
|
|||
dialogs/dialog_dimension_properties_base.cpp
|
||||
dialogs/dialog_drc.cpp
|
||||
dialogs/dialog_drc_base.cpp
|
||||
dialogs/dialog_footprint_checker.cpp
|
||||
dialogs/dialog_footprint_checker_base.cpp
|
||||
dialogs/dialog_footprint_associations.cpp
|
||||
dialogs/dialog_footprint_associations_base.cpp
|
||||
dialogs/dialog_footprint_checker.cpp
|
||||
dialogs/dialog_footprint_checker_base.cpp
|
||||
dialogs/dialog_footprint_chooser.cpp
|
||||
dialogs/dialog_footprint_properties.cpp
|
||||
dialogs/dialog_footprint_properties_base.cpp
|
||||
dialogs/dialog_footprint_properties_fp_editor.cpp
|
||||
|
@ -287,6 +287,7 @@ set( PCBNEW_CLASS_SRCS
|
|||
footprint_editor_utils.cpp
|
||||
footprint_editor_settings.cpp
|
||||
fp_tree_synchronizing_adapter.cpp
|
||||
footprint_chooser_frame.cpp
|
||||
footprint_edit_frame.cpp
|
||||
footprint_libraries_utils.cpp
|
||||
footprint_viewer_frame.cpp
|
||||
|
@ -356,6 +357,7 @@ set( PCBNEW_CLASS_SRCS
|
|||
|
||||
widgets/appearance_controls.cpp
|
||||
widgets/appearance_controls_base.cpp
|
||||
widgets/panel_footprint_chooser.cpp
|
||||
widgets/panel_selection_filter.cpp
|
||||
widgets/panel_selection_filter_base.cpp
|
||||
widgets/pcb_properties_panel.cpp
|
||||
|
|
|
@ -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 */
|
|
@ -394,8 +394,6 @@ void DIALOG_EXCHANGE_FOOTPRINTS::processFootprint( FOOTPRINT* aFootprint, const
|
|||
msg += _( ": OK" );
|
||||
m_MessageWindow->Report( msg, RPT_SEVERITY_ACTION );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
@ -403,7 +401,7 @@ void DIALOG_EXCHANGE_FOOTPRINTS::ViewAndSelectFootprint( wxCommandEvent& event )
|
|||
{
|
||||
wxString newname = m_newID->GetValue();
|
||||
|
||||
KIWAY_PLAYER* frame = Kiway().Player( FRAME_FOOTPRINT_VIEWER_MODAL, true );
|
||||
KIWAY_PLAYER* frame = Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true );
|
||||
|
||||
if( frame->ShowModal( &newname, this ) )
|
||||
{
|
||||
|
|
|
@ -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 */
|
|
@ -1244,7 +1244,7 @@ void FOOTPRINT::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_I
|
|||
UnescapeString( Value().GetText() ) );
|
||||
|
||||
if( aFrame->IsType( FRAME_FOOTPRINT_VIEWER )
|
||||
|| aFrame->IsType( FRAME_FOOTPRINT_VIEWER_MODAL )
|
||||
|| aFrame->IsType( FRAME_FOOTPRINT_CHOOSER )
|
||||
|| aFrame->IsType( FRAME_FOOTPRINT_EDITOR ) )
|
||||
{
|
||||
size_t padCount = GetPadCount( DO_NOT_INCLUDE_NPTH );
|
||||
|
|
|
@ -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
|
|
@ -106,29 +106,12 @@ BEGIN_EVENT_TABLE( FOOTPRINT_VIEWER_FRAME, PCB_BASE_FRAME )
|
|||
END_EVENT_TABLE()
|
||||
|
||||
|
||||
/*
|
||||
* Note: FOOTPRINT_VIEWER_FRAME can be created in "modal mode", or as a usual frame.
|
||||
*/
|
||||
#define PARENT_STYLE ( KICAD_DEFAULT_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT )
|
||||
#define MODAL_STYLE ( KICAD_DEFAULT_DRAWFRAME_STYLE | wxSTAY_ON_TOP )
|
||||
#define NONMODAL_STYLE ( KICAD_DEFAULT_DRAWFRAME_STYLE )
|
||||
|
||||
|
||||
FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent,
|
||||
FRAME_T aFrameType ) :
|
||||
PCB_BASE_FRAME( aKiway, aParent, aFrameType, _( "Footprint Library Browser" ),
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
aFrameType == FRAME_FOOTPRINT_VIEWER_MODAL ? ( aParent ? PARENT_STYLE : MODAL_STYLE )
|
||||
: NONMODAL_STYLE,
|
||||
aFrameType == FRAME_FOOTPRINT_VIEWER_MODAL ? FOOTPRINT_VIEWER_FRAME_NAME_MODAL
|
||||
: FOOTPRINT_VIEWER_FRAME_NAME ),
|
||||
FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||
PCB_BASE_FRAME( aKiway, aParent, FRAME_FOOTPRINT_VIEWER, _( "Footprint Library Browser" ),
|
||||
wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE,
|
||||
FOOTPRINT_VIEWER_FRAME_NAME ),
|
||||
m_comp( LIB_ID(), wxEmptyString, wxEmptyString, KIID_PATH(), {} )
|
||||
{
|
||||
wxASSERT( aFrameType == FRAME_FOOTPRINT_VIEWER_MODAL || aFrameType == FRAME_FOOTPRINT_VIEWER );
|
||||
|
||||
if( aFrameType == FRAME_FOOTPRINT_VIEWER_MODAL )
|
||||
SetModal( true );
|
||||
|
||||
m_aboutTitle = _HKI( "KiCad Footprint Library Viewer" );
|
||||
|
||||
// Force the items to always snap
|
||||
|
@ -1067,13 +1050,13 @@ bool FOOTPRINT_VIEWER_FRAME::ShowModal( wxString* aFootprint, wxWindow* aParent
|
|||
if( WX_INFOBAR* infobar = GetInfoBar() )
|
||||
{
|
||||
button = new wxHyperlinkCtrl( infobar, wxID_ANY,
|
||||
_( "Manage symbol libraries" ),
|
||||
wxEmptyString );
|
||||
button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent & aEvent )>(
|
||||
[=]( wxHyperlinkEvent& aEvent )
|
||||
{
|
||||
InvokePcbLibTableEditor( &Kiway(), this );
|
||||
} ) );
|
||||
_( "Manage footprint libraries" ),
|
||||
wxEmptyString );
|
||||
button->Bind( wxEVT_COMMAND_HYPERLINK,
|
||||
[=]( wxHyperlinkEvent& aEvent )
|
||||
{
|
||||
InvokePcbLibTableEditor( &Kiway(), this );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ public:
|
|||
void KiwayMailIn( KIWAY_EXPRESS& mail ) override;
|
||||
|
||||
protected:
|
||||
FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType );
|
||||
FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent );
|
||||
|
||||
MAGNETIC_SETTINGS m_magneticItems;
|
||||
|
||||
|
|
|
@ -30,15 +30,13 @@ using namespace std::placeholders;
|
|||
#include <footprint.h>
|
||||
#include <confirm.h>
|
||||
#include <connectivity/connectivity_data.h>
|
||||
#include <dialog_choose_footprint.h>
|
||||
#include <dialog_footprint_chooser.h>
|
||||
#include <dialog_get_footprint_by_name.h>
|
||||
#include <eda_list_dialog.h>
|
||||
#include <footprint_edit_frame.h>
|
||||
#include <footprint_info_impl.h>
|
||||
#include <footprint_tree_pane.h>
|
||||
#include <footprint_viewer_frame.h>
|
||||
#include <fp_lib_table.h>
|
||||
#include <core/ignore.h>
|
||||
#include <io_mgr.h>
|
||||
#include <string_utils.h>
|
||||
#include <kiway.h>
|
||||
|
@ -52,8 +50,6 @@ using namespace std::placeholders;
|
|||
#include <widgets/wx_progress_reporters.h>
|
||||
#include <dialog_pad_properties.h>
|
||||
|
||||
#include "fp_tree_model_adapter.h"
|
||||
|
||||
|
||||
static wxArrayString s_FootprintHistoryList;
|
||||
static unsigned s_FootprintHistoryMaxCount = 8;
|
||||
|
@ -181,120 +177,25 @@ bool FOOTPRINT_EDIT_FRAME::LoadFootprintFromBoard( FOOTPRINT* aFootprint )
|
|||
}
|
||||
|
||||
|
||||
wxString PCB_BASE_FRAME::SelectFootprintFromLibBrowser()
|
||||
FOOTPRINT* PCB_BASE_FRAME::SelectFootprintFromLibrary( LIB_ID aPreselect )
|
||||
{
|
||||
// Close the current non-modal Lib browser if opened, and open a new one, in "modal" mode:
|
||||
FOOTPRINT_VIEWER_FRAME* viewer;
|
||||
viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_FOOTPRINT_VIEWER, false );
|
||||
|
||||
if( viewer )
|
||||
{
|
||||
viewer->Destroy();
|
||||
// Destroy() does not immediately delete the viewer, if some events are pending.
|
||||
// (for this reason delete operator cannot be used blindly with "top level" windows)
|
||||
// so gives a slice of time to delete the viewer frame.
|
||||
// This is especially important in OpenGL mode to avoid recreating context before
|
||||
// the old one is deleted.
|
||||
wxSafeYield();
|
||||
}
|
||||
|
||||
SetFocus();
|
||||
|
||||
// Creates the modal Lib browser:
|
||||
viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_FOOTPRINT_VIEWER_MODAL, true, this );
|
||||
|
||||
wxString fpid;
|
||||
ignore_unused( viewer->ShowModal( &fpid, this ) );
|
||||
|
||||
viewer->Destroy();
|
||||
|
||||
return fpid;
|
||||
}
|
||||
|
||||
|
||||
FOOTPRINT* PCB_BASE_FRAME::SelectFootprintFromLibTree( LIB_ID aPreselect )
|
||||
{
|
||||
FP_LIB_TABLE* fpTable = Prj().PcbFootprintLibs();
|
||||
wxString footprintName;
|
||||
LIB_ID fpid;
|
||||
FOOTPRINT* footprint = nullptr;
|
||||
|
||||
static wxString lastComponentName;
|
||||
|
||||
// Load footprint files:
|
||||
WX_PROGRESS_REPORTER* progressReporter = new WX_PROGRESS_REPORTER( this,
|
||||
_( "Loading Footprint Libraries" ), 3 );
|
||||
GFootprintList.ReadFootprintFiles( fpTable, nullptr, progressReporter );
|
||||
bool cancel = progressReporter->WasCancelled();
|
||||
|
||||
// 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( cancel )
|
||||
return nullptr;
|
||||
|
||||
if( GFootprintList.GetErrorCount() )
|
||||
GFootprintList.DisplayErrors( this );
|
||||
|
||||
wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER> ptr = FP_TREE_MODEL_ADAPTER::Create( this, fpTable );
|
||||
FP_TREE_MODEL_ADAPTER* adapter = static_cast<FP_TREE_MODEL_ADAPTER*>( ptr.get() );
|
||||
|
||||
std::vector<LIB_TREE_ITEM*> historyInfos;
|
||||
|
||||
for( const wxString& item : s_FootprintHistoryList )
|
||||
{
|
||||
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( aPreselect.IsValid() )
|
||||
adapter->SetPreselectNode( aPreselect, 0 );
|
||||
else if( historyInfos.size() )
|
||||
adapter->SetPreselectNode( historyInfos[0]->GetLibId(), 0 );
|
||||
|
||||
adapter->AddLibraries( this );
|
||||
|
||||
wxString title;
|
||||
title.Printf( _( "Choose Footprint (%d items loaded)" ), adapter->GetItemCount() );
|
||||
|
||||
DIALOG_CHOOSE_FOOTPRINT dialog( this, title, ptr );
|
||||
DIALOG_FOOTPRINT_CHOOSER dialog( this, aPreselect, s_FootprintHistoryList );
|
||||
|
||||
if( dialog.ShowQuasiModal() == wxID_CANCEL )
|
||||
return nullptr;
|
||||
|
||||
// Save any changes to column widths, etc.
|
||||
adapter->SaveSettings();
|
||||
fpid = dialog.GetSelectedLibId();
|
||||
|
||||
if( dialog.IsExternalBrowserSelected() )
|
||||
{
|
||||
// SelectFootprintFromLibBrowser() returns the "full" footprint name, i.e.
|
||||
// <lib_name>/<footprint name> or LIB_ID format "lib_name:fp_name:rev#"
|
||||
footprintName = SelectFootprintFromLibBrowser();
|
||||
|
||||
if( footprintName.IsEmpty() ) // Cancel command
|
||||
return nullptr;
|
||||
else
|
||||
fpid.Parse( footprintName );
|
||||
}
|
||||
if( !fpid.IsValid() )
|
||||
return nullptr;
|
||||
else
|
||||
{
|
||||
fpid = dialog.GetSelectedLibId();
|
||||
|
||||
if( !fpid.IsValid() )
|
||||
return nullptr;
|
||||
else
|
||||
footprintName = fpid.Format().wx_str();
|
||||
}
|
||||
footprintName = fpid.Format().wx_str();
|
||||
|
||||
try
|
||||
{
|
||||
|
|
|
@ -92,7 +92,8 @@ PCB_BASE_FRAME::~PCB_BASE_FRAME()
|
|||
m_spaceMouse = nullptr;
|
||||
|
||||
// Ensure m_canvasType is up to date, to save it in config
|
||||
m_canvasType = GetCanvas()->GetBackend();
|
||||
if( GetCanvas() )
|
||||
m_canvasType = GetCanvas()->GetBackend();
|
||||
|
||||
delete m_pcb;
|
||||
m_pcb = nullptr;
|
||||
|
@ -992,7 +993,7 @@ PCB_VIEWERS_SETTINGS_BASE* PCB_BASE_FRAME::GetViewerSettingsBase() const
|
|||
return Pgm().GetSettingsManager().GetAppSettings<PCBNEW_SETTINGS>();
|
||||
|
||||
case FRAME_FOOTPRINT_VIEWER:
|
||||
case FRAME_FOOTPRINT_VIEWER_MODAL:
|
||||
case FRAME_FOOTPRINT_CHOOSER:
|
||||
case FRAME_FOOTPRINT_PREVIEW:
|
||||
case FRAME_CVPCB:
|
||||
case FRAME_CVPCB_DISPLAY:
|
||||
|
|
|
@ -1054,7 +1054,7 @@ bool PCB_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
|
|||
if( fpViewer && !fpViewer->Close() ) // Can close footprint viewer?
|
||||
return false;
|
||||
|
||||
fpViewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_FOOTPRINT_VIEWER_MODAL, false );
|
||||
fpViewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_FOOTPRINT_CHOOSER, false );
|
||||
|
||||
if( fpViewer && !fpViewer->Close() ) // Can close modal footprint viewer?
|
||||
return false;
|
||||
|
|
|
@ -88,7 +88,7 @@ PCB_VIEWERS_SETTINGS_BASE* PCB_PAINTER::viewer_settings()
|
|||
return Pgm().GetSettingsManager().GetAppSettings<PCBNEW_SETTINGS>();
|
||||
|
||||
case FRAME_FOOTPRINT_VIEWER:
|
||||
case FRAME_FOOTPRINT_VIEWER_MODAL:
|
||||
case FRAME_FOOTPRINT_CHOOSER:
|
||||
case FRAME_FOOTPRINT_PREVIEW:
|
||||
case FRAME_CVPCB:
|
||||
case FRAME_CVPCB_DISPLAY:
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <fp_lib_table.h>
|
||||
#include <footprint_edit_frame.h>
|
||||
#include <footprint_viewer_frame.h>
|
||||
#include <footprint_chooser_frame.h>
|
||||
#include <footprint_wizard_frame.h>
|
||||
#include <footprint_preview_panel.h>
|
||||
#include <footprint_info_impl.h>
|
||||
|
@ -112,8 +113,10 @@ static struct IFACE : public KIFACE_BASE, public UNITS_PROVIDER
|
|||
return new FOOTPRINT_EDIT_FRAME( aKiway, aParent );
|
||||
|
||||
case FRAME_FOOTPRINT_VIEWER:
|
||||
case FRAME_FOOTPRINT_VIEWER_MODAL:
|
||||
return new FOOTPRINT_VIEWER_FRAME( aKiway, aParent, FRAME_T( aClassId ) );
|
||||
return new FOOTPRINT_VIEWER_FRAME( aKiway, aParent );
|
||||
|
||||
case FRAME_FOOTPRINT_CHOOSER:
|
||||
return new FOOTPRINT_CHOOSER_FRAME( aKiway, aParent );
|
||||
|
||||
case FRAME_FOOTPRINT_WIZARD:
|
||||
return new FOOTPRINT_WIZARD_FRAME( aKiway, aParent, FRAME_T( aClassId ) );
|
||||
|
|
|
@ -1086,7 +1086,7 @@ int BOARD_EDITOR_CONTROL::PlaceFootprint( const TOOL_EVENT& aEvent )
|
|||
if( !fp )
|
||||
{
|
||||
// Pick the footprint to be placed
|
||||
fp = m_frame->SelectFootprintFromLibTree();
|
||||
fp = m_frame->SelectFootprintFromLibrary();
|
||||
|
||||
if( fp == nullptr )
|
||||
continue;
|
||||
|
|
|
@ -150,8 +150,7 @@ bool PCB_SELECTION_TOOL::Init()
|
|||
{
|
||||
PCB_BASE_FRAME* frame = getEditFrame<PCB_BASE_FRAME>();
|
||||
|
||||
if( frame && ( frame->IsType( FRAME_FOOTPRINT_VIEWER )
|
||||
|| frame->IsType( FRAME_FOOTPRINT_VIEWER_MODAL ) ) )
|
||||
if( frame && frame->IsType( FRAME_FOOTPRINT_VIEWER ) )
|
||||
{
|
||||
frame->AddStandardSubMenus( m_menu );
|
||||
return true;
|
||||
|
|
|
@ -67,7 +67,6 @@ int PCB_VIEWER_TOOLS::Show3DViewer( const TOOL_EVENT& aEvent )
|
|||
EDA_3D_VIEWER_FRAME* draw3DFrame = frame()->CreateAndShow3D_Frame();
|
||||
|
||||
if( frame()->IsType( FRAME_FOOTPRINT_VIEWER )
|
||||
|| frame()->IsType( FRAME_FOOTPRINT_VIEWER_MODAL )
|
||||
|| frame()->IsType( FRAME_FOOTPRINT_WIZARD ) )
|
||||
{
|
||||
// A stronger version of Raise() which promotes the window to its parent's level.
|
||||
|
|
|
@ -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 */
|
Loading…
Reference in New Issue