void DrawPropertyControls()
        {
            GUILayout.BeginHorizontal();

            // Property dropdown:
            EditorGUI.BeginChangeCheck();
            currentProperty = (ParticleProperty)EditorGUILayout.Popup(currentProperty, particlePropertyNames.ToArray());
            if (EditorGUI.EndChangeCheck())
            {
                newProperty = GetPropertyValue(currentProperty, lastSelectedParticle);
                ParticlePropertyChanged();
            }

            // Property value:
            EditorGUI.showMixedValue = false;
            float selectionProperty = GetPropertyValue(currentProperty, lastSelectedParticle);

            for (int i = 0; i < selectionStatus.Length; i++)
            {
                if (selectionStatus[i] && !Mathf.Approximately(GetPropertyValue(currentProperty, i), selectionProperty))
                {
                    EditorGUI.showMixedValue = true;
                }
            }

            EditorGUI.BeginChangeCheck();
            newProperty = EditorGUILayout.FloatField(newProperty, GUILayout.Width(88));
            if (EditorGUI.EndChangeCheck())
            {
                // If we are not in paint mode, allow instant change of particle properties:
                if (!paintBrush)
                {
                    Undo.RecordObject(actor, "Set particle property");
                    for (int i = 0; i < selectionStatus.Length; i++)
                    {
                        if (!selectionStatus[i])
                        {
                            continue;
                        }
                        SetPropertyValue(currentProperty, i, newProperty);
                    }
                    ParticlePropertyChanged();
                }
            }

            EditorGUI.showMixedValue = false;

            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();

            if (GUILayout.Button(new GUIContent(Resources.Load <Texture2D>("FillButton"), "Fill property value"), GUILayout.MaxHeight(24), GUILayout.Width(42)))
            {
                Undo.RecordObject(actor, "Property fill");
                for (int i = 0; i < selectionStatus.Length; i++)
                {
                    // Skip unselected particles, if selection mask is on.
                    if (selectionMask && !selectionStatus[i])
                    {
                        continue;
                    }

                    SetPropertyValue(currentProperty, i, newProperty);
                }
                ParticlePropertyChanged();
            }

            selectionMask = GUILayout.Toggle(selectionMask, new GUIContent(Resources.Load <Texture2D>("MaskButton"), "Selection mask"), GUI.skin.FindStyle("Button"), GUILayout.MaxHeight(24), GUILayout.Width(42));

            EditorGUI.BeginChangeCheck();
            textureProperties = GUILayout.Toggle(textureProperties, new GUIContent(Resources.Load <Texture2D>("TextureButton")), GUI.skin.FindStyle("Button"), GUILayout.MaxHeight(24), GUILayout.Width(42));
            if (EditorGUI.EndChangeCheck())
            {
                if (textureProperties)
                {
                    paintBrush = false;
                }
                ForceWindowRelayout();
            }

            EditorGUI.BeginChangeCheck();
            paintBrush = GUILayout.Toggle(paintBrush, new GUIContent(Resources.Load <Texture2D>("PaintButton"), "Paint brush"), GUI.skin.FindStyle("Button"), GUILayout.MaxHeight(24), GUILayout.Width(42));
            if (EditorGUI.EndChangeCheck())
            {
                if (paintBrush)
                {
                    selectionBrush    = false;
                    textureProperties = false;
                }
                ForceWindowRelayout();
            }

            GUILayout.EndHorizontal();

            if (paintBrush)
            {
                GUILayout.BeginHorizontal();
                if (GUILayout.Toggle(paintMode == PaintBrushType.Gaussian, new GUIContent(Resources.Load <Texture2D>("GaussianButton"), "Soft brush"), GUI.skin.FindStyle("ButtonLeft"), GUILayout.MaxHeight(28)))
                {
                    paintMode = PaintBrushType.Gaussian;
                }
                if (GUILayout.Toggle(paintMode == PaintBrushType.Pencil, new GUIContent(Resources.Load <Texture2D>("PencilButton"), "Pencil"), GUI.skin.FindStyle("ButtonMid"), GUILayout.MaxHeight(28)))
                {
                    paintMode = PaintBrushType.Pencil;
                }
                if (GUILayout.Toggle(paintMode == PaintBrushType.Smooth, new GUIContent(Resources.Load <Texture2D>("SmoothButton"), "Smooth"), GUI.skin.FindStyle("ButtonRight"), GUILayout.MaxHeight(28)))
                {
                    paintMode = PaintBrushType.Smooth;
                }
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                GUILayout.Label("Radius");
                brushRadius = EditorGUILayout.Slider(brushRadius, 5, 200);
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                GUILayout.Label("Opacity");
                brushOpacity = EditorGUILayout.Slider(brushOpacity, 0, 1);
                GUILayout.EndHorizontal();

                EditorGUI.BeginChangeCheck();

                // auto range visualization:
                autoRangeDraw = GUILayout.Toggle(autoRangeDraw, "Auto range visualization");

                if (!autoRangeDraw)
                {
                    GUILayout.BeginHorizontal();
                    GUILayout.Label("Min");
                    GUILayout.FlexibleSpace();
                    minPropertyValue = EditorGUILayout.FloatField(minPropertyValue, GUILayout.Width(EditorGUIUtility.fieldWidth));
                    GUILayout.FlexibleSpace();
                    GUILayout.Label("Max");
                    GUILayout.FlexibleSpace();
                    maxPropertyValue = EditorGUILayout.FloatField(maxPropertyValue, GUILayout.Width(EditorGUIUtility.fieldWidth));
                    GUILayout.EndHorizontal();
                }

                if (EditorGUI.EndChangeCheck())
                {
                    ParticlePropertyChanged();
                    ForceWindowRelayout();
                }
            }

            if (textureProperties)
            {
                GUILayout.BeginHorizontal();
                float oldLabelWidth = EditorGUIUtility.labelWidth;
                EditorGUIUtility.labelWidth = 40;
                GUILayout.Label("Source");
                propertyTexture             = (Texture2D)EditorGUILayout.ObjectField("", propertyTexture, typeof(Texture2D), false);
                EditorGUIUtility.labelWidth = oldLabelWidth;
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                GUILayout.Label("Source channel");
                GUILayout.FlexibleSpace();
                textureChannel = (TextureChannel)EditorGUILayout.EnumPopup(textureChannel);
                GUILayout.EndHorizontal();

                EditorGUI.BeginChangeCheck();

                GUILayout.BeginHorizontal();
                GUILayout.Label("Min value");
                GUILayout.FlexibleSpace();
                minPropertyValue = EditorGUILayout.FloatField(minPropertyValue, GUILayout.Width(EditorGUIUtility.fieldWidth));
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                GUILayout.Label("Max value");
                GUILayout.FlexibleSpace();
                maxPropertyValue = EditorGUILayout.FloatField(maxPropertyValue, GUILayout.Width(EditorGUIUtility.fieldWidth));
                GUILayout.EndHorizontal();

                if (GUILayout.Button("Load property"))
                {
                    Undo.RecordObject(actor, "Load particle property");
                    if (!actor.ReadParticlePropertyFromTexture(propertyTexture, (int i, Color color) => {
                        if (!selectionMask || selectionStatus[i])
                        {
                            SetPropertyValue(currentProperty, i, minPropertyValue + color[(int)textureChannel] * (maxPropertyValue - minPropertyValue));
                        }
                    }))
                    {
                        EditorUtility.DisplayDialog("Invalid texture", "The texture is either null or not readable.", "Ok");
                    }
                    ParticlePropertyChanged();
                }

                // auto range visualization:
                autoRangeDraw = GUILayout.Toggle(autoRangeDraw, "Auto range visualization");

                if (EditorGUI.EndChangeCheck())
                {
                    ParticlePropertyChanged();
                }
            }
        }
        void UpdateEditMode()
        {
            paintMode = GUILayout.Toggle(paintMode, new GUIContent("Paint skin master/slave", Resources.Load <Texture2D>("PaintButton")), "LargeButton");

            // skin channel selector:
            if (paintMode)
            {
                GUILayout.BeginHorizontal();

                if (GUILayout.Toggle(brushType == PaintBrushType.Add, new GUIContent("Add", Resources.Load <Texture2D>("AddIcon")), GUI.skin.FindStyle("ButtonLeft")))
                {
                    brushType = PaintBrushType.Add;
                }

                if (GUILayout.Toggle(brushType == PaintBrushType.Remove, new GUIContent("Remove", Resources.Load <Texture2D>("RemoveIcon")), GUI.skin.FindStyle("ButtonMid")))
                {
                    brushType = PaintBrushType.Remove;
                }

                if (GUILayout.Button(new GUIContent("Fill", Resources.Load <Texture2D>("FillButton")), GUI.skin.FindStyle("ButtonMid")))
                {
                    if (sourceObject != null && Selection.activeGameObject == sourceObject)
                    {
                        for (int i = 0; i < skinMap.masterFlags.Length; ++i)
                        {
                            skinMap.masterFlags[i] |= (uint)(1 << selectedSkinChannel);
                        }
                    }
                    if (targetObject != null && Selection.activeGameObject == targetObject)
                    {
                        for (int i = 0; i < skinMap.slaveFlags.Length; ++i)
                        {
                            skinMap.slaveFlags[i] |= (uint)(1 << selectedSkinChannel);
                        }
                    }
                }

                if (GUILayout.Button(new GUIContent("Clear", Resources.Load <Texture2D>("ClearButton2")), GUI.skin.FindStyle("ButtonRight")))
                {
                    if (sourceObject != null && Selection.activeGameObject == sourceObject)
                    {
                        for (int i = 0; i < skinMap.masterFlags.Length; ++i)
                        {
                            skinMap.masterFlags[i] &= ~(uint)(1 << selectedSkinChannel);
                        }
                    }
                    if (targetObject != null && Selection.activeGameObject == targetObject)
                    {
                        for (int i = 0; i < skinMap.slaveFlags.Length; ++i)
                        {
                            skinMap.slaveFlags[i] &= ~(uint)(1 << selectedSkinChannel);
                        }
                    }
                }

                GUILayout.EndHorizontal();

                brushRadius         = EditorGUILayout.Slider("Brush radius", brushRadius, 5, 200);
                selectedSkinChannel = EditorGUILayout.Popup("Skin channel:", selectedSkinChannel, availableChannels);

                GUILayout.BeginHorizontal();
                if (GUILayout.Button("Copy channel to:"))
                {
                    CopySkinChannels(selectedSkinChannel, targetSkinChannel);
                }
                targetSkinChannel = EditorGUILayout.Popup(targetSkinChannel, availableChannels);
                GUILayout.EndHorizontal();
            }

            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Bind"))
            {
                if (sourceObject != null && targetObject != null)
                {
                    skinMap.Bind(sourceObject.transform, targetObject.transform);
                }
                EditorUtility.SetDirty(target);
            }

            if (GUILayout.Button("Done"))
            {
                EditorApplication.delayCall += ExitSkinEditMode;
            }
            GUILayout.EndHorizontal();

            DrawTransformInspector("Source transform", sourceObject);
            DrawTransformInspector("Target transform", targetObject);

            // Change materials when painting weights:
            if (Event.current.type == EventType.Repaint)
            {
                UpdateSourceObject();
                UpdateTargetObject();
            }
        }