Draggable UI [Deprecated | Temporary]

After scrapping the original documentation for a UI dragging resource in favor of the upcoming update I received several requests to retain the documentation for temporary use until the update releases. Please keep in mind that this resource contains only rudimentary features seen in the new update and should only be used to mimic how the deprecated draggable property worked.

Download the resource here.

Note: The module not only allows you to create customized draggable items but also lets you make items selectable, it was intended to be used to create inventories and other types of containers. Selecting and dragging items are two distinct, separate features that have nothing to do with each other and will not affect each other aside from mouse interaction.

Lists

local ui = script.Parent.Frame -- the item you want to make draggable

local DragUI = require(game.ReplicatedStorage.DragUI)
local list = DragUI.Create()
local dragger = list.Create(item)

Lists are collection objects used to store draggable items and represent common item containers (ex. inventories) found in games. Lists should be made for containers where you only want a single item out of a group of items to be selectable or draggable at a time. Lists allows you to prevent this “single selection” trait of containers from interfering with other containers, i.e. selecting an inventory item only deselects other inventory items and will not deselect hotbar items.

List Properties:

list.draggables = {} -- table of draggables in the list
list.pressing = nil -- the draggable that the mouse is currently held down on
list.dragging = nil -- the draggable currently being dragged
list.singleselection = singleSelectionDefault -- [True/false] the type of selection limitation
list.selected = {} -- table of draggables which are currently selected

These properties are pretty straight forward, except for list.singleselection. If this property is true then only one item will be selectable at a time, if you select an item any selected items will be deselected. If this property is false then you can select multiple items at a time and selecting an item will not deselect other items.

List Methods:

list:SetSelected(object: any): {Object}
list.Create(dragTarget: GuiObject, inputElement: GuiObject?): {}

Using :SetSelected() on a list allows you to pass a list of draggable objects, or just one draggable object, to have them/it selected and this will deselect any selected objects which are not passed. This method is useful for batch selecting a bunch of objects exclusively.

Lists which serve as containers (ex. inventories, loot bags, chests) prevent draggable objects from interfering with the selection or dragging of draggables outside of their respective lists. If your draggable object is not a part of a container and holds no relationship to other UI elements you can create a list exclusively to hold that item like so:

Ex. Creating a draggable frame with its own list, will not interact with any other draggables.

local draggable = DragUI.Create().Create(frame)

Draggables

Creating a draggable:

list.Create(dragTarget: GuiObject, inputElement: GuiObject?): {}

Using .Create() on a list will create a draggable item for that list. Note that draggable items are not able to be transferred between lists. This method will return a draggable object which has its own properties and methods. The second parameter inputElement: GuiObject is optional and determines the GuiObject that the mouse must interact with to drag the frame. If you call this method with just the dragTarget parameter specified then the target and the input element will be the same GuiObject.

Ex. Drag a frame using the mouse anywhere on the frame

local draggable = list.Create(frame) -- Mouse input on frame will control frame's dragging

Ex. Passing dragTarget as a frame & inputElement as an image label in the corner of the frame.

local draggable = list.Create(frame, frame.ImageLabel) -- Drag a frame with an internal element

Draggable Properties:

-- READ ONLY PROPERTIES, PLEASE DO NOT TRY TO CHANGE THESE
object.element = dragTarget -- the draggable ui  element
object.input = inputElement -- the input ui element
object.connection = nil -- connection if the objects dragging is active
object.relativity = nil -- mouse position relativity to the element when dragging started
object.position = nil -- the position of the element before dragging started
object.size = nil -- the size of the element before dragging started

-- Read only, each property has a corresponding attribute.
-- The attributes will update these properties automatically.
object.selectable = selectableDefault
object.selected = false
object.draggable = draggableDefault
object.useanchor = useAnchorDefault
object.anchor = anchorDefault
object.uselimits = useLimitsDefault
object.usebounds = useBoundsDefault

-- YOU CAN CHANGE THESE EVENT PROPERTIES
object.onSelect = function() end -- Happens right after selecting the object
object.onDeselect = function() end -- Happens right after deselecting the object
object.onStart = function() end -- Happens right after the dragging starts
object.onStop = function() end -- Happens right after the dragging stops

Note: Almost all draggable properties are intended to be read-only and changing them will cause attributes to not be updated. Reading properties allows you to see information about the element when dragging started. The only changable properties are the callback functions you can set to run during the events. These are NOT events that you can :Connect() to, these are callbacks and allow you to pass code to the object to run.

Draggable Attributes:

When you register a new draggable object the following attributes will appear on the element. These attributes allow you to change the way the mouse interacts with the element.

Note: Disabling MouseDraggable or MouseSelectable does not stop you from using attributes or methods to control dragging and selecting, it merely prevents mouse input from being using to control dragging and selecting.

Note: In order for UseBounds to take effect UseLimits must already be enabled.

image

MouseDraggable & MouseSelectable

The MouseDraggable & MouseSelectable attributes control whether or not the mouse can be used to control dragging and selecting and object, respectively. Note If these are disabled they DO NOT interfere with an attribute or method’s ability to control dragging and selecting, they merely block mouse input from being used.

Note: If MouseSelectable is enabled then dragging will only begin once the mouse moves outside of the element’s bounds while being held down, otherwise if MouseSelectable is disabled then dragging will begin once the mouse is held down.

Note: If MouseDraggable is enabled then selection only occurs when the mouse is released, otherwise if MouseDraggable is disabled then selection will occur when mouse is pressed

Drag & Selected

The Drag & Selected attributes will control dragging and selection, respectively. If Drag is enabled then the object will be dragged until Drag is disabled. If Selected is enabled then the object will be selected until Selected is disabled.

SetAnchor & Anchor

Anchors tell your mouse where it should be relative to the size of the draggable element when being dragged. They function similarly to AnchorPoints except they are not bound to a 0 to 1 range.

If UseAnchor is enabled then Anchor will be used to position the draggable element relative to the mouse, otherwise if UseAnchor is disabled then the mouse’s relativity to the draggable element when dragging begins will be kept.

Ex. UseAnchor is Disabled

Ex. UseAnchor is Enabled

UseLimits & UseBounds

The UseLimits attribute will restrict the draggable element’s position to its parent’s bounds.

The UseBounds attribute will restrict the draggable element’s bounds to its parent’s bounds.

Note: The UseBounds attribute being enabled will only take effect while the UseLimits attribute is enabled.

Ex. UseLimits is Enabled

Ex. UseLimits & UseBounds are Enabled

Draggable Methods:

-- Dragging Methods
object:Start() -- Starts dragging, equivalent to setting the "Drag" attribute to true
object:Stop() -- 
object:Update() -- Updates the element to where it would be if you were currently dragging it
-- ^ You probably won't ever need to use :Update() but its available if you do

-- Selecting Methods
object:Select() -- Will select the object if its not already selected
object:Deselect() -- Will deselect the object if its selected

-- Helper Methods
object:Parent(parent: GuiObject?) -- Parent the element while retaining its position and size on the screen

-- Methods to update properties properly, optional replacement for setting attributes
object:SetDraggable(draggable: boolean?)
object:SetSelectable(selectable: boolean?)
object:SetUseAnchor(useAnchor: boolean?)
object:SetAnchor(anchor: Vector2?)
object:SetUseLimits(useLimits: boolean?)
object:SetUseBounds(useBounds: boolean?) -- Sets the usebounds property and updates the UseBounds attribute

Note: Draggable methods are not necessary to use because the attributes set on the draggable element can control almost all functionality of the object. Methods are just available if you ever prefer them or need some complicated work done.

Note: All methods to update properties & set attributes can be passed with no parameter. If the parameter is nil then the method will use a default value. Default values can be found at the top of the module. This is true for every method except for :SetAnchor(anchor: Vector2?), if you do not specify a parameter then the anchor will be the AnchorPoint of the element.

Example Code

local frame = script.Parent
local list = DragUI.Create()
local draggable = list.Create(frame)

draggable:SetSelectable(false) -- Want to prevent it from being selectable?
frame:SetAttribute("Selectable", true) -- Nope, Just kidding!

-- Want to enable an anchor?
frame:SetUseAnchor(true) -- Enable the anchor being used
frame:SetAnchor(Vector2.new(.5, .5)) -- Want the anchor to be at the center?
frame:SetAnchor() -- Nope, lets make the anchor match the AnchorPoint!

-- Want to enable position locking?
frame:SetUseLimits(true) -- Yes, lock the position.
frame:SetUseBounds(true) -- Let's lock the bounds as well!

draggable.onSelect = function() -- Highlight effect when selected?
	draggable.element:FindFirstChildOfClass("UIStroke").Enabled = true
end

draggable.onDeselect = function() -- Remove highlight effect when deselected?
	draggable.element:FindFirstChildOfClass("UIStroke").Enabled = false
end

draggable.onStart = function()
	draggable:Parent(frame.Parent.Parent) -- Want to parent it elsewhere and keep its position & size on screen?
end

draggable.onStop = function()
	frame.Size = draggable.size -- Want to revert its Position when dragging stops?
	frame.Position = draggable.position -- Want to revert its Position when dragging stops?
end

Experiment with this and see if it suits your needs until the update releases. If not, and you really need some functionality now, send me a PM and I will assist you further. Thanks for still getting some use out of this!

2 Likes