Exemplo n.º 1
0
void ToolManager::Reset()
{
   int ndx;

   // Disconnect all docked bars
   for( ndx = 0; ndx < ToolBarCount; ndx++ )
   {
      wxWindow *parent;
      ToolDock *dock;
      ToolBar *bar = mBars[ ndx ];

      // Disconnect the bar
      if( bar->IsDocked() )
      {
         bar->GetDock()->Undock( bar );
         parent = NULL;
      }
      else
      {
         parent = bar->GetParent();
      }

      if( ndx == SelectionBarID )
      {
         dock = mBotDock;

         wxCommandEvent e;
         bar->GetEventHandler()->ProcessEvent(e);
      }
      else
      {
         dock = mTopDock;
         bar->ReCreateButtons();
      }

      bar->EnableDisableButtons();
#if 0
      if( bar->IsResizable() )
      {
         bar->SetSize(bar->GetBestFittingSize());
      }
#endif
      dock->Dock( bar );

      Expose( ndx, ndx ==  DeviceBarID ? false : true );

      if( parent )
      {
         parent->Destroy();
      }
   }

   LayoutToolBars();
   Updated();
} 
Exemplo n.º 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() );

   // 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
}
Exemplo n.º 3
0
//
// Read the toolbar states
//
void ToolManager::ReadConfig()
{
   wxString oldpath = gPrefs->GetPath();
   wxArrayInt unordered[ DockCount ];
   int order[ DockCount ][ ToolBarCount ];
   bool show[ ToolBarCount ];
   int width[ ToolBarCount ];
   int height[ ToolBarCount ];
   int x, y;
   int dock, ord, ndx;

#if defined(__WXMAC__)
   // Disable window animation
   wxSystemOptions::SetOption( wxMAC_WINDOW_PLAIN_TRANSITION, 1 );
#endif

   // Invalidate all order entries
   for( dock = 0; dock < DockCount; dock++ )
   {
      for( ord = 0; ord < ToolBarCount; ord++ )
      {
         order[ dock ][ ord ] = NoBarID;
      }
   }

   // Change to the bar root
   gPrefs->SetPath( wxT("/GUI/ToolBars") );

   // Load and apply settings for each bar
   for( ndx = 0; ndx < ToolBarCount; ndx++ )
   {
      ToolBar *bar = mBars[ ndx ];

      // Change to the bar subkey
      gPrefs->SetPath( bar->GetSection() );

      // Read in all the settings
      gPrefs->Read( wxT("Dock"), &dock, ndx == SelectionBarID ? BotDockID : TopDockID );
      gPrefs->Read( wxT("Order"), &ord, NoBarID );
      gPrefs->Read( wxT("Show"), &show[ ndx ], true );

      gPrefs->Read( wxT("X"), &x, -1 );
      gPrefs->Read( wxT("Y"), &y, -1 );
      gPrefs->Read( wxT("W"), &width[ ndx ], -1 );
      gPrefs->Read( wxT("H"), &height[ ndx ], -1 );

      // Docked or floating?
      if( dock )
      {
         // Default to top dock if the ID isn't valid
         if( dock < NoDockID || dock > DockCount ) {
            dock = TopDockID;
         }

         // Create the bar with the correct parent
         if( dock == TopDockID )
         {
            bar->Create( mTopDock );
         }
         else
         {
            bar->Create( mBotDock );
         }

#ifdef EXPERIMENTAL_SYNC_LOCK
         // Set the width
         if( width[ ndx ] >= bar->GetSize().x )
         {
            wxSize sz( width[ ndx ], bar->GetSize().y );
            bar->SetSize( sz );
            bar->Layout();
         }
#else
         // note that this section is here because if you had been using sync-lock and now you aren't,
         // the space for the extra button is stored in audacity.cfg, and so you get an extra space
         // in the EditToolbar.
         // It is needed so that the meterToolbar size gets preserved.
         // Longer-term we should find a better fix for this.
         wxString thisBar = bar->GetSection();
         if( thisBar != wxT("Edit"))
         {
            // Set the width
            if( width[ ndx ] >= bar->GetSize().x )
            {
               wxSize sz( width[ ndx ], bar->GetSize().y );
               bar->SetSize( sz );
               bar->Layout();
            }
         }
#endif
         // Is order within range and unoccupied?
         if( ( ord >= 0 ) &&
             ( ord < ToolBarCount ) &&
             ( order[ dock - 1 ][ ord ] == NoBarID ) )
         {
            // Insert at ordered location
            order[ dock - 1 ][ ord ] = ndx;
         }
         else
         {
            // These must go at the end
            unordered[ dock - 1 ].Add( ndx );
         }
      }
      else
      {
         // Create the bar (with the top dock being temporary parent)
         bar->Create( mTopDock );

         // Construct a new floater
         ToolFrame *f = new ToolFrame( mParent, this, bar, wxPoint( x, y ) );

         // Set the width and height
         if( width[ ndx ] != -1 && height[ ndx ] != -1 )
         {
            wxSize sz( width[ ndx ], height[ ndx ] );
            f->SetSizeHints( sz );
            f->SetSize( sz );
            f->Layout();
         }

         // Show or hide it
         bar->Expose( show[ ndx ] );

         // Inform toolbar of change
         bar->SetDocked( NULL, false );
      }

      // Change back to the bar root
      //gPrefs->SetPath( wxT("..") );  <-- Causes a warning...
      // May or may not have gone into a subdirectory,
      // so use an absolute path.
      gPrefs->SetPath( wxT("/GUI/ToolBars") );
   }

   // Add all toolbars to their target dock
   for( dock = 0; dock < DockCount; dock++ )
   {
      ToolDock *d = ( dock + 1 == TopDockID ? mTopDock : mBotDock );

      // Add all ordered toolbars
      for( ord = 0; ord < ToolBarCount; ord++ )
      {
         ndx = order[ dock ][ ord ];

         // Bypass empty slots
         if( ndx != NoBarID )
         {
            ToolBar *t = mBars[ ndx ];

            // Dock it
            d->Dock( t );

            // Hide the bar
            if( !show[ t->GetId() ] )
            {
               d->ShowHide( t->GetId() );
            }
         }
      }

      // Add all unordered toolbars
      for( ord = 0; ord < (int) unordered[ dock ].GetCount(); ord++ )
      {
         ToolBar *t = mBars[ unordered[ dock ][ ord ] ];

         // Dock it
         d->Dock( t );

         // Hide the bar
         if( !show[ t->GetId() ] )
         {
            d->ShowHide( t->GetId() );
         }
      }
   }

   // Restore original config path
   gPrefs->SetPath( oldpath );

#if defined(__WXMAC__)
   // Reinstate original transition
   wxSystemOptions::SetOption( wxMAC_WINDOW_PLAIN_TRANSITION, mTransition );
#endif
}
Exemplo n.º 4
0
void ToolManager::Reset()
{
   int ndx;

   // The mInputMeter and mOutputMeter may be in use if audio is playing
   // when this happens.
   gAudioIO->SetMeters( NULL, NULL );

   // Disconnect all docked bars
   for( ndx = 0; ndx < ToolBarCount; ndx++ )
   {
      wxWindow *parent;
      ToolDock *dock;
      ToolBar *bar = mBars[ ndx ];

      // Disconnect the bar
      if( bar->IsDocked() )
      {
         bar->GetDock()->Undock( bar );
         parent = NULL;
      }
      else
      {
         parent = bar->GetParent();
      }

      if( ndx == SelectionBarID )
      {
         dock = mBotDock;

         wxCommandEvent e;
         bar->GetEventHandler()->ProcessEvent(e);
      }
      else
      {
         dock = mTopDock;
         bar->ReCreateButtons();
      }

      bar->EnableDisableButtons();
#if 0
      if( bar->IsResizable() )
      {
         bar->SetSize(bar->GetBestFittingSize());
      }
#endif
      dock->Dock( bar );

      Expose( ndx, true );

      if( parent )
      {
         parent->Destroy();
      }
   }
   // TODO:??
   // If audio was playing, we stopped the VU meters,
   // It would be nice to show them again, but hardly essential as
   // they will show up again on the next play.
   // SetVUMeters(AudacityProject *p);
   LayoutToolBars();
   Updated();
}
Exemplo n.º 5
0
//
// Read the toolbar states
//
void ToolManager::ReadConfig()
{
   wxString oldpath = gPrefs->GetPath();
   wxArrayInt unordered[ DockCount ];
   bool show[ ToolBarCount ];
   int width[ ToolBarCount ];
   int height[ ToolBarCount ];
   int x, y;
   int dock, ndx;
   bool someFound { false };

#if defined(__WXMAC__)
   // Disable window animation
   wxSystemOptions::SetOption( wxMAC_WINDOW_PLAIN_TRANSITION, 1 );
#endif

   // Change to the bar root
   gPrefs->SetPath( wxT("/GUI/ToolBars") );

   ToolBarConfiguration::Legacy topLegacy, botLegacy;

   // Load and apply settings for each bar
   for( ndx = 0; ndx < ToolBarCount; ndx++ )
   {
      ToolBar *bar = mBars[ ndx ].get();
      //wxPoint Center = mParent->GetPosition() + (mParent->GetSize() * 0.33);
      //wxPoint Center( 
      //   wxSystemSettings::GetMetric( wxSYS_SCREEN_X ) /2 ,
      //   wxSystemSettings::GetMetric( wxSYS_SCREEN_Y ) /2 );

      // Change to the bar subkey
      gPrefs->SetPath( bar->GetSection() );

      bool bShownByDefault = true;
      int defaultDock = TopDockID;
      
      if( ndx == SelectionBarID )
         defaultDock = BotDockID;
      if( ndx == MeterBarID )
         bShownByDefault = false;
      if( ndx == ScrubbingBarID )
         bShownByDefault = false;

#ifdef EXPERIMENTAL_SPECTRAL_EDITING
      if( ndx == SpectralSelectionBarID ){
         defaultDock = BotDockID;
         bShownByDefault = false; // Only show if asked for.  
      }
#endif

      // Read in all the settings
      gPrefs->Read( wxT("Dock"), &dock, -1);
      const bool found = (dock != -1);
      if (found)
         someFound = true;
      if (!found)
         dock = defaultDock;
      
      ToolDock *d;
      ToolBarConfiguration::Legacy *pLegacy;
      switch(dock)
      {
         case TopDockID: d = mTopDock; pLegacy = &topLegacy; break;
         case BotDockID: d = mBotDock; pLegacy = &botLegacy;  break;
         default:        d = nullptr; pLegacy = nullptr; break;
      }

      bool ordered = ToolBarConfiguration::Read
         (d ? &d->GetConfiguration() : nullptr,
          pLegacy,
          bar, show[ ndx ], bShownByDefault)
      && found;

      gPrefs->Read( wxT("X"), &x, -1 );
      gPrefs->Read( wxT("Y"), &y, -1 );
      gPrefs->Read( wxT("W"), &width[ ndx ], -1 );
      gPrefs->Read( wxT("H"), &height[ ndx ], -1 );

      bar->SetVisible( show[ ndx ] );

      // Docked or floating?
      if( dock )
      {
         // Default to top dock if the ID isn't valid
         if( dock < NoDockID || dock > DockCount ) {
            dock = TopDockID;
         }

         // Create the bar with the correct parent
         if( dock == TopDockID )
         {
            bar->Create( mTopDock );
         }
         else
         {
            bar->Create( mBotDock );
         }

         // Set the width and height
         if( width[ ndx ] != -1 && height[ ndx ] != -1 )
         {
            wxSize sz( width[ ndx ], height[ ndx ] );
            bar->SetSize( sz );
         }

#ifdef EXPERIMENTAL_SYNC_LOCK
         // Set the width
         if( width[ ndx ] >= bar->GetSize().x )
         {
            wxSize sz( width[ ndx ], bar->GetSize().y );
            bar->SetSize( sz );
            bar->Layout();
         }
#else
         // note that this section is here because if you had been using sync-lock and now you aren't,
         // the space for the extra button is stored in audacity.cfg, and so you get an extra space
         // in the EditToolbar.
         // It is needed so that the meterToolbar size gets preserved.
         // Longer-term we should find a better fix for this.
         wxString thisBar = bar->GetSection();
         if( thisBar != wxT("Edit"))
         {
            // Set the width
            if( width[ ndx ] >= bar->GetSize().x )
            {
               wxSize sz( width[ ndx ], bar->GetSize().y );
               bar->SetSize( sz );
               bar->Layout();
            }
         }
#endif

         if (!ordered)
         {
            // These must go at the end
            unordered[ dock - 1 ].Add( ndx );
         }
      }
      else
      {
         // Create the bar (with the top dock being temporary parent)
         bar->Create( mTopDock );

         // Construct a NEW floater
         wxASSERT(mParent);
         ToolFrame *f = safenew ToolFrame( mParent, this, bar, wxPoint( x, y ) );

         // Set the width and height
         if( width[ ndx ] != -1 && height[ ndx ] != -1 )
         {
            wxSize sz( width[ ndx ], height[ ndx ] );
            f->SetSizeHints( sz );
            f->SetSize( sz );
            f->Layout();
            if( (x!=-1) && (y!=-1) )
               bar->SetPositioned();
         }

         // Required on Linux Xfce
         wxSize msz(width[ndx],height[ndx]-1);
         bar->GetParent()->SetMinSize(msz);

         // Inform toolbar of change
         bar->SetDocked( NULL, false );

         // Show or hide it
         Expose( ndx, show[ ndx ] );
      }

      // Change back to the bar root
      //gPrefs->SetPath( wxT("..") );  <-- Causes a warning...
      // May or may not have gone into a subdirectory,
      // so use an absolute path.
      gPrefs->SetPath( wxT("/GUI/ToolBars") );
   }

   mTopDock->GetConfiguration().PostRead(topLegacy);
   mBotDock->GetConfiguration().PostRead(botLegacy);

   // Add all toolbars to their target dock
   for( dock = 0; dock < DockCount; dock++ )
   {
      ToolDock *d = ( dock + 1 == TopDockID ? mTopDock : mBotDock );

      d->LoadConfig();

      // Add all unordered toolbars
      bool deviceWasPositioned = false;
      for( int ord = 0; ord < (int) unordered[ dock ].GetCount(); ord++ )
      {
         ToolBar *t = mBars[ unordered[ dock ][ ord ] ].get();

         if (deviceWasPositioned &&
             t->GetType() == DeviceBarID)
            continue;

         if (someFound &&
             t->GetType() == ScrubbingBarID) {
            // Special case code to put the NEW scrubbing toolbar where we
            // want it, when audacity.cfg is present from an older version
            ToolBar *lastRoot {};

            // Change from the ideal configuration to the constrained one,
            // just as when dragging and dropping
            ToolBarConfiguration dummy;
            mTopDock->WrapConfiguration(dummy);

            // Start a NEW row with just the scrubbing toolbar
            auto &configuration = mTopDock->GetConfiguration();
            for (const auto place : configuration)
               if (place.position.rightOf == nullptr)
                  lastRoot = place.pTree->pBar;
            ToolBarConfiguration::Position position {
               nullptr, lastRoot, false
            };
            mTopDock->Dock(t, false, position);

            // Reposition the device toolbar, if it was docked above,
            // right of scrubbing
            const auto deviceToolBar = mBars[ DeviceBarID ].get();
            if (deviceToolBar->GetDock() == mTopDock) {
               deviceToolBar->GetDock()->Undock(deviceToolBar);
               position = { t, nullptr };
               mTopDock->Dock(deviceToolBar, false, position);

               // Remember not to place the device toolbar again
               deviceWasPositioned = true;
            }
            Expose( t->GetId(), show[ t->GetId() ] );
            continue;
         }

         // Dock it
         d->Dock( t, false );

         // Show or hide the bar
         Expose( t->GetId(), show[ t->GetId() ] );
      }
   }

   // Restore original config path
   gPrefs->SetPath( oldpath );

#if defined(__WXMAC__)
   // Reinstate original transition
   wxSystemOptions::SetOption( wxMAC_WINDOW_PLAIN_TRANSITION, mTransition );
#endif

   if (!someFound)
      Reset();
}
Exemplo n.º 6
0
void ToolManager::Reset()
{
   // Disconnect all docked bars
   for ( const auto &entry : DefaultConfigTable )
   {
      int ndx = entry.barID;
      ToolBar *bar = mBars[ ndx ].get();

      ToolBarConfiguration::Position position {
         (entry.rightOf == NoBarID) ? nullptr : mBars[ entry.rightOf ].get(),
         (entry.below == NoBarID) ? nullptr : mBars[ entry.below ].get()
      };

      wxWindow *floater;
      ToolDock *dock;
      bool expose = true;

      // Disconnect the bar
      if( bar->IsDocked() )
      {
         bar->GetDock()->Undock( bar );
         floater = NULL;
      }
      else
      {
         floater = bar->GetParent();
      }

      if (ndx == SelectionBarID 
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
         || ndx == SpectralSelectionBarID
#endif
         )
      {
         dock = mBotDock;

         wxCommandEvent e;
         bar->GetEventHandler()->ProcessEvent(e);
      }
      else
      {
         dock = mTopDock;
         bar->ReCreateButtons();
      }

      bar->EnableDisableButtons();
#if 0
      if( bar->IsResizable() )
      {
         bar->SetSize(bar->GetBestFittingSize());
      }
#endif

      if( ndx == MeterBarID
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
         || ndx == SpectralSelectionBarID
#endif
         || ndx == ScrubbingBarID
         )
      {
         expose = false;
      }

      if( dock != NULL )
      {
         // when we dock, we reparent, so bar is no longer a child of floater.
         dock->Dock( bar, false, position );
         Expose( ndx, expose );
         //OK (and good) to DELETE floater, as bar is no longer in it.
         if( floater )
            floater->Destroy();
      }
      else
      {
         // The (tool)bar has a dragger window round it, the floater.
         // in turn floater will have mParent (the entire App) as its
         // parent.

         // Maybe construct a NEW floater
         // this happens if we have just been bounced out of a dock.
         if( floater == NULL ) {
            wxASSERT(mParent);
            floater = safenew ToolFrame( mParent, this, bar, wxPoint(-1,-1) );
            bar->Reparent( floater );
         }

         // This bar is undocked and invisible.
         // We are doing a reset toolbars, so even the invisible undocked bars should
         // be moved somewhere sensible. Put bar near center of window.
         // If there were multiple hidden toobars the ndx * 10 adjustment means 
         // they won't overlap too much.
         floater->CentreOnParent( );
         floater->Move( floater->GetPosition() + wxSize( ndx * 10 - 200, ndx * 10 ));
         bar->SetDocked( NULL, false );
         Expose( ndx, false );
      }

   }
   // TODO:??
   // If audio was playing, we stopped the VU meters,
   // It would be nice to show them again, but hardly essential as
   // they will show up again on the next play.
   // SetVUMeters(AudacityProject *p);
   LayoutToolBars();
   Updated();
}
Exemplo n.º 7
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
}