Apply Eeschema cursor updating architecture to PCBNew.

Fixes https://gitlab.com/kicad/code/kicad/issues/8135
This commit is contained in:
Jeff Young 2021-04-12 11:10:22 +01:00
parent 2cba64b258
commit a4c08e2af6
4 changed files with 72 additions and 38 deletions

View File

@ -88,18 +88,18 @@ SCH_BASE_FRAME::SCH_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aWindo
createCanvas(); createCanvas();
Bind( wxEVT_IDLE, Bind( wxEVT_IDLE,
[this]( wxIdleEvent& aEvent ) [this]( wxIdleEvent& aEvent )
{ {
// Handle cursor adjustments. While we can get motion and key events through // Handle cursor adjustments. While we can get motion and key events through
// wxWidgets, we can't get modifier-key-up events. // wxWidgets, we can't get modifier-key-up events.
if( m_toolManager ) if( m_toolManager )
{ {
EE_SELECTION_TOOL* selTool = m_toolManager->GetTool<EE_SELECTION_TOOL>(); EE_SELECTION_TOOL* selTool = m_toolManager->GetTool<EE_SELECTION_TOOL>();
if( selTool ) if( selTool )
selTool->OnIdle( aEvent ); selTool->OnIdle( aEvent );
} }
} ); } );
} }

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2014 CERN * Copyright (C) 2014 CERN
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -26,18 +26,19 @@
#include <kiface_i.h> #include <kiface_i.h>
#include <pcb_base_edit_frame.h> #include <pcb_base_edit_frame.h>
#include <tool/tool_manager.h> #include <tool/tool_manager.h>
#include <tools/pcb_actions.h>
#include <tools/pcb_selection_tool.h>
#include <pcbnew_settings.h> #include <pcbnew_settings.h>
#include <pgm_base.h> #include <pgm_base.h>
#include <board.h> #include <board.h>
#include "footprint_info_impl.h" #include <dimension.h>
#include <footprint_info_impl.h>
#include <project.h> #include <project.h>
#include <settings/color_settings.h> #include <settings/color_settings.h>
#include <settings/settings_manager.h> #include <settings/settings_manager.h>
#include <tools/pcb_actions.h>
#include <dialogs/dialog_grid_settings.h>
#include <widgets/appearance_controls.h> #include <widgets/appearance_controls.h>
#include <dialogs/dialog_grid_settings.h>
#include <dialogs/eda_view_switcher.h> #include <dialogs/eda_view_switcher.h>
#include <dimension.h>
#include <wildcards_and_files_ext.h> #include <wildcards_and_files_ext.h>
@ -50,6 +51,19 @@ PCB_BASE_EDIT_FRAME::PCB_BASE_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent,
m_selectionFilterPanel( nullptr ), m_selectionFilterPanel( nullptr ),
m_appearancePanel( nullptr ) m_appearancePanel( nullptr )
{ {
Bind( wxEVT_IDLE,
[this]( wxIdleEvent& aEvent )
{
// Handle cursor adjustments. While we can get motion and key events through
// wxWidgets, we can't get modifier-key-up events.
if( m_toolManager )
{
PCB_SELECTION_TOOL* selTool = m_toolManager->GetTool<PCB_SELECTION_TOOL>();
if( selTool )
selTool->OnIdle( aEvent );
}
} );
} }

View File

@ -104,6 +104,7 @@ PCB_SELECTION_TOOL::PCB_SELECTION_TOOL() :
m_multiple( false ), m_multiple( false ),
m_skip_heuristics( false ), m_skip_heuristics( false ),
m_highlight_modifier( false ), m_highlight_modifier( false ),
m_nonModifiedCursor( KICURSOR::ARROW ),
m_enteredGroup( nullptr ), m_enteredGroup( nullptr ),
m_priv( std::make_unique<PRIV>() ) m_priv( std::make_unique<PRIV>() )
{ {
@ -259,6 +260,27 @@ void PCB_SELECTION_TOOL::setModifiersState( bool aShiftState, bool aCtrlState, b
} }
void PCB_SELECTION_TOOL::OnIdle( wxIdleEvent& aEvent )
{
if( m_frame->ToolStackIsEmpty() && !m_multiple )
{
wxMouseState keyboardState = wxGetMouseState();
setModifiersState( keyboardState.ShiftDown(), keyboardState.ControlDown(),
keyboardState.AltDown() );
if( m_additive )
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ADD );
else if( m_subtractive )
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::SUBTRACT );
else if( m_exclusive_or )
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::XOR );
else
m_frame->GetCanvas()->SetCurrentCursor( m_nonModifiedCursor );
}
}
int PCB_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) int PCB_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
{ {
// Main loop: keep receiving events // Main loop: keep receiving events
@ -430,25 +452,18 @@ int PCB_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
if( m_frame->ToolStackIsEmpty() ) if( m_frame->ToolStackIsEmpty() )
{ {
//move cursor prediction // move cursor prediction
if( !modifier_enabled if( !modifier_enabled
&& dragAction == MOUSE_DRAG_ACTION::DRAG_SELECTED && dragAction == MOUSE_DRAG_ACTION::DRAG_SELECTED
&& !m_selection.Empty() && !m_selection.Empty()
&& evt->HasPosition() && evt->HasPosition()
&& selectionContains( evt->Position() ) ) && selectionContains( evt->Position() ) )
{ {
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::MOVING ); m_nonModifiedCursor = KICURSOR::MOVING;
} }
else else
{ {
if( m_additive ) m_nonModifiedCursor = KICURSOR::ARROW;
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ADD );
else if( m_subtractive )
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::SUBTRACT );
else if( m_exclusive_or )
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::XOR );
else
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
} }
} }
} }

View File

@ -72,6 +72,8 @@ public:
/// @copydoc TOOL_BASE::Reset() /// @copydoc TOOL_BASE::Reset()
void Reset( RESET_REASON aReason ) override; void Reset( RESET_REASON aReason ) override;
void OnIdle( wxIdleEvent& aEvent );
/** /**
* The main loop. * The main loop.
*/ */
@ -360,26 +362,29 @@ private:
void unhighlightInternal( BOARD_ITEM* aItem, int aHighlightMode, bool aUsingOverlay ); void unhighlightInternal( BOARD_ITEM* aItem, int aHighlightMode, bool aUsingOverlay );
PCB_BASE_FRAME* m_frame; // Pointer to the parent frame private:
PCB_SELECTION m_selection; // Current state of selection PCB_BASE_FRAME* m_frame; // Pointer to the parent frame
PCB_SELECTION m_selection; // Current state of selection
SELECTION_FILTER_OPTIONS m_filter; SELECTION_FILTER_OPTIONS m_filter;
bool m_additive; // Items should be added to selection (instead of replacing) bool m_additive; // Add to selection (instead of replacing)
bool m_subtractive; // Items should be removed from selection bool m_subtractive; // Remove from selection
bool m_exclusive_or; // Items' selection state should be toggled bool m_exclusive_or; // Items' selection state should be toggled
bool m_multiple; // Multiple selection mode is active bool m_multiple; // Multiple selection mode is active
bool m_skip_heuristics; // Heuristics are not allowed when choosing item under cursor bool m_skip_heuristics; // Heuristics are not allowed when choosing
bool m_highlight_modifier; // select highlight net on left click // item under cursor
bool m_highlight_modifier; // select highlight net on left click
PCB_GROUP* m_enteredGroup; // If non-null, selections are limited to KICURSOR m_nonModifiedCursor; // Cursor in the absence of shift/ctrl/alt
// members of this group
KIGFX::VIEW_GROUP m_enteredGroupOverlay; // Overlay for the entered group's frame.
PCB_GROUP* m_enteredGroup; // If non-null, selections are limited to
// members of this group
KIGFX::VIEW_GROUP m_enteredGroupOverlay; // Overlay for the entered group's frame.
/// Private state (opaque pointer/compilation firewall) /// Private state (opaque pointer/compilation firewall)
class PRIV; class PRIV;
std::unique_ptr<PRIV> m_priv; std::unique_ptr<PRIV> m_priv;
}; };
#endif /* PCB_SELECTION_TOOL_H */ #endif /* PCB_SELECTION_TOOL_H */