.. MASH Technical file, created by Ian Waters
   sphinx-quickstart on Wed Apr 19 16:21:02 2017.
   You can adapt this file completely to your liking, but it should at least
   contain the root `toctree` directive.

.. _dropWindow:

The Drop Window
************************
This little utility allows you to create interactive 'Smart Presets'.
Consider the situation when you want to do 'something' to an object.
Generally in Maya, when this is the case you need to select the items (sometimes in a specific order) before running the script.
The Drop Window makes this more intuative by presenting a window (mid script) for a user to drag items into, the script will be fed the names of the dropped items and will continue.

.. image:: _examples/DropWindowTitle.png


Simple Example
===================
Download this 'smart preset' then drag and drop it onto the Maya viewport (from your desktop for example).
The preset will present the drop window and ask for you to drag in an object to distribute some spheres onto.
For example you could create a large torus (or ANY other mesh), then drag it from the Outliner into the drop window. The result will be the below.

.. image:: _examples/DropWindow.png

:download:`Sphere Cluster Smart Preset <_examples/sphereClusterSmartPreset.py>`

Walkthrough
===================
Firstly you need to import Flux (MASH's UI framework) to access the Drop Window.

.. code-block:: python

	import flux.core as fx

Your Smart Preset will need to be a Python Generator, if you don't know what one of those is, just edit the preset rather then building one from scratch.
At some point in your script, when it makes sense to present the drop window (and you can have as many as you like per script) you would create the window like so:

.. code-block:: python

	def runPreset():
		'''
		... Some cool code ...
		'''
		fx.DropWindow.getDrop(label='Put a window title here:', lambda data: smartPreset.send(data))
		node = yield
		'''
		'node' will be a string of all the nodes you dropped onto the Drop Window
		Multiple nodes will be newline seperated.
		One way to split the string is like so:
		'''
		nodeList = node.split('\n')
		print nodeList # print it out so that this example actually does something
		'''
		Finish the Generator with a Yield so that it knows where to stop.
		'''
		yield

	'''
	Now run your Smart Preset like so
	'''
	smartPreset = runPreset()
	smartPreset.next()



The script will wait for the window to be interacted with (by dragging something on to it) before continueing. It's very polite about it and Maya is completely interactive while it waits.

Options
===================

You can specify the type of node required by your preset using the 'accepts' aguement. This should be an array of acceptable node types.

.. code-block:: python

	fx.DropWindow.getDrop(label='Drag in a mesh:', callback=lambda data: smartPreset.send(data), title='Cool Preset', accepts=['mesh'])
	firstNodes = yield


For more complex presets (see Pile Of Stuff in the API Examples) you can have a multi-step preset. To do this you need to supply a list of labels for each step, and a list of lists, containing the acceptable node types.

.. image:: _examples/dropStep2.png

.. code-block:: python

	# Add labels for each step of the smart preset
    steps = [
        'Step 1: Drag in your stuff:', 
        'Step 2: Drag in a pile starting shape (like a cone):'
    ]
    
    # List the accepted node types for each step
    acceptableNodeTypes = [
        ['mesh'], 
        ['mesh']
    ]

    # create the drop window
    fx.DropWindow.getDrop(steps, callback=lambda data: smartPreset.send(data), title='MASH - Pile of Stuff', accepts=acceptableNodeTypes)
    node = yield

    # get the second step drop
    node = yield

UIs
===================

You can add controls to your drop window, to do this you create a list of controls for each step, and put those into a list.

.. code-block:: python

	controls = [
        [cmds.intSliderGrp('iterationsSliderGrp', label='Iterations', field=True, min=0, max=20, value=10)]
    ]

Remember, this is a list of lists reguardless of how many steps you have!
You then add the controls to the drop window using the 'ui=' arguement.

.. code-block:: python

	# create the Drop Window
    fx.DropWindow.getDrop(label='Drag in a MASH Waiter:', callback=lambda data: smartPreset.send(data), title='MASH - Fix Intersections', accepts=['MASH_Waiter'], ui=controls)

It's very important to clean up the UI when you're done to prevent problems with further runs of the script.

.. code-block:: python

	[cmds.deleteUI(y, control=True ) for x in controls for y in x]

You can specify the minimum width of your widget with the 'minWidth=' arguement. Height is automatically worked out for you.

.. image:: _examples/controls.png