void wxSplitterWindow::OnMouseCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(event)) { if (m_dragMode != wxSPLIT_DRAG_DRAGGING) return; m_dragMode = wxSPLIT_DRAG_NONE; SetCursor(* wxSTANDARD_CURSOR); // Erase old tracker if ( !IsLive(this) ) { DrawSashTracker(m_oldX, m_oldY); } }
void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event) { int x = (int)event.GetX(), y = (int)event.GetY(); if (GetWindowStyle() & wxSP_NOSASH) return; // with wxSP_LIVE_UPDATE style the splitter windows are always resized // following the mouse movement while it drags the sash, without it we only // draw the sash at the new position but only resize the windows when the // dragging is finished #if defined( __WXMAC__ ) && TARGET_API_MAC_OSX == 1 bool isLive = true ; #else bool isLive = (GetWindowStyleFlag() & wxSP_LIVE_UPDATE) != 0; #endif if (event.LeftDown()) { if ( SashHitTest(x, y) ) { // Start the drag now m_dragMode = wxSPLIT_DRAG_DRAGGING; // Capture mouse and set the cursor CaptureMouse(); SetResizeCursor(); if ( !isLive ) { // remember the initial sash position and draw the initial // shadow sash m_sashPositionCurrent = m_sashPosition; DrawSashTracker(x, y); } m_oldX = x; m_oldY = y; SetResizeCursor(); return; } } else if (event.LeftUp() && m_dragMode == wxSPLIT_DRAG_DRAGGING) { // We can stop dragging now and see what we've got. m_dragMode = wxSPLIT_DRAG_NONE; // Release mouse and unset the cursor ReleaseMouse(); SetCursor(* wxSTANDARD_CURSOR); // exit if unsplit after doubleclick if ( !IsSplit() ) { return; } // Erase old tracker if ( !isLive ) { DrawSashTracker(m_oldX, m_oldY); } // the position of the click doesn't exactly correspond to // m_sashPosition, rather it changes it by the distance by which the // mouse has moved int diff = m_splitMode == wxSPLIT_VERTICAL ? x - m_oldX : y - m_oldY; int posSashOld = isLive ? m_sashPosition : m_sashPositionCurrent; int posSashNew = OnSashPositionChanging(posSashOld + diff); if ( posSashNew == -1 ) { // change not allowed return; } if ( m_permitUnsplitAlways || m_minimumPaneSize == 0 ) { // Deal with possible unsplit scenarios if ( posSashNew == 0 ) { // We remove the first window from the view wxWindow *removedWindow = m_windowOne; m_windowOne = m_windowTwo; m_windowTwo = (wxWindow *) NULL; OnUnsplit(removedWindow); wxSplitterEvent event(wxEVT_COMMAND_SPLITTER_UNSPLIT, this); event.m_data.win = removedWindow; (void)DoSendEvent(event); SetSashPositionAndNotify(0); } else if ( posSashNew == GetWindowSize() ) { // We remove the second window from the view wxWindow *removedWindow = m_windowTwo; m_windowTwo = (wxWindow *) NULL; OnUnsplit(removedWindow); wxSplitterEvent event(wxEVT_COMMAND_SPLITTER_UNSPLIT, this); event.m_data.win = removedWindow; (void)DoSendEvent(event); SetSashPositionAndNotify(0); } else { SetSashPositionAndNotify(posSashNew); } } else { SetSashPositionAndNotify(posSashNew); } SizeWindows(); } // left up && dragging else if ((event.Moving() || event.Leaving() || event.Entering()) && (m_dragMode == wxSPLIT_DRAG_NONE)) { if ( event.Leaving() || !SashHitTest(x, y) ) OnLeaveSash(); else OnEnterSash(); } else if (event.Dragging() && (m_dragMode == wxSPLIT_DRAG_DRAGGING)) { int diff = m_splitMode == wxSPLIT_VERTICAL ? x - m_oldX : y - m_oldY; if ( !diff ) { // nothing to do, mouse didn't really move far enough return; } int posSashOld = isLive ? m_sashPosition : m_sashPositionCurrent; int posSashNew = OnSashPositionChanging(posSashOld + diff); if ( posSashNew == -1 ) { // change not allowed return; } if ( posSashNew == m_sashPosition ) return; // Erase old tracker if ( !isLive ) { DrawSashTracker(m_oldX, m_oldY); } if (m_splitMode == wxSPLIT_VERTICAL) x = posSashNew; else y = posSashNew; // Remember old positions m_oldX = x; m_oldY = y; #ifdef __WXMSW__ // As we captured the mouse, we may get the mouse events from outside // our window - for example, negative values in x, y. This has a weird // consequence under MSW where we use unsigned values sometimes and // signed ones other times: the coordinates turn as big positive // numbers and so the sash is drawn on the *right* side of the window // instead of the left (or bottom instead of top). Correct this. if ( (short)m_oldX < 0 ) m_oldX = 0; if ( (short)m_oldY < 0 ) m_oldY = 0; #endif // __WXMSW__ // Draw new one if ( !isLive ) { m_sashPositionCurrent = posSashNew; DrawSashTracker(m_oldX, m_oldY); } else { DoSetSashPosition(posSashNew); m_needUpdating = true; } } else if ( event.LeftDClick() && m_windowTwo ) { OnDoubleClickSash(x, y); } }
void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event) { int x = (int)event.GetX(), y = (int)event.GetY(); if ( GetWindowStyle() & wxSP_NOSASH ) { event.Skip(); return; } bool isLive = IsLive(this); if (event.LeftDown()) { if ( SashHitTest(x, y) ) { // Start the drag now m_dragMode = wxSPLIT_DRAG_DRAGGING; // Capture mouse and set the cursor CaptureMouse(); SetResizeCursor(); if ( !isLive ) { // remember the initial sash position and draw the initial // shadow sash m_sashPositionCurrent = m_sashPosition; m_oldX = (m_splitMode == wxSPLIT_VERTICAL ? m_sashPositionCurrent : x); m_oldY = (m_splitMode != wxSPLIT_VERTICAL ? m_sashPositionCurrent : y); DrawSashTracker(m_oldX, m_oldY); } m_ptStart = wxPoint(x,y); m_sashStart = m_sashPosition; return; } } else if (event.LeftUp() && m_dragMode == wxSPLIT_DRAG_DRAGGING) { // We can stop dragging now and see what we've got. m_dragMode = wxSPLIT_DRAG_NONE; // Release mouse and unset the cursor ReleaseMouse(); SetCursor(* wxSTANDARD_CURSOR); // exit if unsplit after doubleclick if ( !IsSplit() ) { return; } // Erase old tracker if ( !isLive ) { DrawSashTracker(m_oldX, m_oldY); } // the position of the click doesn't exactly correspond to // m_sashPosition, rather it changes it by the distance by which the // mouse has moved int diff = m_splitMode == wxSPLIT_VERTICAL ? x - m_ptStart.x : y - m_ptStart.y; int posSashNew = OnSashPositionChanging(m_sashStart + diff); if ( posSashNew == -1 ) { // change not allowed return; } if ( m_permitUnsplitAlways || m_minimumPaneSize == 0 ) { // Deal with possible unsplit scenarios if ( posSashNew == 0 ) { // We remove the first window from the view wxWindow *removedWindow = m_windowOne; m_windowOne = m_windowTwo; m_windowTwo = NULL; OnUnsplit(removedWindow); wxSplitterEvent eventUnsplit(wxEVT_SPLITTER_UNSPLIT, this); eventUnsplit.m_data.win = removedWindow; (void)DoSendEvent(eventUnsplit); SetSashPositionAndNotify(0); } else if ( posSashNew == GetWindowSize() ) { // We remove the second window from the view wxWindow *removedWindow = m_windowTwo; m_windowTwo = NULL; OnUnsplit(removedWindow); wxSplitterEvent eventUnsplit(wxEVT_SPLITTER_UNSPLIT, this); eventUnsplit.m_data.win = removedWindow; (void)DoSendEvent(eventUnsplit); SetSashPositionAndNotify(0); } else { SetSashPositionAndNotify(posSashNew); } } else { SetSashPositionAndNotify(posSashNew); } SizeWindows(); } // left up && dragging else if ((event.Moving() || event.Leaving() || event.Entering()) && (m_dragMode == wxSPLIT_DRAG_NONE)) { if ( event.Leaving() || !SashHitTest(x, y) ) OnLeaveSash(); else OnEnterSash(); } else if (event.Dragging() && (m_dragMode == wxSPLIT_DRAG_DRAGGING)) { int diff = m_splitMode == wxSPLIT_VERTICAL ? x - m_ptStart.x : y - m_ptStart.y; int posSashNew = OnSashPositionChanging(m_sashStart + diff); if ( posSashNew == -1 ) { // change not allowed return; } if ( !isLive ) { if ( posSashNew == m_sashPositionCurrent ) return; m_sashPositionCurrent = posSashNew; // Erase old tracker DrawSashTracker(m_oldX, m_oldY); m_oldX = (m_splitMode == wxSPLIT_VERTICAL ? m_sashPositionCurrent : x); m_oldY = (m_splitMode != wxSPLIT_VERTICAL ? m_sashPositionCurrent : y); #ifdef __WXMSW__ // As we captured the mouse, we may get the mouse events from outside // our window - for example, negative values in x, y. This has a weird // consequence under MSW where we use unsigned values sometimes and // signed ones other times: the coordinates turn as big positive // numbers and so the sash is drawn on the *right* side of the window // instead of the left (or bottom instead of top). Correct this. if ( (short)m_oldX < 0 ) m_oldX = 0; if ( (short)m_oldY < 0 ) m_oldY = 0; #endif // __WXMSW__ // Draw new one DrawSashTracker(m_oldX, m_oldY); } else { if ( posSashNew == m_sashPosition ) return; DoSetSashPosition(posSashNew); // in live mode, the new position is the actual sash position, clear requested position! m_requestedSashPosition = INT_MAX; m_needUpdating = true; } } else if ( event.LeftDClick() && m_windowTwo ) { OnDoubleClickSash(x, y); } else { event.Skip(); } }
void wxSashWindow::OnMouseEvent(wxMouseEvent& event) { wxCoord x = 0, y = 0; event.GetPosition(&x, &y); wxSashEdgePosition sashHit = SashHitTest(x, y); if (event.LeftDown()) { CaptureMouse(); m_mouseCaptured = true; if ( sashHit != wxSASH_NONE ) { // Required for X to specify that // that we wish to draw on top of all windows // - and we optimise by specifying the area // for creating the overlap window. // Find the first frame or dialog and use this to specify // the area to draw on. wxWindow* parent = this; while (parent && !parent->IsKindOf(CLASSINFO(wxDialog)) && !parent->IsKindOf(CLASSINFO(wxFrame))) parent = parent->GetParent(); wxScreenDC::StartDrawingOnTop(parent); // We don't say we're dragging yet; we leave that // decision for the Dragging() branch, to ensure // the user has dragged a little bit. m_dragMode = wxSASH_DRAG_LEFT_DOWN; m_draggingEdge = sashHit; m_firstX = x; m_firstY = y; if ( (sashHit == wxSASH_LEFT) || (sashHit == wxSASH_RIGHT) ) { if (m_currentCursor != m_sashCursorWE) { SetCursor(*m_sashCursorWE); } m_currentCursor = m_sashCursorWE; } else { if (m_currentCursor != m_sashCursorNS) { SetCursor(*m_sashCursorNS); } m_currentCursor = m_sashCursorNS; } } } else if ( event.LeftUp() && m_dragMode == wxSASH_DRAG_LEFT_DOWN ) { // Wasn't a proper drag if (m_mouseCaptured) ReleaseMouse(); m_mouseCaptured = false; wxScreenDC::EndDrawingOnTop(); m_dragMode = wxSASH_DRAG_NONE; m_draggingEdge = wxSASH_NONE; } else if (event.LeftUp() && m_dragMode == wxSASH_DRAG_DRAGGING) { // We can stop dragging now and see what we've got. m_dragMode = wxSASH_DRAG_NONE; if (m_mouseCaptured) ReleaseMouse(); m_mouseCaptured = false; // Erase old tracker DrawSashTracker(m_draggingEdge, m_oldX, m_oldY); // End drawing on top (frees the window used for drawing // over the screen) wxScreenDC::EndDrawingOnTop(); int w, h; GetSize(&w, &h); int xp, yp; GetPosition(&xp, &yp); wxSashEdgePosition edge = m_draggingEdge; m_draggingEdge = wxSASH_NONE; wxRect dragRect; wxSashDragStatus status = wxSASH_STATUS_OK; // the new height and width of the window - if -1, it didn't change int newHeight = wxDefaultCoord, newWidth = wxDefaultCoord; // NB: x and y may be negative and they're relative to the sash window // upper left corner, while xp and yp are expressed in the parent // window system of coordinates, so adjust them! After this // adjustment, all coordinates are relative to the parent window. y += yp; x += xp; switch (edge) { case wxSASH_TOP: if ( y > yp + h ) { // top sash shouldn't get below the bottom one status = wxSASH_STATUS_OUT_OF_RANGE; } else { newHeight = h - (y - yp); } break; case wxSASH_BOTTOM: if ( y < yp ) { // bottom sash shouldn't get above the top one status = wxSASH_STATUS_OUT_OF_RANGE; } else { newHeight = y - yp; } break; case wxSASH_LEFT: if ( x > xp + w ) { // left sash shouldn't get beyond the right one status = wxSASH_STATUS_OUT_OF_RANGE; } else { newWidth = w - (x - xp); } break; case wxSASH_RIGHT: if ( x < xp ) { // and the right sash, finally, shouldn't be beyond the // left one status = wxSASH_STATUS_OUT_OF_RANGE; } else { newWidth = x - xp; } break; case wxSASH_NONE: // can this happen at all? break; } if ( newHeight == wxDefaultCoord ) { // didn't change newHeight = h; } else { // make sure it's in m_minimumPaneSizeY..m_maximumPaneSizeY range newHeight = wxMax(newHeight, m_minimumPaneSizeY); newHeight = wxMin(newHeight, m_maximumPaneSizeY); } if ( newWidth == wxDefaultCoord ) { // didn't change newWidth = w; } else { // make sure it's in m_minimumPaneSizeY..m_maximumPaneSizeY range newWidth = wxMax(newWidth, m_minimumPaneSizeX); newWidth = wxMin(newWidth, m_maximumPaneSizeX); } dragRect = wxRect(x, y, newWidth, newHeight); wxSashEvent eventSash(GetId(), edge); eventSash.SetEventObject(this); eventSash.SetDragStatus(status); eventSash.SetDragRect(dragRect); GetEventHandler()->ProcessEvent(eventSash); } else if ( event.LeftUp() ) { if (m_mouseCaptured) ReleaseMouse(); m_mouseCaptured = false; } else if ((event.Moving() || event.Leaving()) && !event.Dragging()) { // Just change the cursor if required if ( sashHit != wxSASH_NONE ) { if ( (sashHit == wxSASH_LEFT) || (sashHit == wxSASH_RIGHT) ) { if (m_currentCursor != m_sashCursorWE) { SetCursor(*m_sashCursorWE); } m_currentCursor = m_sashCursorWE; } else { if (m_currentCursor != m_sashCursorNS) { SetCursor(*m_sashCursorNS); } m_currentCursor = m_sashCursorNS; } } else { SetCursor(wxNullCursor); m_currentCursor = NULL; } } else if ( event.Dragging() && ((m_dragMode == wxSASH_DRAG_DRAGGING) || (m_dragMode == wxSASH_DRAG_LEFT_DOWN)) ) { if ( (m_draggingEdge == wxSASH_LEFT) || (m_draggingEdge == wxSASH_RIGHT) ) { if (m_currentCursor != m_sashCursorWE) { SetCursor(*m_sashCursorWE); } m_currentCursor = m_sashCursorWE; } else { if (m_currentCursor != m_sashCursorNS) { SetCursor(*m_sashCursorNS); } m_currentCursor = m_sashCursorNS; } if (m_dragMode == wxSASH_DRAG_LEFT_DOWN) { m_dragMode = wxSASH_DRAG_DRAGGING; DrawSashTracker(m_draggingEdge, x, y); } else { if ( m_dragMode == wxSASH_DRAG_DRAGGING ) { // Erase old tracker DrawSashTracker(m_draggingEdge, m_oldX, m_oldY); // Draw new one DrawSashTracker(m_draggingEdge, x, y); } } m_oldX = x; m_oldY = y; } else if ( event.LeftDClick() ) { // Nothing } else { } }