Remove multi-threading for footprint loading.
Also don't load the footprints up front. The whole purpose of the footprint-info stuff is to have enough info about the footprints to filter them *without* loading. After that just load individual footprints as we need them. Fixes https://gitlab.com/kicad/code/kicad/issues/6177
This commit is contained in:
parent
23803fac31
commit
93dc7feea3
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017-2018 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017 Chris Pavlina <pavlina.chris@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
|
@ -24,14 +24,14 @@
|
|||
#include <kiway.h>
|
||||
|
||||
|
||||
FOOTPRINT_PREVIEW_WIDGET::FOOTPRINT_PREVIEW_WIDGET( wxWindow* aParent, KIWAY& aKiway ):
|
||||
wxPanel( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
|
||||
wxFULL_REPAINT_ON_RESIZE | wxTAB_TRAVERSAL ),
|
||||
m_prev_panel( nullptr ),
|
||||
m_status( nullptr ),
|
||||
m_statusPanel( nullptr ),
|
||||
m_statusSizer( nullptr ),
|
||||
m_outerSizer( nullptr )
|
||||
FOOTPRINT_PREVIEW_WIDGET::FOOTPRINT_PREVIEW_WIDGET( wxWindow* aParent, KIWAY& aKiway ) :
|
||||
wxPanel( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
|
||||
wxFULL_REPAINT_ON_RESIZE | wxTAB_TRAVERSAL ),
|
||||
m_prev_panel( nullptr ),
|
||||
m_status( nullptr ),
|
||||
m_statusPanel( nullptr ),
|
||||
m_statusSizer( nullptr ),
|
||||
m_outerSizer( nullptr )
|
||||
{
|
||||
m_prev_panel = FOOTPRINT_PREVIEW_PANEL_BASE::Create( this, aKiway );
|
||||
|
||||
|
@ -46,12 +46,14 @@ FOOTPRINT_PREVIEW_WIDGET::FOOTPRINT_PREVIEW_WIDGET( wxWindow* aParent, KIWAY& aK
|
|||
m_statusSizer->Add( 0, 0, 1 ); // add a spacer
|
||||
m_statusPanel->SetSizer( m_statusSizer );
|
||||
|
||||
// Give the status panel the same color scheme as the canvas so it isn't jarring when switched to
|
||||
// Give the status panel the same color scheme as the canvas so it isn't jarring when
|
||||
// switched to
|
||||
m_statusPanel->SetBackgroundColour( m_prev_panel->GetBackgroundColor().ToColour() );
|
||||
m_statusPanel->SetForegroundColour( m_prev_panel->GetForegroundColor().ToColour() );
|
||||
m_status->SetForegroundColour( m_prev_panel->GetForegroundColor().ToColour() );
|
||||
|
||||
// Set our background so wx doesn't render a normal control background momentarily when rapidly
|
||||
// navigating with arrow keys
|
||||
// Set our background so wx doesn't render a normal control background momentarily when
|
||||
// rapidly navigating with arrow keys
|
||||
SetBackgroundColour( m_prev_panel->GetBackgroundColor().ToColour() );
|
||||
SetForegroundColour( m_prev_panel->GetForegroundColor().ToColour() );
|
||||
|
||||
|
@ -59,13 +61,9 @@ FOOTPRINT_PREVIEW_WIDGET::FOOTPRINT_PREVIEW_WIDGET( wxWindow* aParent, KIWAY& aK
|
|||
m_outerSizer->Add( m_prev_panel->GetWindow(), 1, wxALL | wxEXPAND, 0 );
|
||||
m_outerSizer->Add( m_statusPanel, 1, wxALL | wxEXPAND, 0 );
|
||||
|
||||
// Hide the status panel to start
|
||||
m_statusPanel->Hide();
|
||||
|
||||
m_prev_panel->SetStatusHandler( [this]( FOOTPRINT_STATUS s ){ this->OnStatusChange( s ); } );
|
||||
|
||||
SetSizer( m_outerSizer );
|
||||
Layout();
|
||||
|
||||
SetStatusText( wxEmptyString );
|
||||
}
|
||||
|
||||
|
||||
|
@ -87,30 +85,17 @@ void FOOTPRINT_PREVIEW_WIDGET::ClearStatus()
|
|||
}
|
||||
|
||||
|
||||
void FOOTPRINT_PREVIEW_WIDGET::CacheFootprint( const LIB_ID& aFPID )
|
||||
{
|
||||
if( m_prev_panel )
|
||||
(void) m_prev_panel->CacheFootprint( aFPID );
|
||||
}
|
||||
|
||||
|
||||
void FOOTPRINT_PREVIEW_WIDGET::DisplayFootprint( const LIB_ID& aFPID )
|
||||
{
|
||||
if( m_prev_panel )
|
||||
(void) m_prev_panel->DisplayFootprint( aFPID );
|
||||
}
|
||||
if( !m_prev_panel )
|
||||
return;
|
||||
|
||||
wxBusyCursor busy;
|
||||
|
||||
void FOOTPRINT_PREVIEW_WIDGET::OnStatusChange( FOOTPRINT_STATUS aStatus )
|
||||
{
|
||||
switch( aStatus )
|
||||
{
|
||||
case FPS_NOT_FOUND: SetStatusText( _( "Footprint not found" ) ); break;
|
||||
case FPS_LOADING: SetStatusText( _( "Loading..." ) ); break;
|
||||
case FPS_READY: ClearStatus(); break;
|
||||
}
|
||||
|
||||
Refresh();
|
||||
if( m_prev_panel->DisplayFootprint( aFPID ) )
|
||||
ClearStatus();
|
||||
else
|
||||
SetStatusText( _( "Footprint not found." ) );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017-2020 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
|
||||
|
@ -43,11 +43,11 @@ wxDEFINE_EVENT( EVT_FOOTPRINT_SELECTED, wxCommandEvent );
|
|||
|
||||
|
||||
FOOTPRINT_SELECT_WIDGET::FOOTPRINT_SELECT_WIDGET( EDA_DRAW_FRAME* aFrame, wxWindow* aParent,
|
||||
FOOTPRINT_LIST* aFpList, bool aUpdate, int aMaxItems ) :
|
||||
FOOTPRINT_LIST* aFpList, bool aUpdate,
|
||||
int aMaxItems ) :
|
||||
wxPanel( aParent ),
|
||||
m_kiway( nullptr ),
|
||||
m_update( aUpdate ),
|
||||
m_finished_loading( false ),
|
||||
m_max_items( aMaxItems ),
|
||||
m_last_item( 0 ),
|
||||
m_fp_list( aFpList ),
|
||||
|
@ -73,26 +73,13 @@ void FOOTPRINT_SELECT_WIDGET::Load( KIWAY& aKiway, PROJECT& aProject )
|
|||
|
||||
try
|
||||
{
|
||||
auto fp_lib_table = aProject.PcbFootprintLibs( aKiway );
|
||||
m_fp_list = FOOTPRINT_LIST::GetInstance( aKiway );
|
||||
|
||||
// We parent to the eda frame so that the taskbar progress indicator displays on it
|
||||
WX_PROGRESS_REPORTER progressReporter( m_eda_frame, _( "Loading Footprint Libraries" ), 2 );
|
||||
m_fp_list->ReadFootprintFiles( fp_lib_table, nullptr, &progressReporter );
|
||||
FootprintsLoaded();
|
||||
m_fp_filter.SetList( *m_fp_list );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
// no footprint libraries available
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FOOTPRINT_SELECT_WIDGET::FootprintsLoaded()
|
||||
{
|
||||
m_fp_filter.SetList( *m_fp_list );
|
||||
|
||||
m_finished_loading = true;
|
||||
|
||||
if( m_update )
|
||||
UpdateList();
|
||||
|
@ -215,7 +202,7 @@ bool FOOTPRINT_SELECT_WIDGET::UpdateList()
|
|||
{
|
||||
int n_items = 0;
|
||||
|
||||
if( !m_fp_list || !m_finished_loading )
|
||||
if( !m_fp_list )
|
||||
return false;
|
||||
|
||||
wxWindowUpdateLocker lock( m_fp_sel_ctrl );
|
||||
|
|
|
@ -430,7 +430,6 @@ void DIALOG_CHOOSE_SYMBOL::ShowFootprint( wxString const& aName )
|
|||
if( lib_id.Parse( aName ) == -1 && lib_id.IsValid() )
|
||||
{
|
||||
m_fp_preview->ClearStatus();
|
||||
m_fp_preview->CacheFootprint( lib_id );
|
||||
m_fp_preview->DisplayFootprint( lib_id );
|
||||
}
|
||||
else
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FOOTPRINT_PREVIEW_WIDGET_H
|
||||
#define __FOOTPRINT_PREVIEW_WIDGET_H
|
||||
#ifndef FOOTPRINT_PREVIEW_WIDGET_H
|
||||
#define FOOTPRINT_PREVIEW_WIDGET_H
|
||||
|
||||
#include <wx/panel.h>
|
||||
#include <functional>
|
||||
|
@ -35,13 +35,6 @@ class wxStaticText;
|
|||
class wxSizer;
|
||||
|
||||
|
||||
enum FOOTPRINT_STATUS {
|
||||
FPS_NOT_FOUND = 0,
|
||||
FPS_READY = 1,
|
||||
FPS_LOADING = 2
|
||||
};
|
||||
|
||||
|
||||
class FOOTPRINT_PREVIEW_WIDGET: public wxPanel
|
||||
{
|
||||
public:
|
||||
|
@ -59,7 +52,7 @@ public:
|
|||
* if Kiway is not available. If this returns false, no other methods should
|
||||
* be called.
|
||||
*/
|
||||
bool IsInitialized() const { return !! m_prev_panel; }
|
||||
bool IsInitialized() const { return m_prev_panel != nullptr; }
|
||||
|
||||
/**
|
||||
* Set the contents of the status label and display it.
|
||||
|
@ -71,12 +64,6 @@ public:
|
|||
*/
|
||||
void ClearStatus();
|
||||
|
||||
/**
|
||||
* Preload a footprint into the cache. This must be called prior to
|
||||
* DisplayFootprint, and may be called early.
|
||||
*/
|
||||
void CacheFootprint( const LIB_ID& aFPID );
|
||||
|
||||
/**
|
||||
* Set the currently displayed footprint. Any footprint passed in here
|
||||
* must have been passed to CacheFootprint before.
|
||||
|
@ -84,12 +71,6 @@ public:
|
|||
void DisplayFootprint( const LIB_ID& aFPID );
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Callback from the FOOTPRINT_PREVIEW_PANEL
|
||||
*/
|
||||
void OnStatusChange( FOOTPRINT_STATUS aStatus );
|
||||
|
||||
FOOTPRINT_PREVIEW_PANEL_BASE* m_prev_panel;
|
||||
|
||||
wxStaticText* m_status;
|
||||
|
@ -100,9 +81,6 @@ private:
|
|||
};
|
||||
|
||||
|
||||
typedef std::function<void( FOOTPRINT_STATUS )> FOOTPRINT_STATUS_HANDLER;
|
||||
|
||||
|
||||
/**
|
||||
* Base class for the actual viewer panel. The implementation is in
|
||||
* pcbnew/footprint_preview_panel.cpp, accessed via kiface.
|
||||
|
@ -112,22 +90,11 @@ class APIEXPORT FOOTPRINT_PREVIEW_PANEL_BASE
|
|||
public:
|
||||
virtual ~FOOTPRINT_PREVIEW_PANEL_BASE() {}
|
||||
|
||||
/**
|
||||
* Preload a footprint into the cache. This must be called prior to
|
||||
* DisplayFootprint, and may be called early.
|
||||
*/
|
||||
virtual void CacheFootprint( LIB_ID const& aFPID ) = 0;
|
||||
|
||||
/**
|
||||
* Set the currently displayed footprint. Any footprint passed in here
|
||||
* must have been passed to CacheFootprint before.
|
||||
*/
|
||||
virtual void DisplayFootprint( LIB_ID const& aFPID ) = 0;
|
||||
|
||||
/**
|
||||
* Set the callback to receive status updates.
|
||||
*/
|
||||
virtual void SetStatusHandler( FOOTPRINT_STATUS_HANDLER aHandler ) = 0;
|
||||
virtual bool DisplayFootprint( LIB_ID const& aFPID ) = 0;
|
||||
|
||||
/**
|
||||
* Get the underlying wxWindow.
|
||||
|
@ -148,4 +115,4 @@ public:
|
|||
};
|
||||
|
||||
|
||||
#endif // __FOOTPRINT_PREVIEW_WIDGET_H
|
||||
#endif // FOOTPRINT_PREVIEW_WIDGET_H
|
||||
|
|
|
@ -129,7 +129,6 @@ private:
|
|||
wxSizer* m_sizer;
|
||||
|
||||
bool m_update;
|
||||
bool m_finished_loading;
|
||||
int m_max_items;
|
||||
wxString m_default_footprint;
|
||||
wxString m_other_footprint;
|
||||
|
@ -140,7 +139,6 @@ private:
|
|||
bool m_zero_filter;
|
||||
EDA_DRAW_FRAME* m_eda_frame;
|
||||
|
||||
void FootprintsLoaded();
|
||||
void OnComboBox( wxCommandEvent& aEvent );
|
||||
void OnComboInteractive( wxCommandEvent& aEvent );
|
||||
|
||||
|
|
|
@ -226,7 +226,6 @@ void DIALOG_CHOOSE_FOOTPRINT::OnComponentPreselected( wxCommandEvent& aEvent )
|
|||
else
|
||||
{
|
||||
m_preview_ctrl->ClearStatus();
|
||||
m_preview_ctrl->CacheFootprint( lib_id );
|
||||
m_preview_ctrl->DisplayFootprint( lib_id );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2016-2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2016-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017 Chris Pavlina <pavlina.chris@gmail.com>
|
||||
* Copyright (C) 2016 Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
|
@ -20,7 +20,6 @@
|
|||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <utility>
|
||||
|
||||
#include "pcbnew_settings.h"
|
||||
|
@ -29,8 +28,6 @@
|
|||
#include <eda_draw_frame.h>
|
||||
#include <footprint_preview_panel.h>
|
||||
#include <fp_lib_table.h>
|
||||
#include <id.h>
|
||||
#include <io_mgr.h>
|
||||
#include <kiway.h>
|
||||
#include <math/box2.h>
|
||||
#include <pcb_painter.h>
|
||||
|
@ -42,226 +39,14 @@
|
|||
#include <wx/stattext.h>
|
||||
#include <zoom_defines.h>
|
||||
|
||||
/**
|
||||
* Threadsafe interface class between loader thread and panel class.
|
||||
*/
|
||||
class FP_THREAD_IFACE
|
||||
{
|
||||
using CACHE_ENTRY = FOOTPRINT_PREVIEW_PANEL::CACHE_ENTRY;
|
||||
|
||||
public:
|
||||
FP_THREAD_IFACE() : m_panel( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
/// Retrieve a cache entry by LIB_ID
|
||||
OPT<CACHE_ENTRY> GetFromCache( const LIB_ID& aFPID )
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( m_lock );
|
||||
auto it = m_cachedFootprints.find( aFPID );
|
||||
|
||||
if( it != m_cachedFootprints.end() )
|
||||
return it->second;
|
||||
else
|
||||
return NULLOPT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Push an entry to the loading queue and a placeholder to the cache;
|
||||
* return the placeholder.
|
||||
*/
|
||||
CACHE_ENTRY AddToQueue( const LIB_ID& aEntry )
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( m_lock );
|
||||
|
||||
CACHE_ENTRY ent = { aEntry, nullptr, FPS_LOADING };
|
||||
m_cachedFootprints[aEntry] = ent;
|
||||
m_loaderQueue.push_back( ent );
|
||||
|
||||
return ent;
|
||||
}
|
||||
|
||||
/// Pop an entry from the queue, or empty option if none is available.
|
||||
OPT<CACHE_ENTRY> PopFromQueue()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( m_lock );
|
||||
|
||||
if( m_loaderQueue.empty() )
|
||||
{
|
||||
return NULLOPT;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto ent = m_loaderQueue.front();
|
||||
m_loaderQueue.pop_front();
|
||||
return ent;
|
||||
}
|
||||
}
|
||||
|
||||
/// Add an entry to the cache.
|
||||
void AddToCache( const CACHE_ENTRY& aEntry )
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( m_lock );
|
||||
m_cachedFootprints[aEntry.fpid] = aEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Threadsafe accessor to set the current footprint.
|
||||
*/
|
||||
void SetCurrentFootprint( LIB_ID aFp )
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( m_lock );
|
||||
m_current_fp = std::move( aFp );
|
||||
}
|
||||
|
||||
/**
|
||||
* Threadsafe accessor to get the current footprint.
|
||||
*/
|
||||
LIB_ID GetCurrentFootprint()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( m_lock );
|
||||
return m_current_fp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the associated panel, for QueueEvent() and GetTable().
|
||||
*/
|
||||
void SetPanel( FOOTPRINT_PREVIEW_PANEL* aPanel )
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( m_lock );
|
||||
m_panel = aPanel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the associated panel.
|
||||
*/
|
||||
FOOTPRINT_PREVIEW_PANEL* GetPanel()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( m_lock );
|
||||
return m_panel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post an event to the panel, if the panel still exists. Return whether
|
||||
* the event was posted.
|
||||
*/
|
||||
bool QueueEvent( const wxEvent& aEvent )
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( m_lock );
|
||||
|
||||
if( m_panel )
|
||||
{
|
||||
m_panel->GetEventHandler()->QueueEvent( aEvent.Clone() );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an FP_LIB_TABLE, or null if the panel is dead.
|
||||
*/
|
||||
FP_LIB_TABLE* GetTable()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( m_lock );
|
||||
return m_panel ? m_panel->Prj().PcbFootprintLibs() : nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
std::deque<CACHE_ENTRY> m_loaderQueue;
|
||||
std::map<LIB_ID, CACHE_ENTRY> m_cachedFootprints;
|
||||
LIB_ID m_current_fp;
|
||||
FOOTPRINT_PREVIEW_PANEL* m_panel;
|
||||
std::mutex m_lock;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Footprint loader thread to prevent footprint loading from locking the UI.
|
||||
* Interface is via a FP_THREAD_IFACE.
|
||||
*/
|
||||
class FP_LOADER_THREAD : public wxThread
|
||||
{
|
||||
using CACHE_ENTRY = FOOTPRINT_PREVIEW_PANEL::CACHE_ENTRY;
|
||||
|
||||
std::shared_ptr<FP_THREAD_IFACE> m_iface;
|
||||
|
||||
public:
|
||||
FP_LOADER_THREAD( const std::shared_ptr<FP_THREAD_IFACE>& aIface )
|
||||
: wxThread( wxTHREAD_DETACHED ), m_iface( aIface )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
~FP_LOADER_THREAD()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ProcessEntry( CACHE_ENTRY& aEntry )
|
||||
{
|
||||
FP_LIB_TABLE* fptbl = m_iface->GetTable();
|
||||
|
||||
if( !fptbl )
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
aEntry.footprint.reset( fptbl->FootprintLoadWithOptionalNickname( aEntry.fpid ) );
|
||||
|
||||
if( !aEntry.footprint )
|
||||
aEntry.status = FPS_NOT_FOUND;
|
||||
}
|
||||
catch( const IO_ERROR& )
|
||||
{
|
||||
aEntry.status = FPS_NOT_FOUND;
|
||||
}
|
||||
|
||||
if( aEntry.status != FPS_NOT_FOUND )
|
||||
aEntry.status = FPS_READY;
|
||||
|
||||
m_iface->AddToCache( aEntry );
|
||||
|
||||
if( aEntry.fpid == m_iface->GetCurrentFootprint() )
|
||||
{
|
||||
wxCommandEvent evt( wxEVT_COMMAND_TEXT_UPDATED, 1 );
|
||||
m_iface->QueueEvent( evt );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual void* Entry() override
|
||||
{
|
||||
while( m_iface->GetPanel() )
|
||||
{
|
||||
auto ent = m_iface->PopFromQueue();
|
||||
|
||||
if( ent )
|
||||
ProcessEntry( *ent );
|
||||
else
|
||||
wxMilliSleep( 100 );
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
FOOTPRINT_PREVIEW_PANEL::FOOTPRINT_PREVIEW_PANEL( KIWAY* aKiway, wxWindow* aParent,
|
||||
std::unique_ptr<KIGFX::GAL_DISPLAY_OPTIONS> aOpts, GAL_TYPE aGalType )
|
||||
: PCB_DRAW_PANEL_GAL( aParent, -1, wxPoint( 0, 0 ), wxSize( 200, 200 ), *aOpts, aGalType ),
|
||||
KIWAY_HOLDER( aKiway, KIWAY_HOLDER::PANEL ),
|
||||
m_displayOptions( std::move( aOpts ) ),
|
||||
m_currentFootprint( nullptr ),
|
||||
m_footprintDisplayed( true )
|
||||
std::unique_ptr<KIGFX::GAL_DISPLAY_OPTIONS> aOpts,
|
||||
GAL_TYPE aGalType ) :
|
||||
PCB_DRAW_PANEL_GAL( aParent, -1, wxPoint( 0, 0 ), wxSize( 200, 200 ), *aOpts, aGalType ),
|
||||
KIWAY_HOLDER( aKiway, KIWAY_HOLDER::PANEL ),
|
||||
m_displayOptions( std::move( aOpts ) ),
|
||||
m_currentFootprint( nullptr )
|
||||
{
|
||||
m_iface = std::make_shared<FP_THREAD_IFACE>();
|
||||
m_iface->SetPanel( this );
|
||||
m_loader = new FP_LOADER_THREAD( m_iface );
|
||||
m_loader->Run();
|
||||
|
||||
SetStealsFocus( false );
|
||||
ShowScrollbars( wxSHOW_SB_NEVER, wxSHOW_SB_NEVER );
|
||||
EnableScrolling( false, false ); // otherwise Zoom Auto disables GAL canvas
|
||||
|
@ -273,9 +58,6 @@ FOOTPRINT_PREVIEW_PANEL::FOOTPRINT_PREVIEW_PANEL( KIWAY* aKiway, wxWindow* aPare
|
|||
Raise();
|
||||
Show( true );
|
||||
StartDrawing();
|
||||
|
||||
Connect( wxEVT_COMMAND_TEXT_UPDATED,
|
||||
wxCommandEventHandler( FOOTPRINT_PREVIEW_PANEL::OnLoaderThreadUpdate ), NULL, this );
|
||||
}
|
||||
|
||||
|
||||
|
@ -287,8 +69,6 @@ FOOTPRINT_PREVIEW_PANEL::~FOOTPRINT_PREVIEW_PANEL( )
|
|||
GetView()->Clear();
|
||||
m_currentFootprint->SetParent( nullptr );
|
||||
}
|
||||
|
||||
m_iface->SetPanel( nullptr );
|
||||
}
|
||||
|
||||
|
||||
|
@ -310,24 +90,6 @@ const COLOR4D& FOOTPRINT_PREVIEW_PANEL::GetForegroundColor()
|
|||
}
|
||||
|
||||
|
||||
FOOTPRINT_PREVIEW_PANEL::CACHE_ENTRY FOOTPRINT_PREVIEW_PANEL::CacheAndReturn( const LIB_ID& aFPID )
|
||||
{
|
||||
auto opt_ent = m_iface->GetFromCache( aFPID );
|
||||
|
||||
if( opt_ent )
|
||||
return *opt_ent;
|
||||
else
|
||||
return m_iface->AddToQueue( aFPID );
|
||||
}
|
||||
|
||||
|
||||
// This is separate to avoid having to export CACHE_ENTRY to the global namespace
|
||||
void FOOTPRINT_PREVIEW_PANEL::CacheFootprint( const LIB_ID& aFPID )
|
||||
{
|
||||
(void) CacheAndReturn( aFPID );
|
||||
}
|
||||
|
||||
|
||||
void FOOTPRINT_PREVIEW_PANEL::renderFootprint( std::shared_ptr<FOOTPRINT> aFootprint )
|
||||
{
|
||||
if( m_currentFootprint )
|
||||
|
@ -337,24 +99,25 @@ void FOOTPRINT_PREVIEW_PANEL::renderFootprint( std::shared_ptr<FOOTPRINT> aFootp
|
|||
m_currentFootprint->SetParent( nullptr );
|
||||
}
|
||||
|
||||
aFootprint->SetParent( m_dummyBoard.get() );
|
||||
m_currentFootprint = aFootprint;
|
||||
|
||||
if( !m_currentFootprint )
|
||||
return;
|
||||
|
||||
m_currentFootprint->SetParent( m_dummyBoard.get() );
|
||||
|
||||
// Ensure we are not using the high contrast mode to display the selected footprint
|
||||
KIGFX::PAINTER* painter = GetView()->GetPainter();
|
||||
auto settings = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( painter->GetSettings() );
|
||||
settings->SetContrastModeDisplay( HIGH_CONTRAST_MODE::NORMAL );
|
||||
|
||||
GetView()->Add( aFootprint.get() );
|
||||
GetView()->SetVisible( aFootprint.get(), true );
|
||||
GetView()->Update( aFootprint.get(), KIGFX::ALL );
|
||||
GetView()->Add( m_currentFootprint.get() );
|
||||
GetView()->SetVisible( m_currentFootprint.get(), true );
|
||||
GetView()->Update( m_currentFootprint.get(), KIGFX::ALL );
|
||||
|
||||
// Save a reference to the footprint's shared pointer to say we are using it in the
|
||||
// preview panel
|
||||
m_currentFootprint = aFootprint;
|
||||
|
||||
BOX2I bbox = aFootprint->ViewBBox();
|
||||
bbox.Merge( aFootprint->Value().ViewBBox() );
|
||||
bbox.Merge( aFootprint->Reference().ViewBBox() );
|
||||
BOX2I bbox = m_currentFootprint->ViewBBox();
|
||||
bbox.Merge( m_currentFootprint->Value().ViewBBox() );
|
||||
bbox.Merge( m_currentFootprint->Reference().ViewBBox() );
|
||||
|
||||
if( bbox.GetSize().x > 0 && bbox.GetSize().y > 0 )
|
||||
{
|
||||
|
@ -369,38 +132,23 @@ void FOOTPRINT_PREVIEW_PANEL::renderFootprint( std::shared_ptr<FOOTPRINT> aFootp
|
|||
}
|
||||
|
||||
|
||||
void FOOTPRINT_PREVIEW_PANEL::DisplayFootprint ( const LIB_ID& aFPID )
|
||||
bool FOOTPRINT_PREVIEW_PANEL::DisplayFootprint( const LIB_ID& aFPID )
|
||||
{
|
||||
m_currentFPID = aFPID;
|
||||
m_iface->SetCurrentFootprint( aFPID );
|
||||
m_footprintDisplayed = false;
|
||||
FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs();
|
||||
|
||||
CACHE_ENTRY fpe = CacheAndReturn( m_currentFPID );
|
||||
|
||||
if( m_handler )
|
||||
m_handler( fpe.status );
|
||||
|
||||
if( fpe.status == FPS_READY )
|
||||
try
|
||||
{
|
||||
if( !m_footprintDisplayed )
|
||||
{
|
||||
renderFootprint( fpe.footprint );
|
||||
m_footprintDisplayed = true;
|
||||
Refresh();
|
||||
}
|
||||
m_currentFootprint.reset( fptbl->FootprintLoadWithOptionalNickname( aFPID ) );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
m_currentFootprint.reset();
|
||||
}
|
||||
}
|
||||
|
||||
renderFootprint( m_currentFootprint );
|
||||
Refresh();
|
||||
|
||||
void FOOTPRINT_PREVIEW_PANEL::OnLoaderThreadUpdate( wxCommandEvent& aEvent )
|
||||
{
|
||||
DisplayFootprint( m_currentFPID );
|
||||
}
|
||||
|
||||
|
||||
void FOOTPRINT_PREVIEW_PANEL::SetStatusHandler( FOOTPRINT_STATUS_HANDLER aHandler )
|
||||
{
|
||||
m_handler = aHandler;
|
||||
return m_currentFootprint != nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2016-2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2016-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017 Chris Pavlina <pavlina.chris@gmail.com>
|
||||
* Copyright (C) 2016 Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
|
@ -41,29 +41,21 @@ class FOOTPRINT;
|
|||
class KIWAY;
|
||||
class IO_MGR;
|
||||
class BOARD;
|
||||
class FP_LOADER_THREAD;
|
||||
class FP_THREAD_IFACE;
|
||||
|
||||
|
||||
/**
|
||||
* Panel that renders a single footprint via Cairo GAL, meant to be exported
|
||||
* through Kiface.
|
||||
*/
|
||||
class FOOTPRINT_PREVIEW_PANEL :
|
||||
public PCB_DRAW_PANEL_GAL, public KIWAY_HOLDER, public FOOTPRINT_PREVIEW_PANEL_BASE
|
||||
class FOOTPRINT_PREVIEW_PANEL : public PCB_DRAW_PANEL_GAL,
|
||||
public KIWAY_HOLDER,
|
||||
public FOOTPRINT_PREVIEW_PANEL_BASE
|
||||
{
|
||||
friend class FP_THREAD_IFACE;
|
||||
friend class FP_LOADER_THREAD;
|
||||
|
||||
public:
|
||||
|
||||
virtual ~FOOTPRINT_PREVIEW_PANEL( );
|
||||
|
||||
virtual void CacheFootprint( const LIB_ID& aFPID ) override;
|
||||
|
||||
virtual void DisplayFootprint( const LIB_ID& aFPID ) override;
|
||||
|
||||
virtual void SetStatusHandler( FOOTPRINT_STATUS_HANDLER aHandler ) override;
|
||||
virtual bool DisplayFootprint( const LIB_ID& aFPID ) override;
|
||||
|
||||
virtual const KIGFX::COLOR4D& GetBackgroundColor() override;
|
||||
virtual const KIGFX::COLOR4D& GetForegroundColor() override;
|
||||
|
@ -74,13 +66,6 @@ public:
|
|||
static FOOTPRINT_PREVIEW_PANEL* New( KIWAY* aKiway, wxWindow* aParent );
|
||||
|
||||
private:
|
||||
struct CACHE_ENTRY
|
||||
{
|
||||
LIB_ID fpid;
|
||||
std::shared_ptr<FOOTPRINT> footprint;
|
||||
FOOTPRINT_STATUS status;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a new panel
|
||||
*
|
||||
|
@ -93,24 +78,12 @@ private:
|
|||
std::unique_ptr<KIGFX::GAL_DISPLAY_OPTIONS> aOpts,
|
||||
GAL_TYPE aGalType );
|
||||
|
||||
|
||||
virtual CACHE_ENTRY CacheAndReturn( const LIB_ID& aFPID );
|
||||
|
||||
void OnLoaderThreadUpdate( wxCommandEvent& aEvent );
|
||||
|
||||
void renderFootprint( std::shared_ptr<FOOTPRINT> aFootprint );
|
||||
|
||||
private:
|
||||
FP_LOADER_THREAD* m_loader;
|
||||
std::shared_ptr<FP_THREAD_IFACE> m_iface;
|
||||
FOOTPRINT_STATUS_HANDLER m_handler;
|
||||
|
||||
std::unique_ptr<BOARD> m_dummyBoard;
|
||||
std::unique_ptr<KIGFX::GAL_DISPLAY_OPTIONS> m_displayOptions;
|
||||
|
||||
std::shared_ptr<FOOTPRINT> m_currentFootprint;
|
||||
LIB_ID m_currentFPID;
|
||||
bool m_footprintDisplayed;
|
||||
std::shared_ptr<FOOTPRINT> m_currentFootprint;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue