drag & drop allows us to mark a panel as draggable & listening to its movements when dragged by the player, opening up a whole new way of player interaction
The Breakdown
this PR adds 2 components, a Draggable component and a Slot component. the Draggable Component is responsible for the dragging interaction, sending RPCs to the server, & keeping itself within the constraints. the Slot Component's purpose is to allow draggables to be attached to the panel, with an optional primitive string filter to only allow draggables with a matching filter in.
the Draggable Component comes with 4 seperate position send types, you might prefer one over the other depending on your scenario:
public enum PositionSendType : byte{
// the Position normalized to the Screen resolution
NormalizedScreen,
// the Position normalized to the panel's limitParent (even if the setting is not used)*
NormalizedParent,
// the offset from the Draggable's last position
Relative,
// the offset from the anchor
RelativeAnchor
}
* if the limitParent setting is not used, it still calculates the parent to use for the NormalizedParent setting. dragging the panel outside of the panel will produce values greater or lower than 0 - 1. the limitParentIndex is also supported for this usecase
the JSON Implementation - Draggable
{
"type":"Draggable", // All thats required to make the panel draggable
"maxDistance": -1, // how far the draggable is allowed to be dragged from its parent
"anchorOffset": "0 0", // if the anchor should be offset from the draggable's initial position the offset can be specified here
"limitToParent": false, // Limits the Draggable to the closest non-slot parent, does not work combined with maxDistance
"parentLimitIndex": 1, // if limitToParent is true, this index allows you to specify how many non slot parents it should traverse before finding the limit
"parentPadding": "0 0", // if limitToParent is true, specifies additional padding that the draggable should be contained. can be negative to allow the draggable to slightly travel outside the parent
"dropAnywhere": true, // if false, the draggable will return to its last valid position (its initial position by default) unless swapped or attached to a slot
"keepOnTop": false, // if true the draggable will stay detached from its parent, reccomended for unrestricted draggables
"allowSwapping": false, // if true the draggable can be swapped with other draggables if dragged ontop of eachother
"dragAlpha": 1, // if the alpha of the draggable's graphics should be lowered while being dragged.
"positionRPC": "NormalizedScreen", // how the position should be processed before being sent via RPCs*
"filter": null // the filter string this draggable should carry, see #Slots & Filtering
}
* Depending on other settings the default value for the positionRPC field may change.
if maxDistance is used, the default will be RelativeAnchor
if limitToParent is used, the default will be NormalizedParent
these are only defaults, you can still override this by specifying the field in the json
the JSON Implementation - Slot
{
"type":"Draggable", // All thats required to make the panel a slot
"filter": null, // if not null it will only allow draggables with a matching filter string
}
Slots & Filtering
Slots come with a built in filter system that allows you to specify what draggables can be attached.
if the slot has no filter, any draggable can be inserted. if the slot has a filter it only allows Draggables with a matching filter property. in the demo video this is shown with the green Draggable & Slots, the gray slots will accept any draggable while the green slot will only accept the matching Draggable. this is accomplished by setting the filter string
when building a system arround slots & the swapping of Draggables, its reccomended to set the dropAnywhere setting to false to make Draggables return to their last position if a
Implementing Drag & Drop into our UIs
The Breakdown
this PR adds 2 components, a
Draggable
component and aSlot
component. the Draggable Component is responsible for the dragging interaction, sending RPCs to the server, & keeping itself within the constraints. the Slot Component's purpose is to allow draggables to be attached to the panel, with an optional primitive string filter to only allow draggables with a matching filter in.Demo:
https://github.com/Facepunch/Rust.Community/assets/33698270/8747ba06-2b71-49cd-b171-b20fe4a799ae
Receiving RPCs
Draggable's will send 1 of 2 RPC calls on the CommunityEntity depending on which action is performed:
the position Type
the Draggable Component comes with 4 seperate position send types, you might prefer one over the other depending on your scenario:
the JSON Implementation - Draggable
* Depending on other settings the default value for the positionRPC field may change.
RelativeAnchor
NormalizedParent
the JSON Implementation - Slot
Slots & Filtering
Slots come with a built in filter system that allows you to specify what draggables can be attached.
this is how the filtering is evaluated:
if the slot has no filter, any draggable can be inserted. if the slot has a filter it only allows Draggables with a matching filter property. in the demo video this is shown with the green Draggable & Slots, the gray slots will accept any draggable while the green slot will only accept the matching Draggable. this is accomplished by setting the filter string
when building a system arround slots & the swapping of Draggables, its reccomended to set the
dropAnywhere
setting to false to make Draggables return to their last position if a