protected override void OnRotateToolWindowGUI(CardinalPathWithRotation path)
            {
                EditorGUILayout.LabelField("Rotation", EditorStyles.centeredGreyMiniLabel);

                using (var scope = new ChangeCheckScope(path))
                {
                    using (new LabelWidthScope(EditorGUIUtility.singleLineHeight))
                    {
                        Vector3 eulerAngles = default(Vector3);
                        bool lookTangent = true;
                        eulerAngles = path.GetNodeRatation(selectedNode, Space.Self).eulerAngles;
                        lookTangent = path.IsNodeLookTangent(selectedNode);

                        eulerAngles.x = EditorGUILayout.FloatField("X", eulerAngles.x);
                        eulerAngles.y = EditorGUILayout.FloatField("Y", eulerAngles.y);
                        eulerAngles.z = EditorGUILayout.FloatField("Z", eulerAngles.z);
                        lookTangent = EditorGUIKit.IndentedToggleButton("Look Tangent", lookTangent);

                        if (scope.changed)
                        {
                            path.SetNodeRatation(selectedNode, Quaternion.Euler(eulerAngles), Space.Self);
                            path.SetNodeLookTangent(selectedNode, lookTangent);
                        }
                    }
                }
            }
            protected override void OnMoveToolWindowGUI(T path)
            {
                string label = _selectedType == 0 ? "Position" : (_selectedType == 1 ? "Forward Ctrl-point" : "Back Ctrl-point");

                EditorGUILayout.LabelField(label, EditorStyles.centeredGreyMiniLabel);

                using (var scope = new ChangeCheckScope(path))
                {
                    Vector3 point;

                    if (_selectedType == -1)
                    {
                        point = path.GetNodeBackControlPoint(selectedNode, Space.Self);
                    }
                    else if (_selectedType == 0)
                    {
                        point = path.GetNodePosition(selectedNode, Space.Self);
                    }
                    else
                    {
                        point = path.GetNodeForwardControlPoint(selectedNode, Space.Self);
                    }

                    using (new LabelWidthScope(EditorGUIUtility.singleLineHeight))
                    {
                        point.x = EditorGUILayout.FloatField("X", point.x);
                        point.y = EditorGUILayout.FloatField("Y", point.y);
                        point.z = EditorGUILayout.FloatField("Z", point.z);
                    }

                    if (scope.changed)
                    {
                        if (_selectedType == -1)
                        {
                            path.SetNodeBackControlPoint(selectedNode, point, Space.Self);
                        }
                        else if (_selectedType == 0)
                        {
                            path.SetNodePosition(selectedNode, point, Space.Self);
                        }
                        else
                        {
                            path.SetNodeForwardControlPoint(selectedNode, point, Space.Self);
                        }
                    }
                }

                using (var scope = new ChangeCheckScope(path))
                {
                    using (new LabelWidthScope(EditorGUIUtility.singleLineHeight))
                    {
                        bool broken = EditorGUIKit.IndentedToggleButton("Broken", path.IsNodeBroken(selectedNode));
                        if (scope.changed)
                        {
                            path.SetNodeBroken(selectedNode, broken);
                        }
                    }
                }
            }
            public override void OnInspectorGUI()
            {
                base.OnInspectorGUI();

                var path = target as CardinalPathWithRotation;

                using (var scope = new ChangeCheckScope(path))
                {
                    bool value = EditorGUIKit.IndentedToggleButton("Preview Rotation", path._previewRotation);
                    if (scope.changed) path._previewRotation = value;
                }
            }
            public override void OnInspectorGUI()
            {
                // Edit Button

                var rect = EditorGUILayout.GetControlRect(true, 23);

                rect.x    += EditorGUIUtility.labelWidth;
                rect.width = 33;

                using (var scope = new ChangeCheckScope(null))
                {
                    bool edit = GUI.Toggle(rect, FloatingWindow.target == target, EditorGUIUtility.IconContent("EditCollider"), EditorGUIKit.buttonStyle);
                    rect.x     = rect.xMax + 5;
                    rect.width = 140;
                    EditorGUI.LabelField(rect, "Edit Path", EditorGUIKit.middleLeftLabelStyle);
                    if (scope.changed)
                    {
                        FloatingWindow.target = edit ? target : null;
                    }
                }

                // circular

                using (var scope = new ChangeCheckScope(target))
                {
                    bool circular = EditorGUILayout.Toggle("Circular", target.circular);
                    if (scope.changed)
                    {
                        target.circular = circular;
                    }
                }

                // World Scale

                using (var scope = new ChangeCheckScope(target))
                {
                    float value = EditorGUILayout.FloatField(
                        EditorGUIKit.TempContent("World Scale", null, "Use \"World Scale\" to scale the path instead of scales of transform."),
                        target.worldScale);
                    if (scope.changed)
                    {
                        target.worldScale = value;
                    }
                }

                // Length Error

                using (var scope = new ChangeCheckScope(target))
                {
                    float value = EditorGUILayout.FloatField("Length Error", target.lengthError);
                    if (scope.changed)
                    {
                        target.lengthError = value;
                    }
                }

                // Length

                if (target.isSamplesValid)
                {
                    EditorGUILayout.FloatField("Length", target.length);
                }
                else
                {
                    rect = EditorGUILayout.GetControlRect();
                    EditorGUI.LabelField(rect, "Length");
                    rect.xMin += EditorGUIUtility.labelWidth;

                    // Calculate Button

                    if (GUI.Button(rect, "Calculate", EditorStyles.miniButton))
                    {
                        Undo.RecordObject(target, "Calculate");
                        target.ValidateSamples();
                    }
                }

                // Visible

                using (var scope = new ChangeCheckScope(target))
                {
                    bool value = EditorGUIKit.IndentedToggleButton("Always Visible", target._alwaysVisible);
                    if (scope.changed)
                    {
                        target._alwaysVisible = value;
                    }
                }
            }