PcoWSkbVqDnWTu_dm2ix

Drag and Drop in Studio Widgets

Drag and Drop in Studio Widgets

10 min

Using drag and drop interaction in plugins is a simple way to improve the flow of data in Plugins. Be sure to familiarize yourself with studio widgets by reading the articles/Building Studio Widgets article first!

Creating a Drag Source

A drag action can be started by calling Plugin/StartDrag. This should be done when the user presses a mouse button on some UI element, typically a TextButton or ImageButton within a widget. So, we begin by creating a widget normally: the following code sample creates a single window with a button inside it.

-- Create the widget first
local widgetInfo = DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Float, true, true, 300, 200)
local dragSourceWidget = plugin:CreateDockWidgetPluginGui("Drag Source", widgetInfo)
dragSourceWidget.Title = "Drag Source"

-- Create a TextButton that will initiate the drag
local dragButton = Instance.new("TextButton")
dragButton.Size = UDim2.new(1, 0, 1, 0)
dragButton.Text = "Drag me!"
dragButton.Parent = dragSourceWidget

Initiating the Drag

Immediately when the user clicks on the TextButton, we want the drag to start. Normally for buttons, the GuiButton/Activated|Activated event would be used, but we use GuiButton/MouseButton1Down|MouseButton1Down instead beause it fires as soon as the mouse is pressed, not after it is released.

local function onButton1Down()
	local dragInfo = {
		Data = "Hello, world",      -- The data being dragged
		MimeType = "text/plain",    -- Describes the MIME type of the data
		Sender = "SomeDragSource",  -- Describes from where the data originated
		MouseIcon = "",             -- Image content to use for the cursor
		DragIcon = "",              -- Image content to render under the cursor during drag
		HotSpot = Vector2.new(0, 0) -- Where on the DragIcon to center the cursor
	}
	plugin:StartDrag(dragInfo)
end

dragButton.MouseButton1Down:Connect(onButton1Down)

It is within this function that the data to drag should be determined: its type should be reflectd in the MimeType key, the content of the drag should be within the Data key, and the sender should describe itself in the Sender key. See the Plugin/StartDrag page for more details.

Creating a Drop Target

The PluginGui/PluginDragDropped|PluginDragDropped event fires when the user releases their mouse on a window during a drag. We need a drop target, so create a second widget with a TextLabel to detect drops:

local dragTargetWidget = plugin:CreateDockWidgetPluginGui("Drop Target", widgetInfo)
dragTargetWidget.Title = "Drop Target"

-- This TextLabel will display what was dropped
local textLabel = Instance.new("TextLabel")
textLabel.Size = UDim2.new(1, 0, 1, 0)
textLabel.Text = "Drop here..."
textLabel.Parent = dragTargetWidget

Processing the Drop Action

Then connect the PluginGui/PluginDragDropped|PluginDragDropped event on the drop target widget:

local function onDragDrop(dragData)
	print("PluginDragDropped")
	if dragData.MimeType == "text/plain" then
		textLabel.Text = dragData.Data
	else
		textLabel.Text = dragData.MimeType
	end
end
dragTargetWidget.PluginDragDropped:connect(onDragDrop)

While a drag is still in progress, these three events fire as the user moves their mouse over a widget:

  • PluginGui/PluginDragEntered|PluginDragEntered – fires when the user hovers the mouse over a window
  • PluginGui/PluginDragMoved|PluginDragMoved – fires repeatedly as the user moves their mouse over a window. Useful to show a “Drop here!” message.
  • PluginGui/PluginDragLeft|PluginDragLeft – fires when the user’s cursor leaves a window. Useful to hide a “Drop here!” message.