// **************************************************************************** // // Function Name: RWindowView::OnAutoScrollTimer( ) // // Description: Called by the autoscroll timer when its timer elapses // // Returns: Nothing // // Exceptions: None // // **************************************************************************** // void RWindowView::OnAutoScrollTimer( ) { // Get the modifier key state YModifierKey modifierKeys = GetModifierKeyState( ); // Get the current mouse position in both device coordinates and local coordinates #ifdef _WINDOWS POINT pt; ::GetCursorPos( &pt ); GetCWnd( ).ScreenToClient( &pt ); RRealPoint devicePoint = RRealPoint( pt.x, pt.y ); RRealPoint localPoint = devicePoint; ::DeviceUnitsToLogicalUnits( localPoint, *this ); localPoint = ConvertPointToLocalCoordinateSystem( localPoint ); #endif // Get the direction to autoscroll EDirection autoScrollDirection = GetAutoScrollDirection( localPoint ); // If the left button is no longer down, or we are not moving in the same direction, // kill the timer. if( !( IsMouseCaptured() /*modifierKeys & kModifierLeftButton*/ ) || !( autoScrollDirection & m_AutoScrollDirection ) ) { delete m_pAutoScrollTimer; m_pAutoScrollTimer = 0; } // Otherwise, we are good to autoscroll. Simulate a mouse move event else OnXMouseMessage( kMouseMove, devicePoint, modifierKeys ); }
void EDA_DRAW_PANEL::OnKeyEvent( wxKeyEvent& event ) { int localkey; wxPoint pos; localkey = event.GetKeyCode(); switch( localkey ) { default: break; case WXK_ESCAPE: m_abortRequest = true; if( IsMouseCaptured() ) EndMouseCapture(); else EndMouseCapture( ID_NO_TOOL_SELECTED, m_defaultCursor, wxEmptyString ); break; } /* Normalize keys code to easily handle keys from Ctrl+A to Ctrl+Z * They have an ascii code from 1 to 27 remapped * to GR_KB_CTRL + 'A' to GR_KB_CTRL + 'Z' */ if( event.ControlDown() && localkey >= WXK_CONTROL_A && localkey <= WXK_CONTROL_Z ) localkey += 'A' - 1; /* Disallow shift for keys that have two keycodes on them (e.g. number and * punctuation keys) leaving only the "letter keys" of A-Z. * Then, you can have, e.g. Ctrl-5 and Ctrl-% (GB layout) * and Ctrl-( and Ctrl-5 (FR layout). * Otherwise, you'd have to have to say Ctrl-Shift-5 on a FR layout */ bool keyIsLetter = ( localkey >= 'A' && localkey <= 'Z' ) || ( localkey >= 'a' && localkey <= 'z' ); if( event.ShiftDown() && ( keyIsLetter || localkey > 256 ) ) localkey |= GR_KB_SHIFT; if( event.ControlDown() ) localkey |= GR_KB_CTRL; if( event.AltDown() ) localkey |= GR_KB_ALT; INSTALL_UNBUFFERED_DC( DC, this ); // Some key commands use the current mouse position: refresh it. pos = wxGetMousePosition() - GetScreenPosition(); // Compute the cursor position in drawing units. Also known as logical units to wxDC. pos = wxPoint( DC.DeviceToLogicalX( pos.x ), DC.DeviceToLogicalY( pos.y ) ); GetParent()->SetMousePosition( pos ); if( !GetParent()->GeneralControl( &DC, pos, localkey ) ) event.Skip(); }
void OnMouseMove(suic::MouseEventArg& e) { if (IsMouseCaptured()) { int iHorz = e.MousePoint().x - _prev.x; int iVert = e.MousePoint().y - _prev.y; int newPos = _trackStart; if (CoreFlags::Horizontal == _slider->GetOrientation()) { newPos += iHorz; if (newPos < 0) { newPos = 0; } if (newPos > _slider->RenderSize().cx - GetDesiredSize().cx) { newPos = _slider->RenderSize().cx - GetDesiredSize().cx; } iHorz = newPos - _trackPos; } else { newPos += iVert; if (newPos < 0) { newPos = 0; } if (newPos > _slider->RenderSize().cy - GetDesiredSize().cy) { newPos = _slider->RenderSize().cy - GetDesiredSize().cy; } iVert = newPos - _trackPos; } if (ThumbDragDelta && newPos != _trackPos) { _trackPos = newPos; DragDeltaEventArg de(iHorz, iVert); ThumbDragDelta(de); } } }
virtual void OnMouseMove(suic::MouseEventArg& e) { if (e.LeftButton() != suic::eMousePress) { if (IsMouseCaptured()) { suic::HwndHelper::CloseWindow(this); } return; } __super::OnMouseMove(e); }
void EDA_DRAW_PANEL::OnMouseEvent( wxMouseEvent& event ) { int localbutt = 0; BASE_SCREEN* screen = GetScreen(); 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() ) // No mouse capture in progress. SetAutoPanRequest( false ); if( GetParent()->IsActive() ) SetFocus(); else return; if( !event.IsButton() && !event.Moving() && !event.Dragging() ) return; if( event.RightDown() ) { 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; INSTALL_UNBUFFERED_DC( DC, this ); DC.SetBackground( *wxBLACK_BRUSH ); // 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 ) ) { if( m_ClickTimer ) { m_ClickTimer->Stop(); wxDELETE( m_ClickTimer ); } GetParent()->OnLeftDClick( &DC, GetParent()->RefPos( true ) ); // 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 ) { EDA_ITEM* item = screen->GetCurItem(); m_CursorClickPos = GetParent()->RefPos( true ); // If we have an item already selected, or we are using a tool, // we won't use the disambiguation menu so process the click immediately if( ( item && item->GetFlags() ) || GetParent()->GetToolId() != ID_NO_TOOL_SELECTED ) GetParent()->OnLeftClick( &DC, m_CursorClickPos ); else { wxDELETE( m_ClickTimer ); m_ClickTimer = new wxTimer(this, ID_MOUSE_DOUBLECLICK); m_ClickTimer->StartOnce( m_doubleClickInterval ); } } } 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(); INSTALL_UNBUFFERED_DC( dc, this ); CrossHairOff( &dc ); SetCursor( wxCURSOR_SIZING ); } if( event.ButtonUp( wxMOUSE_BTN_MIDDLE ) ) { INSTALL_UNBUFFERED_DC( dc, this ); CrossHairOn( &dc ); SetCursor( (wxStockCursor) m_currentCursor ); } if( event.MiddleIsDown() ) { wxPoint currentPosition = event.GetPosition(); double scale = GetParent()->GetScreen()->GetScalingFactor(); int x = m_PanStartCenter.x + KiROUND( (double) ( m_PanStartEventPosition.x - currentPosition.x ) / scale ); int y = m_PanStartCenter.y + KiROUND( (double) ( m_PanStartEventPosition.y - currentPosition.y ) / scale ); GetParent()->RedrawScreen( wxPoint( x, y ), false ); } // Calling the general function on mouse changes (and pseudo key commands) GetParent()->GeneralControl( &DC, event.GetLogicalPosition( DC ), 0 ); /*******************************/ /* Control of block commands : */ /*******************************/ // Command block can't start if mouse is dragging a new panel static EDA_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( &DC ); 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; if( !GetParent()->HandleBlockBegin( &DC, 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, &DC ); SetAutoPanRequest( false ); } SetCursor( (wxStockCursor) m_currentCursor ); } else if( screen->m_BlockLocate.GetState() == STATE_BLOCK_END ) { SetAutoPanRequest( false ); GetParent()->HandleBlockEnd( &DC ); 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, &DC ); } } lastPanel = this; #ifdef __WXGTK3__ // Screen has to be updated on every operation, otherwise the cursor leaves a trail (when xor // operation is changed to copy) or is not updated at all. Refresh(); #endif }
void EDA_DRAW_PANEL::OnMouseEvent( wxMouseEvent& event ) { int localrealbutt = 0, localbutt = 0; BASE_SCREEN* screen = GetScreen(); 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() ) // No mouse capture in progress. m_requestAutoPan = false; if( GetParent()->IsActive() ) SetFocus(); else return; if( !event.IsButton() && !event.Moving() && !event.Dragging() ) return; if( event.RightDown() ) { OnRightClick( event ); return; } if( m_ignoreMouseEvents ) return; if( event.LeftIsDown() ) localrealbutt |= GR_M_LEFT_DOWN; if( event.MiddleIsDown() ) localrealbutt |= GR_M_MIDDLE_DOWN; 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; localrealbutt |= localbutt; // compensation default wxGTK INSTALL_UNBUFFERED_DC( DC, this ); DC.SetBackground( *wxBLACK_BRUSH ); // 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( &DC, GetParent()->RefPos( true ) ); // 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( &DC, GetParent()->RefPos( true ) ); } 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_enableMiddleButtonPan ) { if( m_panScrollbarLimits ) { int ppux, ppuy; GetScrollPixelsPerUnit( &ppux, &ppuy ); GetViewStart( &m_PanStartCenter.x, &m_PanStartCenter.y ); m_PanStartCenter.x *= ppux; m_PanStartCenter.y *= ppuy; } else m_PanStartCenter = GetParent()->GetScrollCenterPosition(); m_PanStartEventPosition = event.GetPosition(); INSTALL_UNBUFFERED_DC( dc, this ); CrossHairOff( &dc ); } if( event.ButtonUp( wxMOUSE_BTN_MIDDLE ) && m_enableMiddleButtonPan ) { INSTALL_UNBUFFERED_DC( dc, this ); CrossHairOn( &dc ); } if( event.MiddleIsDown() && m_enableMiddleButtonPan ) { wxPoint currentPosition = event.GetPosition(); if( m_panScrollbarLimits ) { int x, y; int tmpX, tmpY; int ppux, ppuy; int maxX, maxY; int vsizeX, vsizeY; int csizeX, csizeY; GetViewStart( &tmpX, &tmpY ); GetScrollPixelsPerUnit( &ppux, &ppuy ); GetVirtualSize( &vsizeX, &vsizeY ); GetClientSize( &csizeX, &csizeY ); maxX = vsizeX - csizeX; maxY = vsizeY - csizeY; x = m_PanStartCenter.x + m_PanStartEventPosition.x - currentPosition.x; y = m_PanStartCenter.y + m_PanStartEventPosition.y - currentPosition.y; bool shouldMoveCursor = false; if( x < 0 ) { currentPosition.x += x; x = 0; shouldMoveCursor = true; } if( y < 0 ) { currentPosition.y += y; y = 0; shouldMoveCursor = true; } if( x > maxX ) { currentPosition.x += ( x - maxX ); x = maxX; shouldMoveCursor = true; } if( y > maxY ) { currentPosition.y += ( y - maxY ); y = maxY; shouldMoveCursor = true; } if( shouldMoveCursor ) WarpPointer( currentPosition.x, currentPosition.y ); Scroll( x/ppux, y/ppuy ); double scale = GetParent()->GetScreen()->GetScalingFactor(); wxPoint center = GetParent()->GetScrollCenterPosition(); center.x += KiROUND( (double) ( x - tmpX ) / scale ) / ppux; center.y += KiROUND( (double) ( y - tmpY ) / scale ) / ppuy; GetParent()->SetScrollCenterPosition( center ); Refresh(); Update(); } else { double scale = GetParent()->GetScreen()->GetScalingFactor(); int x = m_PanStartCenter.x + KiROUND( (double) ( m_PanStartEventPosition.x - currentPosition.x ) / scale ); int y = m_PanStartCenter.y + KiROUND( (double) ( m_PanStartEventPosition.y - currentPosition.y ) / scale ); GetParent()->RedrawScreen( wxPoint( x, y ), false ); } } if( event.ButtonUp( wxMOUSE_BTN_MIDDLE ) && !m_enableMiddleButtonPan && (screen->m_BlockLocate.GetState() == STATE_NO_BLOCK) ) { // The middle button has been released, with no block command: // We use it for a zoom center at cursor position command wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED, ID_POPUP_ZOOM_CENTER ); cmd.SetEventObject( this ); GetEventHandler()->ProcessEvent( cmd ); } // Calling the general function on mouse changes (and pseudo key commands) GetParent()->GeneralControl( &DC, event.GetLogicalPosition( DC ), 0 ); /*******************************/ /* Control of block commands : */ /*******************************/ // Command block can't start if mouse is dragging a new panel static EDA_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() || ( !m_enableMiddleButtonPan && event.MiddleDown() ) ) { if( screen->m_BlockLocate.GetState() == STATE_BLOCK_MOVE ) { m_requestAutoPan = false; GetParent()->HandleBlockPlace( &DC ); m_ignoreNextLeftButtonRelease = true; } } else if( ( m_canStartBlock >= 0 ) && ( event.LeftIsDown() || ( !m_enableMiddleButtonPan && event.MiddleIsDown() ) ) && !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; if( !m_enableMiddleButtonPan && event.MiddleIsDown() ) cmd_type |= MOUSE_MIDDLE; // 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 { if( !GetParent()->HandleBlockBegin( &DC, cmd_type, m_CursorStartPos ) ) { // should not occur: error GetParent()->DisplayToolMsg( wxT( "EDA_DRAW_PANEL::OnMouseEvent() Block Error" ) ); } else { m_requestAutoPan = true; SetCursor( wxCURSOR_SIZING ); } } } } if( event.ButtonUp( wxMOUSE_BTN_LEFT ) || ( !m_enableMiddleButtonPan && event.ButtonUp( wxMOUSE_BTN_MIDDLE ) ) ) { /* 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, &DC ); m_requestAutoPan = false; } SetCursor( (wxStockCursor) m_currentCursor ); } else if( screen->m_BlockLocate.GetState() == STATE_BLOCK_END ) { m_requestAutoPan = false; GetParent()->HandleBlockEnd( &DC ); SetCursor( (wxStockCursor) m_currentCursor ); if( screen->m_BlockLocate.GetState() == STATE_BLOCK_MOVE ) { m_requestAutoPan = 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, &DC ); } } #if 0 wxString msg_debug; msg_debug.Printf( " block state %d, cmd %d", screen->m_BlockLocate.GetState(), screen->m_BlockLocate.GetCommand() ); GetParent()->PrintMsg( msg_debug ); #endif lastPanel = this; }