void DragUtil::TrackerMoveListener::ControlMoved( GuiTk::ControlEvent::Pointer event) { // Get the curslor location as a point Point location(event->x, event->y); // Select a drop target; use the global one by default IDropTarget::Pointer target; void* targetControl = Tweaklets::Get(GuiWidgetsTweaklet::KEY)->GetCursorControl(); // Get the ITracker which fired the event ITracker* tracker = static_cast<ITracker*> (event->item); // Get the drop target for this location target = DragUtil::GetDropTarget(targetControl, draggedItem, location, tracker->GetRectangle()); // Set up the tracker feedback based on the target Rectangle snapTarget; if (target != 0) { snapTarget = target->GetSnapRectangle(); tracker->SetCursor(target->GetCursor()); } else { tracker->SetCursor(DnDTweaklet::CURSOR_INVALID); } // If snapping then reset the tracker's rectangle based on the current drop target if (allowSnapping) { if (snapTarget.width == 0 || snapTarget.height == 0) { snapTarget = Rectangle(sourceBounds.x + location.x - initialLocation.x, sourceBounds.y + location.y - initialLocation.y, sourceBounds.width, sourceBounds.height); } // Try to prevent flicker: don't change the rectangles if they're already in // the right location Rectangle currentRectangle = tracker->GetRectangle(); if (!(currentRectangle == snapTarget)) { tracker->SetRectangle(snapTarget); } } }
void QtTrackerMoveListener::Moved(QtTracker* tracker, const QPoint& location) { // Select a drop target; use the global one by default IDropTarget::Pointer target; QWidget* targetControl = Tweaklets::Get(GuiWidgetsTweaklet::KEY)->GetCursorControl(); // Get the drop target for this location target = DragUtil::GetDropTarget(targetControl, draggedItem, location, tracker->GetRectangle()); // Set up the tracker feedback based on the target QRect snapTarget; if (target != 0) { snapTarget = target->GetSnapRectangle(); tracker->SetCursor(target->GetCursor()); } else { tracker->SetCursor(CURSOR_INVALID); } // If snapping then reset the tracker's rectangle based on the current drop target if (allowSnapping) { if (snapTarget.width() < 0 || snapTarget.height() < 0) { snapTarget = QRect(sourceBounds.x() + location.x() - initialLocation.x(), sourceBounds.y() + location.y() - initialLocation.y(), sourceBounds.width(), sourceBounds.height()); } // Try to prevent flicker: don't change the rectangles if they're already in // the right location QRect currentRectangle = tracker->GetRectangle(); if (!(currentRectangle == snapTarget)) { tracker->SetRectangle(snapTarget); } } }
bool DragUtil::PerformDrag(Object::Pointer draggedItem, const Rectangle& sourceBounds, const Point& initialLocation, bool allowSnapping) { IDropTarget::Pointer target = DragToTarget(draggedItem, sourceBounds, initialLocation, allowSnapping); if (target == 0) { return false; } target->Drop(); target->DragFinished(true); return true; }
IDropTarget::Pointer DragUtil::DragToTarget(Object::Pointer draggedItem, const Rectangle& sourceBounds, const Point& initialLocation, bool allowSnapping) { //final Display display = Display.getCurrent(); // Testing...immediately 'drop' onto the test target if (forcedDropTarget != 0) { Point location = forcedDropTarget->GetLocation(); void* currentControl = Tweaklets::Get(GuiWidgetsTweaklet::KEY)->FindControl( forcedDropTarget->GetShells(), location); return GetDropTarget(currentControl, draggedItem, location, sourceBounds); } // Create a tracker. This is just an XOR rect on the screen. // As it moves we notify the drag listeners. ITracker* tracker = Tweaklets::Get(DnDTweaklet::KEY)->CreateTracker(); //tracker.setStippled(true); GuiTk::IControlListener::Pointer trackerListener(new TrackerMoveListener( draggedItem, sourceBounds, initialLocation, allowSnapping)); tracker->AddControlListener(trackerListener); // Setup...when the drag starts we might already be over a valid target, check this... // If there is a 'global' target then skip the check IDropTarget::Pointer target; void* startControl = Tweaklets::Get(GuiWidgetsTweaklet::KEY)->GetCursorControl(); if (startControl != 0 && allowSnapping) { target = GetDropTarget(startControl, draggedItem, initialLocation, sourceBounds); } // Set up an initial tracker rectangle Rectangle startRect = sourceBounds; if (target != 0) { Rectangle rect = target->GetSnapRectangle(); if (rect.width != 0 && rect.height != 0) { startRect = rect; } tracker->SetCursor(target->GetCursor()); } if (startRect.width != 0 && startRect.height != 0) { tracker->SetRectangle(startRect); } // Tracking Loop...tracking is preformed on the 'SWT.Move' listener registered // against the tracker. // // HACK: // // Some control needs to capture the mouse during the drag or other // // controls will interfere with the cursor // Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); // if (shell != null) // { // shell.setCapture(true); // } // Run tracker until mouse up occurs or escape key pressed. bool trackingOk = tracker->Open(); // // HACK: // // Release the mouse now // if (shell != null) // { // shell.setCapture(false); // } // Done tracking... // Get the current drop target IDropTarget::Pointer dropTarget; Point finalLocation = Tweaklets::Get(GuiWidgetsTweaklet::KEY)->GetCursorLocation(); void* targetControl = Tweaklets::Get(GuiWidgetsTweaklet::KEY)->GetCursorControl(); dropTarget = GetDropTarget(targetControl, draggedItem, finalLocation, tracker->GetRectangle()); // Cleanup... delete tracker; // if we're going to perform a 'drop' then delay the issuing of the 'finished' // callback until after it's done... if (trackingOk) { return dropTarget; } else if (dropTarget != 0) { // If the target can handle a 'finished' notification then send one dropTarget->DragFinished(false); } return IDropTarget::Pointer(0); }