diff --git a/common/legacy_gal/eda_draw_frame.cpp b/common/legacy_gal/eda_draw_frame.cpp index 3c65c15788..dd0add61b3 100644 --- a/common/legacy_gal/eda_draw_frame.cpp +++ b/common/legacy_gal/eda_draw_frame.cpp @@ -544,11 +544,6 @@ void EDA_DRAW_FRAME::OnMouseEvent( wxMouseEvent& event ) } -void EDA_DRAW_FRAME::OnLeftDClick( wxDC* DC, const wxPoint& MousePos ) -{ -} - - void EDA_DRAW_FRAME::DisplayToolMsg( const wxString& msg ) { SetStatusText( msg, 5 ); @@ -1192,18 +1187,6 @@ bool EDA_DRAW_FRAME::GeneralControlKeyMovement( int aHotKey, wxPoint *aPos, bool } -bool EDA_DRAW_FRAME::isBusy() const -{ - const BASE_SCREEN* screen = GetScreen(); - - if( !screen ) - return false; - - return ( screen->GetCurItem() && screen->GetCurItem()->GetEditFlags() ) - || ( screen->m_BlockLocate.GetState() != STATE_NO_BLOCK ); -} - - const BOX2I EDA_DRAW_FRAME::GetDocumentExtents() const { return BOX2I(); diff --git a/common/legacy_wx/eda_draw_frame.cpp b/common/legacy_wx/eda_draw_frame.cpp index d58bbb66ed..97bbbf94dd 100644 --- a/common/legacy_wx/eda_draw_frame.cpp +++ b/common/legacy_wx/eda_draw_frame.cpp @@ -586,11 +586,6 @@ void EDA_DRAW_FRAME::OnMouseEvent( wxMouseEvent& event ) } -void EDA_DRAW_FRAME::OnLeftDClick( wxDC* DC, const wxPoint& MousePos ) -{ -} - - void EDA_DRAW_FRAME::DisplayToolMsg( const wxString& msg ) { SetStatusText( msg, 5 ); diff --git a/eeschema/controle.cpp b/eeschema/controle.cpp index 8749a161f3..6867cdef3b 100644 --- a/eeschema/controle.cpp +++ b/eeschema/controle.cpp @@ -33,71 +33,6 @@ #include -bool SCH_EDIT_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KEY aHotKey ) -{ - // Filter out the 'fake' mouse motion after a keyboard movement - if( !aHotKey && m_movingCursorWithKeyboard ) - { - m_movingCursorWithKeyboard = false; - return false; - } - - // when moving mouse, use the "magnetic" grid, unless the shift+ctrl keys is pressed - // for next cursor position - // ( shift or ctrl key down are PAN command with mouse wheel) - bool snapToGrid = true; - - if( !aHotKey && wxGetKeyState( WXK_SHIFT ) && wxGetKeyState( WXK_CONTROL ) ) - snapToGrid = false; - - // Cursor is left off grid only if no block in progress - if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK ) - snapToGrid = true; - - wxPoint pos = aPosition; - bool keyHandled = GeneralControlKeyMovement( aHotKey, &pos, snapToGrid ); - - if( GetToolId() == ID_NO_TOOL_SELECTED ) - m_canvas->CrossHairOff( aDC ); - else - m_canvas->CrossHairOn( aDC ); - - GetGalCanvas()->GetViewControls()->SetSnapping( snapToGrid ); - SetCrossHairPosition( pos, snapToGrid ); - - if( m_canvas->IsMouseCaptured() ) - m_canvas->CallMouseCapture( aDC, aPosition, true ); - - if( aHotKey ) - { - if( m_movingCursorWithKeyboard ) // The hotkey was a move crossahir cursor command - { - // The crossair was moved. move the mouse cursor to the new crosshair position: - GetGalCanvas()->GetViewControls()->WarpCursor( GetCrossHairPosition(), true ); - m_movingCursorWithKeyboard = 0; - } - else - { - SCH_SCREEN* screen = GetScreen(); - bool hk_handled; - - if( screen->GetCurItem() && screen->GetCurItem()->GetEditFlags() ) - hk_handled = OnHotKey( aDC, aHotKey, aPosition, screen->GetCurItem() ); - else - hk_handled = OnHotKey( aDC, aHotKey, aPosition, NULL ); - - if( hk_handled ) - keyHandled = true; - } - } - - UpdateStatusBar(); /* Display cursor coordinates info */ - - return keyHandled; -} - - - bool LIB_VIEW_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KEY aHotKey ) { bool eventHandled = true; diff --git a/eeschema/edit_bitmap.cpp b/eeschema/edit_bitmap.cpp index 667f3f4f28..6db54bb595 100644 --- a/eeschema/edit_bitmap.cpp +++ b/eeschema/edit_bitmap.cpp @@ -72,18 +72,6 @@ SCH_BITMAP* SCH_EDIT_FRAME::CreateNewImage() } -void SCH_EDIT_FRAME::RotateImage( SCH_BITMAP* aItem ) -{ - if( aItem->GetEditFlags( ) == 0 ) - SaveCopyInUndoList( aItem, UR_ROTATED, false, aItem->GetPosition() ); - - aItem->Rotate( aItem->GetPosition() ); - - RefreshItem( aItem ); - OnModify(); -} - - void SCH_EDIT_FRAME::MirrorImage( SCH_BITMAP* aItem, bool Is_X_axis ) { if( aItem->GetEditFlags( ) == 0 ) diff --git a/eeschema/edit_component_in_schematic.cpp b/eeschema/edit_component_in_schematic.cpp index 4c8efc45a0..6db5638060 100644 --- a/eeschema/edit_component_in_schematic.cpp +++ b/eeschema/edit_component_in_schematic.cpp @@ -92,27 +92,6 @@ void SCH_EDIT_FRAME::EditComponentFieldText( SCH_FIELD* aField ) } -void SCH_EDIT_FRAME::RotateField( SCH_FIELD* aField ) -{ - wxCHECK_RET( aField != NULL && aField->Type() == SCH_FIELD_T && !aField->GetText().IsEmpty(), - wxT( "Cannot rotate invalid schematic field." ) ); - - SCH_COMPONENT* component = (SCH_COMPONENT*) aField->GetParent(); - - // Save old component in undo list if not already in edit, or moving. - if( aField->GetEditFlags() == 0 ) - SaveCopyInUndoList( component, UR_CHANGED ); - - if( aField->GetTextAngle() == TEXT_ANGLE_HORIZ ) - aField->SetTextAngle( TEXT_ANGLE_VERT ); - else - aField->SetTextAngle( TEXT_ANGLE_HORIZ ); - - RefreshItem( aField ); - OnModify(); -} - - void SCH_EDIT_FRAME::EditComponent( SCH_COMPONENT* aComponent ) { wxCHECK_RET( aComponent != nullptr && aComponent->Type() == SCH_COMPONENT_T, diff --git a/eeschema/edit_label.cpp b/eeschema/edit_label.cpp index fba791789f..8500de75b2 100644 --- a/eeschema/edit_label.cpp +++ b/eeschema/edit_label.cpp @@ -47,24 +47,6 @@ static bool lastTextBold = false; static bool lastTextItalic = false; -void SCH_EDIT_FRAME::ChangeTextOrient( SCH_TEXT* aTextItem ) -{ - wxCHECK_RET( (aTextItem != NULL) && aTextItem->CanIncrementLabel(), - wxT( "Invalid schematic text item." ) ); - - int orient = ( aTextItem->GetLabelSpinStyle() + 1 ) & 3; - - // Save current text orientation in undo list if is not already in edit. - if( aTextItem->GetEditFlags() == 0 ) - SaveCopyInUndoList( aTextItem, UR_CHANGED ); - - aTextItem->SetLabelSpinStyle( orient ); - - RefreshItem( aTextItem ); - OnModify(); -} - - SCH_TEXT* SCH_EDIT_FRAME::CreateNewText( int aType ) { SCH_TEXT* textItem = NULL; diff --git a/eeschema/getpart.cpp b/eeschema/getpart.cpp index 422a04f8a4..03027b65fb 100644 --- a/eeschema/getpart.cpp +++ b/eeschema/getpart.cpp @@ -208,6 +208,7 @@ SCH_BASE_FRAME::COMPONENT_SELECTION SCH_BASE_FRAME::SelectComponentFromLibTree( } +// JEY TODO: obsolete once mover to modern toolset is complete void SCH_EDIT_FRAME::OrientComponent( COMPONENT_ORIENTATION_T aOrientation ) { SCH_SCREEN* screen = GetScreen(); diff --git a/eeschema/hotkeys.cpp b/eeschema/hotkeys.cpp index a86255aa5d..b9bc8a0afe 100644 --- a/eeschema/hotkeys.cpp +++ b/eeschema/hotkeys.cpp @@ -478,23 +478,6 @@ bool SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, } break; - case HK_LEFT_CLICK: - case HK_LEFT_DCLICK: // Simulate a double left click: generate 2 events - if( screen->m_BlockLocate.GetState() == STATE_BLOCK_MOVE ) - { - GetCanvas()->SetAutoPanRequest( false ); - HandleBlockPlace( aDC ); - } - else if( screen->m_BlockLocate.GetState() == STATE_NO_BLOCK ) - { - auto pos = GetCrossHairPosition(); - OnLeftClick( aDC, pos ); - - if( hotKey->m_Idcommand == HK_LEFT_DCLICK ) - OnLeftDClick( aDC, pos ); - } - break; - case HK_ZOOM_IN: case HK_ZOOM_OUT: case HK_ZOOM_REDRAW: diff --git a/eeschema/list_operations.h b/eeschema/list_operations.h index a62effb7be..d65fd8e2fa 100644 --- a/eeschema/list_operations.h +++ b/eeschema/list_operations.h @@ -32,7 +32,6 @@ class SCH_SCREEN; class PICKED_ITEMS_LIST; void SetSchItemParent( SCH_ITEM* Struct, SCH_SCREEN* Screen ); -void RotateListOfItems( PICKED_ITEMS_LIST& aItemsList, const wxPoint& rotationPoint ); void MirrorY( PICKED_ITEMS_LIST& aItemsList, const wxPoint& aMirrorPoint ); void MirrorX( PICKED_ITEMS_LIST& aItemsList, const wxPoint& aMirrorPoint ); diff --git a/eeschema/onleftclick.cpp b/eeschema/onleftclick.cpp index 980711b23f..677234260c 100644 --- a/eeschema/onleftclick.cpp +++ b/eeschema/onleftclick.cpp @@ -35,57 +35,6 @@ #include #include -void SCH_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) -{ - SCH_ITEM* item = GetScreen()->GetCurItem(); - SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool(); - - if( GetToolId() == ID_NO_TOOL_SELECTED ) - { - m_canvas->SetAutoPanRequest( false ); - SetRepeatItem( NULL ); - - // item_flags != 0 means a current item in edit - if( item && item->GetEditFlags() ) - { - switch( item->Type() ) - { - case SCH_LABEL_T: - case SCH_GLOBAL_LABEL_T: - case SCH_HIER_LABEL_T: - case SCH_TEXT_T: - case SCH_SHEET_PIN_T: - case SCH_SHEET_T: - case SCH_BUS_WIRE_ENTRY_T: - case SCH_BUS_BUS_ENTRY_T: - case SCH_JUNCTION_T: - case SCH_COMPONENT_T: - case SCH_FIELD_T: - case SCH_BITMAP_T: - case SCH_NO_CONNECT_T: - AddItemToScreen( item ); - GetCanvas()->GetView()->ClearPreview(); - GetCanvas()->GetView()->ClearHiddenFlags(); - return; - - default: - wxFAIL_MSG( wxT( "SCH_EDIT_FRAME::OnLeftClick error. Item type <" ) + - item->GetClass() + wxT( "> is already being edited." ) ); - item->ClearFlags(); - break; - } - } - else - { - item = selTool->SelectPoint( aPosition ); - } - } - - if( !item ) // If clicked on a empty area, clear any highligthed symbol - GetCanvas()->GetView()->HighlightItem( nullptr, nullptr ); -} - - /** * Function OnLeftDClick * called on a double click event from the drawpanel mouse handler @@ -95,7 +44,7 @@ void SCH_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) * validate and finish the command */ void SCH_EDIT_FRAME::OnLeftDClick( wxDC* aDC, const wxPoint& aPosition ) - +// JEY TODO: move to selection tool double-click handling.... { SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool(); EDA_ITEM* item = GetScreen()->GetCurItem(); diff --git a/eeschema/operations_on_items_lists.cpp b/eeschema/operations_on_items_lists.cpp index a51ddc8aa2..382f5863fc 100644 --- a/eeschema/operations_on_items_lists.cpp +++ b/eeschema/operations_on_items_lists.cpp @@ -72,17 +72,6 @@ void SetSchItemParent( SCH_ITEM* Struct, SCH_SCREEN* Screen ) } -void RotateListOfItems( PICKED_ITEMS_LIST& aItemsList, const wxPoint& rotationPoint ) -{ - for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ ) - { - SCH_ITEM* item = static_cast( aItemsList.GetPickedItem( ii ) ); - item->Rotate( rotationPoint ); // Place it in its new position. - item->ClearFlags(); - } -} - - void MirrorY( PICKED_ITEMS_LIST& aItemsList, const wxPoint& aMirrorPoint ) { for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ ) @@ -302,5 +291,23 @@ SCH_ITEM* DuplicateStruct( SCH_ITEM* aDrawStruct, bool aClone ) if( aClone ) NewDrawStruct->SetTimeStamp( aDrawStruct->GetTimeStamp() ); + NewDrawStruct->ClearFlags( SELECTED | HIGHLIGHTED | BRIGHTENED ); + + if( NewDrawStruct->Type() == SCH_COMPONENT_T ) + { + SCH_PINS& pins = static_cast( NewDrawStruct )->GetPins(); + + for( SCH_PIN& pin : pins ) + pin.ClearFlags( SELECTED | HIGHLIGHTED | BRIGHTENED ); + + std::vector fields; + static_cast( NewDrawStruct )->GetFields( fields, false ); + + for( SCH_FIELD* field : fields ) + field->ClearFlags( SELECTED | HIGHLIGHTED | BRIGHTENED ); + } + + // JEY TODO: sheets and sheet pins? + return NewDrawStruct; } diff --git a/eeschema/sch_base_frame.cpp b/eeschema/sch_base_frame.cpp index 958bacc142..47516dba78 100644 --- a/eeschema/sch_base_frame.cpp +++ b/eeschema/sch_base_frame.cpp @@ -121,8 +121,7 @@ void SCH_BASE_FRAME::setupTools() m_toolManager->InitTools(); // Run the selection tool, it is supposed to be always active - // JEY TODO: enable when we move event loop over to modern toolset... - //m_toolManager->InvokeTool( "eeschema.InteractiveSelection" ); + m_toolManager->InvokeTool( "eeschema.InteractiveSelection" ); GetCanvas()->SetEventDispatcher( m_toolDispatcher ); } diff --git a/eeschema/sch_draw_panel.cpp b/eeschema/sch_draw_panel.cpp index d4d1273a07..cec6057a4c 100644 --- a/eeschema/sch_draw_panel.cpp +++ b/eeschema/sch_draw_panel.cpp @@ -82,17 +82,6 @@ SCH_DRAW_PANEL::SCH_DRAW_PANEL( wxWindow* aParentWindow, wxWindowID aWindowId, // on updated viewport data. m_viewControls = new KIGFX::WX_VIEW_CONTROLS( m_view, this ); - const wxEventType events[] = - { - wxEVT_LEFT_UP, wxEVT_LEFT_DOWN, wxEVT_LEFT_DCLICK, - wxEVT_RIGHT_UP, wxEVT_RIGHT_DOWN, wxEVT_RIGHT_DCLICK, - wxEVT_MIDDLE_UP, wxEVT_MIDDLE_DOWN, wxEVT_MIDDLE_DCLICK, - wxEVT_MOTION, wxEVT_MOUSEWHEEL, - }; - - for( auto e : events ) - Connect( e, wxMouseEventHandler( SCH_DRAW_PANEL::OnMouseEvent ), NULL, this ); - Connect( wxEVT_CHAR, wxKeyEventHandler( SCH_DRAW_PANEL::OnKeyEvent ), NULL, this ); Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( SCH_DRAW_PANEL::OnCharHook ), NULL, this ); @@ -100,7 +89,6 @@ SCH_DRAW_PANEL::SCH_DRAW_PANEL( wxWindow* aParentWindow, wxWindowID aWindowId, Pgm().CommonSettings()->Read( ENBL_ZOOM_NO_CENTER_KEY, &m_enableZoomNoCenter, false ); Pgm().CommonSettings()->Read( ENBL_AUTO_PAN_KEY, &m_enableAutoPan, true ); - m_canStartBlock = -1; // Command block can start if >= 0 m_abortRequest = false; m_ignoreMouseEvents = false; // Be sure a mouse release button event will be ignored when creating the canvas @@ -111,7 +99,6 @@ SCH_DRAW_PANEL::SCH_DRAW_PANEL( wxWindow* aParentWindow, wxWindowID aWindowId, m_mouseCaptureCallback = NULL; m_endMouseCaptureCallback = NULL; - m_enableBlockCommands = false; m_minDragEventCount = 0; m_cursorLevel = 0; @@ -256,260 +243,6 @@ EDA_DRAW_FRAME* SCH_DRAW_PANEL::GetParent() const } -void SCH_DRAW_PANEL::OnMouseEvent( wxMouseEvent& event ) -{ - int localbutt = 0; - BASE_SCREEN* screen = GetScreen(); - auto controls = GetViewControls(); - auto vmp = VECTOR2I( controls->GetMousePosition() ); - wxPoint mousePos ( vmp.x, vmp.y ); - - event.Skip(); - - if( !screen ) - return; - - /* Adjust value to filter mouse displacement before consider the drag - * mouse is really a drag command, not just a movement while click - */ -#define MIN_DRAG_COUNT_FOR_START_BLOCK_COMMAND 5 - - if( event.Leaving() ) - m_canStartBlock = -1; - - if( !IsMouseCaptured() && !controls->GetSettings().m_cursorCaptured ) - SetAutoPanRequest( false ); - - if( GetParent()->IsActive() ) - SetFocus(); - else - return; - - if( !event.IsButton() && !event.Moving() && !event.Dragging() ) - return; - - if( event.RightUp() ) - { - OnRightClick( event ); - return; - } - - if( m_ignoreMouseEvents ) - return; - - if( event.LeftDown() ) - localbutt = GR_M_LEFT_DOWN; - - if( event.ButtonDClick( 1 ) ) - localbutt = GR_M_LEFT_DOWN | GR_M_DCLICK; - - if( event.MiddleDown() ) - localbutt = GR_M_MIDDLE_DOWN; - - // Compute the cursor position in drawing (logical) units. - //GetParent()->SetMousePosition( event.GetLogicalPosition( DC ) ); - - int kbstat = 0; - - if( event.ShiftDown() ) - kbstat |= GR_KB_SHIFT; - - if( event.ControlDown() ) - kbstat |= GR_KB_CTRL; - - if( event.AltDown() ) - kbstat |= GR_KB_ALT; - - // Calling Double Click and Click functions : - if( localbutt == (int) ( GR_M_LEFT_DOWN | GR_M_DCLICK ) ) - { - GetParent()->OnLeftDClick( nullptr, mousePos ); - - // inhibit a response to the mouse left button release, - // because we have a double click, and we do not want a new - // OnLeftClick command at end of this Double Click - m_ignoreNextLeftButtonRelease = true; - } - else if( event.LeftUp() ) - { - // A block command is in progress: a left up is the end of block - // or this is the end of a double click, already seen - // Note also m_ignoreNextLeftButtonRelease can be set by - // the call to OnLeftClick(), so do not change it after calling OnLeftClick - bool ignoreEvt = m_ignoreNextLeftButtonRelease; - m_ignoreNextLeftButtonRelease = false; - - if( screen->m_BlockLocate.GetState() == STATE_NO_BLOCK && !ignoreEvt ) - GetParent()->OnLeftClick( nullptr, mousePos ); - - } - else if( !event.LeftIsDown() ) - { - /* be sure there is a response to a left button release command - * even when a LeftUp event is not seen. This happens when a - * double click opens a dialog box, and the release mouse button - * is made when the dialog box is opened. - */ - m_ignoreNextLeftButtonRelease = false; - } - - if( event.ButtonDown( wxMOUSE_BTN_MIDDLE ) ) - { - m_PanStartCenter = GetParent()->GetScrollCenterPosition(); - m_PanStartEventPosition = event.GetPosition(); - - CrossHairOff( ); - SetCurrentCursor( wxCURSOR_SIZING ); - } - - if( event.ButtonUp( wxMOUSE_BTN_MIDDLE ) ) - { - CrossHairOn(); - SetDefaultCursor(); - } - - if( event.MiddleIsDown() ) - { - // already managed by EDA_DRAW_PANEL_GAL mouse event handler. - return; - } - - // Calling the general function on mouse changes (and pseudo key commands) - GetParent()->GeneralControl( nullptr, mousePos ); - - /*******************************/ - /* Control of block commands : */ - /*******************************/ - - // Command block can't start if mouse is dragging a new panel - static SCH_DRAW_PANEL* lastPanel; - if( lastPanel != this ) - { - m_minDragEventCount = 0; - m_canStartBlock = -1; - } - - /* A new command block can start after a release buttons - * and if the drag is enough - * This is to avoid a false start block when a dialog box is dismissed, - * or when changing panels in hierarchy navigation - * or when clicking while and moving mouse - */ - if( !event.LeftIsDown() && !event.MiddleIsDown() ) - { - m_minDragEventCount = 0; - m_canStartBlock = 0; - - /* Remember the last cursor position when a drag mouse starts - * this is the last position ** before ** clicking a button - * this is useful to start a block command from the point where the - * mouse was clicked first - * (a filter creates a delay for the real block command start, and - * we must remember this point) - */ - m_CursorStartPos = GetParent()->GetCrossHairPosition(); - } - - if( m_enableBlockCommands && !(localbutt & GR_M_DCLICK) ) - { - if( !screen->IsBlockActive() ) - { - screen->m_BlockLocate.SetOrigin( m_CursorStartPos ); - } - - if( event.LeftDown() ) - { - if( screen->m_BlockLocate.GetState() == STATE_BLOCK_MOVE ) - { - SetAutoPanRequest( false ); - GetParent()->HandleBlockPlace( nullptr ); - m_ignoreNextLeftButtonRelease = true; - } - } - else if( ( m_canStartBlock >= 0 ) && event.LeftIsDown() && !IsMouseCaptured() ) - { - // Mouse is dragging: if no block in progress, start a block command. - if( screen->m_BlockLocate.GetState() == STATE_NO_BLOCK ) - { - // Start a block command - int cmd_type = kbstat; - - // A block command is started if the drag is enough. A small - // drag is ignored (it is certainly a little mouse move when - // clicking) not really a drag mouse - if( m_minDragEventCount < MIN_DRAG_COUNT_FOR_START_BLOCK_COMMAND ) - m_minDragEventCount++; - else - { - auto cmd = (GetParent()->GetToolId() == ID_ZOOM_SELECTION) ? BLOCK_ZOOM : 0; - - DBG(printf("start block\n");) - - if( !GetParent()->HandleBlockBegin( nullptr, cmd_type, m_CursorStartPos, cmd ) ) - { - // should not occur: error - GetParent()->DisplayToolMsg( - wxT( "EDA_DRAW_PANEL::OnMouseEvent() Block Error" ) ); - } - else - { - SetAutoPanRequest( true ); - SetCursor( wxCURSOR_SIZING ); - } - } - } - } - - if( event.ButtonUp( wxMOUSE_BTN_LEFT ) ) - { - /* Release the mouse button: end of block. - * The command can finish (DELETE) or have a next command (MOVE, - * COPY). However the block command is canceled if the block - * size is small because a block command filtering is already - * made, this case happens, but only when the on grid cursor has - * not moved. - */ - #define BLOCK_MINSIZE_LIMIT 1 - bool BlockIsSmall = - ( std::abs( screen->m_BlockLocate.GetWidth() ) < BLOCK_MINSIZE_LIMIT ) - && ( std::abs( screen->m_BlockLocate.GetHeight() ) < BLOCK_MINSIZE_LIMIT ); - - if( (screen->m_BlockLocate.GetState() != STATE_NO_BLOCK) && BlockIsSmall ) - { - if( m_endMouseCaptureCallback ) - { - m_endMouseCaptureCallback( this, nullptr ); - SetAutoPanRequest( false ); - } - - //SetCursor( (wxStockCursor) m_currentCursor ); - } - else if( screen->m_BlockLocate.GetState() == STATE_BLOCK_END ) - { - SetAutoPanRequest( false ); - GetParent()->HandleBlockEnd( nullptr ); - //SetCursor( (wxStockCursor) m_currentCursor ); - if( screen->m_BlockLocate.GetState() == STATE_BLOCK_MOVE ) - { - SetAutoPanRequest( true ); - SetCursor( wxCURSOR_HAND ); - } - } - } - } - - // End of block command on a double click - // To avoid an unwanted block move command if the mouse is moved while double clicking - if( localbutt == (int) ( GR_M_LEFT_DOWN | GR_M_DCLICK ) ) - { - if( !screen->IsBlockActive() && IsMouseCaptured() ) - m_endMouseCaptureCallback( this, nullptr ); - } - - lastPanel = this; -} - - bool SCH_DRAW_PANEL::OnRightClick( wxMouseEvent& event ) { auto controls = GetViewControls(); diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp index 87b3efa1b9..c2c5aa31bb 100644 --- a/eeschema/sch_edit_frame.cpp +++ b/eeschema/sch_edit_frame.cpp @@ -286,8 +286,6 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME ) EVT_MENU( ID_CANCEL_CURRENT_COMMAND, SCH_EDIT_FRAME::OnCancelCurrentCommand ) EVT_MENU( ID_SCH_DRAG_ITEM, SCH_EDIT_FRAME::OnDragItem ) - EVT_MENU_RANGE( ID_SCH_ROTATE_CLOCKWISE, ID_SCH_ROTATE_COUNTERCLOCKWISE, - SCH_EDIT_FRAME::OnRotate ) EVT_MENU_RANGE( ID_SCH_EDIT_ITEM, ID_SCH_EDIT_COMPONENT_FOOTPRINT, SCH_EDIT_FRAME::OnEditItem ) EVT_MENU_RANGE( ID_SCH_MIRROR_X, ID_SCH_ORIENT_NORMAL, SCH_EDIT_FRAME::OnOrient ) diff --git a/eeschema/sch_edit_frame.h b/eeschema/sch_edit_frame.h index f5a9c5ed0f..f1254966eb 100644 --- a/eeschema/sch_edit_frame.h +++ b/eeschema/sch_edit_frame.h @@ -265,8 +265,6 @@ public: */ wxMenu* GetUnfoldBusMenu( SCH_LINE* aBus ); - bool GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KEY aHotKey ) override; - /** * Return the project file parameter list for Eeschema. * @@ -375,7 +373,6 @@ public: void KiwayMailIn( KIWAY_EXPRESS& aEvent ) override; - void OnLeftClick( wxDC* aDC, const wxPoint& aPosition ) override; void OnLeftDClick( wxDC* aDC, const wxPoint& aPosition ) override; bool OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ) override; void OnSelectOptionToolbar( wxCommandEvent& event ); @@ -796,12 +793,6 @@ private: */ void OnMoveItem( wxCommandEvent& aEvent ); - /** - * Handle the #ID_SCH_ROTATE_CLOCKWISE and #ID_SCH_ROTATE_COUNTERCLOCKWISE events - * used to rotate schematic items and blocks. - */ - void OnRotate( wxCommandEvent& aEvent ); - /** * Handle the #ID_SCH_EDIT_ITEM event used to edit schematic items. */ @@ -937,7 +928,6 @@ private: // Text, label, glabel void EditSchematicText( SCH_TEXT* TextStruct ); - void ChangeTextOrient( SCH_TEXT* aTextItem ); /** * Command event handler to change a text type to another one. @@ -961,9 +951,6 @@ private: */ void DeleteConnection( bool DeleteFullConnection ); - // Images: - void RotateImage( SCH_BITMAP* aItem ); - /** * Mirror a bitmap. * @@ -983,17 +970,6 @@ private: // Hierarchical Sheet & PinSheet void InstallHierarchyFrame( wxPoint& pos ); - /** - * Rotate a sheet object. - * - * Sheets do not have a anchor point. Because rotating it from its origin or its end is - * not friendly, the rotation is made around its center. - * - * @param aSheet the hierarchical sheet to rotate - * @param aRotCCW = true to rotate CCW, false to rotate CW - */ - void RotateHierarchicalSheet( SCH_SHEET* aSheet, bool aRotCCW ); - /** * Mirror a hierarchical sheet. * @@ -1144,8 +1120,6 @@ private: */ void EditComponentFieldText( SCH_FIELD* aField ); - void RotateField( SCH_FIELD* aField ); - /** * Paste a list of items from the block stack. */ @@ -1247,8 +1221,6 @@ private: void addJunctionMenuEntries( wxMenu* aMenu, SCH_JUNCTION* aJunction ); public: - void Key( wxDC* DC, int hotkey, EDA_ITEM* DrawStruct ); - /** * Initialize the parameters used by the block paste command. */ @@ -1327,6 +1299,12 @@ public: */ void SaveUndoItemInUndoList( SCH_ITEM* aItem ); + /** + * Performs an undo of the last edit WITHOUT logging a corresponding redo. Used to cancel + * an in-progress operation. + */ + void RollbackSchematicFromUndo(); + /** * Create a symbol library file with the name of the root document plus the '-cache' suffix, * diff --git a/eeschema/sch_painter.cpp b/eeschema/sch_painter.cpp index cc3b828160..70f46985a5 100644 --- a/eeschema/sch_painter.cpp +++ b/eeschema/sch_painter.cpp @@ -235,11 +235,6 @@ COLOR4D SCH_PAINTER::getRenderColor( const EDA_ITEM* aItem, int aLayer, bool aOn { return color.Brightened( 0.5 ); } - // JEY TODO: IsMoving checks can go away after seleciton model is fully implemented... - else if( aItem->IsMoving() ) - { - return color.Brightened( 0.5 ); - } else if( aItem->IsHighlighted() ) { if ( aOnBackgroundLayer ) @@ -329,10 +324,6 @@ bool SCH_PAINTER::setColors( const LIB_ITEM* aItem, int aLayer ) { COLOR4D color = getRenderColor( aItem, LAYER_DEVICE, false ); - // These actions place the item over others, so allow a modest transparency here - if( aItem->IsMoving() || aItem->IsDragging() || aItem->IsResized() ) - color = color.WithAlpha( 0.75 ); - m_gal->SetStrokeColor( color ); m_gal->SetIsFill( aItem->GetFillMode() == FILLED_SHAPE ); m_gal->SetFillColor( color ); @@ -1102,7 +1093,10 @@ void SCH_PAINTER::draw( SCH_COMPONENT *aComp, int aLayer ) orientPart( &tempPart, aComp->GetOrientation()); for( auto& tempItem : tempPart.GetDrawItems() ) + { + tempItem.SetFlags( aComp->GetFlags() ); // SELECTED, HIGHLIGHTED, BRIGHTENED tempItem.Move( tempItem.GetPosition() + (wxPoint) mapCoords( aComp->GetPosition() ) ); + } // Copy the pin info from the component to the temp pins LIB_PINS tempPins; @@ -1287,7 +1281,7 @@ void SCH_PAINTER::draw( SCH_SHEET *aSheet, int aLayer ) } else if( aLayer == LAYER_SHEET ) { - m_gal->SetStrokeColor( m_schSettings.GetLayerColor( LAYER_SHEET ) ); + m_gal->SetStrokeColor( getRenderColor( aSheet, LAYER_SHEET, false ) ); m_gal->SetIsStroke( true ); m_gal->SetIsFill( false ); @@ -1302,7 +1296,7 @@ void SCH_PAINTER::draw( SCH_SHEET *aSheet, int aLayer ) if( aSheet->IsVerticalOrientation() ) nameAngle = -M_PI/2; - m_gal->SetStrokeColor( m_schSettings.GetLayerColor( LAYER_SHEETNAME ) ); + m_gal->SetStrokeColor( getRenderColor( aSheet, LAYER_SHEETNAME, false ) ); auto text = wxT( "Sheet: " ) + aSheet->GetName(); @@ -1319,7 +1313,7 @@ void SCH_PAINTER::draw( SCH_SHEET *aSheet, int aLayer ) txtSize = aSheet->GetFileNameSize(); m_gal->SetGlyphSize( VECTOR2D( txtSize, txtSize ) ); - m_gal->SetStrokeColor( m_schSettings.GetLayerColor( LAYER_SHEETFILENAME ) ); + m_gal->SetStrokeColor( getRenderColor( aSheet, LAYER_SHEETFILENAME, false ) ); m_gal->SetVerticalJustify( GR_TEXT_VJUSTIFY_TOP ); text = wxT( "File: " ) + aSheet->GetFileName(); diff --git a/eeschema/sch_pin.cpp b/eeschema/sch_pin.cpp index bb5e508362..d81c1b4a51 100644 --- a/eeschema/sch_pin.cpp +++ b/eeschema/sch_pin.cpp @@ -110,24 +110,19 @@ wxPoint SCH_PIN::GetTransformedPosition() const const EDA_RECT SCH_PIN::GetBoundingBox() const { - // Due to pins being relative to their component parent's position, this is unlikely - // to do what a caller wants. Use HitTest() directly instead. - wxFAIL_MSG( "SCH_PINs bounding box is relative to parent component" ); + TRANSFORM t = GetParentComponent()->GetTransform(); + EDA_RECT r = m_libPin->GetBoundingBox(); + + r = t.TransformCoordinate( r ); + r.Offset( GetParentComponent()->GetPosition() ); - return m_libPin->GetBoundingBox(); + return r; } bool SCH_PIN::HitTest( const wxPoint& aPosition ) const { - // Pin hit testing is relative to the components position and orientation in the - // schematic. The hit test position must be converted to library coordinates. - TRANSFORM t = GetParentComponent()->GetTransform().InverseTransform(); - wxPoint pos = t.TransformCoordinate( aPosition - GetParentComponent()->GetPosition() ); - - pos.y *= -1; // Y axis polarity in schematic is inverted from library. - - return m_libPin->GetBoundingBox().Contains( pos ); + return GetBoundingBox().Contains( aPosition ); } diff --git a/eeschema/schedit.cpp b/eeschema/schedit.cpp index 7589d6f1e2..4597c2633c 100644 --- a/eeschema/schedit.cpp +++ b/eeschema/schedit.cpp @@ -652,139 +652,6 @@ void SCH_EDIT_FRAME::SelectAllFromSheet( wxCommandEvent& aEvent ) } -void SCH_EDIT_FRAME::OnRotate( wxCommandEvent& aEvent ) -{ - SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool(); - SCH_SCREEN* screen = GetScreen(); - SCH_ITEM* item = screen->GetCurItem(); - BLOCK_SELECTOR& block = screen->m_BlockLocate; - - // Allows block rotate operation on hot key. - if( block.GetState() != STATE_NO_BLOCK ) - { - // Compute the rotation center and put it on grid: - wxPoint rotationPoint = GetNearestGridPosition( block.Centre() ); - - if( block.GetCommand() != BLOCK_DUPLICATE && block.GetCommand() != BLOCK_PASTE ) - { - SaveCopyInUndoList( block.GetItems(), UR_ROTATED, block.AppendUndo(), rotationPoint ); - block.SetAppendUndo(); - } - - RotateListOfItems( block.GetItems(), rotationPoint ); - - m_canvas->CallMouseCapture( nullptr, wxDefaultPosition, false ); - m_canvas->Refresh(); - return; - } - - if( item == NULL ) - { - // If we didn't get here by a hot key, then something has gone wrong. - if( aEvent.GetInt() == 0 ) - return; - - EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject(); - - wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) ); - - item = selTool->SelectPoint( data->GetPosition(), SCH_COLLECTOR::RotatableItems ); - - // Exit if no item found at the current location or the item is already being edited. - if( item == NULL || item->GetEditFlags() != 0 ) - return; - } - - switch( item->Type() ) - { - case SCH_COMPONENT_T: - { - SCH_COMPONENT* component = static_cast( item ); - - if( aEvent.GetId() == ID_SCH_ROTATE_CLOCKWISE ) - OrientComponent( CMP_ROTATE_CLOCKWISE ); - else if( aEvent.GetId() == ID_SCH_ROTATE_COUNTERCLOCKWISE ) - OrientComponent( CMP_ROTATE_COUNTERCLOCKWISE ); - else - wxFAIL_MSG( wxT( "Unknown rotate item command ID." ) ); - - if( m_autoplaceFields ) - component->AutoAutoplaceFields( GetScreen() ); - - break; - } - - case SCH_TEXT_T: - case SCH_LABEL_T: - case SCH_GLOBAL_LABEL_T: - case SCH_HIER_LABEL_T: - m_canvas->MoveCursorToCrossHair(); - ChangeTextOrient( (SCH_TEXT*) item ); - break; - - case SCH_BUS_BUS_ENTRY_T: - case SCH_BUS_WIRE_ENTRY_T: - m_canvas->MoveCursorToCrossHair(); - SaveCopyInUndoList( item, UR_CHANGED ); - item->Rotate( m_canvas->GetParent()->GetCrossHairPosition() ); - break; - - case SCH_FIELD_T: - m_canvas->MoveCursorToCrossHair(); - RotateField( (SCH_FIELD*) item ); - if( item->GetParent()->Type() == SCH_COMPONENT_T ) - { - // Now that we're moving a field, they're no longer autoplaced. - SCH_COMPONENT *parent = static_cast( item->GetParent() ); - parent->ClearFieldsAutoplaced(); - } - break; - - case SCH_BITMAP_T: - RotateImage( (SCH_BITMAP*) item ); - // The bitmap is cached in Opengl: clear the cache, because - // the cache data is invalid - GetCanvas()->GetView()->RecacheAllItems(); - break; - - case SCH_SHEET_T: - if( !item->IsNew() ) // rotate a sheet during its creation has no sense - { - bool retCCW = ( aEvent.GetId() == ID_SCH_ROTATE_COUNTERCLOCKWISE ); - RotateHierarchicalSheet( static_cast( item ), retCCW ); - } - - break; - - case SCH_JUNCTION_T: - case SCH_NO_CONNECT_T: - // these items are not rotated, because rotation does not change them. - break; - - default: - // Other items (wires...) cannot be rotated, at least during creation - if( item->IsNew() ) - break; - - wxFAIL_MSG( wxString::Format( wxT( "Cannot rotate schematic item type %s." ), - GetChars( item->GetClass() ) ) ); - } - - RefreshItem( item ); - - if( item->IsMoving() ) - { - if( m_canvas->IsMouseCaptured() ) - m_canvas->CallMouseCapture( nullptr, wxDefaultPosition, false ); - else - m_toolManager->RunAction( SCH_ACTIONS::refreshPreview, true ); - } - - if( item->GetEditFlags() == 0 ) - screen->SetCurItem( nullptr ); -} - - void SCH_EDIT_FRAME::OnEditItem( wxCommandEvent& aEvent ) { SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool(); diff --git a/eeschema/schematic_undo_redo.cpp b/eeschema/schematic_undo_redo.cpp index f8ea68ad7c..a06febdb87 100644 --- a/eeschema/schematic_undo_redo.cpp +++ b/eeschema/schematic_undo_redo.cpp @@ -111,7 +111,7 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_ITEM* aItem, bool aAppend, const wxPoint& aTransformPoint ) { - PICKED_ITEMS_LIST* commandToUndo = NULL; + PICKED_ITEMS_LIST* commandToUndo = NULL; if( aItem == NULL ) return; @@ -349,7 +349,7 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed void SCH_EDIT_FRAME::GetSchematicFromUndoList( wxCommandEvent& event ) { - if( GetScreen()->GetUndoCommandCount() <= 0 || isBusy() ) + if( GetScreen()->GetUndoCommandCount() <= 0 ) return; /* Get the old list */ @@ -373,7 +373,7 @@ void SCH_EDIT_FRAME::GetSchematicFromUndoList( wxCommandEvent& event ) void SCH_EDIT_FRAME::GetSchematicFromRedoList( wxCommandEvent& event ) { - if( GetScreen()->GetRedoCommandCount() == 0 || isBusy() ) + if( GetScreen()->GetRedoCommandCount() == 0 ) return; /* Get the old list */ @@ -394,3 +394,20 @@ void SCH_EDIT_FRAME::GetSchematicFromRedoList( wxCommandEvent& event ) GetCanvas()->Refresh(); OnModify(); } + + +void SCH_EDIT_FRAME::RollbackSchematicFromUndo() +{ + PICKED_ITEMS_LIST* undo = GetScreen()->PopCommandFromUndoList(); + PutDataInPreviousState( undo, false ); + + undo->ClearListAndDeleteItems(); + delete undo; + + SetSheetNumberAndCount(); + + TestDanglingEnds(); + + SyncView(); + GetCanvas()->Refresh(); +} diff --git a/eeschema/sheet.cpp b/eeschema/sheet.cpp index 5c0e525db6..3d106f88ed 100644 --- a/eeschema/sheet.cpp +++ b/eeschema/sheet.cpp @@ -304,37 +304,6 @@ bool SCH_EDIT_FRAME::EditSheet( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy, } -void SCH_EDIT_FRAME::RotateHierarchicalSheet( SCH_SHEET* aSheet, bool aRotCCW ) -{ - if( aSheet == NULL ) - return; - - // Save old sheet in undo list if not already in edit, or moving. - if( aSheet->GetEditFlags() == 0 ) - SaveCopyInUndoList( aSheet, UR_CHANGED ); - - // Rotate the sheet on itself. Sheets do not have a anchor point. - // Rotation is made around it center - wxPoint rotPoint = aSheet->GetBoundingBox().Centre(); - - // Keep this rotation point on the grid, otherwise all items of this sheet - // will be moved off grid - rotPoint = GetNearestGridPosition( rotPoint ); - - // rotate CCW, or CW. to rotate CW, rotate 3 times - aSheet->Rotate( rotPoint ); - - if( !aRotCCW ) - { - aSheet->Rotate( rotPoint ); - aSheet->Rotate( rotPoint ); - } - - GetCanvas()->GetView()->Update( aSheet ); - OnModify(); -} - - void SCH_EDIT_FRAME::MirrorSheet( SCH_SHEET* aSheet, bool aFromXaxis ) { if( aSheet == NULL ) diff --git a/eeschema/tools/sch_actions.cpp b/eeschema/tools/sch_actions.cpp index 69c8326f7a..8f3be6269a 100644 --- a/eeschema/tools/sch_actions.cpp +++ b/eeschema/tools/sch_actions.cpp @@ -37,6 +37,9 @@ OPT SCH_ACTIONS::TranslateLegacyId( int aId ) { switch( aId ) { + case ID_NO_TOOL_SELECTED: + return SCH_ACTIONS::selectionActivate.MakeEvent(); + case ID_CANCEL_CURRENT_COMMAND: return ACTIONS::cancelInteractive.MakeEvent(); @@ -176,6 +179,10 @@ OPT SCH_ACTIONS::TranslateLegacyId( int aId ) case ID_SCHEMATIC_DELETE_ITEM_BUTT: return SCH_ACTIONS::deleteItemCursor.MakeEvent(); + case ID_POPUP_MOVE_BLOCK: + case ID_SCH_MOVE_ITEM: + return SCH_ACTIONS::move.MakeEvent(); + case ID_POPUP_SCH_DELETE: return SCH_ACTIONS::remove.MakeEvent(); @@ -184,6 +191,12 @@ OPT SCH_ACTIONS::TranslateLegacyId( int aId ) case ID_SIM_TUNE: return SCH_ACTIONS::simTune.MakeEvent(); + + case ID_SCH_ROTATE_CLOCKWISE: + return SCH_ACTIONS::rotateCW.MakeEvent(); + + case ID_SCH_ROTATE_COUNTERCLOCKWISE: + return SCH_ACTIONS::rotateCCW.MakeEvent(); } return OPT(); diff --git a/eeschema/tools/sch_actions.h b/eeschema/tools/sch_actions.h index 8f144df68d..143f6d03c2 100644 --- a/eeschema/tools/sch_actions.h +++ b/eeschema/tools/sch_actions.h @@ -115,7 +115,8 @@ public: static TOOL_ACTION editActivate; static TOOL_ACTION move; static TOOL_ACTION duplicate; - static TOOL_ACTION rotate; + static TOOL_ACTION rotateCW; + static TOOL_ACTION rotateCCW; static TOOL_ACTION properties; static TOOL_ACTION remove; static TOOL_ACTION addJunction; diff --git a/eeschema/tools/sch_edit_tool.cpp b/eeschema/tools/sch_edit_tool.cpp index 2080d52fa7..1599550f51 100644 --- a/eeschema/tools/sch_edit_tool.cpp +++ b/eeschema/tools/sch_edit_tool.cpp @@ -27,7 +27,12 @@ #include #include #include +#include #include +#include +#include +#include +#include #include #include #include @@ -45,9 +50,14 @@ TOOL_ACTION SCH_ACTIONS::duplicate( "eeschema.InteractiveEdit.duplicate", AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_DUPLICATE_ITEM ), _( "Duplicate" ), _( "Duplicates the selected item(s)" ), duplicate_xpm ); -TOOL_ACTION SCH_ACTIONS::rotate( "eeschema.InteractiveEdit.rotate", +TOOL_ACTION SCH_ACTIONS::rotateCW( "eeschema.InteractiveEdit.rotateCW", + AS_GLOBAL, 0, + _( "Rotate Clockwise" ), _( "Rotates selected item(s) clockwise" ), + rotate_cw_xpm, AF_NONE ); + +TOOL_ACTION SCH_ACTIONS::rotateCCW( "eeschema.InteractiveEdit.rotateCCW", AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ROTATE ), - _( "Rotate" ), _( "Rotates selected item(s)" ), + _( "Rotate" ), _( "Rotates selected item(s) counter-clockwise" ), rotate_ccw_xpm, AF_NONE ); TOOL_ACTION SCH_ACTIONS::properties( "eeschema.InteractiveEdit.properties", @@ -61,10 +71,12 @@ TOOL_ACTION SCH_ACTIONS::remove( "eeschema.InteractiveEdit.remove", SCH_EDIT_TOOL::SCH_EDIT_TOOL() : TOOL_INTERACTIVE( "eeschema.InteractiveEdit" ), + m_selectionTool( nullptr ), m_view( nullptr ), m_controls( nullptr ), m_frame( nullptr ), - m_menu( *this ) + m_menu( *this ), + m_dragging( false ) { }; @@ -76,6 +88,15 @@ SCH_EDIT_TOOL::~SCH_EDIT_TOOL() bool SCH_EDIT_TOOL::Init() { + // Find the selection tool, so they can cooperate + m_selectionTool = m_toolMgr->GetTool(); + + if( !m_selectionTool ) + { + DisplayError( NULL, _( "eeshema.InteractiveSelection tool is not available" ) ); + return false; + } + auto activeToolFunctor = [ this ] ( const SELECTION& aSel ) { return ( m_frame->GetToolId() != ID_NO_TOOL_SELECTED ); }; @@ -92,6 +113,8 @@ bool SCH_EDIT_TOOL::Init() void SCH_EDIT_TOOL::Reset( RESET_REASON aReason ) { + m_dragging = false; + // Init variables used by every drawing tool m_view = static_cast( getView() ); m_controls = getViewControls(); @@ -99,12 +122,344 @@ void SCH_EDIT_TOOL::Reset( RESET_REASON aReason ) } +int SCH_EDIT_TOOL::Main( const TOOL_EVENT& aEvent ) +{ + KIGFX::VIEW_CONTROLS* controls = getViewControls(); + + controls->SetSnapping( true ); + VECTOR2I originalCursorPos = controls->GetCursorPosition(); + + // Be sure that there is at least one item that we can modify. If nothing was selected before, + // try looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection) + SELECTION& selection = m_selectionTool->RequestSelection( SCH_COLLECTOR::DraggableItems ); + bool unselect = selection.IsHover(); + + if( m_dragging || selection.Empty() ) + return 0; + + Activate(); + controls->ShowCursor( true ); + controls->SetAutoPan( true ); + + bool restore_state = false; + VECTOR2I totalMovement; + OPT_TOOL_EVENT evt = aEvent; + VECTOR2I prevPos; + + // Main loop: keep receiving events + do + { + controls->SetSnapping( !evt->Modifier( MD_ALT ) ); + + if( evt->IsAction( &SCH_ACTIONS::editActivate ) || evt->IsAction( &SCH_ACTIONS::move ) + || evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) + { + if( m_dragging && evt->Category() == TC_MOUSE ) + { + m_cursor = controls->GetCursorPosition(); + VECTOR2I movement( m_cursor - prevPos ); + selection.SetReferencePoint( m_cursor ); + + totalMovement += movement; + prevPos = m_cursor; + + // Drag items to the current cursor position + for( int i = 0; i < selection.GetSize(); ++i ) + { + SCH_ITEM* item = static_cast( selection.GetItem( i ) ); + + // Don't double move footprint pads, fields, etc. + if( item->GetParent() && item->GetParent()->IsSelected() ) + continue; + + item->Move( (wxPoint)movement ); + item->SetFlags( IS_MOVED ); + updateView( item ); + } + + m_frame->UpdateMsgPanel(); + } + else if( !m_dragging ) // Prepare to start dragging + { + // Save items, so changes can be undone + for( int i = 0; i < selection.GetSize(); ++i ) + { + SCH_ITEM* item = static_cast( selection.GetItem( i ) ); + + // Don't double move footprint pads, fields, etc. + if( item->GetParent() && item->GetParent()->IsSelected() ) + continue; + + m_frame->SaveCopyInUndoList( item, UR_CHANGED, i > 0 ); + } + + m_cursor = controls->GetCursorPosition(); + + if( selection.HasReferencePoint() ) + { + // start moving with the reference point attached to the cursor + VECTOR2I delta = m_cursor - selection.GetReferencePoint(); + + // Drag items to the current cursor position + for( int i = 0; i < selection.GetSize(); ++i ) + { + SCH_ITEM* item = static_cast( selection.GetItem( i ) ); + + // Don't double move footprint pads, fields, etc. + if( item->GetParent() && item->GetParent()->IsSelected() ) + continue; + + item->Move( (wxPoint)delta ); + } + + selection.SetReferencePoint( m_cursor ); + } + else if( selection.Size() == 1 ) + { + // Set the current cursor position to the first dragged item origin, so the + // movement vector could be computed later + updateModificationPoint( selection ); + m_cursor = originalCursorPos; + } + else + { + updateModificationPoint( selection ); + } + + controls->SetCursorPosition( m_cursor, false ); + + prevPos = m_cursor; + controls->SetAutoPan( true ); + m_dragging = true; + } + } + + else if( evt->IsAction( &ACTIONS::cancelInteractive ) || evt->IsCancel() || evt->IsActivate() ) + { + if( m_dragging ) + restore_state = true; + + break; + } + + else if( evt->Action() == TA_UNDO_REDO_PRE ) + { + unselect = true; + break; + } + + // Dispatch TOOL_ACTIONs + else if( evt->Category() == TC_COMMAND ) + { + if( evt->IsAction( &SCH_ACTIONS::remove ) ) + { + // exit the loop, as there is no further processing for removed items + break; + } + else if( evt->IsAction( &SCH_ACTIONS::duplicate ) ) + { + // On duplicate, stop moving this item + // The duplicate tool should then select the new item and start + // a new move procedure + break; + } + } + + else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) + { + break; // Finish + } + + } while( ( evt = Wait() ) ); //Should be assignment not equality test + + controls->ForceCursorPosition( false ); + controls->ShowCursor( false ); + controls->SetSnapping( false ); + controls->SetAutoPan( false ); + + m_dragging = false; + + // Discard reference point when selection is "dropped" onto the board (ie: not dragging anymore) + selection.ClearReferencePoint(); + + for( auto item : selection ) + item->ClearFlags( IS_MOVED ); + + //if( unselect || restore_state ) + m_toolMgr->RunAction( SCH_ACTIONS::selectionClear, true ); + + if( restore_state ) + m_frame->RollbackSchematicFromUndo(); + else + m_frame->OnModify(); + + return 0; +} + + +bool SCH_EDIT_TOOL::updateModificationPoint( SELECTION& aSelection ) +{ + if( m_dragging && aSelection.HasReferencePoint() ) + return false; + + // When there is only one item selected, the reference point is its position... + if( aSelection.Size() == 1 ) + { + SCH_ITEM* item = static_cast( aSelection.Front() ); + wxPoint pos = item->GetPosition(); + aSelection.SetReferencePoint( pos ); + } + // ...otherwise modify items with regard to the grid-snapped cursor position + else + { + m_cursor = getViewControls()->GetCursorPosition( true ); + aSelection.SetReferencePoint( m_cursor ); + } + + return true; +} + + +int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent ) +{ + SCH_SELECTION_TOOL* selTool = m_toolMgr->GetTool(); + SELECTION selection = selTool->RequestSelection( SCH_COLLECTOR::RotatableItems ); + + if( selection.GetSize() == 0 ) + return 0; + + wxPoint rotPoint; + bool clockwise = ( aEvent.Matches( SCH_ACTIONS::rotateCW.MakeEvent() ) ); + SCH_ITEM* item = static_cast( selection.GetItem( 0 ) ); + bool connections = false; + bool moving = item->IsMoving(); + + if( selection.GetSize() == 1 ) + { + if( !moving ) + m_frame->SaveCopyInUndoList( item, UR_CHANGED ); + + switch( item->Type() ) + { + case SCH_COMPONENT_T: + { + SCH_COMPONENT* component = static_cast( item ); + + if( clockwise ) + component->SetOrientation( CMP_ROTATE_CLOCKWISE ); + else + component->SetOrientation( CMP_ROTATE_COUNTERCLOCKWISE ); + + if( m_frame->GetAutoplaceFields() ) + component->AutoAutoplaceFields( m_frame->GetScreen() ); + + break; + } + + case SCH_TEXT_T: + case SCH_LABEL_T: + case SCH_GLOBAL_LABEL_T: + case SCH_HIER_LABEL_T: + { + SCH_TEXT* textItem = static_cast( item ); + textItem->SetLabelSpinStyle( ( textItem->GetLabelSpinStyle() + 1 ) & 3 ); + break; + } + + case SCH_BUS_BUS_ENTRY_T: + case SCH_BUS_WIRE_ENTRY_T: + item->Rotate( item->GetPosition() ); + break; + + case SCH_FIELD_T: + { + SCH_FIELD* field = static_cast( item ); + + if( field->GetTextAngle() == TEXT_ANGLE_HORIZ ) + field->SetTextAngle( TEXT_ANGLE_VERT ); + else + field->SetTextAngle( TEXT_ANGLE_HORIZ ); + + // Now that we're moving a field, they're no longer autoplaced. + if( item->GetParent()->Type() == SCH_COMPONENT_T ) + { + SCH_COMPONENT *parent = static_cast( item->GetParent() ); + parent->ClearFieldsAutoplaced(); + } + + break; + } + + case SCH_BITMAP_T: + item->Rotate( item->GetPosition() ); + // The bitmap is cached in Opengl: clear the cache to redraw + getView()->RecacheAllItems(); + break; + + case SCH_SHEET_T: + { + SCH_SHEET* sheet = static_cast( item ); + + // Rotate the sheet on itself. Sheets do not have a anchor point. + rotPoint = m_frame->GetNearestGridPosition( sheet->GetBoundingBox().Centre() ); + + if( clockwise ) + { + sheet->Rotate( rotPoint ); + } + else + { + sheet->Rotate( rotPoint ); + sheet->Rotate( rotPoint ); + sheet->Rotate( rotPoint ); + } + + break; + } + + default: + break; + } + + connections = item->IsConnectable(); + m_frame->RefreshItem( item ); + } + else if( selection.GetSize() > 1 ) + { + rotPoint = m_frame->GetNearestGridPosition( (wxPoint)selection.GetCenter() ); + + for( unsigned ii = 0; ii < selection.GetSize(); ii++ ) + { + item = static_cast( selection.GetItem( ii ) ); + + if( !moving ) + m_frame->SaveCopyInUndoList( item, UR_CHANGED, ii > 0 ); + + item->Rotate( rotPoint ); + + connections |= item->IsConnectable(); + m_frame->RefreshItem( item ); + } + } + + if( !item->IsMoving() ) + { + if( connections ) + m_frame->TestDanglingEnds(); + + m_frame->OnModify(); + } + + return 0; +} + + int SCH_EDIT_TOOL::Remove( const TOOL_EVENT& aEvent ) { SCH_SELECTION_TOOL* selTool = m_toolMgr->GetTool(); std::vector lockedItems; - // get a copy instead of reference (as we're going to clear the selection before removing items) + // get a copy instead of reference (we're going to clear the selection before removing items) SELECTION selectionCopy = selTool->RequestSelection(); if( selectionCopy.Empty() ) @@ -113,9 +468,9 @@ int SCH_EDIT_TOOL::Remove( const TOOL_EVENT& aEvent ) // As we are about to remove items, they have to be removed from the selection first m_toolMgr->RunAction( SCH_ACTIONS::selectionClear, true ); - for( EDA_ITEM* it : selectionCopy ) + for( unsigned ii = 0; ii < selectionCopy.GetSize(); ii++ ) { - SCH_ITEM* item = static_cast( it ); + SCH_ITEM* item = static_cast( selectionCopy.GetItem( ii ) ); bool itemHasConnections = item->IsConnectable(); m_frame->GetScreen()->SetCurItem( nullptr ); @@ -133,7 +488,22 @@ int SCH_EDIT_TOOL::Remove( const TOOL_EVENT& aEvent ) } +void SCH_EDIT_TOOL::updateView( EDA_ITEM* aItem ) +{ + KICAD_T itemType = aItem->Type(); + + if( itemType == SCH_PIN_T || itemType == SCH_FIELD_T || itemType == SCH_SHEET_PIN_T ) + getView()->Update( aItem->GetParent() ); + else + getView()->Update( aItem ); +} + + void SCH_EDIT_TOOL::setTransitions() { - Go( &SCH_EDIT_TOOL::Remove, SCH_ACTIONS::remove.MakeEvent() ); + Go( &SCH_EDIT_TOOL::Main, SCH_ACTIONS::editActivate.MakeEvent() ); + Go( &SCH_EDIT_TOOL::Main, SCH_ACTIONS::move.MakeEvent() ); + Go( &SCH_EDIT_TOOL::Rotate, SCH_ACTIONS::rotateCW.MakeEvent() ); + Go( &SCH_EDIT_TOOL::Rotate, SCH_ACTIONS::rotateCCW.MakeEvent() ); + Go( &SCH_EDIT_TOOL::Remove, SCH_ACTIONS::remove.MakeEvent() ); } diff --git a/eeschema/tools/sch_edit_tool.h b/eeschema/tools/sch_edit_tool.h index a9b4da36a2..7cad3b8954 100644 --- a/eeschema/tools/sch_edit_tool.h +++ b/eeschema/tools/sch_edit_tool.h @@ -30,6 +30,7 @@ class SCH_EDIT_FRAME; +class SCH_SELECTION_TOOL; class SCH_EDIT_TOOL : public TOOL_INTERACTIVE @@ -50,19 +51,48 @@ public: return m_menu; } + /** + * Function Main() + * + * Main loop in which events are handled. + */ + int Main( const TOOL_EVENT& aEvent ); + + int Rotate( const TOOL_EVENT& aEvent ); + + /** + * Function Remove() + * + * Deletes the selected items, or the item under the cursor. + */ int Remove( const TOOL_EVENT& aEvent ); private: + ///> Returns the right modification point (e.g. for rotation), depending on the number of + ///> selected items. + bool updateModificationPoint( SELECTION& aSelection ); + + ///> Similar to getView()->Update(), but handles items that are redrawn by their parents. + void updateView( EDA_ITEM* ); + ///> Sets up handlers for various events. void setTransitions() override; private: - KIGFX::SCH_VIEW* m_view; + SCH_SELECTION_TOOL* m_selectionTool; + KIGFX::SCH_VIEW* m_view; KIGFX::VIEW_CONTROLS* m_controls; - SCH_EDIT_FRAME* m_frame; + SCH_EDIT_FRAME* m_frame; /// Menu model displayed by the tool. - TOOL_MENU m_menu; + TOOL_MENU m_menu; + + ///> Flag determining if anything is being dragged right now + bool m_dragging; + + ///> Last cursor position (needed for getModificationPoint() to avoid changes + ///> of edit reference point). + VECTOR2I m_cursor; }; #endif //KICAD_SCH_EDIT_TOOL_H diff --git a/eeschema/tools/sch_selection_tool.cpp b/eeschema/tools/sch_selection_tool.cpp index 8a43d26270..eea68b960f 100644 --- a/eeschema/tools/sch_selection_tool.cpp +++ b/eeschema/tools/sch_selection_tool.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -74,7 +75,6 @@ SCH_SELECTION_TOOL::SCH_SELECTION_TOOL() : m_subtractive( false ), m_multiple( false ), m_skip_heuristics( false ), - m_locked( true ), m_menu( *this ) { } @@ -100,7 +100,6 @@ bool SCH_SELECTION_TOOL::Init() void SCH_SELECTION_TOOL::Reset( RESET_REASON aReason ) { m_frame = getEditFrame(); - m_locked = true; if( aReason == TOOL_BASE::MODEL_RELOAD ) { @@ -182,10 +181,8 @@ int SCH_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) { if( m_additive || m_subtractive || m_selection.Empty() ) { - // JEY TODO: move block selection to SCH_SELECTION_TOOL - //selectMultiple(); + selectMultiple(); } - else { // Check if dragging has started within any of selected items bounding box @@ -318,6 +315,15 @@ void SCH_SELECTION_TOOL::guessSelectionCandidates( SCH_COLLECTOR& collector, } +static EDA_RECT getRect( const SCH_ITEM* aItem ) +{ + if( aItem->Type() == SCH_COMPONENT_T ) + return static_cast( aItem )->GetBodyBoundingBox(); + + return aItem->GetBoundingBox(); +} + + SELECTION& SCH_SELECTION_TOOL::RequestSelection( const KICAD_T aFilterList[] ) { if( m_selection.Empty() ) @@ -366,15 +372,138 @@ bool SCH_SELECTION_TOOL::selectCursor( const KICAD_T aFilterList[], bool aForceS } +bool SCH_SELECTION_TOOL::selectMultiple() +{ + bool cancelled = false; // Was the tool cancelled while it was running? + m_multiple = true; // Multiple selection mode is active + KIGFX::VIEW* view = getView(); + + KIGFX::PREVIEW::SELECTION_AREA area; + view->Add( &area ); + + while( OPT_TOOL_EVENT evt = Wait() ) + { + if( evt->IsAction( &ACTIONS::cancelInteractive ) || evt->IsActivate() || evt->IsCancel() ) + { + cancelled = true; + break; + } + + if( evt->IsDrag( BUT_LEFT ) ) + { + // Start drawing a selection box + area.SetOrigin( evt->DragOrigin() ); + area.SetEnd( evt->Position() ); + area.SetAdditive( m_additive ); + area.SetSubtractive( m_subtractive ); + + view->SetVisible( &area, true ); + view->Update( &area ); + getViewControls()->SetAutoPan( true ); + } + + if( evt->IsMouseUp( BUT_LEFT ) ) + { + getViewControls()->SetAutoPan( false ); + + // End drawing the selection box + view->SetVisible( &area, false ); + + // Mark items within the selection box as selected + std::vector selectedItems; + + // Filter the view items based on the selection box + BOX2I selectionBox = area.ViewBBox(); + view->Query( selectionBox, selectedItems ); // Get the list of selected items + + std::vector::iterator it, it_end; + + int width = area.GetEnd().x - area.GetOrigin().x; + int height = area.GetEnd().y - area.GetOrigin().y; + + /* Selection mode depends on direction of drag-selection: + * Left > Right : Select objects that are fully enclosed by selection + * Right > Left : Select objects that are crossed by selection + */ + bool windowSelection = width >= 0 ? true : false; + + if( view->IsMirroredX() ) + windowSelection = !windowSelection; + + // Construct an EDA_RECT to determine BOARD_ITEM selection + EDA_RECT selectionRect( wxPoint( area.GetOrigin().x, area.GetOrigin().y ), + wxSize( width, height ) ); + + selectionRect.Normalize(); + + for( it = selectedItems.begin(), it_end = selectedItems.end(); it != it_end; ++it ) + { + SCH_ITEM* item = static_cast( it->first ); + + if( !item || !selectable( item ) ) + continue; + + if( windowSelection ) + { + BOX2I bbox = getRect( item ); + + if( selectionBox.Contains( bbox ) ) + { + if( m_subtractive ) + unselect( item ); + else + select( item ); + } + } + else + { + if( item->HitTest( selectionRect, false ) ) + { + if( m_subtractive ) + unselect( item ); + else + select( item ); + } + } + } + + if( m_frame ) + { + if( m_selection.Size() == 1 ) + m_frame->GetScreen()->SetCurItem( static_cast( m_selection.Front() ) ); + else + m_frame->GetScreen()->SetCurItem( nullptr ); + } + + // Inform other potentially interested tools + if( !m_selection.Empty() ) + m_toolMgr->ProcessEvent( EVENTS::SelectedEvent ); + + break; // Stop waiting for events + } + } + + getViewControls()->SetAutoPan( false ); + + // Stop drawing the selection box + view->Remove( &area ); + m_multiple = false; // Multiple selection mode is inactive + + if( !cancelled ) + m_selection.ClearReferencePoint(); + + return cancelled; +} + + int SCH_SELECTION_TOOL::SelectItems( const TOOL_EVENT& aEvent ) { - std::vector* items = aEvent.Parameter*>(); + PICKED_ITEMS_LIST* pickedItems = aEvent.Parameter(); - if( items ) + if( pickedItems ) { - // Perform individual selection of each item before processing the event. - for( auto item : *items ) - select( item ); + for( unsigned ii = 0; ii < pickedItems->GetCount(); ii++ ) + select( (SCH_ITEM*) pickedItems->GetPickedItem( ii ) ); m_toolMgr->ProcessEvent( EVENTS::SelectedEvent ); } @@ -402,13 +531,12 @@ int SCH_SELECTION_TOOL::SelectItem( const TOOL_EVENT& aEvent ) int SCH_SELECTION_TOOL::UnselectItems( const TOOL_EVENT& aEvent ) { - std::vector* items = aEvent.Parameter*>(); + PICKED_ITEMS_LIST* pickedItems = aEvent.Parameter(); - if( items ) + if( pickedItems ) { - // Perform individual unselection of each item before processing the event - for( auto item : *items ) - unselect( item ); + for( unsigned ii = 0; ii < pickedItems->GetCount(); ii++ ) + unselect( (SCH_ITEM*) pickedItems->GetPickedItem( ii ) ); m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent ); } @@ -456,43 +584,6 @@ int SCH_SELECTION_TOOL::SelectionMenu( const TOOL_EVENT& aEvent ) bool SCH_SELECTION_TOOL::doSelectionMenu( SCH_COLLECTOR* aCollector ) { SCH_ITEM* current = nullptr; -#if 1 -// ==================================================================================== -// JEY TODO: use wxWidgets event loop for showing menu until we move to modern toolset event loop - wxMenu selectMenu; - - AddMenuItem( &selectMenu, wxID_NONE, _( "Clarify Selection" ), KiBitmap( info_xpm ) ); - selectMenu.AppendSeparator(); - - for( int i = 0; i < aCollector->GetCount() && i < MAX_SELECT_ITEM_IDS; i++ ) - { - SCH_ITEM* item = ( *aCollector )[i]; - wxString text = item->GetSelectMenuText( m_frame->GetUserUnits() ); - BITMAP_DEF xpm = item->GetMenuImage(); - AddMenuItem( &selectMenu, i, text, KiBitmap( xpm ) ); - } - - // Set to NULL in case the user aborts the clarification context menu. - m_frame->GetScreen()->SetCurItem( nullptr ); - int idx = m_frame->GetPopupMenuSelectionFromUser( selectMenu ); - - if( idx == wxID_NONE ) - { - m_frame->GetScreen()->SetCurItem( nullptr ); - return false; - } - - m_frame->GetCanvas()->MoveCursorToCrossHair(); - - current = ( *aCollector )[ idx ]; - m_frame->GetScreen()->SetCurItem( current ); - - aCollector->Empty(); - aCollector->Append( current ); - return true; - -// ==================================================================================== -#endif CONTEXT_MENU menu; int limit = std::min( MAX_SELECT_ITEM_IDS, aCollector->GetCount() ); @@ -549,12 +640,18 @@ bool SCH_SELECTION_TOOL::doSelectionMenu( SCH_COLLECTOR* aCollector ) break; } + + getView()->UpdateItems(); + m_frame->GetCanvas()->Refresh(); } if( current ) { unhighlight( current, BRIGHTENED ); + getView()->UpdateItems(); + m_frame->GetCanvas()->Refresh(); + aCollector->Empty(); aCollector->Append( current ); return true; @@ -605,8 +702,6 @@ void SCH_SELECTION_TOOL::clearSelection() if( m_frame ) m_frame->GetScreen()->SetCurItem( nullptr ); - m_locked = true; - // Inform other potentially interested tools m_toolMgr->ProcessEvent( EVENTS::ClearedEvent ); } @@ -643,11 +738,7 @@ void SCH_SELECTION_TOOL::toggleSelection( SCH_ITEM* aItem, bool aForce ) void SCH_SELECTION_TOOL::select( SCH_ITEM* aItem ) { - if( aItem->IsSelected() ) - return; - highlight( aItem, SELECTED, &m_selection ); - getView()->Update( &m_selection ); if( m_frame ) { @@ -668,13 +759,9 @@ void SCH_SELECTION_TOOL::select( SCH_ITEM* aItem ) void SCH_SELECTION_TOOL::unselect( SCH_ITEM* aItem ) { unhighlight( aItem, SELECTED, &m_selection ); - getView()->Update( &m_selection ); if( m_frame && m_frame->GetScreen()->GetCurItem() == aItem ) m_frame->GetScreen()->SetCurItem( nullptr ); - - if( m_selection.Empty() ) - m_locked = true; } @@ -689,10 +776,10 @@ void SCH_SELECTION_TOOL::highlight( SCH_ITEM* aItem, int aMode, SELECTION* aGrou aGroup->Add( aItem ); // Highlight pins and fields. (All the other component children are currently only - // represented in the LIB_PART.) + // represented in the LIB_PART and will inherit the settings of the parent component.) if( aItem->Type() == SCH_COMPONENT_T ) { - SCH_PINS pins = static_cast( aItem )->GetPins(); + SCH_PINS& pins = static_cast( aItem )->GetPins(); for( SCH_PIN& pin : pins ) { @@ -705,23 +792,31 @@ void SCH_SELECTION_TOOL::highlight( SCH_ITEM* aItem, int aMode, SELECTION* aGrou std::vector fields; static_cast( aItem )->GetFields( fields, false ); - for( auto field : fields ) + for( SCH_FIELD* field : fields ) { if( aMode == SELECTED ) field->SetSelected(); else if( aMode == BRIGHTENED ) field->SetBrightened(); - - // JEY TODO: do these need hiding from view and adding to aGroup? } } + else if( aItem->Type() == SCH_SHEET_T ) + { + SCH_SHEET_PINS& pins = static_cast( aItem )->GetPins(); - // JEY TODO: Sheets and sheet pins? + for( SCH_SHEET_PIN& pin : pins ) + { + if( aMode == SELECTED ) + pin.SetSelected(); + else if( aMode == BRIGHTENED ) + pin.SetBrightened(); + } + } - // Many selections are very temporal and updating the display each time just - // creates noise. - if( aMode == BRIGHTENED ) - getView()->MarkTargetDirty( KIGFX::TARGET_OVERLAY ); + if( aItem->Type() == SCH_PIN_T || aItem->Type() == SCH_FIELD_T ) + getView()->Update( aItem->GetParent() ); + else + getView()->Update( aItem ); } @@ -739,7 +834,7 @@ void SCH_SELECTION_TOOL::unhighlight( SCH_ITEM* aItem, int aMode, SELECTION* aGr // represented in the LIB_PART.) if( aItem->Type() == SCH_COMPONENT_T ) { - SCH_PINS pins = static_cast( aItem )->GetPins(); + SCH_PINS& pins = static_cast( aItem )->GetPins(); for( SCH_PIN& pin : pins ) { @@ -752,23 +847,31 @@ void SCH_SELECTION_TOOL::unhighlight( SCH_ITEM* aItem, int aMode, SELECTION* aGr std::vector fields; static_cast( aItem )->GetFields( fields, false ); - for( auto field : fields ) + for( SCH_FIELD* field : fields ) { if( aMode == SELECTED ) field->ClearSelected(); else if( aMode == BRIGHTENED ) field->ClearBrightened(); - - // JEY TODO: do these need showing and updating? } } + else if( aItem->Type() == SCH_SHEET_T ) + { + SCH_SHEET_PINS& pins = static_cast( aItem )->GetPins(); - // JEY TODO: Sheets and sheet pins? + for( SCH_SHEET_PIN& pin : pins ) + { + if( aMode == SELECTED ) + pin.ClearSelected(); + else if( aMode == BRIGHTENED ) + pin.ClearBrightened(); + } + } - // Many selections are very temporal and updating the display each time just - // creates noise. - if( aMode == BRIGHTENED ) - getView()->MarkTargetDirty( KIGFX::TARGET_OVERLAY ); + if( aItem->Type() == SCH_PIN_T || aItem->Type() == SCH_FIELD_T ) + getView()->Update( aItem->GetParent() ); + else + getView()->Update( aItem ); } diff --git a/eeschema/tools/sch_selection_tool.h b/eeschema/tools/sch_selection_tool.h index bd1a04f20c..ace3cf7f5c 100644 --- a/eeschema/tools/sch_selection_tool.h +++ b/eeschema/tools/sch_selection_tool.h @@ -123,6 +123,15 @@ private: */ bool selectCursor( const KICAD_T aFilterList[], bool aForceSelect = false ); + /** + * Function selectMultiple() + * Handles drawing a selection box that allows one to select many items at + * the same time. + * + * @return true if the function was cancelled (i.e. CancelEvent was received). + */ + bool selectMultiple(); + /** * Apply heuristics to try and determine a single object when multiple are found under the * cursor. @@ -213,7 +222,6 @@ private: bool m_subtractive; // Items should be removed from selection bool m_multiple; // Multiple selection mode is active bool m_skip_heuristics; // Heuristics are not allowed when choosing item under cursor - bool m_locked; // Other tools are not allowed to modify locked items TOOL_MENU m_menu; }; diff --git a/include/draw_frame.h b/include/draw_frame.h index f80ad6efb9..e1a659ddcf 100644 --- a/include/draw_frame.h +++ b/include/draw_frame.h @@ -221,11 +221,6 @@ protected: */ void RefreshCrossHair( const wxPoint &aOldPos, const wxPoint &aEvtPos, wxDC* aDC ); - /** - * @return true if an item edit or a block operation is in progress. - */ - bool isBusy() const; - /** * Stores the canvas type in the application settings. */ @@ -744,8 +739,8 @@ public: void DisplayToolMsg( const wxString& msg ); virtual void RedrawActiveWindow( wxDC* DC, bool EraseBg ) = 0; - virtual void OnLeftClick( wxDC* DC, const wxPoint& MousePos ) = 0; - virtual void OnLeftDClick( wxDC* DC, const wxPoint& MousePos ); + virtual void OnLeftClick( wxDC* DC, const wxPoint& MousePos ) {}; + virtual void OnLeftDClick( wxDC* DC, const wxPoint& MousePos ) {}; virtual bool OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu ) = 0; virtual void ToolOnRightClick( wxCommandEvent& event ); void AdjustScrollBars( const wxPoint& aCenterPosition ); diff --git a/include/legacy_gal/class_drawpanel.h b/include/legacy_gal/class_drawpanel.h index 8851e39183..7e4d2b6e4b 100644 --- a/include/legacy_gal/class_drawpanel.h +++ b/include/legacy_gal/class_drawpanel.h @@ -75,11 +75,6 @@ protected: /// Abort mouse capture callback function. END_MOUSE_CAPTURE_CALLBACK m_endMouseCaptureCallback; - /// useful to avoid false start block in certain cases - /// (like switch from a sheet to another sheet - /// >= 0 (or >= n) if a block can start - int m_canStartBlock; - int m_doubleClickInterval; public: @@ -100,7 +95,6 @@ public: m_PrintIsMirrored( false ), m_mouseCaptureCallback( nullptr ), m_endMouseCaptureCallback( nullptr ), - m_canStartBlock( true ), m_doubleClickInterval( 0 ) {}; @@ -150,7 +144,7 @@ public: bool GetPrintMirrored() const { return m_PrintIsMirrored; } void SetPrintMirrored( bool aMirror ) { m_PrintIsMirrored = aMirror; } - void SetCanStartBlock( int aStartBlock ) { m_canStartBlock = aStartBlock; } + void SetCanStartBlock( int aStartBlock ) { /* JEY TODO: remove */ } /** * Function DrawBackGround