Difference between revisions of "Experimental:Drag-and-Drop"
Line 13: | Line 13: | ||
== Setting Up A Draggable Panel == | == Setting Up A Draggable Panel == | ||
− | To use the callback system to create a draggable panel, first be sure the <code>When Dragging This</code> parameter on your component is set to <code>Use Drag/Drop Callbacks</code>. Next, you will use the <code> | + | To use the callback system to create a draggable panel, first be sure the <code>When Dragging This</code> parameter on your component is set to <code>Use Drag/Drop Callbacks</code>. Next, you will use the <code>onDragStartGetItems</code> callback to tell the system what item or items will be dragged when the user clicks and drags on the panel. After the drag is complete, you will receive an <code>onDragEnd</code> callback in which you can script any further actions to be taken. |
====<code>onDragStartGetItems(comp)</code> → <code>list of item dicts</code>==== | ====<code>onDragStartGetItems(comp)</code> → <code>list of item dicts</code>==== |
Revision as of 22:58, 22 July 2020
TouchDesigner supports Drag-and-Drop functionality as a shortcut to complex import/export and copy/paste functionality. Drag-and-Drop functionality allows you to:
- Import TouchDesigner-readable files.
- Export data from TouchDesigner nodes to external applications.
- Copy and/or move nodes from one TouchDesigner network to another.
- Add TouchDesigner-readable file(s), Panel components or TouchDesigner nodes to open control panels.
Panel Components have options for Drag and Drop on their Drag/Drop page of parameters. These parameters can be used to inherit the Drag/Drop settings from the panel's parents, or to force Drag/Drop on or off.
Contents
Drag/Drop Callbacks[edit]
To create custom drag/drop systems for your UI, you can use Python Drag/Drop Callbacks with all Panel Components. Once you set your panel to Use Drag/Drop Callbacks
in either the When Dragging This
or the On Dropping Into
parameter, you can press the Create button in the Drag/Drop Callbacks
parameter to create a default callbacks DAT. Edit this DAT to set up your custom Drag/Drop behavior.
Setting Up A Draggable Panel[edit]
To use the callback system to create a draggable panel, first be sure the When Dragging This
parameter on your component is set to Use Drag/Drop Callbacks
. Next, you will use the onDragStartGetItems
callback to tell the system what item or items will be dragged when the user clicks and drags on the panel. After the drag is complete, you will receive an onDragEnd
callback in which you can script any further actions to be taken.
onDragStartGetItems(comp)
→ list of item dicts
[edit]
- Called when information about dragged items is required.
comp
- the panel Component that is being dragged
- You must return a list of item dicts from the callback to start a drag operation. An item dict is a dictionary of information about dragged objects. The only required key for this dictionary is
"item"
. TouchDesigner will act is if the items defined in the list were selected and dragged. For more advanced systems, you can also include any other keys you want.
- Example
onDragStartGetItems
callback codereturn [{'item': comp}]
drags the panel operator itselfreturn [{'item': comp.parent()}]
drags the panel's parentreturn [{'item': op('custom1')}, {'item': op('custom2')}]
drags two operatorsreturn [{'item': comp.par.x}]
drags the panel's x parameterreturn [{'item': op('myCHOP')['speed']}]
drags a CHOP'sspeed
channel.
onDragEnd(comp, accepted, dropResults)
[edit]
- Called when a drag action ends.
comp
- the panel component that was being draggedaccepted
- True if the drag was accepteddropResults
- a dict of drop results. In custom systems, this is the return value of onDropGetResults. For TouchDesigner default drops, print this to get more information about the drop.
- This callback can be used if you need to take special actions after a drop has occurred.
Setting Up A Panel As A Drop Target[edit]
To use the callback system to set up dropping onto a panel, start by making sure the On Dropping Into
parameter on your component is set to Use Drag/Drop Callbacks
. The first step in receiving a drop is determining whether the panel can accept the items being dragged over it (a.k.a. hovering) using the onHoverStartGetAccept
callback. If an acceptable item is dropped onto the panel, you can then use the onDropGetResults
callback to react to the drop. The onHoverEnd
callback can be used to script any actions to be taken when items are dragged into and then back out of the panel's area. This would most often be used to turn off any visual hover indicators.
onHoverStartGetAccept(comp, dragItems)
→ True if drag items are acceptable
[edit]
- Called when comp needs to know if dragItems are acceptable as a drop. You must return True if you want to accept
dragItems
for dropping.comp
- the panel component being hovered overdragItems
- a list of item dicts being dragged over comp
- The easiest way to see this in action is to use the following code in this callback and watch the textport when you drag various items over your panel:
debug('\nonHoverStartGetAccept', comp.path, '\n\t', dragItems)
onHoverEnd(comp, dragItems)
[edit]
- Called when dragItems leave comp's hover area.
comp
- the panel component being hovered overdragItems
- a list of item dicts being dragged over comp
onDropGetResults(comp, dragItems)
→ Dict of results
[edit]
- Called when comp receives a drop of dragItems. This will only be called if onHoverStartGetAccept has returned True for these dragItems.
comp
- the panel component being hovered overdragItems
- a list of item dicts being dragged over comp
- Returning a dictionary of items from this function is optional, but allows you to set up cross-communication between drag sources and drop targets. The dictionary should have results with descriptive keys. The following key/value pairs are standard and should be used when possible:
'createdOPs':[<list of created ops in order of corresponding drag item>]
Legacy Drag/Drop System[edit]
How Component Drag-and-Drop Works[edit]
- Anything dropped into a network that Allows Drop will be handled by the Network's Drop Script, regardless of whether you are dropping onto a node viewer, a control panel view, or a network editor in either list view or node view. No menu will popup.
- By default, Components Do Not Allow Drop.
- If a Component Does Not Allow Drop, you will only be able to drop things into it via the network editor list or node view. A menu may popup to give you a list of options.
- If the node being dropped has a Dropped Component or Drop Destination Script, then the Move option will not be available.
- A node that has a Dropped Component or Drop Destination Script will still drop as itself if you drop it onto parameters or Text DATs. It will also save as a *.tox of itself if you drop it onto a windows desktop or folder.
Drop Scripts - Text[edit]
A component's Drop Script would get run when you drop another component or an external file into that component.
Each component network can be set to allow dragging-and-dropping. In a component's parameter dialog, there is a Drag tab where you can modify the settings. You can set a components to use its parents settings, or to use custom scripts. By default, the settings of the root folder for Dragging is Do Not Allow Drag and for Dropping Do Not Allow Drop, with the default Drop Script specified at /sys/drop
.
To set up your own Drop Script, set your component's parameter Drop to Allow Drop, and enter the path for the DAT specifying your Drop Script onto the Drop Script parameter. This DAT will be executed whenever something is dropped onto this component. The parameters passed to the Drop Script in Python are:
args[0]
- dropped node name, CHOP channel or file name, depending on what is dropped
args[1]
- x position in network coordinates when the mouse was released
args[2]
- y position in network coordinates when the mouse was released
args[3]
- the number of the item being dropped
args[4]
- the total number of items being dropped
args[5]
- the operator type or file extension
args[6]
- the fullpath of the network or node the node or channel was dragged from, or the parent directory
args[7]
- the network accepting this drop
Drop Script - Tables[edit]
If you want to process individual node types or file types, you can use a drop table. Specify a Table DAT in the drop script field. TouchDesigner will automatically look for 2 columns in the table. The first column should indicate the data type and the second should indicate the Text DAT that holds the script to process that data type. TouchDesigner will call the script for each data and with the above parameters. Here is a sample drop table:
chop chop_script handle CHOP nodes
sop sop_script handle SOP nodes
channel channel_script handle channel data
cmd cmd_script runs a .cmd file
tox tox_script loads a .tox file
Columns are not limited to two, but only the first two columns will be used to process drops.
Drag Scripts[edit]
You can specify whether a component is allowed to be dragged. The default settings for root is Do Not Allow Drag. This means that you cannot click on the control panel view of a component and drag it to a network you can drop in. However, you will still be able to drag the Node View of that component and drop it.
The parameters passed to the Drag Script in Python are:
args[0]
- dragged operator name
args[1]
- the index of the operator dragged
args[2]
- the total number of operators being dragged
args[3]
- operator type
args[4]
- parent path of dragged operator
There are a couple of ways to modify what operator will be dropped when you drag a Component. The Dropped Component parameter is the easiest way to specify an alternative operator to drop. Note that this alternative operator must exist, otherwise the component itself will be dropped. The alternative is only used when dropping onto a network or control panel. Text pasted via dragging and dropping, or files saved via dropping onto the desktop, will still use the original.
Drop Destination Scripts[edit]
A more flexible way to specify alternatives to drop, is to use the Drop Destination Script.
If a Drop Destination Script is specified, a temporary network is created and the component (or the alternative operator specified in Dropped Component) is copied to this network. You can add or modify operators in this network.
Then echo a list of paths. TouchDesigner will look at the list of paths output by this script, and will copy them to the dropped network.
A node path is specified relative to the current component when the script exits. If a node cannot be found for a string, TouchDesigner will assume that it is a file and dropped the string as a file into the drop network.
The arguments for the Destination Drop Script are:
arg[0]
- full path of script
arg[1]
- copy of component (or alternative operator specified in parameter Dropped Component)
arg[2]
- full path of temporary network (in /sys)
arg[3]
- name of component (or alternative operator specified in parameter Dropped Component)
arg[4]
- full path of component parent (where the drag came from) (or alternative operator parent)
arg[5]
- operator type of copy
Drop Types[edit]
By default, dragging a component drops operators or file paths. If a drop destination script is specified, you can also add a DAT table with a list of return types that the drop destination script will provide. Return types can be one of the op types (COMP,TOP,CHOP,SOP,MAT,DAT), channel, or supported filetypes. For example, a DAT table containing just
jpg
tiff
top
will only let the component being dropped into know that it will only provide those 3 types. If the component being dropped into has a table of types and corresponding scripts, then you will only be able to drop if there is a matching type. i.e., if the drop script table looks like this:
top top_script
then only tops supplied by the drop destination script will be accepted by the component.
See also File Types
Exporting is the connection of CHOP channels to parameters of operators. The output of each exporting CHOP is one or more channels, active only while the CHOP Viewer is on. The current value of a channel can be exported to a parameter of any operator, overriding that parameter's value. See Parameter.
An Operator Family that manipulates text strings: multi-line text or tables. Multi-line text is often a command Script, but can be any multi-line text. Tables are rows and columns of cells, each containing a text string.
A custom interactive control panel built within TouchDesigner. Panels are created using Panel Components whose look is created entirely with TOPs.
An Operator Family that contains its own Network inside. There are twelve 3D Object Component and eight 2D Panel Component types. See also Network Path.
An Operator Family which operate on Channels (a series of numbers) which are used for animation, audio, mathematics, simulation, logic, UI construction, and many other applications.
Every component contains a network of operators that create and modify data. The operators are connected by wires that define where data is routed after the operator cooks its inputs and generates an output.
TouchDesigner Component file, the file type used to save a Component from TouchDesigner.
A form of DATs (Data Operators) that is structured as rows and columns of text strings.
An Operator Family that reads, creates and modifies 3D polygons, curves, NURBS surfaces, spheres, meatballs and other 3D surface data.