ADDED: lib tree previews.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/2418
This commit is contained in:
Jeff Young 2023-09-02 22:13:48 +01:00
parent c64b44913c
commit e6b0a6abca
20 changed files with 325 additions and 86 deletions

View File

@ -391,6 +391,25 @@ void EDA_DRAW_PANEL_GAL::Refresh( bool aEraseBackground, const wxRect* aRect )
void EDA_DRAW_PANEL_GAL::ForceRefresh() void EDA_DRAW_PANEL_GAL::ForceRefresh()
{ {
if( !m_drawingEnabled )
{
if( m_gal && m_gal->IsInitialized() )
{
Connect( wxEVT_PAINT, wxPaintEventHandler( EDA_DRAW_PANEL_GAL::onPaint ), nullptr,
this );
Connect( wxEVT_IDLE, wxIdleEventHandler( EDA_DRAW_PANEL_GAL::onIdle ), nullptr, this );
m_drawingEnabled = true;
}
else
{
// Try again soon
m_refreshTimer.StartOnce( 100 );
return;
}
}
DoRePaint(); DoRePaint();
} }
@ -613,26 +632,7 @@ void EDA_DRAW_PANEL_GAL::onIdle( wxIdleEvent& aEvent )
void EDA_DRAW_PANEL_GAL::onRefreshTimer( wxTimerEvent& aEvent ) void EDA_DRAW_PANEL_GAL::onRefreshTimer( wxTimerEvent& aEvent )
{ {
if( !m_drawingEnabled ) ForceRefresh();
{
if( m_gal && m_gal->IsInitialized() )
{
Connect( wxEVT_PAINT, wxPaintEventHandler( EDA_DRAW_PANEL_GAL::onPaint ), nullptr,
this );
Connect( wxEVT_IDLE, wxIdleEventHandler( EDA_DRAW_PANEL_GAL::onIdle ), nullptr, this );
m_drawingEnabled = true;
}
else
{
// Try again soon
m_refreshTimer.StartOnce( 100 );
return;
}
}
DoRePaint();
} }

View File

@ -36,7 +36,7 @@
#include <wx/settings.h> #include <wx/settings.h>
#include <wx/sizer.h> #include <wx/sizer.h>
#include <wx/srchctrl.h> #include <wx/srchctrl.h>
#include <wx/timer.h> #include <wx/popupwin.h>
constexpr int RECENT_SEARCHES_MAX = 10; constexpr int RECENT_SEARCHES_MAX = 10;
@ -54,10 +54,14 @@ LIB_TREE::LIB_TREE( wxWindow* aParent, const wxString& aRecentSearchesKey, LIB_T
m_details_ctrl( nullptr ), m_details_ctrl( nullptr ),
m_inTimerEvent( false ), m_inTimerEvent( false ),
m_recentSearchesKey( aRecentSearchesKey ), m_recentSearchesKey( aRecentSearchesKey ),
m_skipNextRightClick( false ) m_skipNextRightClick( false ),
m_previewWindow( nullptr )
{ {
wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL ); wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL );
m_hoverTimer.SetOwner( this );
Bind( wxEVT_TIMER, &LIB_TREE::onHoverTimer, this, m_hoverTimer.GetId() );
// Search text control // Search text control
if( aFlags & SEARCH ) if( aFlags & SEARCH )
{ {
@ -177,6 +181,10 @@ LIB_TREE::LIB_TREE( wxWindow* aParent, const wxString& aRecentSearchesKey, LIB_T
m_tree_ctrl->Bind( wxEVT_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK, &LIB_TREE::onHeaderContextMenu, m_tree_ctrl->Bind( wxEVT_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK, &LIB_TREE::onHeaderContextMenu,
this ); this );
// wxDataViewCtrl eats its mouseMoved events, so we're forced to use idle events to track
// the hover state
Bind( wxEVT_IDLE, &LIB_TREE::onIdle, this );
// Process hotkeys when the tree control has focus: // Process hotkeys when the tree control has focus:
m_tree_ctrl->Bind( wxEVT_CHAR_HOOK, &LIB_TREE::onTreeCharHook, this ); m_tree_ctrl->Bind( wxEVT_CHAR_HOOK, &LIB_TREE::onTreeCharHook, this );
@ -215,6 +223,9 @@ LIB_TREE::~LIB_TREE()
{ {
// Stop the timer during destruction early to avoid potential race conditions (that do happen) // Stop the timer during destruction early to avoid potential race conditions (that do happen)
m_debounceTimer->Stop(); m_debounceTimer->Stop();
m_hoverTimer.Stop();
hidePreview();
} }
@ -590,6 +601,111 @@ void LIB_TREE::onQueryMouseMoved( wxMouseEvent& aEvent )
} }
#define PREVIEW_SIZE wxSize( 240, 200 )
void LIB_TREE::showPreview( wxDataViewItem aItem )
{
if( aItem.IsOk() && m_adapter->HasPreview( aItem ) )
{
m_hoverItem = aItem;
wxWindow* topLevelParent = m_parent;
while( topLevelParent && !topLevelParent->IsTopLevel() )
topLevelParent = topLevelParent->GetParent();
m_previewWindow = new wxPopupWindow( topLevelParent );
m_previewWindow->SetPosition( wxPoint( m_tree_ctrl->GetScreenRect().GetRight() - 10,
wxGetMousePosition().y - PREVIEW_SIZE.y / 2 ) );
m_previewWindow->SetSize( PREVIEW_SIZE );
m_previewWindow->Freeze();
m_previewWindow->Show();
m_adapter->ShowPreview( m_previewWindow, aItem );
m_previewWindow->Thaw();
}
}
void LIB_TREE::hidePreview()
{
m_hoverItem = wxDataViewItem();
if( m_previewWindow )
{
m_previewWindow->Hide();
m_previewWindow->Destroy();
m_previewWindow = nullptr;
}
}
void LIB_TREE::onIdle( wxIdleEvent& aEvent )
{
// The wxDataViewCtrl won't give us its mouseMoved events so we're forced to use idle
// events to track the hover state
wxWindow* topLevelParent = m_parent;
while( topLevelParent && !topLevelParent->IsTopLevel() )
topLevelParent = topLevelParent->GetParent();
wxWindow* topLevelFocus = FindFocus();
while( topLevelFocus && !topLevelFocus->IsTopLevel() )
topLevelFocus = topLevelFocus->GetParent();
wxPoint screenPos = wxGetMousePosition();
wxRect screenRect = m_tree_ctrl->GetScreenRect();
if( topLevelFocus != topLevelParent || !screenRect.Contains( screenPos ) )
{
m_hoverTimer.Stop();
hidePreview();
return;
}
wxPoint clientPos = m_tree_ctrl->ScreenToClient( screenPos );
if( m_hoverItem.IsOk() )
{
wxDataViewItem item;
wxDataViewColumn* col = nullptr;
m_tree_ctrl->HitTest( clientPos, item, col );
if( item != m_hoverItem )
{
hidePreview();
m_hoverPos = clientPos;
showPreview( item );
}
return;
}
if( m_hoverPos != clientPos )
{
m_hoverPos = clientPos;
m_hoverTimer.Start( 400, wxTIMER_ONE_SHOT );
}
}
void LIB_TREE::onHoverTimer( wxTimerEvent& aEvent )
{
hidePreview();
wxDataViewItem item;
wxDataViewColumn* col = nullptr;
m_tree_ctrl->HitTest( m_hoverPos, item, col );
if( item != m_tree_ctrl->GetSelection() )
showPreview( item );
}
void LIB_TREE::onTreeCharHook( wxKeyEvent& aKeyStroke ) void LIB_TREE::onTreeCharHook( wxKeyEvent& aKeyStroke )
{ {
onQueryCharHook( aKeyStroke ); onQueryCharHook( aKeyStroke );
@ -628,6 +744,8 @@ void LIB_TREE::onTreeSelect( wxDataViewEvent& aEvent )
void LIB_TREE::onTreeActivate( wxDataViewEvent& aEvent ) void LIB_TREE::onTreeActivate( wxDataViewEvent& aEvent )
{ {
hidePreview();
if( !GetSelectedLibId().IsValid() ) if( !GetSelectedLibId().IsValid() )
toggleExpand( m_tree_ctrl->GetSelection() ); // Expand library/part units subtree toggleExpand( m_tree_ctrl->GetSelection() ); // Expand library/part units subtree
else else
@ -644,6 +762,8 @@ void LIB_TREE::onDetailsLink( wxHtmlLinkEvent& aEvent )
void LIB_TREE::onPreselect( wxCommandEvent& aEvent ) void LIB_TREE::onPreselect( wxCommandEvent& aEvent )
{ {
hidePreview();
if( m_details_ctrl ) if( m_details_ctrl )
{ {
int unit = 0; int unit = 0;
@ -661,6 +781,8 @@ void LIB_TREE::onPreselect( wxCommandEvent& aEvent )
void LIB_TREE::onItemContextMenu( wxDataViewEvent& aEvent ) void LIB_TREE::onItemContextMenu( wxDataViewEvent& aEvent )
{ {
hidePreview();
if( m_skipNextRightClick ) if( m_skipNextRightClick )
{ {
m_skipNextRightClick = false; m_skipNextRightClick = false;
@ -731,6 +853,8 @@ void LIB_TREE::onItemContextMenu( wxDataViewEvent& aEvent )
void LIB_TREE::onHeaderContextMenu( wxDataViewEvent& aEvent ) void LIB_TREE::onHeaderContextMenu( wxDataViewEvent& aEvent )
{ {
hidePreview();
ACTION_MENU menu( true, nullptr ); ACTION_MENU menu( true, nullptr );
menu.Add( ACTIONS::selectColumns ); menu.Add( ACTIONS::selectColumns );

View File

@ -24,7 +24,6 @@
#include <widgets/wx_panel.h> #include <widgets/wx_panel.h>
#include <wx/dcclient.h> #include <wx/dcclient.h>
#include <wx/settings.h> #include <wx/settings.h>
#include "gal/color4d.h"
WX_PANEL::WX_PANEL( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, WX_PANEL::WX_PANEL( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
long style, const wxString& name ) : long style, const wxString& name ) :
@ -32,7 +31,8 @@ WX_PANEL::WX_PANEL( wxWindow* parent, wxWindowID id, const wxPoint& pos, const w
m_leftBorder( false ), m_leftBorder( false ),
m_rightBorder( false ), m_rightBorder( false ),
m_topBorder( false ), m_topBorder( false ),
m_bottomBorder( false ) m_bottomBorder( false ),
m_borderColor( KIGFX::COLOR4D::UNSPECIFIED )
{ {
this->Connect( wxEVT_PAINT, wxPaintEventHandler( WX_PANEL::OnPaint ) ); this->Connect( wxEVT_PAINT, wxPaintEventHandler( WX_PANEL::OnPaint ) );
} }
@ -49,9 +49,15 @@ void WX_PANEL::OnPaint( wxPaintEvent& event )
wxRect rect( wxPoint( 0, 0 ), GetClientSize() ); wxRect rect( wxPoint( 0, 0 ), GetClientSize() );
wxPaintDC dc( this ); wxPaintDC dc( this );
KIGFX::COLOR4D border = m_borderColor;
if( border == KIGFX::COLOR4D::UNSPECIFIED )
{
KIGFX::COLOR4D bg = wxSystemSettings::GetColour( wxSYS_COLOUR_FRAMEBK ); KIGFX::COLOR4D bg = wxSystemSettings::GetColour( wxSYS_COLOUR_FRAMEBK );
KIGFX::COLOR4D fg = wxSystemSettings::GetColour( wxSYS_COLOUR_ACTIVEBORDER ); KIGFX::COLOR4D fg = wxSystemSettings::GetColour( wxSYS_COLOUR_ACTIVEBORDER );
KIGFX::COLOR4D border = fg.Mix( bg, 0.18 ); border = fg.Mix( bg, 0.18 );
}
dc.SetPen( wxPen( border.ToColour(), 1 ) ); dc.SetPen( wxPen( border.ToColour(), 1 ) );
if( m_leftBorder ) if( m_leftBorder )

View File

@ -294,7 +294,7 @@ wxPanel* DIALOG_CHOOSE_SYMBOL::ConstructRightPanel( wxWindow* aParent )
wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL ); wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL );
EDA_DRAW_PANEL_GAL::GAL_TYPE backend = m_parent->GetCanvas()->GetBackend(); EDA_DRAW_PANEL_GAL::GAL_TYPE backend = m_parent->GetCanvas()->GetBackend();
m_symbol_preview = new SYMBOL_PREVIEW_WIDGET( panel, &Kiway(), backend ); m_symbol_preview = new SYMBOL_PREVIEW_WIDGET( panel, &Kiway(), true, backend );
m_symbol_preview->SetLayoutDirection( wxLayout_LeftToRight ); m_symbol_preview->SetLayoutDirection( wxLayout_LeftToRight );
if( m_show_footprints ) if( m_show_footprints )

View File

@ -89,10 +89,12 @@ DIALOG_RESCUE_EACH::DIALOG_RESCUE_EACH( wxWindow* aParent,
{ {
wxASSERT( aCurrentSheet ); wxASSERT( aCurrentSheet );
m_previewOldWidget = new SYMBOL_PREVIEW_WIDGET( m_previewOldPanel, &Kiway(), aGalBackEndType ); m_previewOldWidget = new SYMBOL_PREVIEW_WIDGET( m_previewOldPanel, &Kiway(), false,
aGalBackEndType );
m_SizerOldPanel->Add( m_previewOldWidget, 1, wxEXPAND | wxALL, 5 ); m_SizerOldPanel->Add( m_previewOldWidget, 1, wxEXPAND | wxALL, 5 );
m_previewNewWidget = new SYMBOL_PREVIEW_WIDGET( m_previewNewPanel, &Kiway(), aGalBackEndType ); m_previewNewWidget = new SYMBOL_PREVIEW_WIDGET( m_previewNewPanel, &Kiway(), false,
aGalBackEndType );
m_SizerNewPanel->Add( m_previewNewWidget, 1, wxEXPAND | wxALL, 5 ); m_SizerNewPanel->Add( m_previewNewWidget, 1, wxEXPAND | wxALL, 5 );
// Set the info message, customized to include the proper suffix. // Set the info message, customized to include the proper suffix.

View File

@ -30,6 +30,8 @@
#include <symbol_lib_table.h> #include <symbol_lib_table.h>
#include <tools/symbol_editor_control.h> #include <tools/symbol_editor_control.h>
#include <string_utils.h> #include <string_utils.h>
#include <symbol_preview_widget.h>
#include <widgets/wx_panel.h>
wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER> wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER>
@ -357,3 +359,40 @@ bool SYMBOL_TREE_SYNCHRONIZING_ADAPTER::GetAttr( wxDataViewItem const& aItem, un
return true; return true;
} }
bool SYMBOL_TREE_SYNCHRONIZING_ADAPTER::HasPreview( const wxDataViewItem& aItem )
{
LIB_TREE_NODE* node = ToNode( aItem );
wxCHECK( node, false );
return node->m_Type == LIB_TREE_NODE::LIBID;
}
void SYMBOL_TREE_SYNCHRONIZING_ADAPTER::ShowPreview( wxWindow* aParent, const wxDataViewItem& aItem )
{
LIB_TREE_NODE* node = ToNode( aItem );
wxCHECK( node, /* void */ );
wxBoxSizer* mainSizer = new wxBoxSizer( wxVERTICAL );
aParent->SetSizer( mainSizer );
WX_PANEL* panel = new WX_PANEL( aParent );
panel->SetBorders( true, true, true, true );
panel->SetBorderColor( KIGFX::COLOR4D::BLACK );
wxBoxSizer* panelSizer = new wxBoxSizer( wxVERTICAL );
panel->SetSizer( panelSizer );
EDA_DRAW_PANEL_GAL::GAL_TYPE backend = m_frame->GetCanvas()->GetBackend();
SYMBOL_PREVIEW_WIDGET* preview = new SYMBOL_PREVIEW_WIDGET( panel, &m_frame->Kiway(),
false, backend );
preview->SetLayoutDirection( wxLayout_LeftToRight );
panelSizer->Add( preview, 1, wxEXPAND|wxALL, 1 );
mainSizer->Add( panel, 1, wxEXPAND, 0 );
aParent->Layout();
preview->DisplaySymbol( node->m_LibId, node->m_Unit );
}

View File

@ -50,6 +50,9 @@ public:
wxDataViewItem GetCurrentDataViewItem() override; wxDataViewItem GetCurrentDataViewItem() override;
virtual bool HasPreview( const wxDataViewItem& aItem ) override;
virtual void ShowPreview( wxWindow* aParent, const wxDataViewItem& aItem ) override;
protected: protected:
void updateLibrary( LIB_TREE_NODE_LIB& aLibNode ); void updateLibrary( LIB_TREE_NODE_LIB& aLibNode );

View File

@ -29,7 +29,7 @@
SYMBOL_DIFF_WIDGET::SYMBOL_DIFF_WIDGET( wxWindow* aParent, SYMBOL_DIFF_WIDGET::SYMBOL_DIFF_WIDGET( wxWindow* aParent,
EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType ) : EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType ) :
SYMBOL_PREVIEW_WIDGET( aParent, nullptr, aCanvasType ), SYMBOL_PREVIEW_WIDGET( aParent, nullptr, false, aCanvasType ),
m_libraryItem( nullptr ), m_libraryItem( nullptr ),
m_slider( nullptr ) m_slider( nullptr )
{ {

View File

@ -32,12 +32,13 @@
#include <wx/stattext.h> #include <wx/stattext.h>
SYMBOL_PREVIEW_WIDGET::SYMBOL_PREVIEW_WIDGET( wxWindow* aParent, KIWAY* aKiway, SYMBOL_PREVIEW_WIDGET::SYMBOL_PREVIEW_WIDGET( wxWindow* aParent, KIWAY* aKiway, bool aIncludeStatus,
EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType ) : EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType ) :
wxPanel( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ), wxPanel( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ),
m_kiway( aKiway ), m_kiway( aKiway ),
m_preview( nullptr ), m_preview( nullptr ),
m_status( nullptr ), m_status( nullptr ),
m_statusPanel( nullptr ),
m_statusSizer( nullptr ), m_statusSizer( nullptr ),
m_previewItem( nullptr ) m_previewItem( nullptr )
{ {
@ -84,6 +85,10 @@ SYMBOL_PREVIEW_WIDGET::SYMBOL_PREVIEW_WIDGET( wxWindow* aParent, KIWAY* aKiway,
settings->m_ShowPinsElectricalType = app_settings->m_LibViewPanel.show_pin_electrical_type; settings->m_ShowPinsElectricalType = app_settings->m_LibViewPanel.show_pin_electrical_type;
settings->m_ShowPinNumbers = app_settings->m_LibViewPanel.show_pin_numbers; settings->m_ShowPinNumbers = app_settings->m_LibViewPanel.show_pin_numbers;
m_outerSizer = new wxBoxSizer( wxVERTICAL );
if( aIncludeStatus )
{
m_statusPanel = new wxPanel( this ); m_statusPanel = new wxPanel( this );
m_statusPanel->SetBackgroundColour( backgroundColor.ToColour() ); m_statusPanel->SetBackgroundColour( backgroundColor.ToColour() );
m_status = new wxStaticText( m_statusPanel, wxID_ANY, wxEmptyString ); m_status = new wxStaticText( m_statusPanel, wxID_ANY, wxEmptyString );
@ -102,12 +107,16 @@ SYMBOL_PREVIEW_WIDGET::SYMBOL_PREVIEW_WIDGET( wxWindow* aParent, KIWAY* aKiway,
// Give the preview panel a small top border to align its top with the status panel, // Give the preview panel a small top border to align its top with the status panel,
// and give the status panel a small bottom border to align its bottom with the preview // and give the status panel a small bottom border to align its bottom with the preview
// panel. // panel.
m_outerSizer = new wxBoxSizer( wxVERTICAL );
m_outerSizer->Add( m_preview, 1, wxTOP | wxEXPAND, 5 ); m_outerSizer->Add( m_preview, 1, wxTOP | wxEXPAND, 5 );
m_outerSizer->Add( m_statusPanel, 1, wxBOTTOM | wxEXPAND, 5 ); m_outerSizer->Add( m_statusPanel, 1, wxBOTTOM | wxEXPAND, 5 );
// Hide the status panel to start // Hide the status panel to start
m_statusPanel->Hide(); m_statusPanel->Hide();
}
else
{
m_outerSizer->Add( m_preview, 1, wxEXPAND, 0 );
}
SetSizer( m_outerSizer ); SetSizer( m_outerSizer );
Layout(); Layout();
@ -127,6 +136,8 @@ SYMBOL_PREVIEW_WIDGET::~SYMBOL_PREVIEW_WIDGET()
void SYMBOL_PREVIEW_WIDGET::SetStatusText( wxString const& aText ) void SYMBOL_PREVIEW_WIDGET::SetStatusText( wxString const& aText )
{ {
wxCHECK( m_statusPanel, /* void */ );
m_status->SetLabel( aText ); m_status->SetLabel( aText );
m_preview->Hide(); m_preview->Hide();
m_statusPanel->Show(); m_statusPanel->Show();
@ -232,7 +243,10 @@ void SYMBOL_PREVIEW_WIDGET::DisplaySymbol( const LIB_ID& aSymbolID, int aUnit, i
if( !m_preview->IsShown() ) if( !m_preview->IsShown() )
{ {
m_preview->Show(); m_preview->Show();
if( m_statusPanel )
m_statusPanel->Hide(); m_statusPanel->Hide();
Layout(); // Ensure panel size is up to date. Layout(); // Ensure panel size is up to date.
} }
@ -281,6 +295,9 @@ void SYMBOL_PREVIEW_WIDGET::DisplayPart( LIB_SYMBOL* aSymbol, int aUnit, int aCo
m_preview->ForceRefresh(); m_preview->ForceRefresh();
m_preview->Show(); m_preview->Show();
if( m_statusPanel )
m_statusPanel->Hide(); m_statusPanel->Hide();
Layout(); Layout();
} }

View File

@ -43,7 +43,7 @@ public:
* @param aKiway - an active Kiway instance * @param aKiway - an active Kiway instance
* @param aCanvasType = the type of canvas (GAL_TYPE_OPENGL or GAL_TYPE_CAIRO only) * @param aCanvasType = the type of canvas (GAL_TYPE_OPENGL or GAL_TYPE_CAIRO only)
*/ */
SYMBOL_PREVIEW_WIDGET( wxWindow* aParent, KIWAY* aKiway, SYMBOL_PREVIEW_WIDGET( wxWindow* aParent, KIWAY* aKiway, bool aIncludeStatus,
EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType ); EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType );
~SYMBOL_PREVIEW_WIDGET() override; ~SYMBOL_PREVIEW_WIDGET() override;

View File

@ -259,7 +259,10 @@ public:
LIB_TREE_NODE* GetTreeNodeFor( const wxDataViewItem& aSelection ) const; LIB_TREE_NODE* GetTreeNodeFor( const wxDataViewItem& aSelection ) const;
virtual wxString GenerateInfo( const LIB_ID& aLibId, int aUnit ) { return wxEmptyString; }; virtual wxString GenerateInfo( const LIB_ID& aLibId, int aUnit ) { return wxEmptyString; }
virtual bool HasPreview( const wxDataViewItem& aItem ) { return false; }
virtual void ShowPreview( wxWindow* aParent, const wxDataViewItem& aItem ) {}
/** /**
* Return the number of symbols loaded in the tree. * Return the number of symbols loaded in the tree.

View File

@ -26,6 +26,7 @@
#define LIB_TREE_H #define LIB_TREE_H
#include <wx/panel.h> #include <wx/panel.h>
#include <wx/timer.h>
#include <lib_tree_model_adapter.h> #include <lib_tree_model_adapter.h>
#include <html_window.h> #include <html_window.h>
#include <widgets/wx_dataviewctrl.h> #include <widgets/wx_dataviewctrl.h>
@ -35,6 +36,7 @@ class wxHtmlLinkEvent;
class wxSearchCtrl; class wxSearchCtrl;
class wxTimer; class wxTimer;
class wxTimerEvent; class wxTimerEvent;
class wxPopupWindow;
class STD_BITMAP_BUTTON; class STD_BITMAP_BUTTON;
class ACTION_MENU; class ACTION_MENU;
class LIB_ID; class LIB_ID;
@ -204,6 +206,9 @@ protected:
void updateRecentSearchMenu(); void updateRecentSearchMenu();
void showPreview( wxDataViewItem aItem );
void hidePreview();
void onQueryText( wxCommandEvent& aEvent ); void onQueryText( wxCommandEvent& aEvent );
void onQueryCharHook( wxKeyEvent& aEvent ); void onQueryCharHook( wxKeyEvent& aEvent );
void onQueryMouseMoved( wxMouseEvent& aEvent ); void onQueryMouseMoved( wxMouseEvent& aEvent );
@ -212,6 +217,9 @@ protected:
void onTreeActivate( wxDataViewEvent& aEvent ); void onTreeActivate( wxDataViewEvent& aEvent );
void onTreeCharHook( wxKeyEvent& aEvent ); void onTreeCharHook( wxKeyEvent& aEvent );
void onIdle( wxIdleEvent& aEvent );
void onHoverTimer( wxTimerEvent& aEvent );
void onDetailsLink( wxHtmlLinkEvent& aEvent ); void onDetailsLink( wxHtmlLinkEvent& aEvent );
void onPreselect( wxCommandEvent& aEvent ); void onPreselect( wxCommandEvent& aEvent );
void onItemContextMenu( wxDataViewEvent& aEvent ); void onItemContextMenu( wxDataViewEvent& aEvent );
@ -232,6 +240,11 @@ protected:
wxString m_recentSearchesKey; wxString m_recentSearchesKey;
bool m_skipNextRightClick; bool m_skipNextRightClick;
wxPoint m_hoverPos;
wxDataViewItem m_hoverItem;
wxTimer m_hoverTimer;
wxPopupWindow* m_previewWindow;
}; };
///< Custom event sent when a new symbol is preselected ///< Custom event sent when a new symbol is preselected

View File

@ -25,6 +25,7 @@
#define WX_PANEL_H #define WX_PANEL_H
#include <wx/panel.h> #include <wx/panel.h>
#include <gal/color4d.h>
class WX_PANEL : public wxPanel class WX_PANEL : public wxPanel
{ {
@ -43,6 +44,11 @@ public:
m_bottomBorder = aBottom; m_bottomBorder = aBottom;
} }
void SetBorderColor( const KIGFX::COLOR4D& aColor )
{
m_borderColor = aColor;
}
private: private:
void OnPaint( wxPaintEvent& event ); void OnPaint( wxPaintEvent& event );
@ -51,6 +57,8 @@ private:
bool m_rightBorder; bool m_rightBorder;
bool m_topBorder; bool m_topBorder;
bool m_bottomBorder; bool m_bottomBorder;
KIGFX::COLOR4D m_borderColor;
}; };

View File

@ -673,8 +673,9 @@ std::set<int> g_excludedLayers =
}; };
PANEL_PCBNEW_COLOR_SETTINGS::PANEL_PCBNEW_COLOR_SETTINGS( wxWindow* aParent, BOARD* aBoard ) PANEL_PCBNEW_COLOR_SETTINGS::PANEL_PCBNEW_COLOR_SETTINGS( wxWindow* aParent, BOARD* aBoard ) :
: PANEL_COLOR_SETTINGS( aParent ), PANEL_COLOR_SETTINGS( aParent ),
UNITS_PROVIDER( pcbIUScale, EDA_UNITS::MILLIMETRES ),
m_preview( nullptr ), m_preview( nullptr ),
m_page( nullptr ), m_page( nullptr ),
m_titleBlock( nullptr ), m_titleBlock( nullptr ),
@ -762,7 +763,7 @@ void PANEL_PCBNEW_COLOR_SETTINGS::createSwatches()
createSwatch( layer, name ); createSwatch( layer, name );
} }
m_preview = FOOTPRINT_PREVIEW_PANEL::New( nullptr, m_panel1 ); m_preview = FOOTPRINT_PREVIEW_PANEL::New( nullptr, m_panel1, this );
m_preview->GetGAL()->SetAxesEnabled( false ); m_preview->GetGAL()->SetAxesEnabled( false );
m_previewPanelSizer->Add( m_preview, 1, wxEXPAND, 5 ); m_previewPanelSizer->Add( m_preview, 1, wxEXPAND, 5 );

View File

@ -22,13 +22,14 @@
#define PANEL_PCBNEW_COLOR_SETTINGS_H_ #define PANEL_PCBNEW_COLOR_SETTINGS_H_
#include <dialogs/panel_color_settings.h> #include <dialogs/panel_color_settings.h>
#include <units_provider.h>
class PAGE_INFO; class PAGE_INFO;
class FOOTPRINT_PREVIEW_PANEL; class FOOTPRINT_PREVIEW_PANEL;
class TITLE_BLOCK; class TITLE_BLOCK;
class PANEL_PCBNEW_COLOR_SETTINGS : public PANEL_COLOR_SETTINGS class PANEL_PCBNEW_COLOR_SETTINGS : public PANEL_COLOR_SETTINGS, public UNITS_PROVIDER
{ {
public: public:
PANEL_PCBNEW_COLOR_SETTINGS( wxWindow* aParent, BOARD* aBoard ); PANEL_PCBNEW_COLOR_SETTINGS( wxWindow* aParent, BOARD* aBoard );

View File

@ -44,6 +44,7 @@
#include <dialog_shim.h> #include <dialog_shim.h>
FOOTPRINT_PREVIEW_PANEL::FOOTPRINT_PREVIEW_PANEL( KIWAY* aKiway, wxWindow* aParent, FOOTPRINT_PREVIEW_PANEL::FOOTPRINT_PREVIEW_PANEL( KIWAY* aKiway, wxWindow* aParent,
UNITS_PROVIDER* aUnitsProvider,
std::unique_ptr<KIGFX::GAL_DISPLAY_OPTIONS> aOpts, std::unique_ptr<KIGFX::GAL_DISPLAY_OPTIONS> aOpts,
GAL_TYPE aGalType ) : GAL_TYPE aGalType ) :
PCB_DRAW_PANEL_GAL( aParent, -1, wxPoint( 0, 0 ), wxSize( 200, 200 ), *aOpts, aGalType ), PCB_DRAW_PANEL_GAL( aParent, -1, wxPoint( 0, 0 ), wxSize( 200, 200 ), *aOpts, aGalType ),
@ -55,18 +56,7 @@ FOOTPRINT_PREVIEW_PANEL::FOOTPRINT_PREVIEW_PANEL( KIWAY* aKiway, wxWindow* aPare
ShowScrollbars( wxSHOW_SB_NEVER, wxSHOW_SB_NEVER ); ShowScrollbars( wxSHOW_SB_NEVER, wxSHOW_SB_NEVER );
EnableScrolling( false, false ); // otherwise Zoom Auto disables GAL canvas EnableScrolling( false, false ); // otherwise Zoom Auto disables GAL canvas
wxWindow* topLevelParent = aParent; m_userUnits = aUnitsProvider->GetUserUnits();
while( topLevelParent && !topLevelParent->IsTopLevel() )
topLevelParent = topLevelParent->GetParent();
if( topLevelParent )
{
if( DIALOG_SHIM* parentDlg = dynamic_cast<DIALOG_SHIM*>( topLevelParent ) )
m_userUnits = parentDlg->GetUserUnits();
else if( UNITS_PROVIDER* parentFrame = dynamic_cast<UNITS_PROVIDER*>( topLevelParent ) )
m_userUnits = parentFrame->GetUserUnits();
}
m_dummyBoard = std::make_unique<BOARD>(); m_dummyBoard = std::make_unique<BOARD>();
m_dummyBoard->SetUserUnits( m_userUnits ); m_dummyBoard->SetUserUnits( m_userUnits );
@ -245,7 +235,8 @@ wxWindow* FOOTPRINT_PREVIEW_PANEL::GetWindow()
} }
FOOTPRINT_PREVIEW_PANEL* FOOTPRINT_PREVIEW_PANEL::New( KIWAY* aKiway, wxWindow* aParent ) FOOTPRINT_PREVIEW_PANEL* FOOTPRINT_PREVIEW_PANEL::New( KIWAY* aKiway, wxWindow* aParent,
UNITS_PROVIDER* aUnitsProvider )
{ {
PCBNEW_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<PCBNEW_SETTINGS>(); PCBNEW_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<PCBNEW_SETTINGS>();
@ -267,8 +258,9 @@ FOOTPRINT_PREVIEW_PANEL* FOOTPRINT_PREVIEW_PANEL::New( KIWAY* aKiway, wxWindow*
gal_opts = std::make_unique<KIGFX::GAL_DISPLAY_OPTIONS>(); gal_opts = std::make_unique<KIGFX::GAL_DISPLAY_OPTIONS>();
gal_opts->ReadConfig( *Pgm().GetCommonSettings(), cfg->m_Window, aParent ); gal_opts->ReadConfig( *Pgm().GetCommonSettings(), cfg->m_Window, aParent );
auto canvasType = static_cast<EDA_DRAW_PANEL_GAL::GAL_TYPE>( cfg->m_Graphics.canvas_type ); auto galType = static_cast<EDA_DRAW_PANEL_GAL::GAL_TYPE>( cfg->m_Graphics.canvas_type );
auto panel = new FOOTPRINT_PREVIEW_PANEL( aKiway, aParent, std::move( gal_opts ), canvasType ); FOOTPRINT_PREVIEW_PANEL* panel = new FOOTPRINT_PREVIEW_PANEL( aKiway, aParent, aUnitsProvider,
std::move( gal_opts ), galType );
panel->UpdateColors(); panel->UpdateColors();

View File

@ -66,7 +66,8 @@ public:
virtual void RefreshAll() override; virtual void RefreshAll() override;
static FOOTPRINT_PREVIEW_PANEL* New( KIWAY* aKiway, wxWindow* aParent ); static FOOTPRINT_PREVIEW_PANEL* New( KIWAY* aKiway, wxWindow* aParent,
UNITS_PROVIDER* aUnitsProvider );
private: private:
/** /**
@ -77,9 +78,8 @@ private:
* @param aOpts the GAL options (ownership is assumed) * @param aOpts the GAL options (ownership is assumed)
* @param aGalType the displayed GAL type * @param aGalType the displayed GAL type
*/ */
FOOTPRINT_PREVIEW_PANEL( KIWAY* aKiway, wxWindow* aParent, FOOTPRINT_PREVIEW_PANEL( KIWAY* aKiway, wxWindow* aParent, UNITS_PROVIDER* aUnitsProvider,
std::unique_ptr<KIGFX::GAL_DISPLAY_OPTIONS> aOpts, std::unique_ptr<KIGFX::GAL_DISPLAY_OPTIONS> aOpts, GAL_TYPE aGalType );
GAL_TYPE aGalType );
void renderFootprint( std::shared_ptr<FOOTPRINT> aFootprint ); void renderFootprint( std::shared_ptr<FOOTPRINT> aFootprint );

View File

@ -27,6 +27,7 @@
#include <project/project_file.h> #include <project/project_file.h>
#include <fp_tree_synchronizing_adapter.h> #include <fp_tree_synchronizing_adapter.h>
#include <footprint_edit_frame.h> #include <footprint_edit_frame.h>
#include <footprint_preview_panel.h>
#include <fp_lib_table.h> #include <fp_lib_table.h>
#include <footprint_info_impl.h> #include <footprint_info_impl.h>
#include <string_utils.h> #include <string_utils.h>
@ -304,3 +305,29 @@ bool FP_TREE_SYNCHRONIZING_ADAPTER::GetAttr( wxDataViewItem const& aItem, unsign
} }
bool FP_TREE_SYNCHRONIZING_ADAPTER::HasPreview( const wxDataViewItem& aItem )
{
LIB_TREE_NODE* node = ToNode( aItem );
wxCHECK( node, false );
return node->m_Type == LIB_TREE_NODE::LIBID;
}
void FP_TREE_SYNCHRONIZING_ADAPTER::ShowPreview( wxWindow* aParent, const wxDataViewItem& aItem )
{
LIB_TREE_NODE* node = ToNode( aItem );
wxCHECK( node, /* void */ );
wxBoxSizer* mainSizer = new wxBoxSizer( wxVERTICAL );
aParent->SetSizer( mainSizer );
FOOTPRINT_PREVIEW_PANEL* preview = FOOTPRINT_PREVIEW_PANEL::New( &m_frame->Kiway(), aParent,
m_frame );
preview->GetGAL()->SetAxesEnabled( false );
mainSizer->Add( preview, 1, wxEXPAND|wxALL, 1 );
aParent->Layout();
preview->DisplayFootprint( node->m_LibId );
}

View File

@ -46,6 +46,9 @@ public:
wxDataViewItem GetCurrentDataViewItem() override; wxDataViewItem GetCurrentDataViewItem() override;
virtual bool HasPreview( const wxDataViewItem& aItem ) override;
virtual void ShowPreview( wxWindow* aParent, const wxDataViewItem& aItem ) override;
protected: protected:
FP_TREE_SYNCHRONIZING_ADAPTER( FOOTPRINT_EDIT_FRAME* aFrame, FP_LIB_TABLE* aLibs ); FP_TREE_SYNCHRONIZING_ADAPTER( FOOTPRINT_EDIT_FRAME* aFrame, FP_LIB_TABLE* aLibs );

View File

@ -119,7 +119,7 @@ static struct IFACE : public KIFACE_BASE, public UNITS_PROVIDER
return new FOOTPRINT_WIZARD_FRAME( aKiway, aParent, FRAME_T( aClassId ) ); return new FOOTPRINT_WIZARD_FRAME( aKiway, aParent, FRAME_T( aClassId ) );
case FRAME_FOOTPRINT_PREVIEW: case FRAME_FOOTPRINT_PREVIEW:
return dynamic_cast< wxWindow* >( FOOTPRINT_PREVIEW_PANEL::New( aKiway, aParent ) ); return FOOTPRINT_PREVIEW_PANEL::New( aKiway, aParent, this );
case DIALOG_CONFIGUREPATHS: case DIALOG_CONFIGUREPATHS:
{ {