Disable previews when context menu active and when scrolling.

This commit is contained in:
Jeff Young 2023-09-06 16:23:13 +01:00
parent c07e9c834f
commit 6a73f48106
2 changed files with 59 additions and 15 deletions

View File

@ -56,7 +56,8 @@ LIB_TREE::LIB_TREE( wxWindow* aParent, const wxString& aRecentSearchesKey, LIB_T
m_inTimerEvent( false ), m_inTimerEvent( false ),
m_recentSearchesKey( aRecentSearchesKey ), m_recentSearchesKey( aRecentSearchesKey ),
m_skipNextRightClick( false ), m_skipNextRightClick( false ),
m_previewWindow( nullptr ) m_previewWindow( nullptr ),
m_previewDisabled( false )
{ {
wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL ); wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL );
@ -603,13 +604,15 @@ void LIB_TREE::onQueryMouseMoved( wxMouseEvent& aEvent )
#define PREVIEW_SIZE wxSize( 240, 200 ) #define PREVIEW_SIZE wxSize( 240, 200 )
#define HOVER_TIMER_MILLIS 400
void LIB_TREE::showPreview( wxDataViewItem aItem ) void LIB_TREE::showPreview( wxDataViewItem aItem )
{ {
if( aItem.IsOk() && m_adapter->HasPreview( aItem ) ) if( aItem.IsOk() && m_adapter->HasPreview( aItem ) )
{ {
m_hoverItem = aItem; m_previewItem = aItem;
m_previewItemRect = m_tree_ctrl->GetItemRect( m_previewItem );
wxWindow* topLevelParent = wxGetTopLevelParent( m_parent ); wxWindow* topLevelParent = wxGetTopLevelParent( m_parent );
@ -629,7 +632,7 @@ void LIB_TREE::showPreview( wxDataViewItem aItem )
void LIB_TREE::hidePreview() void LIB_TREE::hidePreview()
{ {
m_hoverItem = wxDataViewItem(); m_previewItem = wxDataViewItem();
if( m_previewWindow ) if( m_previewWindow )
{ {
@ -645,13 +648,18 @@ void LIB_TREE::onIdle( wxIdleEvent& aEvent )
// The wxDataViewCtrl won't give us its mouseMoved events so we're forced to use idle // The wxDataViewCtrl won't give us its mouseMoved events so we're forced to use idle
// events to track the hover state // events to track the hover state
// The dang thing won't give us scroll events either, so we implement a poor-man's
// scroll-checker using the last-known positions of the preview or hover items.
wxWindow* topLevelParent = wxGetTopLevelParent( m_parent ); wxWindow* topLevelParent = wxGetTopLevelParent( m_parent );
wxWindow* topLevelFocus = wxGetTopLevelParent( wxWindow::FindFocus() ); wxWindow* topLevelFocus = wxGetTopLevelParent( wxWindow::FindFocus() );
wxPoint screenPos = wxGetMousePosition(); wxPoint screenPos = wxGetMousePosition();
wxRect screenRect = m_tree_ctrl->IsShown() ? m_tree_ctrl->GetScreenRect() : wxRect(); wxRect screenRect = m_tree_ctrl->GetScreenRect();
if( topLevelFocus != topLevelParent || !screenRect.Contains( screenPos ) ) if( !m_tree_ctrl->IsShown() || m_previewDisabled
|| topLevelFocus != topLevelParent
|| !screenRect.Contains( screenPos ) )
{ {
m_hoverTimer.Stop(); m_hoverTimer.Stop();
hidePreview(); hidePreview();
@ -659,17 +667,28 @@ void LIB_TREE::onIdle( wxIdleEvent& aEvent )
} }
wxPoint clientPos = m_tree_ctrl->ScreenToClient( screenPos ); wxPoint clientPos = m_tree_ctrl->ScreenToClient( screenPos );
if( m_hoverItem.IsOk() )
{
wxDataViewItem item; wxDataViewItem item;
wxDataViewColumn* col = nullptr; wxDataViewColumn* col = nullptr;
m_tree_ctrl->HitTest( clientPos, item, col ); m_tree_ctrl->HitTest( clientPos, item, col );
if( item != m_hoverItem ) if( m_previewItem.IsOk() )
{
// Scroll checker
if( m_tree_ctrl->GetItemRect( m_previewItem ) != m_previewItemRect )
{ {
hidePreview(); hidePreview();
m_hoverPos = clientPos; m_hoverPos = clientPos;
m_hoverItem = item;
m_hoverItemRect = m_tree_ctrl->GetItemRect( m_hoverItem );
m_hoverTimer.StartOnce( HOVER_TIMER_MILLIS );
return;
}
if( item != m_previewItem )
{
hidePreview();
showPreview( item ); showPreview( item );
} }
@ -679,7 +698,9 @@ void LIB_TREE::onIdle( wxIdleEvent& aEvent )
if( m_hoverPos != clientPos ) if( m_hoverPos != clientPos )
{ {
m_hoverPos = clientPos; m_hoverPos = clientPos;
m_hoverTimer.Start( 400, wxTIMER_ONE_SHOT ); m_hoverItem = item;
m_hoverItemRect = m_tree_ctrl->GetItemRect( m_hoverItem );
m_hoverTimer.StartOnce( HOVER_TIMER_MILLIS );
} }
} }
@ -688,12 +709,24 @@ void LIB_TREE::onHoverTimer( wxTimerEvent& aEvent )
{ {
hidePreview(); hidePreview();
if( !m_tree_ctrl->IsShown() || m_previewDisabled )
return;
wxDataViewItem item; wxDataViewItem item;
wxDataViewColumn* col = nullptr; wxDataViewColumn* col = nullptr;
m_tree_ctrl->HitTest( m_hoverPos, item, col ); m_tree_ctrl->HitTest( m_hoverPos, item, col );
if( item == m_hoverItem && m_tree_ctrl->GetItemRect( item ) == m_hoverItemRect )
{
if( item != m_tree_ctrl->GetSelection() ) if( item != m_tree_ctrl->GetSelection() )
showPreview( item ); showPreview( item );
}
else // view must have been scrolled
{
m_hoverItem = item;
m_hoverItemRect = m_tree_ctrl->GetItemRect( m_hoverItem );
m_hoverTimer.StartOnce( HOVER_TIMER_MILLIS );
}
} }
@ -780,6 +813,8 @@ void LIB_TREE::onItemContextMenu( wxDataViewEvent& aEvent )
return; return;
} }
m_previewDisabled = true;
if( TOOL_INTERACTIVE* tool = m_adapter->GetContextMenuTool() ) if( TOOL_INTERACTIVE* tool = m_adapter->GetContextMenuTool() )
{ {
if( !GetCurrentTreeNode() ) if( !GetCurrentTreeNode() )
@ -839,12 +874,15 @@ void LIB_TREE::onItemContextMenu( wxDataViewEvent& aEvent )
} }
} }
} }
m_previewDisabled = false;
} }
void LIB_TREE::onHeaderContextMenu( wxDataViewEvent& aEvent ) void LIB_TREE::onHeaderContextMenu( wxDataViewEvent& aEvent )
{ {
hidePreview(); hidePreview();
m_previewDisabled = true;
ACTION_MENU menu( true, nullptr ); ACTION_MENU menu( true, nullptr );
@ -859,6 +897,8 @@ void LIB_TREE::onHeaderContextMenu( wxDataViewEvent& aEvent )
if( dlg.ShowModal() == wxID_OK ) if( dlg.ShowModal() == wxID_OK )
m_adapter->SetShownColumns( dlg.EnabledList() ); m_adapter->SetShownColumns( dlg.EnabledList() );
} }
m_previewDisabled = false;
} }

View File

@ -243,8 +243,12 @@ protected:
wxPoint m_hoverPos; wxPoint m_hoverPos;
wxDataViewItem m_hoverItem; wxDataViewItem m_hoverItem;
wxRect m_hoverItemRect;
wxTimer m_hoverTimer; wxTimer m_hoverTimer;
wxDataViewItem m_previewItem;
wxRect m_previewItemRect;
wxPopupWindow* m_previewWindow; wxPopupWindow* m_previewWindow;
bool m_previewDisabled;
}; };
///< Custom event sent when a new symbol is preselected ///< Custom event sent when a new symbol is preselected