Fixed selecting components with Enter (DIALOG_CHOOSE_COMPONENT)

Added dedicated event types: COMPONENT_SELECTED, COMPONENT_PRESELECTED.
This commit is contained in:
Maciej Suminski 2017-06-25 23:13:39 +02:00
parent 6a3c1720b2
commit ac688e688a
4 changed files with 116 additions and 100 deletions

View File

@ -82,8 +82,8 @@ DIALOG_CHOOSE_COMPONENT::DIALOG_CHOOSE_COMPONENT( SCH_BASE_FRAME* aParent, const
Bind( wxEVT_INIT_DIALOG, &DIALOG_CHOOSE_COMPONENT::OnInitDialog, this ); Bind( wxEVT_INIT_DIALOG, &DIALOG_CHOOSE_COMPONENT::OnInitDialog, this );
Bind( wxEVT_TIMER, &DIALOG_CHOOSE_COMPONENT::OnCloseTimer, this, m_dbl_click_timer->GetId() ); Bind( wxEVT_TIMER, &DIALOG_CHOOSE_COMPONENT::OnCloseTimer, this, m_dbl_click_timer->GetId() );
Bind( wxEVT_DATAVIEW_ITEM_ACTIVATED, &DIALOG_CHOOSE_COMPONENT::OnTreeActivate, this ); Bind( COMPONENT_PRESELECTED, &DIALOG_CHOOSE_COMPONENT::OnComponentPreselected, this );
Bind( wxEVT_DATAVIEW_SELECTION_CHANGED, &DIALOG_CHOOSE_COMPONENT::OnTreeSelect, this ); Bind( COMPONENT_SELECTED, &DIALOG_CHOOSE_COMPONENT::OnComponentSelected, this );
m_sch_view_ctrl->Bind( wxEVT_LEFT_DCLICK, &DIALOG_CHOOSE_COMPONENT::OnSchViewDClick, 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 ); m_sch_view_ctrl->Bind( wxEVT_PAINT, &DIALOG_CHOOSE_COMPONENT::OnSchViewPaint, this );
@ -159,35 +159,6 @@ LIB_ALIAS* DIALOG_CHOOSE_COMPONENT::GetSelectedAlias( int* aUnit ) const
} }
void DIALOG_CHOOSE_COMPONENT::OnTreeSelect( wxDataViewEvent& aEvent )
{
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 )
{
ShowFootprintFor( alias );
PopulateFootprintSelector( alias );
}
else
{
if( m_fp_view_ctrl->IsInitialized() )
m_fp_view_ctrl->SetStatusText( wxEmptyString );
PopulateFootprintSelector( nullptr );
}
}
void DIALOG_CHOOSE_COMPONENT::OnTreeActivate( wxDataViewEvent& aEvent )
{
HandleItemSelection();
}
void DIALOG_CHOOSE_COMPONENT::OnCloseTimer( wxTimerEvent& aEvent ) void DIALOG_CHOOSE_COMPONENT::OnCloseTimer( wxTimerEvent& aEvent )
{ {
// Hack handler because of eaten MouseUp event. See // Hack handler because of eaten MouseUp event. See
@ -318,6 +289,49 @@ void DIALOG_CHOOSE_COMPONENT::OnFootprintSelected( wxCommandEvent& aEvent )
} }
void DIALOG_CHOOSE_COMPONENT::OnComponentPreselected( wxCommandEvent& aEvent )
{
int unit = 0;
LIB_ALIAS* alias = m_tree->GetSelectedAlias( &unit );
m_sch_view_ctrl->Refresh();
if( alias )
{
ShowFootprintFor( alias );
PopulateFootprintSelector( alias );
}
else
{
if( m_fp_view_ctrl->IsInitialized() )
m_fp_view_ctrl->SetStatusText( wxEmptyString );
PopulateFootprintSelector( nullptr );
}
}
void DIALOG_CHOOSE_COMPONENT::OnComponentSelected( wxCommandEvent& aEvent )
{
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
// MouseUp following a double click).
//
// NOW, here's where it gets really fun. wxTreeListCtrl eats MouseUp.
// This isn't really feasible to bypass without a fully custom
// wxDataViewCtrl implementation, and even then might not be fully
// possible (docs are vague). To get around this, we use a one-shot
// timer to schedule the dialog close.
//
// See DIALOG_CHOOSE_COMPONENT::OnCloseTimer for the other end of this
// spaghetti noodle.
m_dbl_click_timer->StartOnce( DIALOG_CHOOSE_COMPONENT::DblClickDelay );
}
}
void DIALOG_CHOOSE_COMPONENT::RenderPreview( LIB_PART* aComponent, int aUnit ) void DIALOG_CHOOSE_COMPONENT::RenderPreview( LIB_PART* aComponent, int aUnit )
{ {
wxPaintDC dc( m_sch_view_ctrl ); wxPaintDC dc( m_sch_view_ctrl );
@ -357,24 +371,3 @@ void DIALOG_CHOOSE_COMPONENT::RenderPreview( LIB_PART* aComponent, int aUnit )
opts.draw_hidden_fields = false; opts.draw_hidden_fields = false;
aComponent->Draw( nullptr, &dc, offset, aUnit, m_deMorganConvert, opts ); aComponent->Draw( nullptr, &dc, offset, aUnit, m_deMorganConvert, opts );
} }
void DIALOG_CHOOSE_COMPONENT::HandleItemSelection()
{
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
// MouseUp following a double click).
//
// NOW, here's where it gets really fun. wxTreeListCtrl eats MouseUp.
// This isn't really feasible to bypass without a fully custom
// wxDataViewCtrl implementation, and even then might not be fully
// possible (docs are vague). To get around this, we use a one-shot
// timer to schedule the dialog close.
//
// See DIALOG_CHOOSE_COMPONENT::OnCloseTimer for the other end of this
// spaghetti noodle.
m_dbl_click_timer->StartOnce( DIALOG_CHOOSE_COMPONENT::DblClickDelay );
}
}

View File

@ -143,14 +143,21 @@ protected:
void OnCloseTimer( wxTimerEvent& aEvent ); void OnCloseTimer( wxTimerEvent& aEvent );
void OnProgressTimer( wxTimerEvent& aEvent ); void OnProgressTimer( wxTimerEvent& aEvent );
void OnTreeSelect( wxDataViewEvent& aEvent );
void OnTreeActivate( wxDataViewEvent& aEvent );
void OnSchViewDClick( wxMouseEvent& aEvent ); void OnSchViewDClick( wxMouseEvent& aEvent );
void OnSchViewPaint( wxPaintEvent& aEvent ); void OnSchViewPaint( wxPaintEvent& aEvent );
void OnFootprintSelected( wxCommandEvent& aEvent ); void OnFootprintSelected( wxCommandEvent& aEvent );
void OnComponentPreselected( wxCommandEvent& aEvent );
/**
* Handle the selection of an item. This is called when either the search
* box or the tree receive an Enter, or the tree receives a double click.
* If the item selected is a category, it is expanded or collapsed; if it
* is a component, the component is picked.
*/
void OnComponentSelected( wxCommandEvent& aEvent );
/** /**
* Look up the footprint for a given alias and display it. * Look up the footprint for a given alias and display it.
*/ */
@ -173,14 +180,6 @@ protected:
*/ */
void RenderPreview( LIB_PART* aComponent, int aUnit ); void RenderPreview( LIB_PART* aComponent, int aUnit );
/**
* Handle the selection of an item. This is called when either the search
* box or the tree receive an Enter, or the tree receives a double click.
* If the item selected is a category, it is expanded or collapsed; if it
* is a component, the component is picked.
*/
void HandleItemSelection();
wxTimer* m_dbl_click_timer; wxTimer* m_dbl_click_timer;
wxPanel* m_sch_view_ctrl; wxPanel* m_sch_view_ctrl;

View File

@ -84,6 +84,8 @@ COMPONENT_TREE::COMPONENT_TREE( wxWindow* aParent,
m_tree_ctrl->Bind( wxEVT_DATAVIEW_ITEM_ACTIVATED, &COMPONENT_TREE::onTreeActivate, 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_tree_ctrl->Bind( wxEVT_DATAVIEW_SELECTION_CHANGED, &COMPONENT_TREE::onTreeSelect, this );
Bind( COMPONENT_PRESELECTED, &COMPONENT_TREE::onPreselect, this );
Layout(); Layout();
sizer->Fit( this ); sizer->Fit( this );
} }
@ -106,30 +108,22 @@ void COMPONENT_TREE::selectIfValid( const wxDataViewItem& aTreeId )
{ {
m_tree_ctrl->EnsureVisible( aTreeId ); m_tree_ctrl->EnsureVisible( aTreeId );
m_tree_ctrl->Select( aTreeId ); m_tree_ctrl->Select( aTreeId );
postSelectEvent(); postPreselectEvent();
} }
} }
void COMPONENT_TREE::postPreselectEvent()
{
wxCommandEvent event( COMPONENT_PRESELECTED );
wxPostEvent( this, event );
}
void COMPONENT_TREE::postSelectEvent() void COMPONENT_TREE::postSelectEvent()
{ {
wxDataViewEvent evt( wxEVT_DATAVIEW_SELECTION_CHANGED ); wxCommandEvent event( COMPONENT_SELECTED );
m_tree_ctrl->GetEventHandler()->ProcessEvent( evt ); wxPostEvent( this, event );
}
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 );
}
} }
@ -145,14 +139,14 @@ void COMPONENT_TREE::onInitDialog( wxInitDialogEvent& aEvent )
} }
// There may be a part preselected in the model. Make sure it is displayed. // There may be a part preselected in the model. Make sure it is displayed.
postSelectEvent(); postPreselectEvent();
} }
void COMPONENT_TREE::onQueryText( wxCommandEvent& aEvent ) void COMPONENT_TREE::onQueryText( wxCommandEvent& aEvent )
{ {
m_adapter->UpdateSearchString( m_query_ctrl->GetLineText( 0 ) ); m_adapter->UpdateSearchString( m_query_ctrl->GetLineText( 0 ) );
postSelectEvent(); postPreselectEvent();
// Required to avoid interaction with SetHint() // Required to avoid interaction with SetHint()
// See documentation for wxTextEntry::SetHint // See documentation for wxTextEntry::SetHint
@ -162,7 +156,8 @@ void COMPONENT_TREE::onQueryText( wxCommandEvent& aEvent )
void COMPONENT_TREE::onQueryEnter( wxCommandEvent& aEvent ) void COMPONENT_TREE::onQueryEnter( wxCommandEvent& aEvent )
{ {
handleSubtree(); if( GetSelectedAlias() )
postSelectEvent();
} }
@ -184,6 +179,38 @@ void COMPONENT_TREE::onQueryCharHook( wxKeyEvent& aKeyStroke )
void COMPONENT_TREE::onTreeSelect( wxDataViewEvent& aEvent ) void COMPONENT_TREE::onTreeSelect( wxDataViewEvent& aEvent )
{
postPreselectEvent();
}
void COMPONENT_TREE::onTreeActivate( wxDataViewEvent& aEvent )
{
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 );
}
else
{
postSelectEvent();
}
}
void COMPONENT_TREE::onDetailsLink( wxHtmlLinkEvent& aEvent )
{
const wxHtmlLinkInfo& info = aEvent.GetLinkInfo();
::wxLaunchDefaultBrowser( info.GetHref() );
}
void COMPONENT_TREE::onPreselect( wxCommandEvent& aEvent )
{ {
if( m_details_ctrl ) if( m_details_ctrl )
{ {
@ -200,15 +227,5 @@ void COMPONENT_TREE::onTreeSelect( wxDataViewEvent& aEvent )
} }
void COMPONENT_TREE::onTreeActivate( wxDataViewEvent& aEvent ) wxDEFINE_EVENT( COMPONENT_PRESELECTED, wxCommandEvent );
{ wxDEFINE_EVENT( COMPONENT_SELECTED, wxCommandEvent );
handleSubtree();
aEvent.Skip();
}
void COMPONENT_TREE::onDetailsLink( wxHtmlLinkEvent& aEvent )
{
const wxHtmlLinkInfo& info = aEvent.GetLinkInfo();
::wxLaunchDefaultBrowser( info.GetHref() );
}

View File

@ -65,14 +65,14 @@ protected:
/** /**
* Post a wxEVT_DATAVIEW_SELECTION_CHANGED to notify the selection handler * Post a wxEVT_DATAVIEW_SELECTION_CHANGED to notify the selection handler
* that a new part has been selected. * that a new part has been preselected.
*/ */
void postSelectEvent(); void postPreselectEvent();
/** /**
* If a library or part is selected, the corresponding subtree is expanded/collapsed. * Post COMPONENT_SELECTED event to notify the selection handler that a part has been selected.
*/ */
void handleSubtree(); void postSelectEvent();
// Event handlers // Event handlers
void onInitDialog( wxInitDialogEvent& aEvent ); void onInitDialog( wxInitDialogEvent& aEvent );
@ -85,6 +85,7 @@ protected:
void onTreeActivate( wxDataViewEvent& aEvent ); void onTreeActivate( wxDataViewEvent& aEvent );
void onDetailsLink( wxHtmlLinkEvent& aEvent ); void onDetailsLink( wxHtmlLinkEvent& aEvent );
void onPreselect( wxCommandEvent& aEvent );
CMP_TREE_MODEL_ADAPTER::PTR m_adapter; CMP_TREE_MODEL_ADAPTER::PTR m_adapter;
@ -93,4 +94,10 @@ protected:
wxHtmlWindow* m_details_ctrl; wxHtmlWindow* m_details_ctrl;
}; };
///> Custom event sent when a new component is preselected
wxDECLARE_EVENT( COMPONENT_PRESELECTED, wxCommandEvent );
///> Custom event sent when a component is selected
wxDECLARE_EVENT( COMPONENT_SELECTED, wxCommandEvent );
#endif /* COMPONENT_TREE_H */ #endif /* COMPONENT_TREE_H */