35#include <wx/settings.h>
37#include <wx/srchctrl.h>
38#include <wx/statline.h>
39#include <wx/popupwin.h>
51 wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER>& aAdapter,
int aFlags,
53 wxPanel( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
54 wxWANTS_CHARS | wxTAB_TRAVERSAL | wxNO_BORDER ),
75 m_previewWindow(
nullptr ),
76 m_previewDisabled(
false )
78 wxBoxSizer* sizer =
new wxBoxSizer( wxVERTICAL );
83 wxBoxSizer* search_sizer =
new wxBoxSizer( wxHORIZONTAL );
85 m_query_ctrl =
new wxSearchCtrl(
this, wxID_ANY );
87 m_query_ctrl->ShowCancelButton(
true );
89 search_sizer->Add( m_query_ctrl, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT, 4 );
91 wxStaticLine* separator =
new wxStaticLine(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL );
92 search_sizer->Add( separator, 0, wxEXPAND|wxTOP|wxBOTTOM, 3 );
94 m_sort_ctrl =
new BITMAP_BUTTON(
this, wxID_ANY, wxNullBitmap, wxDefaultPosition,
95 wxDefaultSize, wxBU_AUTODRAW|0 );
97 m_sort_ctrl->Bind( wxEVT_LEFT_DOWN,
98 [&]( wxMouseEvent& aEvent )
103 menu.Append( 4201,
_(
"Sort by Best Match" ), wxEmptyString, wxITEM_CHECK );
104 menu.Append( 4202,
_(
"Sort Alphabetically" ), wxEmptyString, wxITEM_CHECK );
105 menu.AppendSeparator();
110 menu.Check( 4201,
true );
112 menu.Check( 4202,
true );
115 int menu_id = m_sort_ctrl->GetPopupMenuSelectionFromUser( menu );
117 if( menu_id == 0 || menu_id == 4201 )
122 else if( menu_id == 1 || menu_id == 4202 )
127 else if( menu_id == 3 || menu_id == 4203 )
131 else if( menu_id == 4 || menu_id == 4204 )
138 search_sizer->Add( m_sort_ctrl, 0, wxALIGN_CENTER_VERTICAL, 5 );
140 sizer->Add( search_sizer, 0, wxEXPAND, 5 );
148#if defined( __WXOSX__ )
149 m_query_ctrl->Bind( wxEVT_LEAVE_WINDOW,
150 [
this]( wxMouseEvent& aEvt )
152 SetCursor( wxCURSOR_ARROW );
156 m_query_ctrl->Bind( wxEVT_MENU,
157 [
this]( wxCommandEvent& aEvent )
159 size_t idx = aEvent.GetId() - 1;
169 m_filtersSizer =
new wxBoxSizer( wxVERTICAL );
170 sizer->Add( m_filtersSizer, 0, wxEXPAND | wxLEFT, 4 );
174 int dvFlags = ( aFlags & MULTISELECT ) ? wxDV_MULTIPLE : wxDV_SINGLE;
175 m_tree_ctrl =
new WX_DATAVIEWCTRL(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize, dvFlags );
176 m_adapter->AttachTo( m_tree_ctrl );
180 int rowHeight = FromDIP( 6 ) + GetTextExtent( wxS(
"pdI" ) ).y;
181 m_tree_ctrl->SetRowHeight( rowHeight );
184 sizer->Add( m_tree_ctrl, 5, wxEXPAND, 5 );
187 if( aFlags & DETAILS )
191 wxPoint html_size = ConvertDialogToPixels( wxPoint( 80, 80 ) );
193 m_details_ctrl =
new HTML_WINDOW(
this, wxID_ANY, wxDefaultPosition,
194 wxSize( html_size.x, html_size.y ) );
196 sizer->Add( m_details_ctrl, 2, wxTOP | wxEXPAND, 5 );
200 m_details_ctrl = aDetails;
225 m_query_ctrl->SetDescriptiveText(
_(
"Filter" ) );
226 m_query_ctrl->SetFocus();
227 m_query_ctrl->ChangeValue( wxEmptyString );
228 updateRecentSearchMenu();
237 postPreselectEvent();
247 m_details_ctrl->ShowScrollbars( wxSHOW_SB_ALWAYS, wxSHOW_SB_ALWAYS );
316 if(
m_adapter->GetTreeNodeFor( sel )->m_IsAlreadyPlacedGroup
317 ||
m_adapter->GetTreeNodeFor( sel )->m_IsRecentlyUsedGroup )
331 wxDataViewItemArray selection;
332 int count =
m_tree_ctrl->GetSelections( selection );
334 for(
const wxDataViewItem& item : selection )
336 aSelection.emplace_back(
m_adapter->GetAliasFor( item ) );
339 aUnit->emplace_back(
m_adapter->GetUnitFor( item ) );
358 wxDataViewItemArray selection;
359 int count =
m_tree_ctrl->GetSelections( selection );
361 for(
const wxDataViewItem& item : selection )
363 aSelection.push_back(
m_adapter->GetTreeNodeFor( item ) );
372 wxDataViewItem item =
m_adapter->FindItem( aLibId );
404 std::vector<LIB_ID> expanded;
405 wxDataViewItemArray items;
406 m_adapter->GetChildren( wxDataViewItem(
nullptr ), items );
408 for(
const wxDataViewItem& item : items )
413 expanded.push_back( node->m_LibId );
451 if( !newEntry.IsEmpty() )
454 std::erase( recents, newEntry );
459 recents.insert( recents.begin(), newEntry );
462 wxMenu* menu =
new wxMenu();
464 for(
const wxString&
recent : recents )
465 menu->Append( menu->GetMenuItemCount() + 1,
recent );
467 if( recents.empty() )
468 menu->Append( wxID_ANY,
_(
"recent searches" ) );
516 if( !aTreeId.IsOk() )
555 wxDataViewItemArray siblings;
556 m_adapter->GetChildren( wxDataViewItem( parent ), siblings );
558 int idx = siblings.Index( aTreeId );
560 if( idx + 5 < (
int) siblings.GetCount() )
564 else if( grandParent )
566 wxDataViewItemArray parentsSiblings;
567 m_adapter->GetChildren( wxDataViewItem( grandParent ), parentsSiblings );
569 int p_idx = parentsSiblings.Index( wxDataViewItem( parent ) );
571 if( p_idx + 1 < (
int) parentsSiblings.GetCount() )
588 if( aTreeId.IsOk() && !
m_tree_ctrl->IsExpanded( aTreeId ) )
595 wxCommandEvent event( EVT_LIBITEM_SELECTED );
596 wxPostEvent(
this, event );
602 wxCommandEvent event( EVT_LIBITEM_CHOSEN );
603 wxPostEvent(
this, event );
610 wxDataViewItemArray items;
611 m_adapter->GetChildren( wxDataViewItem(
nullptr ), items );
613 for(
const wxDataViewItem& item : items )
634 for(
const wxDataViewItem& item : aState.
expanded )
670 int hotkey = aKeyStroke.GetKeyCode();
672 int mods = aKeyStroke.GetModifiers();
677 if( wxmods & wxMOD_ALTGR )
682 if( mods & wxMOD_CONTROL )
685 if( mods & wxMOD_ALT )
689 if( mods & wxMOD_SHIFT )
693 if( mods & wxMOD_META )
698 if( mods & wxMOD_WIN )
718 sel =
m_adapter->GetCurrentDataViewItem();
721 : LIB_TREE_NODE::TYPE::INVALID;
723 switch( aKeyStroke.GetKeyCode() )
738 if( type == LIB_TREE_NODE::TYPE::LIBRARY )
746 if( type == LIB_TREE_NODE::TYPE::LIBRARY )
752 case WXK_NUMPAD_ENTER:
757 else if( type == LIB_TREE_NODE::TYPE::LIBRARY )
771#if defined( __WXOSX__ )
772 wxPoint pos = aEvent.GetPosition();
774 int buttonWidth = ctrlRect.GetHeight();
776 if(
m_query_ctrl->IsSearchButtonVisible() && pos.x < buttonWidth )
777 SetCursor( wxCURSOR_ARROW );
778 else if(
m_query_ctrl->IsCancelButtonVisible() && pos.x > ctrlRect.GetWidth() - buttonWidth )
779 SetCursor( wxCURSOR_ARROW );
781 SetCursor( wxCURSOR_IBEAM );
786#define PREVIEW_SIZE wxSize( 240, 200 )
791 if( aItem.IsOk() &&
m_adapter->HasPreview( aItem ) )
796 wxWindow* topLevelParent = wxGetTopLevelParent( m_parent );
830 wxWindow* topLevelParent = wxGetTopLevelParent( m_parent );
831 wxWindow* topLevelFocus = wxGetTopLevelParent( wxWindow::FindFocus() );
833 bool mouseOverWindow =
false;
834 wxPoint screenPos = wxGetMousePosition();
837 mouseOverWindow |=
m_tree_ctrl->GetScreenRect().Contains( screenPos );
846 wxPoint clientPos =
m_tree_ctrl->ScreenToClient( screenPos );
848 wxDataViewColumn* col =
nullptr;
858 if( wxGetDisplayInfo().type == wxDisplayType::wxDisplayWayland )
885 wxDataViewColumn* col =
nullptr;
907 if( aKeyStroke.GetModifiers() == wxMOD_NONE
908 && ( aKeyStroke.GetKeyCode() == WXK_LEFT || aKeyStroke.GetKeyCode() == WXK_RIGHT ) )
913 sel =
m_adapter->GetCurrentDataViewItem();
917 if( aKeyStroke.GetKeyCode() == WXK_RIGHT )
928 if( aKeyStroke.GetSkipped() )
932 int hotkey = aKeyStroke.GetKeyCode();
934 int mods = aKeyStroke.GetModifiers();
936 if( mods & wxMOD_ALTGR )
940 if( mods & wxMOD_ALT )
943 if( mods & wxMOD_CONTROL )
947 if( mods & wxMOD_SHIFT )
951 if( mods & wxMOD_META )
956 if( mods & wxMOD_WIN )
960 if( tool->GetManager()->GetActionManager()->RunHotKey( hotkey ) )
961 aKeyStroke.Skip(
false );
995 const wxHtmlLinkInfo&
info = aEvent.GetLinkInfo();
996 wxString docname =
info.GetHref();
1036 wxDataViewItem item = aEvent.GetItem();
1053 tool->GetManager()->VetoContextMenuMouseWarp();
1054 tool->GetToolMenu().ShowContextMenu();
1057 tool->GetManager()->DispatchContextMenu( evt );
1063 if( current && current->
m_Type == LIB_TREE_NODE::TYPE::LIBRARY )
1071 if( GetPopupMenuSelectionFromUser( menu ) != wxID_NONE )
1078 if( GetPopupMenuSelectionFromUser( menu ) != wxID_NONE )
1097 if( GetPopupMenuSelectionFromUser( menu ) != wxID_NONE )
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
static TOOL_ACTION pinLibrary
static TOOL_ACTION selectLibTreeColumns
static TOOL_ACTION unpinLibrary
static TOOL_ACTION expandAll
static TOOL_ACTION collapseAll
A dialog which allows selecting a list of items from a list of available items, and reordering those ...
const std::vector< wxString > & EnabledList()
Add dark theme support to wxHtmlWindow.
A logical library item identifier and consists of various portions much like a URI.
const UTF8 & GetLibItemName() const
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Model class in the component selector Model-View-Adapter (mediated MVC) architecture.
void onHoverPreview()
Show the hovered item's preview once the mouse stops moving.
void RefreshLibTree()
Refresh the tree (mainly to update highlighting and asterisking)
LIB_TREE_NODE * GetCurrentTreeNode() const
Retrieve the tree node for the first selected item.
void onQueryMouseMoved(wxMouseEvent &aEvent)
wxDataViewItem m_previewItem
WX_DEBOUNCED_ACTION m_queryDebounce
Debounces the query typed in the search control.
HTML_WINDOW * m_details_ctrl
void onTreeActivate(wxDataViewEvent &aEvent)
wxString m_recentSearchesKey
LIB_TREE(wxWindow *aParent, const wxString &aRecentSearchesKey, wxObjectDataPtr< LIB_TREE_MODEL_ADAPTER > &aAdapter, int aFlags=ALL_WIDGETS, HTML_WINDOW *aDetails=nullptr)
Construct a symbol tree.
void onQueryCharHook(wxKeyEvent &aEvent)
void CenterLibId(const LIB_ID &aLibId)
Ensure that an item is visible (preferably centered).
void postSelectEvent()
Post EVT_LIBITEM_CHOSEN event to notify the selection handler that a part has been selected.
wxWindow * GetFocusTarget()
void onQueryDebounce()
Regenerate the tree from the search text once typing pauses.
void onItemContextMenu(wxDataViewEvent &aEvent)
void ShowChangedLanguage()
WX_DATAVIEWCTRL * m_tree_ctrl
void onQueryText(wxCommandEvent &aEvent)
void toggleExpand(const wxDataViewItem &aTreeId)
Expand or collapse a node, switching it to the opposite state.
int GetSelectedTreeNodes(std::vector< LIB_TREE_NODE * > &aSelection) const
Retrieve a list of pointers to selected tree nodes for trees that allow multi-selection.
bool m_skipNextRightClick
void selectIfValid(const wxDataViewItem &aTreeId)
If a wxDataViewitem is valid, select it and post a selection event.
void onIdle(wxIdleEvent &aEvent)
void FocusSearchFieldIfExists()
Focus the search widget if it exists.
std::vector< LIB_ID > GetExpandedLibraries() const
void expandIfValid(const wxDataViewItem &aTreeId)
void onPreselect(wxCommandEvent &aEvent)
wxPopupWindow * m_previewWindow
void SelectLibId(const LIB_ID &aLibId)
Select an item in the tree widget.
void updateRecentSearchMenu()
void showPreview(wxDataViewItem aItem)
wxString GetSearchString() const
void onTreeSelect(wxDataViewEvent &aEvent)
int GetSelectedLibIds(std::vector< LIB_ID > &aSelection, std::vector< int > *aUnit=nullptr) const
Retrieve a list of selections for trees that allow multi-selection.
void postPreselectEvent()
Post a wxEVT_DATAVIEW_SELECTION_CHANGED to notify the selection handler that a new part has been pres...
void Unselect()
Unselect currently selected item in wxDataViewCtrl.
BITMAP_BUTTON * m_sort_ctrl
void onTreeCharHook(wxKeyEvent &aEvent)
void onDetailsLink(wxHtmlLinkEvent &aEvent)
LIB_ID GetSelectedLibId(int *aUnit=nullptr) const
For multi-unit symbols, if the user selects the symbol itself rather than picking an individual unit,...
wxBoxSizer * m_filtersSizer
wxDataViewItem m_hoverItem
void SetSearchString(const wxString &aSearchString)
Save/restore search string.
void setState(const STATE &aState)
Restore the symbol tree widget state from an object.
STATE getState() const
Return the symbol tree widget state.
void ExpandLibId(const LIB_ID &aLibId)
Expand and item i the tree widget.
wxSearchCtrl * m_query_ctrl
void centerIfValid(const wxDataViewItem &aTreeId)
WX_DEBOUNCED_ACTION m_hoverDebounce
Debounces the item preview shown on hover.
void onHeaderContextMenu(wxDataViewEvent &aEvent)
void Regenerate(bool aKeepState)
Regenerate the tree.
wxObjectDataPtr< LIB_TREE_MODEL_ADAPTER > m_adapter
virtual SETTINGS_MANAGER & GetSettingsManager() const
Container for project specific data.
PROJECT & Prj() const
A helper while we are not MDI-capable – return the one and only project.
Extension of the wxDataViewCtrl to include some helper functions for working with items.
static constexpr int TEXT_INPUT_DEBOUNCE_MS
A typical debounce period for text input events, in milliseconds.
static constexpr int HOVER_PREVIEW_DEBOUNCE_MS
A typical debounce period for hover preview events, in milliseconds.
bool GetAssociatedDocument(wxWindow *aParent, const wxString &aDocName, PROJECT *aProject, SEARCH_STACK *aPaths, std::vector< EMBEDDED_FILES * > aFilesStack)
Open a document (file) with the suitable browser.
This file is part of the common library.
static const S_FILTER FILTERS[]
constexpr int RECENT_SEARCHES_MAX
std::map< wxString, std::vector< wxString > > g_recentSearches
wxDEFINE_EVENT(EVT_LIBITEM_SELECTED, wxCommandEvent)
This file contains miscellaneous commonly used macros and functions.
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
PGM_BASE & Pgm()
The global program "get" accessor.
Structure storing state of the symbol tree widget.
LIB_ID selection
Current selection, might be not valid if nothing was selected.
std::vector< wxDataViewItem > expanded
List of expanded nodes.
void EnsureVisibleIfEnabled(wxDataViewCtrl *aWidget, const wxDataViewItem &aItem)
Scroll aItem into view only when aWidget is currently enabled.