Fix event-loop issue with some pickers.

RunAction returns immediately even when called with "run now" flag.

Fixes: lp:1836905
* https://bugs.launchpad.net/kicad/+bug/1836905
This commit is contained in:
Jeff Young 2019-07-17 21:19:23 +01:00
parent 1402087562
commit 7c1049d86b
3 changed files with 37 additions and 16 deletions

View File

@ -1286,19 +1286,20 @@ int EDIT_TOOL::EditFpInFpEditor( const TOOL_EVENT& aEvent )
} }
bool EDIT_TOOL::pickCopyReferencePoint( VECTOR2I& aP ) bool EDIT_TOOL::pickCopyReferencePoint( VECTOR2I& aReferencePoint )
{ {
std::string tool = "pcbnew.InteractiveEdit.selectReferencePoint"; std::string tool = "pcbnew.InteractiveEdit.selectReferencePoint";
STATUS_TEXT_POPUP statusPopup( frame() ); STATUS_TEXT_POPUP statusPopup( frame() );
PCBNEW_PICKER_TOOL* picker = m_toolMgr->GetTool<PCBNEW_PICKER_TOOL>(); PCBNEW_PICKER_TOOL* picker = m_toolMgr->GetTool<PCBNEW_PICKER_TOOL>();
bool retVal = true; OPT<VECTOR2I> pickedPoint;
bool done = false;
statusPopup.SetText( _( "Select reference point for the copy..." ) ); statusPopup.SetText( _( "Select reference point for the copy..." ) );
picker->SetClickHandler( picker->SetClickHandler(
[&]( const VECTOR2D& aPoint ) -> bool [&]( const VECTOR2D& aPoint ) -> bool
{ {
aP = aPoint; pickedPoint = aPoint;
statusPopup.SetText( _( "Selection copied." ) ); statusPopup.SetText( _( "Selection copied." ) );
statusPopup.Expire( 800 ); statusPopup.Expire( 800 );
return false; // we don't need any more points return false; // we don't need any more points
@ -1307,7 +1308,7 @@ bool EDIT_TOOL::pickCopyReferencePoint( VECTOR2I& aP )
picker->SetMotionHandler( picker->SetMotionHandler(
[&] ( const VECTOR2D& aPos ) [&] ( const VECTOR2D& aPos )
{ {
statusPopup.Move( aPos + wxPoint( 20, -50 ) ); statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
} ); } );
picker->SetCancelHandler( picker->SetCancelHandler(
@ -1315,7 +1316,12 @@ bool EDIT_TOOL::pickCopyReferencePoint( VECTOR2I& aP )
{ {
statusPopup.SetText( _( "Copy cancelled." ) ); statusPopup.SetText( _( "Copy cancelled." ) );
statusPopup.Expire( 800 ); statusPopup.Expire( 800 );
retVal = false; } );
picker->SetFinalizeHandler(
[&]( const int& aFinalState )
{
done = true;
} ); } );
statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) ); statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
@ -1323,8 +1329,13 @@ bool EDIT_TOOL::pickCopyReferencePoint( VECTOR2I& aP )
m_toolMgr->RunAction( ACTIONS::pickerTool, true, &tool ); m_toolMgr->RunAction( ACTIONS::pickerTool, true, &tool );
statusPopup.Hide(); while( !done )
return retVal; Wait();
if( pickedPoint.is_initialized() )
aReferencePoint = pickedPoint.get();
return pickedPoint.is_initialized();
} }

View File

@ -35,6 +35,7 @@
class BOARD_COMMIT; class BOARD_COMMIT;
class BOARD_ITEM; class BOARD_ITEM;
class CONNECTIVITY_DATA; class CONNECTIVITY_DATA;
class STATUS_TEXT_POPUP;
namespace KIGFX { namespace KIGFX {
namespace PREVIEW { namespace PREVIEW {
@ -168,12 +169,6 @@ public:
BOARD_COMMIT* GetCurrentCommit() const { return m_commit.get(); } BOARD_COMMIT* GetCurrentCommit() const { return m_commit.get(); }
private: private:
SELECTION_TOOL* m_selectionTool; // Selection tool used for obtaining selected items
bool m_dragging; // Indicates objects are being dragged right now
bool m_lockedSelected; // Determines if we prompt before removing locked objects
VECTOR2I m_cursor; // Last cursor position (needed for getModificationPoint()
// to avoid changes of edit reference point).
///> Returns the right modification point (e.g. for rotation), depending on the number of ///> Returns the right modification point (e.g. for rotation), depending on the number of
///> selected items. ///> selected items.
bool updateModificationPoint( PCBNEW_SELECTION& aSelection ); bool updateModificationPoint( PCBNEW_SELECTION& aSelection );
@ -184,8 +179,14 @@ private:
bool isInteractiveDragEnabled() const; bool isInteractiveDragEnabled() const;
bool changeTrackWidthOnClick( const PCBNEW_SELECTION& selection ); bool changeTrackWidthOnClick( const PCBNEW_SELECTION& selection );
bool pickCopyReferencePoint( VECTOR2I& aP ); bool pickCopyReferencePoint( VECTOR2I& aReferencePoint );
private:
SELECTION_TOOL* m_selectionTool; // Selection tool used for obtaining selected items
bool m_dragging; // Indicates objects are being dragged right now
bool m_lockedSelected; // Determines if we prompt before removing locked objects
VECTOR2I m_cursor; // Last cursor position (needed for getModificationPoint()
// to avoid changes of edit reference point).
std::unique_ptr<BOARD_COMMIT> m_commit; std::unique_ptr<BOARD_COMMIT> m_commit;
}; };

View File

@ -125,6 +125,7 @@ int POSITION_RELATIVE_TOOL::SelectPositionRelativeItem( const TOOL_EVENT& aEvent
std::string tool = "pcbnew.PositionRelative.selectReferenceItem"; std::string tool = "pcbnew.PositionRelative.selectReferenceItem";
PCBNEW_PICKER_TOOL* picker = m_toolMgr->GetTool<PCBNEW_PICKER_TOOL>(); PCBNEW_PICKER_TOOL* picker = m_toolMgr->GetTool<PCBNEW_PICKER_TOOL>();
STATUS_TEXT_POPUP statusPopup( frame() ); STATUS_TEXT_POPUP statusPopup( frame() );
bool done = false;
statusPopup.SetText( _( "Select reference item..." ) ); statusPopup.SetText( _( "Select reference item..." ) );
@ -153,7 +154,7 @@ int POSITION_RELATIVE_TOOL::SelectPositionRelativeItem( const TOOL_EVENT& aEvent
picker->SetMotionHandler( picker->SetMotionHandler(
[&] ( const VECTOR2D& aPos ) [&] ( const VECTOR2D& aPos )
{ {
statusPopup.Move( aPos + wxPoint( 20, -50 ) ); statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
} ); } );
picker->SetCancelHandler( picker->SetCancelHandler(
@ -165,12 +166,20 @@ int POSITION_RELATIVE_TOOL::SelectPositionRelativeItem( const TOOL_EVENT& aEvent
m_dialog->UpdateAnchor( m_anchor_item ); m_dialog->UpdateAnchor( m_anchor_item );
} ); } );
picker->SetFinalizeHandler(
[&]( const int& aFinalState )
{
done = true;
} );
statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) ); statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
statusPopup.Popup(); statusPopup.Popup();
m_toolMgr->RunAction( ACTIONS::pickerTool, true, &tool ); m_toolMgr->RunAction( ACTIONS::pickerTool, true, &tool );
statusPopup.Hide(); while( !done )
Wait();
return 0; return 0;
} }