// // Handle toolbar dragging // void ToolManager::OnMouse( wxMouseEvent & event ) { // Go ahead and set the event to propagate event.Skip(); // Can't do anything if we're not dragging. This also prevents // us from intercepting events that don't belong to us from the // parent since we're Connect()ed to a couple. if( !mDragWindow ) { return; } #if defined(__WXMAC__) // Disable window animation wxSystemOptions::SetOption( wxMAC_WINDOW_PLAIN_TRANSITION, 1 ); #endif // Retrieve the event position wxPoint pos = ( (wxWindow *)event.GetEventObject() )->ClientToScreen( event.GetPosition() ); // Button was released...finish the drag if( !event.LeftIsDown() ) { // Release capture if( mParent->HasCapture() ) { mParent->ReleaseMouse(); } // Hide the indicator mIndicator->Hide(); // Transition the bar to a dock if( mDragDock && !event.ShiftDown() ) { // Trip over...everyone ashore that's going ashore... mDragDock->Dock( mDragBar, mDragBefore ); // Done with the floater mDragWindow->Destroy(); mDragBar->Refresh(false); } else { // Calling SetDocked() to force the grabber button to popup mDragBar->SetDocked( NULL, false ); } // Done dragging mDragWindow = NULL; mDragDock = NULL; mDragBar = NULL; mLastPos.x = mBarPos.x = -1; mLastPos.y = mBarPos.y = -1; mTimer.Stop(); } else if( event.Dragging() && pos != mLastPos ) { // Make toolbar follow the mouse mDragWindow->Move( pos - mDragOffset ); // Remember to prevent excessive movement mLastPos = pos; // Calc the top dock hittest rectangle wxRect tr = mTopDock->GetRect(); tr.SetBottom( tr.GetBottom() + 10 ); tr.SetPosition( mTopDock->GetParent()->ClientToScreen( tr.GetPosition() ) ); // Calc the bottom dock hittest rectangle wxRect br = mBotDock->GetRect(); br.SetTop( br.GetTop() - 10 ); br.SetBottom( br.GetBottom() + 20 ); br.SetPosition( mBotDock->GetParent()->ClientToScreen( br.GetPosition() ) ); // Is mouse pointer within either dock? ToolDock *dock = NULL; if( tr.Contains( pos ) ) { dock = mTopDock; } else if( br.Contains( pos ) ) { dock = mBotDock; } // Looks like we have a winner... if( dock ) { wxPoint p; wxRect r; // Calculate where the bar would be placed mDragBefore = dock->PositionBar( mDragBar, pos, r ); // If different than the last time, the indicator must be moved if( r != mBarPos ) { wxRect dr = dock->GetRect(); // Hide the indicator before changing the shape mIndicator->Hide(); // Decide which direction the arrow should point if( r.GetBottom() >= dr.GetHeight() ) { p.x = dr.GetLeft() + ( dr.GetWidth() / 2 ); p.y = dr.GetBottom() - mDown->GetBox().GetHeight(); mCurrent = mDown; } else { p.x = dr.GetLeft() + r.GetLeft(); p.y = dr.GetTop() + r.GetTop() + ( ( r.GetHeight() - mLeft->GetBox().GetHeight() ) / 2 ); mCurrent = mLeft; } // Change the shape while hidden and then show it if okay mIndicator->SetShape( *mCurrent ); if( !event.ShiftDown() ) { mIndicator->Show(); mIndicator->Update(); } // Move it into position // LL: Do this after the Show() since KDE doesn't move the window // if it's not shown. (Do it outside if the previous IF as well) mIndicator->Move( dock->GetParent()->ClientToScreen( p ) ); // Remember for next go round mBarPos = r; } } else { // Hide the indicator if it's still shown if( mBarPos.x != -1 ) { // Hide any mIndicator->Hide(); mBarPos.x = -1; mBarPos.y = -1; } } // Remember to which dock the drag bar belongs. mDragDock = dock; } #if defined(__WXMAC__) // Reinstate original transition wxSystemOptions::SetOption( wxMAC_WINDOW_PLAIN_TRANSITION, mTransition ); #endif }
// // Handle toolbar dragging // void ToolManager::OnMouse( wxMouseEvent & event ) { // Go ahead and set the event to propagate event.Skip(); // Can't do anything if we're not dragging. This also prevents // us from intercepting events that don't belong to us from the // parent since we're Connect()ed to a couple. if( !mDragWindow ) { return; } #if defined(__WXMAC__) // Disable window animation wxSystemOptions::SetOption( wxMAC_WINDOW_PLAIN_TRANSITION, 1 ); #endif // Retrieve the event position wxPoint pos = ( (wxWindow *)event.GetEventObject() )->ClientToScreen( event.GetPosition() ) - mDragOffset; // Button was released...finish the drag if( !event.LeftIsDown() ) { // Transition the bar to a dock if( mDragDock && !event.ShiftDown() ) { // Trip over...everyone ashore that's going ashore... mDragDock->Dock( mDragBar, true, mDragBefore ); mDragWindow->ClearBar(); // Done with the floater mDragWindow->Destroy(); mDragWindow = nullptr; mDragBar->Refresh(false); } else { // Calling SetDocked() to force the grabber button to popup mDragBar->SetDocked( NULL, false ); } DoneDragging(); } else if( event.Dragging() && pos != mLastPos ) { // Make toolbar follow the mouse mDragWindow->Move( pos ); // Remember to prevent excessive movement mLastPos = pos; // Calc the top dock hittest rectangle wxRect tr = mTopDock->GetRect(); tr.SetBottom( tr.GetBottom() + 10 ); tr.SetPosition( mTopDock->GetParent()->ClientToScreen( tr.GetPosition() ) ); // Calc the bottom dock hittest rectangle wxRect br = mBotDock->GetRect(); br.SetTop( br.GetTop() - 10 ); br.SetBottom( br.GetBottom() + 20 ); br.SetPosition( mBotDock->GetParent()->ClientToScreen( br.GetPosition() ) ); // Add half the bar height. We could use the actual bar height, but that would be confusing as a // bar removed at a place might not dock back there if just let go. // Also add 5 pixels in horizontal direction, so that a click without a move (or a very small move) // lands back where we started. pos += wxPoint( 5, 20 ); // To find which dock, rather than test against pos, test against the whole dragger rect. // This means it is enough to overlap the dock to dock with it. wxRect barRect = mDragWindow->GetRect(); ToolDock *dock = NULL; if( tr.Intersects( barRect ) ) dock = mTopDock; else if( br.Intersects( barRect ) ) dock = mBotDock; // Looks like we have a winner... if( dock ) { wxPoint p; wxRect r; // Calculate where the bar would be placed mDragBefore = dock->PositionBar( mDragBar, pos, r ); // If different than the last time, the indicator must be moved if( r != mBarPos ) { wxRect dr = dock->GetRect(); // Hide the indicator before changing the shape mIndicator->Hide(); // Decide which direction the arrow should point if( r.GetTop() >= dr.GetHeight() ) { const auto &box = mDown->GetBox(); p.x = dr.GetLeft() + ( dr.GetWidth() / 2 ) - (box.GetWidth() / 2); p.y = dr.GetBottom() - box.GetHeight(); mCurrent = mDown.get(); } else { p.x = dr.GetLeft() + r.GetLeft(); p.y = dr.GetTop() + r.GetTop() + ( ( r.GetHeight() - mLeft->GetBox().GetHeight() ) / 2 ); mCurrent = mLeft.get(); } // Change the shape while hidden and then show it if okay mIndicator->SetShape( *mCurrent ); if( !event.ShiftDown() ) { mIndicator->Show(); mIndicator->Update(); } // Move it into position // LL: Do this after the Show() since KDE doesn't move the window // if it's not shown. (Do it outside if the previous IF as well) mIndicator->Move( dock->GetParent()->ClientToScreen( p ) ); // Remember for next go round mBarPos = r; } } else { // Hide the indicator if it's still shown if( mBarPos.x != -1 ) { // Hide any mIndicator->Hide(); mBarPos.x = -1; mBarPos.y = -1; } } // Remember to which dock the drag bar belongs. mDragDock = dock; } #if defined(__WXMAC__) // Reinstate original transition wxSystemOptions::SetOption( wxMAC_WINDOW_PLAIN_TRANSITION, mTransition ); #endif }