diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 8624b1b366..d88d29fad9 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -75,6 +75,7 @@ set( EESCHEMA_DLGS ) set( EESCHEMA_WIDGETS + widgets/component_tree.cpp widgets/widget_eeschema_color_config.cpp widgets/pin_shape_combobox.cpp widgets/pin_type_combobox.cpp diff --git a/eeschema/dialogs/dialog_choose_component.cpp b/eeschema/dialogs/dialog_choose_component.cpp index b219d249b7..f81eb04870 100644 --- a/eeschema/dialogs/dialog_choose_component.cpp +++ b/eeschema/dialogs/dialog_choose_component.cpp @@ -27,30 +27,22 @@ #include #include -#include #include -#include -#include #include -#include #include -#include #include #include #include -#include -#include #include #include #include -#include #include #include +#include #include #include -#include FOOTPRINT_ASYNC_LOADER DIALOG_CHOOSE_COMPONENT::m_fp_loader; @@ -61,7 +53,6 @@ DIALOG_CHOOSE_COMPONENT::DIALOG_CHOOSE_COMPONENT( SCH_BASE_FRAME* aParent, const : DIALOG_SHIM( aParent, wxID_ANY, aTitle, wxDefaultPosition, wxSize( 800, 650 ), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ), m_parent( aParent ), - m_adapter( aAdapter ), m_deMorganConvert( aDeMorganConvert >= 0 ? aDeMorganConvert : 0 ), m_allow_field_edits( aAllowFieldEdits ), m_external_browser_requested( false ) @@ -72,14 +63,14 @@ DIALOG_CHOOSE_COMPONENT::DIALOG_CHOOSE_COMPONENT( SCH_BASE_FRAME* aParent, const auto splitter = new wxSplitterWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_LIVE_UPDATE ); - auto left_panel = ConstructLeftPanel( splitter ); + m_tree = new COMPONENT_TREE( splitter, aAdapter ); auto right_panel = ConstructRightPanel( splitter ); auto buttons = new wxStdDialogButtonSizer(); m_dbl_click_timer = new wxTimer( this ); splitter->SetSashGravity( 0.9 ); splitter->SetMinimumPaneSize( 1 ); - splitter->SplitVertically( left_panel, right_panel, -300 ); + splitter->SplitVertically( m_tree, right_panel, -300 ); buttons->AddButton( new wxButton( this, wxID_OK ) ); buttons->AddButton( new wxButton( this, wxID_CANCEL ) ); @@ -91,15 +82,9 @@ DIALOG_CHOOSE_COMPONENT::DIALOG_CHOOSE_COMPONENT( SCH_BASE_FRAME* aParent, const Bind( wxEVT_INIT_DIALOG, &DIALOG_CHOOSE_COMPONENT::OnInitDialog, this ); Bind( wxEVT_TIMER, &DIALOG_CHOOSE_COMPONENT::OnCloseTimer, this, m_dbl_click_timer->GetId() ); + Bind( wxEVT_DATAVIEW_ITEM_ACTIVATED, &DIALOG_CHOOSE_COMPONENT::OnTreeActivate, this ); + Bind( wxEVT_DATAVIEW_SELECTION_CHANGED, &DIALOG_CHOOSE_COMPONENT::OnTreeSelect, this ); - m_query_ctrl->Bind( wxEVT_TEXT, &DIALOG_CHOOSE_COMPONENT::OnQueryText, this ); - m_query_ctrl->Bind( wxEVT_TEXT_ENTER, &DIALOG_CHOOSE_COMPONENT::OnQueryEnter, this ); - m_query_ctrl->Bind( wxEVT_CHAR_HOOK, &DIALOG_CHOOSE_COMPONENT::OnQueryCharHook, this ); - m_tree_ctrl->Bind( - wxEVT_DATAVIEW_ITEM_ACTIVATED, &DIALOG_CHOOSE_COMPONENT::OnTreeActivate, this ); - m_tree_ctrl->Bind( - wxEVT_DATAVIEW_SELECTION_CHANGED, &DIALOG_CHOOSE_COMPONENT::OnTreeSelect, this ); - m_details_ctrl->Bind( wxEVT_HTML_LINK_CLICKED, &DIALOG_CHOOSE_COMPONENT::OnDetailsLink, this ); m_sch_view_ctrl->Bind( wxEVT_LEFT_DCLICK, &DIALOG_CHOOSE_COMPONENT::OnSchViewDClick, this ); m_sch_view_ctrl->Bind( wxEVT_PAINT, &DIALOG_CHOOSE_COMPONENT::OnSchViewPaint, this ); @@ -122,42 +107,6 @@ DIALOG_CHOOSE_COMPONENT::~DIALOG_CHOOSE_COMPONENT() } -wxPanel* DIALOG_CHOOSE_COMPONENT::ConstructLeftPanel( wxWindow* aParent ) -{ - auto panel = new wxPanel( aParent ); - auto sizer = new wxBoxSizer( wxVERTICAL ); - auto search_sizer = new wxBoxSizer( wxHORIZONTAL ); - - m_query_ctrl = new wxTextCtrl( - panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER ); - - m_tree_ctrl = - new wxDataViewCtrl( panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDV_SINGLE ); - m_adapter->AttachTo( m_tree_ctrl ); - - m_details_ctrl = new wxHtmlWindow( panel, wxID_ANY, wxDefaultPosition, wxSize( 320, 240 ), - wxHW_SCROLLBAR_AUTO | wxSUNKEN_BORDER ); - -// Additional visual cue for GTK, which hides the placeholder text on focus -#ifdef __WXGTK__ - search_sizer->Add( new wxStaticBitmap( panel, wxID_ANY, - wxArtProvider::GetBitmap( wxART_FIND, wxART_FRAME_ICON ) ), - 0, wxALIGN_CENTER | wxALL, 5 ); -#endif - - search_sizer->Add( m_query_ctrl, 1, wxALIGN_CENTER | wxALL | wxEXPAND, 5 ); - - sizer->Add( search_sizer, 0, wxEXPAND, 5 ); - sizer->Add( m_tree_ctrl, 1, wxALL | wxEXPAND, 5 ); - sizer->Add( m_details_ctrl, 1, wxALL | wxEXPAND, 5 ); - - panel->SetSizer( sizer ); - panel->Layout(); - sizer->Fit( panel ); - return panel; -} - - wxPanel* DIALOG_CHOOSE_COMPONENT::ConstructRightPanel( wxWindow* aParent ) { auto panel = new wxPanel( aParent ); @@ -193,12 +142,6 @@ wxPanel* DIALOG_CHOOSE_COMPONENT::ConstructRightPanel( wxWindow* aParent ) void DIALOG_CHOOSE_COMPONENT::OnInitDialog( wxInitDialogEvent& aEvent ) { - // If wxTextCtrl::SetHint() is called before binding wxEVT_TEXT, the event - // handler will intermittently fire. - m_query_ctrl->SetHint( _( "Search" ) ); - m_query_ctrl->SetFocus(); - m_query_ctrl->SetValue( wxEmptyString ); - if( m_fp_view_ctrl->IsInitialized() ) { // This hides the GAL panel and shows the status label @@ -207,99 +150,30 @@ void DIALOG_CHOOSE_COMPONENT::OnInitDialog( wxInitDialogEvent& aEvent ) if( m_fp_sel_ctrl ) m_fp_sel_ctrl->Load( Kiway(), Prj() ); - - // There may be a part preselected in the model. Make sure it is displayed. - PostSelectEvent(); } LIB_ALIAS* DIALOG_CHOOSE_COMPONENT::GetSelectedAlias( int* aUnit ) const { - auto sel = m_tree_ctrl->GetSelection(); - - if( aUnit ) - *aUnit = m_adapter->GetUnitFor( sel ); - - return m_adapter->GetAliasFor( sel ); -} - - -std::vector> DIALOG_CHOOSE_COMPONENT::GetFields() const -{ - return m_field_edits; -} - - -void DIALOG_CHOOSE_COMPONENT::OnQueryText( wxCommandEvent& aEvent ) -{ - m_adapter->UpdateSearchString( m_query_ctrl->GetLineText( 0 ) ); - PostSelectEvent(); - - // Required to avoid interaction with SetHint() - // See documentation for wxTextEntry::SetHint - aEvent.Skip(); -} - - -void DIALOG_CHOOSE_COMPONENT::OnQueryEnter( wxCommandEvent& aEvent ) -{ - HandleItemSelection(); -} - - -void DIALOG_CHOOSE_COMPONENT::SelectIfValid( const wxDataViewItem& aTreeId ) -{ - if( aTreeId.IsOk() ) - { - m_tree_ctrl->EnsureVisible( aTreeId ); - m_tree_ctrl->Select( aTreeId ); - PostSelectEvent(); - } -} - - -void DIALOG_CHOOSE_COMPONENT::PostSelectEvent() -{ - wxDataViewEvent evt( wxEVT_DATAVIEW_SELECTION_CHANGED ); - m_tree_ctrl->GetEventHandler()->ProcessEvent( evt ); -} - - -void DIALOG_CHOOSE_COMPONENT::OnQueryCharHook( wxKeyEvent& aKeyStroke ) -{ - auto const sel = m_tree_ctrl->GetSelection(); - - switch( aKeyStroke.GetKeyCode() ) - { - case WXK_UP: SelectIfValid( GetPrevItem( *m_tree_ctrl, sel ) ); break; - - case WXK_DOWN: SelectIfValid( GetNextItem( *m_tree_ctrl, sel ) ); break; - - default: - aKeyStroke.Skip(); // Any other key: pass on to search box directly. - break; - } + return m_tree->GetSelectedAlias( aUnit ); } void DIALOG_CHOOSE_COMPONENT::OnTreeSelect( wxDataViewEvent& aEvent ) { - auto sel = m_tree_ctrl->GetSelection(); - int unit = m_adapter->GetUnitFor( sel ); - LIB_ALIAS* alias = m_adapter->GetAliasFor( sel ); + std::cout << "dialog choose component handler" << std::endl; // TODO + int unit = 0; + LIB_ALIAS* alias = m_tree->GetSelectedAlias( &unit ); m_sch_view_ctrl->Refresh(); if( alias ) { - m_details_ctrl->SetPage( GenerateAliasInfo( alias, unit ) ); ShowFootprintFor( alias ); PopulateFootprintSelector( alias ); } else { - m_details_ctrl->SetPage( wxEmptyString ); - if( m_fp_view_ctrl->IsInitialized() ) m_fp_view_ctrl->SetStatusText( wxEmptyString ); @@ -400,19 +274,10 @@ void DIALOG_CHOOSE_COMPONENT::PopulateFootprintSelector( LIB_ALIAS* aAlias ) } -void DIALOG_CHOOSE_COMPONENT::OnDetailsLink( wxHtmlLinkEvent& aEvent ) -{ - const wxHtmlLinkInfo& info = aEvent.GetLinkInfo(); - ::wxLaunchDefaultBrowser( info.GetHref() ); -} - - void DIALOG_CHOOSE_COMPONENT::OnSchViewPaint( wxPaintEvent& aEvent ) { - auto sel = m_tree_ctrl->GetSelection(); - - int unit = m_adapter->GetUnitFor( sel ); - LIB_ALIAS* alias = m_adapter->GetAliasFor( sel ); + int unit = 0; + LIB_ALIAS* alias = m_tree->GetSelectedAlias( &unit ); LIB_PART* part = alias ? alias->GetPart() : nullptr; // Don't draw anything (not even the background) if we don't have @@ -496,7 +361,7 @@ void DIALOG_CHOOSE_COMPONENT::RenderPreview( LIB_PART* aComponent, int aUnit ) void DIALOG_CHOOSE_COMPONENT::HandleItemSelection() { - if( m_adapter->GetAliasFor( m_tree_ctrl->GetSelection() ) ) + if( m_tree->GetSelectedAlias() ) { // 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 @@ -512,13 +377,4 @@ void DIALOG_CHOOSE_COMPONENT::HandleItemSelection() // spaghetti noodle. m_dbl_click_timer->StartOnce( DIALOG_CHOOSE_COMPONENT::DblClickDelay ); } - else - { - auto const sel = m_tree_ctrl->GetSelection(); - - if( m_tree_ctrl->IsExpanded( sel ) ) - m_tree_ctrl->Collapse( sel ); - else - m_tree_ctrl->Expand( sel ); - } } diff --git a/eeschema/dialogs/dialog_choose_component.h b/eeschema/dialogs/dialog_choose_component.h index 84f9f5cf2f..b2cd42ffca 100644 --- a/eeschema/dialogs/dialog_choose_component.h +++ b/eeschema/dialogs/dialog_choose_component.h @@ -40,6 +40,7 @@ class wxChoice; class wxButton; class wxTimer; +class COMPONENT_TREE; class FOOTPRINT_PREVIEW_WIDGET; class FOOTPRINT_SELECT_WIDGET; class LIB_ALIAS; @@ -101,7 +102,7 @@ public: ~DIALOG_CHOOSE_COMPONENT(); - /** Function GetSelectedAlias + /** * To be called after this dialog returns from ShowModal(). * * For multi-unit components, if the user selects the component itself @@ -112,13 +113,16 @@ public: * @param aUnit if not NULL, the selected unit is filled in here. * @return the alias that has been selected, or NULL if there is none. */ - LIB_ALIAS* GetSelectedAlias( int* aUnit ) const; + LIB_ALIAS* GetSelectedAlias( int* aUnit = nullptr ) const; /** * Get a list of fields edited by the user. * @return vector of pairs; each.first = field ID, each.second = new value */ - std::vector> GetFields() const; + std::vector> GetFields() const + { + return m_field_edits; + } /** Function IsExternalBrowserSelected * @@ -133,22 +137,15 @@ public: protected: static constexpr int DblClickDelay = 100; // milliseconds - wxPanel* ConstructLeftPanel( wxWindow* aParent ); wxPanel* ConstructRightPanel( wxWindow* aParent ); void OnInitDialog( wxInitDialogEvent& aEvent ); void OnCloseTimer( wxTimerEvent& aEvent ); void OnProgressTimer( wxTimerEvent& aEvent ); - void OnQueryText( wxCommandEvent& aEvent ); - void OnQueryEnter( wxCommandEvent& aEvent ); - void OnQueryCharHook( wxKeyEvent& aEvent ); - void OnTreeSelect( wxDataViewEvent& aEvent ); void OnTreeActivate( wxDataViewEvent& aEvent ); - void OnDetailsLink( wxHtmlLinkEvent& aEvent ); - void OnSchViewDClick( wxMouseEvent& aEvent ); void OnSchViewPaint( wxPaintEvent& aEvent ); @@ -171,17 +168,6 @@ protected: */ void PopulateFootprintSelector( LIB_ALIAS* aAlias ); - /** - * If a wxDataViewitem is valid, select it and post a selection event. - */ - void SelectIfValid( const wxDataViewItem& aTreeId ); - - /** - * Post a wxEVT_DATAVIEW_SELECTION_CHANGED to notify the selection handler - * that a new part has been selected. - */ - void PostSelectEvent(); - /** * Display a given component into the schematic symbol preview. */ @@ -196,16 +182,13 @@ protected: void HandleItemSelection(); wxTimer* m_dbl_click_timer; - wxTextCtrl* m_query_ctrl; - wxDataViewCtrl* m_tree_ctrl; - wxHtmlWindow* m_details_ctrl; wxPanel* m_sch_view_ctrl; FOOTPRINT_SELECT_WIDGET* m_fp_sel_ctrl; FOOTPRINT_PREVIEW_WIDGET* m_fp_view_ctrl; + COMPONENT_TREE* m_tree; SCH_BASE_FRAME* m_parent; - CMP_TREE_MODEL_ADAPTER::PTR m_adapter; int m_deMorganConvert; bool m_allow_field_edits; bool m_external_browser_requested; diff --git a/eeschema/widgets/component_tree.cpp b/eeschema/widgets/component_tree.cpp new file mode 100644 index 0000000000..82ac8cdaac --- /dev/null +++ b/eeschema/widgets/component_tree.cpp @@ -0,0 +1,195 @@ +/* -*- c++ -*- + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 Henner Zeller + * Copyright (C) 2017 Chris Pavlina + * Copyright (C) 2014-2017 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 "component_tree.h" +#include +#include + +#include +#include +#include +#include + +COMPONENT_TREE::COMPONENT_TREE( wxWindow* aParent, CMP_TREE_MODEL_ADAPTER::PTR& aAdapter ) + : wxPanel( aParent ), m_adapter( aAdapter ) +{ + auto sizer = new wxBoxSizer( wxVERTICAL ); + auto search_sizer = new wxBoxSizer( wxHORIZONTAL ); + + m_query_ctrl = new wxTextCtrl( + this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER ); + + m_tree_ctrl = + new wxDataViewCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDV_SINGLE ); + m_adapter->AttachTo( m_tree_ctrl ); + + m_details_ctrl = new wxHtmlWindow( this, wxID_ANY, wxDefaultPosition, wxSize( 320, 240 ), + wxHW_SCROLLBAR_AUTO | wxSUNKEN_BORDER ); + +// Additional visual cue for GTK, which hides the placeholder text on focus +#ifdef __WXGTK__ + search_sizer->Add( new wxStaticBitmap( this, wxID_ANY, + wxArtProvider::GetBitmap( wxART_FIND, wxART_FRAME_ICON ) ), + 0, wxALIGN_CENTER | wxALL, 5 ); +#endif + + search_sizer->Add( m_query_ctrl, 1, wxALIGN_CENTER | wxALL | wxEXPAND, 5 ); + + sizer->Add( search_sizer, 0, wxEXPAND, 5 ); + sizer->Add( m_tree_ctrl, 1, wxALL | wxEXPAND, 5 ); + sizer->Add( m_details_ctrl, 1, wxALL | wxEXPAND, 5 ); + + SetSizer( sizer ); + + Bind( wxEVT_INIT_DIALOG, &COMPONENT_TREE::onInitDialog, this ); + m_query_ctrl->Bind( wxEVT_TEXT, &COMPONENT_TREE::onQueryText, this ); + m_query_ctrl->Bind( wxEVT_TEXT_ENTER, &COMPONENT_TREE::onQueryEnter, this ); + m_query_ctrl->Bind( wxEVT_CHAR_HOOK, &COMPONENT_TREE::onQueryCharHook, this ); + m_tree_ctrl->Bind( wxEVT_DATAVIEW_ITEM_ACTIVATED, &COMPONENT_TREE::onTreeActivate, this ); + m_tree_ctrl->Bind( wxEVT_DATAVIEW_SELECTION_CHANGED, &COMPONENT_TREE::onTreeSelect, this ); + m_details_ctrl->Bind( wxEVT_HTML_LINK_CLICKED, &COMPONENT_TREE::onDetailsLink, this ); + + Layout(); + sizer->Fit( this ); +} + + +LIB_ALIAS* COMPONENT_TREE::GetSelectedAlias( int* aUnit ) const +{ + auto sel = m_tree_ctrl->GetSelection(); + + if( aUnit ) + *aUnit = m_adapter->GetUnitFor( sel ); + + return m_adapter->GetAliasFor( sel ); +} + + +void COMPONENT_TREE::selectIfValid( const wxDataViewItem& aTreeId ) +{ + if( aTreeId.IsOk() ) + { + m_tree_ctrl->EnsureVisible( aTreeId ); + m_tree_ctrl->Select( aTreeId ); + postSelectEvent(); + } +} + + +void COMPONENT_TREE::postSelectEvent() +{ + wxDataViewEvent evt( wxEVT_DATAVIEW_SELECTION_CHANGED ); + m_tree_ctrl->GetEventHandler()->ProcessEvent( evt ); +} + + +void COMPONENT_TREE::handleSubtree() +{ + if( !GetSelectedAlias() ) + { + // Expand library/part units subtree + auto const sel = m_tree_ctrl->GetSelection(); + + if( m_tree_ctrl->IsExpanded( sel ) ) + m_tree_ctrl->Collapse( sel ); + else + m_tree_ctrl->Expand( sel ); + } +} + + +void COMPONENT_TREE::onInitDialog( wxInitDialogEvent& aEvent ) +{ + // If wxTextCtrl::SetHint() is called before binding wxEVT_TEXT, the event + // handler will intermittently fire. + m_query_ctrl->SetHint( _( "Search" ) ); + m_query_ctrl->SetFocus(); + m_query_ctrl->SetValue( wxEmptyString ); + + // There may be a part preselected in the model. Make sure it is displayed. + postSelectEvent(); +} + + +void COMPONENT_TREE::onQueryText( wxCommandEvent& aEvent ) +{ + m_adapter->UpdateSearchString( m_query_ctrl->GetLineText( 0 ) ); + postSelectEvent(); + + // Required to avoid interaction with SetHint() + // See documentation for wxTextEntry::SetHint + aEvent.Skip(); +} + + +void COMPONENT_TREE::onQueryEnter( wxCommandEvent& aEvent ) +{ + handleSubtree(); +} + + +void COMPONENT_TREE::onQueryCharHook( wxKeyEvent& aKeyStroke ) +{ + auto const sel = m_tree_ctrl->GetSelection(); + + switch( aKeyStroke.GetKeyCode() ) + { + case WXK_UP: selectIfValid( GetPrevItem( *m_tree_ctrl, sel ) ); break; + + case WXK_DOWN: selectIfValid( GetNextItem( *m_tree_ctrl, sel ) ); break; + + default: + aKeyStroke.Skip(); // Any other key: pass on to search box directly. + break; + } +} + + +void COMPONENT_TREE::onTreeSelect( wxDataViewEvent& aEvent ) +{ + int unit = 0; + LIB_ALIAS* alias = GetSelectedAlias( &unit ); + + if( alias ) + m_details_ctrl->SetPage( GenerateAliasInfo( alias, unit ) ); + else + m_details_ctrl->SetPage( wxEmptyString ); + + aEvent.Skip(); +} + + +void COMPONENT_TREE::onTreeActivate( wxDataViewEvent& aEvent ) +{ + handleSubtree(); + aEvent.Skip(); +} + + +void COMPONENT_TREE::onDetailsLink( wxHtmlLinkEvent& aEvent ) +{ + const wxHtmlLinkInfo& info = aEvent.GetLinkInfo(); + ::wxLaunchDefaultBrowser( info.GetHref() ); +} diff --git a/eeschema/widgets/component_tree.h b/eeschema/widgets/component_tree.h new file mode 100644 index 0000000000..706fd1d87f --- /dev/null +++ b/eeschema/widgets/component_tree.h @@ -0,0 +1,92 @@ +/* -*- c++ -*- + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 Henner Zeller + * Copyright (C) 2017 Chris Pavlina + * Copyright (C) 2014-2017 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 COMPONENT_TREE_H +#define COMPONENT_TREE_H + +#include +#include + +class wxDataViewCtrl; +class wxTextCtrl; +class wxHtmlWindow; +class wxHtmlLinkEvent; + +/** + * Widget displaying a tree of components with a search text control and description. + */ +class COMPONENT_TREE : public wxPanel +{ +public: + COMPONENT_TREE( wxWindow* aParent, CMP_TREE_MODEL_ADAPTER::PTR& aAdapter ); + + /** + * For multi-unit components, if the user selects the component itself + * rather than picking an individual unit, 0 will be returned in aUnit. + * Beware that this is an invalid unit number - this should be replaced + * with whatever default is desired (usually 1). + * + * @param aUnit if not NULL, the selected unit is filled in here. + * @return the alias that has been selected, or NULL if there is none. + */ + LIB_ALIAS* GetSelectedAlias( int* aUnit = nullptr ) const; + +protected: + /** + * If a wxDataViewitem is valid, select it and post a selection event. + */ + void selectIfValid( const wxDataViewItem& aTreeId ); + + /** + * Post a wxEVT_DATAVIEW_SELECTION_CHANGED to notify the selection handler + * that a new part has been selected. + */ + void postSelectEvent(); + + /** + * If a library or part is selected, the corresponding subtree is expanded/collapsed. + */ + void handleSubtree(); + + // Event handlers + void onInitDialog( wxInitDialogEvent& aEvent ); + + void onQueryText( wxCommandEvent& aEvent ); + void onQueryEnter( wxCommandEvent& aEvent ); + void onQueryCharHook( wxKeyEvent& aEvent ); + + void onTreeSelect( wxDataViewEvent& aEvent ); + void onTreeActivate( wxDataViewEvent& aEvent ); + + void onDetailsLink( wxHtmlLinkEvent& aEvent ); + + CMP_TREE_MODEL_ADAPTER::PTR m_adapter; + + wxTextCtrl* m_query_ctrl; + wxDataViewCtrl* m_tree_ctrl; + wxHtmlWindow* m_details_ctrl; +}; + +#endif /* COMPONENT_TREE_H */