Пример #1
0
//
// 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
}
Пример #2
0
//
// 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
}