private void OnClickFillRow(int row)
    {
        ChromaSDKAnimation2D animation = GetAnimation();

        EditorUtility.SetDirty(animation);
        var frames = animation.Frames; //copy

        Unload();

        if (_mCurrentFrame >= 0 &&
            _mCurrentFrame < frames.Count)
        {
            ChromaDevice2DEnum device = animation.Device;
            int maxRow    = ChromaUtils.GetMaxRow(device);
            int maxColumn = ChromaUtils.GetMaxColumn(device);
            var rows      = frames[_mCurrentFrame];
            if (row < rows.Count && row < maxRow)
            {
                var colors = rows[row];
                for (int j = 0; j < maxColumn; ++j)
                {
                    colors[j] = ChromaUtils.ToBGR(_mColor);
                }
            }
            frames[_mCurrentFrame] = rows;
        }
        animation.Frames = frames;
    }
    private void OnClickFillColumn(int column)
    {
        ChromaSDKAnimation2D animation = GetAnimation();

        EditorUtility.SetDirty(animation);
        var frames = animation.Frames; //copy

        Unload();

        if (_mCurrentFrame >= 0 &&
            _mCurrentFrame < frames.Count)
        {
            ChromaDevice2DEnum device = animation.Device;
            int maxRow    = ChromaUtils.GetMaxRow(device);
            int maxColumn = ChromaUtils.GetMaxColumn(device);
            var rows      = frames[_mCurrentFrame];
            for (int i = 0; i < maxRow; ++i)
            {
                var row = rows[i];
                if (column < row.Count && column < maxColumn)
                {
                    row[column] = ChromaUtils.ToBGR(_mColor);
                }
            }
            frames[_mCurrentFrame] = rows;
        }
        animation.Frames = frames;
    }
    private void OnClickDarkenButton()
    {
        ChromaSDKAnimation2D animation = GetAnimation();

        EditorUtility.SetDirty(animation);
        var frames = animation.Frames; //copy

        Unload();

        if (_mCurrentFrame >= 0 &&
            _mCurrentFrame < frames.Count)
        {
            ChromaDevice2DEnum device = animation.Device;
            int maxRow    = ChromaUtils.GetMaxRow(device);
            int maxColumn = ChromaUtils.GetMaxColumn(device);
            var frame     = frames[_mCurrentFrame];
            for (int i = 0; i < maxRow; ++i)
            {
                var row = frame[i];
                for (int j = 0; j < maxColumn; ++j)
                {
                    Color color = ChromaUtils.ToRGB(row[j]);
                    color.r *= 0.75f;
                    color.g *= 0.75f;
                    color.b *= 0.75f;
                    row[j]   = ChromaUtils.ToBGR(color);
                }
            }
        }
        animation.Frames = frames;
    }
    private void OnClickShiftButton(int y, int x)
    {
        ChromaSDKAnimation2D animation = GetAnimation();

        EditorUtility.SetDirty(animation);
        var frames = animation.Frames; //copy

        Unload();

        if (_mCurrentFrame >= 0 &&
            _mCurrentFrame < frames.Count)
        {
            ChromaDevice2DEnum device = animation.Device;
            int maxRow    = ChromaUtils.GetMaxRow(device);
            int maxColumn = ChromaUtils.GetMaxColumn(device);
            int offsetX   = maxColumn - x;
            int offsetY   = maxRow - y;
            var oldFrame  = frames[_mCurrentFrame];
            var newFrame  = ChromaUtils.CreateColors2D(device);
            for (int i = 0; i < maxRow; ++i)
            {
                var oldRow = oldFrame[(i + offsetY) % maxRow];
                var newRow = newFrame[i];
                for (int j = 0; j < maxColumn; ++j)
                {
                    int color = oldRow[(j + offsetX) % maxColumn];
                    newRow[j] = color;
                }
            }
            frames[_mCurrentFrame] = newFrame;
        }
        animation.Frames = frames;
    }
    private void OnClickSaturateButton()
    {
        ChromaSDKAnimation2D animation = GetAnimation();

        EditorUtility.SetDirty(animation);
        var frames = animation.Frames; //copy

        Unload();

        if (_mCurrentFrame >= 0 &&
            _mCurrentFrame < frames.Count)
        {
            ChromaDevice2DEnum device = animation.Device;
            int maxRow    = ChromaUtils.GetMaxRow(device);
            int maxColumn = ChromaUtils.GetMaxColumn(device);
            var frame     = frames[_mCurrentFrame];
            for (int i = 0; i < maxRow; ++i)
            {
                var row = frame[i];
                for (int j = 0; j < maxColumn; ++j)
                {
                    Color color = ChromaUtils.ToRGB(row[j]);
                    float max   = Mathf.Max(Mathf.Max(color.r, color.g), color.b);
                    color  = Color.Lerp(Color.black, _mColor, max);
                    row[j] = ChromaUtils.ToBGR(color);
                }
            }
        }
        animation.Frames = frames;
    }
    private void OnClickPasteButton()
    {
        ChromaSDKAnimation2D animation = GetAnimation();

        EditorUtility.SetDirty(animation);
        var frames = animation.Frames; //copy

        Unload();

        if (_mCurrentFrame >= 0 &&
            _mCurrentFrame < frames.Count)
        {
            ChromaDevice2DEnum device = animation.Device;
            int maxRow    = ChromaUtils.GetMaxRow(device);
            int maxColumn = ChromaUtils.GetMaxColumn(device);
            if (null != _mColors &&
                _mColors.Count == maxRow &&
                null != _mColors[0] &&
                _mColors[0].Count == maxColumn)
            {
                var frame = ChromaUtils.CreateColors2D(device);
                for (int i = 0; i < maxRow; ++i)
                {
                    for (int j = 0; j < maxColumn; ++j)
                    {
                        frame[i][j] = _mColors[i][j];
                    }
                }
                frames[_mCurrentFrame] = frame;
            }
        }
        animation.Frames = frames;
    }
    private void OnClickAddButton()
    {
        ChromaSDKAnimation2D animation = GetAnimation();

        EditorUtility.SetDirty(animation);
        var frames = animation.Frames; //copy

        Unload();

        if (_mCurrentFrame < 0 ||
            _mCurrentFrame >= frames.Count)
        {
            _mCurrentFrame = 0;
        }
        EffectArray2dInput oldFrame;

        if (frames.Count > 0)
        {
            oldFrame = frames[_mCurrentFrame];
        }
        else
        {
            oldFrame = ChromaUtils.CreateColors2D(animation.Device);
        }
        EffectArray2dInput frame = ChromaUtils.CreateColors2D(animation.Device);

        if (_mCurrentFrame == frames.Count ||
            (_mCurrentFrame + 1) == frames.Count)
        {
            frames.Add(frame);
            _mCurrentFrame = frames.Count - 1;
        }
        else
        {
            ++_mCurrentFrame;
            frames.Insert(_mCurrentFrame, frame);
        }
        // copy colors
        if (_mCurrentFrame >= 0 &&
            _mCurrentFrame < frames.Count)
        {
            ChromaDevice2DEnum device = animation.Device;
            int maxRow    = ChromaUtils.GetMaxRow(device);
            int maxColumn = ChromaUtils.GetMaxColumn(device);
            for (int i = 0; i < maxRow; ++i)
            {
                var row = frame[i];
                for (int j = 0; j < maxColumn; ++j)
                {
                    row[j] = oldFrame[i][j];
                }
            }
        }
        animation.Frames = frames;
        animation.RefreshCurve();
    }
    private void OnClickContrastButton()
    {
        ChromaSDKAnimation2D animation = GetAnimation();

        EditorUtility.SetDirty(animation);
        var frames = animation.Frames; //copy

        Unload();

        if (_mCurrentFrame >= 0 &&
            _mCurrentFrame < frames.Count)
        {
            ChromaDevice2DEnum device = animation.Device;
            int maxRow    = ChromaUtils.GetMaxRow(device);
            int maxColumn = ChromaUtils.GetMaxColumn(device);
            var frame     = frames[_mCurrentFrame];
            for (int i = 0; i < maxRow; ++i)
            {
                var row = frame[i];
                for (int j = 0; j < maxColumn; ++j)
                {
                    Color color = ChromaUtils.ToRGB(row[j]);
                    float avg   = (color.r + color.g + color.b) / 3f;
                    if (avg < 0.5f)
                    {
                        color.r *= 0.75f;
                        color.g *= 0.75f;
                        color.b *= 0.75f;
                    }
                    else if (avg > 0.5f)
                    {
                        color.r = Mathf.Min(1f, color.r * 1.25f);
                        color.g = Mathf.Min(1f, color.g * 1.25f);
                        color.b = Mathf.Min(1f, color.b * 1.25f);
                    }
                    row[j] = ChromaUtils.ToBGR(color);
                }
            }
        }
        animation.Frames = frames;
    }
예제 #9
0
    public void ClearFrames()
    {
        int maxRow    = ChromaUtils.GetMaxRow(this.Device);
        int maxColumn = ChromaUtils.GetMaxColumn(this.Device);

        this._mFrames = new ChromaSDKAnimation2D.ColorFrame2D[1];
        ChromaSDKAnimation2D.ColorFrame2D   colorFrame2D = new ChromaSDKAnimation2D.ColorFrame2D();
        ChromaSDKBaseAnimation.ColorArray[] array        = new ChromaSDKBaseAnimation.ColorArray[maxRow];
        for (int i = 0; i < maxRow; i++)
        {
            array[i] = new ChromaSDKBaseAnimation.ColorArray();
            int[] array2 = new int[maxColumn];
            for (int j = 0; j < maxColumn; j++)
            {
                array2[j] = 0;
            }
            array[i].Colors = array2;
        }
        colorFrame2D.Colors = array;
        this._mFrames[0]    = colorFrame2D;
    }
    /// <summary>
    /// Set frames to the default state
    /// </summary>
    public void ClearFrames()
    {
        int maxRow    = ChromaUtils.GetMaxRow(Device);
        int maxColumn = ChromaUtils.GetMaxColumn(Device);

        _mFrames = new ColorFrame2D[1];
        var frame = new ColorFrame2D();
        var rows  = new ColorArray[maxRow];

        for (int i = 0; i < maxRow; ++i)
        {
            rows[i] = new ColorArray();
            var row = new int[maxColumn];
            for (int j = 0; j < maxColumn; ++j)
            {
                row[j] = 0;
            }
            rows[i].Colors = row;
        }
        frame.Colors = rows;
        _mFrames[0]  = frame;
    }
    private void OnClickExportButton()
    {
        ChromaSDKAnimation2D animation = GetAnimation();

        if (animation)
        {
            string initialFileName = string.Format("{0}.chroma", animation.name);
            string path            = EditorUtility.SaveFilePanel("Save Chroma", GetChromaFolder(), initialFileName, GetChromaExtensions());
            if (!string.IsNullOrEmpty(path))
            {
                EditorPrefs.SetString(KEY_FOLDER_CHROMA, Path.GetDirectoryName(path));
                using (FileStream fs = File.Open(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite))
                {
                    using (BinaryWriter bw = new BinaryWriter(fs))
                    {
                        //version
                        bw.Write((int)ANIMATION_VERSION);

                        //device type
                        bw.Write((byte)ChromaDeviceTypeEnum.Type_2D);

                        //device
                        bw.Write((byte)animation.Device);

                        List <EffectArray2dInput> frames = animation.Frames;

                        //frame count
                        bw.Write(frames.Count);

                        //frames
                        for (int index = 0; index < frames.Count; ++index)
                        {
                            EffectArray2dInput frame = frames[index];

                            //duration
                            float duration = 0.0f;
                            if (index < frames.Count &&
                                index < animation.Curve.keys.Length)
                            {
                                if (index == 0)
                                {
                                    duration = animation.Curve.keys[index].time;
                                }
                                else
                                {
                                    duration =
                                        animation.Curve.keys[index].time -
                                        animation.Curve.keys[index - 1].time;
                                }
                            }
                            bw.Write((float)duration);
                            // colors
                            int maxRow    = ChromaUtils.GetMaxRow(animation.Device);
                            int maxColumn = ChromaUtils.GetMaxColumn(animation.Device);
                            for (int i = 0; i < maxRow; ++i)
                            {
                                List <int> row = frame[i];
                                for (int j = 0; j < maxColumn; ++j)
                                {
                                    int color = row[j];
                                    bw.Write((int)color);
                                }
                            }
                        }
                        bw.Flush();
                        AssetDatabase.Refresh();
                    }
                }
            }
        }
    }
    private void OnClickImportButton()
    {
        ChromaSDKAnimation2D animation = GetAnimation();

        if (animation)
        {
            //string initialPath = string.Format("{0}/{1}.chroma", GetChromaFolder(), animation.name);
            string path = EditorUtility.OpenFilePanel("Open Chroma", GetChromaFolder(), GetChromaExtensions());
            if (!string.IsNullOrEmpty(path))
            {
                EditorPrefs.SetString(KEY_FOLDER_CHROMA, Path.GetDirectoryName(path));
                using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    using (BinaryReader br = new BinaryReader(fs))
                    {
                        //version
                        int version = br.ReadInt32();
                        if (version != ANIMATION_VERSION)
                        {
                            Debug.LogError("Unexpected file version!");
                            return;
                        }

                        //device type
                        if (br.ReadByte() != (byte)ChromaDeviceTypeEnum.Type_2D)
                        {
                            Debug.LogError("Unexpected device type!");
                            return;
                        }

                        //device
                        switch ((ChromaDevice2DEnum)br.ReadByte())
                        {
                        case ChromaDevice2DEnum.Keyboard:
                            animation.Device = ChromaDevice2DEnum.Keyboard;
                            break;

                        case ChromaDevice2DEnum.Keypad:
                            animation.Device = ChromaDevice2DEnum.Keypad;
                            break;

                        case ChromaDevice2DEnum.Mouse:
                            animation.Device = ChromaDevice2DEnum.Mouse;
                            break;

                        default:
                            Debug.LogError("Unexpected device!");
                            return;
                        }

                        List <EffectArray2dInput> frames = new List <EffectArray2dInput>();

                        // reset curve
                        while (animation.Curve.keys.Length > 0)
                        {
                            animation.Curve.RemoveKey(0);
                        }

                        //frame count
                        int frameCount = br.ReadInt32();

                        float time = 0f;

                        //frames
                        for (int index = 0; index < frameCount; ++index)
                        {
                            EffectArray2dInput frame = new EffectArray2dInput();

                            //duration
                            float duration = br.ReadSingle();
                            time += duration;
                            animation.Curve.AddKey(time, 0f);
                            // colors
                            int maxRow    = ChromaUtils.GetMaxRow(animation.Device);
                            int maxColumn = ChromaUtils.GetMaxColumn(animation.Device);
                            for (int i = 0; i < maxRow; ++i)
                            {
                                List <int> row = new List <int>();
                                for (int j = 0; j < maxColumn; ++j)
                                {
                                    int color = br.ReadInt32();
                                    row.Add(color);
                                }
                                frame.Add(row);
                            }
                            frames.Add(frame);
                        }

                        animation.Frames = frames;
                    }
                }
            }
        }
    }
    public override void OnInspectorGUI()
    {
        if (!EditorApplication.isCompiling)
        {
            base.OnInspectorGUI();

            // backup original color
            Color oldBackgroundColor = GUI.backgroundColor;

            ChromaSDKAnimation2D animation = GetAnimation();

            if (_mLastTarget != animation)
            {
                _mLastTarget = animation;
                _mDevice     = animation.Device;
            }

            var frames = animation.Frames; //copy

            if (frames.Count == 0)
            {
                OnClickAddButton();
            }

            // Device
            GUILayout.BeginHorizontal(GUILayout.Width(Screen.width - LAYOUT_PADDING));
            GUILayout.Label("Device:");
            _mDevice = (ChromaDevice2DEnum)EditorGUILayout.EnumPopup(_mDevice, GUILayout.Width(150));
            if (GUILayout.Button("Set", GUILayout.Width(100)))
            {
                OnClickSetDevice();
            }
            GUILayout.FlexibleSpace();
            GUILayout.Label(ChromaUtils.VERSION);
            GUILayout.EndHorizontal();

            bool connected = ChromaConnectionManager.Instance.Connected;

            GUI.enabled = connected;

            GUILayout.BeginHorizontal(GUILayout.Width(Screen.width - LAYOUT_PADDING));

            if (GUILayout.Button("Play"))
            {
                OnClickPlayButton();
            }

            if (GUILayout.Button("Stop"))
            {
                OnClickStopButton();
            }

            GUI.enabled = connected && !animation.IsLoaded();
            if (GUILayout.Button("Load"))
            {
                OnClickLoadButton();
            }

            GUI.enabled = connected && animation.IsLoaded();
            if (GUILayout.Button("Unload"))
            {
                OnClickUnloadButton();
            }

            GUI.enabled = true;

            if (GUILayout.Button("Preview") ||
                Event.current.shift)
            {
                OnClickPreviewButton();
            }

            GUILayout.EndHorizontal();

            // Import

            GUILayout.BeginHorizontal(GUILayout.Width(Screen.width - LAYOUT_PADDING));
            GUILayout.FlexibleSpace();
            if (GUILayout.Button("Import"))
            {
                OnClickImportButton();
            }
            if (GUILayout.Button("Export"))
            {
                OnClickExportButton();
            }
            if (GUILayout.Button("Import Image"))
            {
                OnClickImportImageButton();
            }
            if (GUILayout.Button("Import Animation"))
            {
                OnClickImportAnimationButton();
            }
            if (GUILayout.Button("Reverse Animation"))
            {
                OnClickReverseAnimationButton();
            }
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            // Apply
            GUILayout.BeginHorizontal(GUILayout.Width(Screen.width - LAYOUT_PADDING));

            if (GUILayout.Button("Clear"))
            {
                OnClickClearButton();
            }

            if (GUILayout.Button("Fill"))
            {
                OnClickFillButton();
            }

            if (GUILayout.Button("Random"))
            {
                OnClickRandomButton();
            }

            if (GUILayout.Button("Copy"))
            {
                OnClickCopyButton();
            }

            if (GUILayout.Button("Paste"))
            {
                OnClickPasteButton();
            }

            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal(GUILayout.Width(Screen.width - LAYOUT_PADDING));
            if (GUILayout.Button("Contrast"))
            {
                OnClickContrastButton();
            }
            if (GUILayout.Button("Saturate"))
            {
                OnClickSaturateButton();
            }
            if (GUILayout.Button("Desaturate"))
            {
                OnClickDesaturateButton();
            }
            if (GUILayout.Button("Darken"))
            {
                OnClickDarkenButton();
            }
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal(GUILayout.Width(Screen.width - LAYOUT_PADDING));
            if (GUILayout.Button("Shift Down"))
            {
                OnClickShiftButton(1, 0);
            }
            if (GUILayout.Button("Shift Left"))
            {
                OnClickShiftButton(0, -1);
            }
            if (GUILayout.Button("Shift Right"))
            {
                OnClickShiftButton(0, 1);
            }
            if (GUILayout.Button("Shift Up"))
            {
                OnClickShiftButton(-1, 0);
            }
            GUILayout.EndHorizontal();

            // grid info

            int maxRow    = ChromaUtils.GetMaxRow(animation.Device);
            int maxColumn = ChromaUtils.GetMaxColumn(animation.Device);

            GUILayout.Label(string.Format("{0} x {1}", maxRow, maxColumn));

            if (_mDevice == ChromaDevice2DEnum.Keyboard)
            {
                GUILayout.BeginHorizontal(GUILayout.Width(Screen.width));
                _sToggleLabels = EditorGUILayout.Toggle("Labels:", _sToggleLabels);
                _sLabelColor   = EditorGUILayout.ColorField("Label Color:", _sLabelColor);
                GUILayout.FlexibleSpace();
                GUILayout.EndHorizontal();
            }

            // Preview

            // the grid panel
            GUILayout.BeginHorizontal(GUILayout.Width(Screen.width - LAYOUT_PADDING));

            GUILayout.FlexibleSpace();

            // the left-part

            GUILayout.BeginVertical();
            if (GUILayout.Button(" ", GUILayout.Height(20)))
            {
                OnClickFillButton();
            }
            for (int i = 0; i < maxRow; ++i)
            {
                if (GUILayout.Button(" ", GUILayout.Height(20)))
                {
                    OnClickFillRow(i);
                }
            }
            GUILayout.EndVertical();

            // the right-part

            GUILayout.BeginVertical();

            int boxWidth = Screen.width / (maxColumn + 1) - 5;

            // the top-buttons
            GUILayout.BeginHorizontal(GUILayout.Width(Screen.width - LAYOUT_PADDING));
            for (int j = 0; j < maxColumn; ++j)
            {
                if (GUILayout.Button(" ", GUILayout.Width(boxWidth)))
                {
                    OnClickFillColumn(j);
                }
            }
            GUILayout.EndHorizontal();

            // the main-grid

            string    tooltip     = null;
            Rect      tooltipRect = new Rect(0, 0, 0, 0);
            Texture2D oldTexture  = GUI.skin.button.normal.background;
            SetupBlankTexture();
            if (_mCurrentFrame < frames.Count)
            {
                EffectArray2dInput frame = frames[_mCurrentFrame];
                for (int i = 0; i < maxRow && i < frame.Count; ++i)
                {
                    List <int> row = frame[i];
                    GUILayout.BeginHorizontal(GUILayout.Width(Screen.width - LAYOUT_PADDING));

                    for (int j = 0; j < maxColumn && j < row.Count; ++j)
                    {
                        int color = row[j];
                        GUI.backgroundColor = ChromaUtils.ToRGB(color);
                        // use a box instead of button so it looks better
                        GUILayout.Box("", GUILayout.Width(boxWidth));
                        Rect rect = GUILayoutUtility.GetLastRect();
                        // check for hovering box
                        if (Event.current.alt &&
                            rect.Contains(Event.current.mousePosition))
                        {
                            _mColor = ChromaUtils.ToRGB(color);
                        }
                        if (_mDevice == ChromaDevice2DEnum.Keyboard &&
                            !_sToggleLabels &&
                            rect.Contains(Event.current.mousePosition))
                        {
                            tooltip     = ChromaUtils.GetKeyString(i, j);
                            tooltipRect = rect;
                        }
                        // use the box location to use a button to catch the click event
                        GUI.skin.button.normal.background = _sTextureClear;
                        if (GUI.Button(rect, ""))
                        {
                            OnClickColor(i, j);
                        }
                        GUI.skin.button.normal.background = oldTexture;

                        if (_mDevice == ChromaDevice2DEnum.Keyboard &&
                            _sToggleLabels)
                        {
                            string keyString = ChromaUtils.GetKeyString(i, j);
                            Color  oldColor  = GUI.skin.label.normal.textColor;
                            GUI.skin.label.normal.textColor = _sLabelColor;
                            GUI.Label(rect, keyString);
                            GUI.skin.label.normal.textColor = oldColor;
                        }
                    }

                    GUILayout.EndHorizontal();
                }
            }
            GUI.SetNextControlName("");

            if (!string.IsNullOrEmpty(tooltip))
            {
                var     labelStyle = GUI.skin.GetStyle("Label");
                Vector2 size       = labelStyle.CalcSize(new GUIContent(tooltip));
                tooltipRect.y                 -= 20;
                tooltipRect.width              = size.x + 10;
                tooltipRect.height             = size.y + 10;
                GUI.skin.box.normal.background = _sTextureClear;
                GUI.Box(tooltipRect, " ");
                labelStyle.alignment = TextAnchor.MiddleCenter;
                GUI.Label(tooltipRect, tooltip);
            }

            // end of right-part

            GUILayout.EndVertical();

            GUILayout.FlexibleSpace();

            // end of grid panel
            GUILayout.EndHorizontal();

            // restore original color
            GUI.backgroundColor = oldBackgroundColor;

            // show separator
            EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);

            // Key
            if (animation.Device == ChromaDevice2DEnum.Keyboard)
            {
                GUILayout.BeginHorizontal(GUILayout.Width(Screen.width - LAYOUT_PADDING));
                _mKey = (Keyboard.RZKEY)EditorGUILayout.EnumPopup("Select a key", _mKey);
                if (GUILayout.Button("Set key", GUILayout.Width(100)))
                {
                    OnClickColor(
                        ChromaUtils.GetHighByte((int)_mKey),
                        ChromaUtils.GetLowByte((int)_mKey));
                }
                GUILayout.EndHorizontal();
                GUILayout.BeginHorizontal(GUILayout.Width(Screen.width - LAYOUT_PADDING));
                if (GUILayout.Button("Set RZLED_LOGO"))
                {
                    OnClickColor(
                        ChromaUtils.GetHighByte((int)Keyboard.RZLED.RZLED_LOGO),
                        ChromaUtils.GetLowByte((int)Keyboard.RZLED.RZLED_LOGO));
                }
                GUILayout.EndHorizontal();
            }

            // Led
            if (animation.Device == ChromaDevice2DEnum.Mouse)
            {
                GUILayout.BeginHorizontal(GUILayout.Width(Screen.width - LAYOUT_PADDING));
                _mLed = (Mouse.RZLED2)EditorGUILayout.EnumPopup("Select an LED", _mLed);

                if (GUILayout.Button("Set LED", GUILayout.Width(100)))
                {
                    OnClickColor(
                        ChromaUtils.GetHighByte((int)_mLed),
                        ChromaUtils.GetLowByte((int)_mLed));
                }
                GUILayout.EndHorizontal();
            }

            // preset colors

            GUILayout.BeginHorizontal(GUILayout.Width(Screen.width - LAYOUT_PADDING));
            const float k       = 0.5f;
            Color[]     palette =
            {
                Color.red,    Color.red *k,
                ORANGE,       ORANGE *k,
                Color.yellow, Color.yellow *k,
                Color.green,  Color.green *k,
                Color.blue,   Color.blue *k,
                Color.cyan,   Color.cyan *k,
                PURPLE,       PURPLE *k,
                Color.white,  Color.gray,     Color.black,
            };
            foreach (Color color in palette)
            {
                Color newColor = color;
                newColor.a          = 1f;
                GUI.backgroundColor = newColor;
                // use a box instead of button so it looks better
                GUILayout.Box("", GUILayout.Width(12));
                Rect rect = GUILayoutUtility.GetLastRect();
                // use the box location to use a button to catch the click event
                GUI.skin.button.normal.background = _sTextureClear;
                if (GUI.Button(rect, ""))
                {
                    _mColor = newColor;
                }
                GUI.skin.button.normal.background = oldTexture;
            }
            GUILayout.EndHorizontal();

            // restore original color
            GUI.backgroundColor = oldBackgroundColor;

            // Set the color

            GUILayout.BeginHorizontal(GUILayout.Width(Screen.width - LAYOUT_PADDING));
            _mColor = EditorGUILayout.ColorField(_mColor, GUILayout.Width(40));
            _mColor = EditorGUILayout.ColorField("Brush color", _mColor);
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal(GUILayout.Width(Screen.width - LAYOUT_PADDING));
            GUI.SetNextControlName(CONTROL_OVERRIDE);
            GUILayout.Label("Override Time (ALL frames)");
            _mOverrideFrameTime = EditorGUILayout.FloatField(_mOverrideFrameTime, GUILayout.Width(100));
            GUI.SetNextControlName(string.Empty);
            if (GUILayout.Button("Override", GUILayout.Width(100)))
            {
                OnClickOverrideButton();
            }
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            EditorGUILayout.LabelField("Frame:", string.Format("{0} of {1}",
                                                               _mCurrentFrame + 1,
                                                               null == frames ? 0 : frames.Count));

            float duration = 0.0f;
            if (_mCurrentFrame < frames.Count &&
                _mCurrentFrame < animation.Curve.keys.Length)
            {
                if (_mCurrentFrame == 0)
                {
                    duration = animation.Curve.keys[_mCurrentFrame].time;
                }
                else
                {
                    duration =
                        animation.Curve.keys[_mCurrentFrame].time -
                        animation.Curve.keys[_mCurrentFrame - 1].time;
                }
            }

            GUI.SetNextControlName(CONTROL_DURATION);
            GUILayout.BeginHorizontal(GUILayout.Width(Screen.width - LAYOUT_PADDING));
            float newDuration = EditorGUILayout.FloatField("Duration:", duration);
            if (duration != newDuration &&
                newDuration > 0f)
            {
                if (_mCurrentFrame < frames.Count &&
                    _mCurrentFrame < animation.Curve.keys.Length)
                {
                    float time;
                    if (_mCurrentFrame == 0)
                    {
                        time = newDuration;
                    }
                    else
                    {
                        time = animation.Curve.keys[_mCurrentFrame - 1].time + newDuration;
                    }
                    animation.Curve.RemoveKey(_mCurrentFrame);
                    animation.Curve.AddKey(time, 0f);
                }
            }
            GUILayout.Label("seconds(s)");
            GUILayout.EndHorizontal();
            GUI.SetNextControlName(string.Empty);

            GUILayout.BeginHorizontal(GUILayout.Width(Screen.width - LAYOUT_PADDING));

            if (GUILayout.Button("First"))
            {
                OnClickFirstButton();
            }

            if (GUILayout.Button("Previous"))
            {
                OnClickPreviousButton();
            }

            if (GUILayout.Button("Next"))
            {
                OnClickNextButton();
            }

            if (GUILayout.Button("Last"))
            {
                OnClickLastButton();
            }

            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal(GUILayout.Width(Screen.width - LAYOUT_PADDING));

            if (GUILayout.Button("Add"))
            {
                OnClickAddButton();
            }

            if (GUILayout.Button("Insert"))
            {
                OnClickInsertButton();
            }

            if (GUILayout.Button("Delete"))
            {
                OnClickDeleteButton();
            }

            if (GUILayout.Button("Reset"))
            {
                OnClickResetButton();
            }

            GUILayout.EndHorizontal();


            // Custom Curve
            animation.Curve = EditorGUILayout.CurveField("Edit Curve:", animation.Curve);

            //Debug.Log(GUI.GetNameOfFocusedControl());
            if (string.IsNullOrEmpty(GUI.GetNameOfFocusedControl()))
            {
                Event e = Event.current;
                if (e.type == EventType.keyUp)
                {
                    if (e.keyCode == KeyCode.Delete)
                    {
                        OnClickClearButton();
                        Repaint();
                    }
                    else if (e.keyCode == KeyCode.C &&
                             e.modifiers == EventModifiers.Control)
                    {
                        OnClickCopyButton();
                    }
                    else if (e.keyCode == KeyCode.V &&
                             e.modifiers == EventModifiers.Control)
                    {
                        OnClickPasteButton();
                        Repaint();
                    }
                    else if (e.keyCode == KeyCode.P)
                    {
                        OnClickPlayButton();
                    }
                    else if (e.keyCode == KeyCode.LeftArrow)
                    {
                        OnClickPreviousButton();
                        Repaint();
                    }
                    else if (e.keyCode == KeyCode.RightArrow)
                    {
                        OnClickNextButton();
                        Repaint();
                    }
                    else if (e.keyCode == KeyCode.Plus ||
                             e.keyCode == KeyCode.KeypadPlus)
                    {
                        OnClickAddButton();
                        Repaint();
                    }
                    else if (e.keyCode == KeyCode.Minus ||
                             e.keyCode == KeyCode.KeypadMinus)
                    {
                        OnClickDeleteButton();
                        Repaint();
                    }
                    else if (e.keyCode == KeyCode.Space)
                    {
                        OnClickPlayButton();
                        Repaint();
                    }
                }
            }
        }

        Repaint();
    }
    private void OnGUI()
    {
        if (_mCapturing)
        {
            if (_mTimerCapture < DateTime.Now)
            {
                _mTimerCapture = DateTime.Now + TimeSpan.FromSeconds(_mInterval);
                CaptureFrame();
            }
        }

        GameObject activeGameObject = Selection.activeGameObject;
        Object     activeObject     = Selection.activeObject;

        if (activeGameObject)
        {
            ParticleSystem particleSystem = activeGameObject.GetComponent <ParticleSystem>();
            if (particleSystem)
            {
                _mParticleSystem = particleSystem;
            }
        }

#if SHOW_TEMP_TEXTURE
        _mTempTexture = (Texture2D)EditorGUILayout.ObjectField("TempTexture", _mTempTexture, typeof(Texture2D), true);
#endif

        _mAnimation = (ChromaSDKBaseAnimation)EditorGUILayout.ObjectField("Animation", _mAnimation, typeof(ChromaSDKBaseAnimation), true);

        _mRenderCamera = (Camera)EditorGUILayout.ObjectField("RenderCamera", _mRenderCamera, typeof(Camera), true);

        GUILayout.BeginHorizontal(GUILayout.Width(position.width));
        GUILayout.Label("Select:");
        GUI.enabled = null != _mAnimation;
        if (GUILayout.Button("Animation"))
        {
            Selection.activeGameObject = null;
            Selection.activeObject     = _mAnimation;
        }
        GUI.enabled = null != _mRenderCamera;
        if (GUILayout.Button("Camera"))
        {
            Selection.activeObject     = null;
            Selection.activeGameObject = _mRenderCamera.gameObject;
        }
        GUI.enabled = null != _mParticleSystem;
        if (GUILayout.Button("ParticleSystem"))
        {
            Selection.activeGameObject = null;
            Selection.activeObject     = _mParticleSystem;
        }
        GUI.enabled = true;
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal(GUILayout.Width(position.width));
        GUILayout.Label("Camera:");
        GUI.enabled = null != _mRenderCamera;
        if (GUILayout.Button("Align With View"))
        {
            Selection.activeGameObject = _mRenderCamera.gameObject;
            EditorApplication.ExecuteMenuItem("GameObject/Align With View");
            Selection.activeObject     = activeObject;
            Selection.activeGameObject = activeGameObject;
        }
        GUI.enabled = true;
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal(GUILayout.Width(position.width));
        GUILayout.Label("Animation:");
        if (_mAnimation)
        {
            GUI.enabled = ChromaConnectionManager.Instance.Connected;
            if (GUILayout.Button("Play"))
            {
                _mAnimation.Play();
            }
            GUI.enabled = IsAnimationSelected() && !_mAnimation.IsPlaying();
            if (GUILayout.Button("First"))
            {
                ChromaSDKAnimationBaseEditor.GoToFirstFrame();
            }
            if (GUILayout.Button("Last"))
            {
                ChromaSDKAnimationBaseEditor.GoToLastFrame();
            }
            if (GUILayout.Button("Delete"))
            {
                DeleteFrame();
            }
            GUI.enabled = !_mAnimation.IsPlaying();
            if (GUILayout.Button("Reset"))
            {
                ResetAnimation();
            }
            GUI.enabled = true;
        }
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal(GUILayout.Width(position.width));
        float interval = EditorGUILayout.FloatField("Capture Interval", _mInterval);
        if (interval >= 0.1f)
        {
            _mInterval = interval;
        }
        int frameCount = 0;
        if (_mAnimation)
        {
            frameCount = _mAnimation.GetFrameCount();
        }
        GUILayout.Label(string.Format("{0} frames", frameCount));
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal(GUILayout.Width(position.width));
        GUILayout.Label("Capture:");
        GUI.enabled = null != _mRenderCamera && null != _mAnimation && !_mAnimation.IsPlaying();
        if (GUILayout.Button("1 Frame"))
        {
            CaptureFrame();
        }
        if (GUILayout.Button(_mCapturing ? "Stop" : "Start"))
        {
            _mCapturing = !_mCapturing;
            if (!_mCapturing)
            {
                AutoOverrideTime();
            }
        }
        GUI.enabled = true;
        GUILayout.EndHorizontal();

        Rect rect = GUILayoutUtility.GetLastRect();
        if (_mRenderCamera)
        {
            if (null == _mRenderTexture)
            {
                _mRenderTexture = new RenderTexture(RENDER_TEXTURE_SIZE, RENDER_TEXTURE_SIZE, 24, RenderTextureFormat.ARGB32);
                _mRenderCamera.targetTexture = _mRenderTexture;
            }
            _mRenderCamera.Render();
            rect.y += 30;
            DisplayRenderTexture((int)rect.y, RENDER_TEXTURE_SIZE, RENDER_TEXTURE_SIZE);
            if (_mAnimation)
            {
                rect.y += 300;
                const int padding = 8;
                if (_mAnimation is ChromaSDKAnimation1D)
                {
                    int maxLeds = ChromaUtils.GetMaxLeds((_mAnimation as ChromaSDKAnimation1D).Device);
                    for (int k = 1; (k * maxLeds) < position.width && (rect.y + rect.height) <= position.height; k *= 2)
                    {
                        DisplayRenderTexture((int)rect.y, maxLeds * k, k);
                        rect.y += k + padding;
                    }
                }
                else if (_mAnimation is ChromaSDKAnimation2D)
                {
                    int maxRow    = ChromaUtils.GetMaxRow((_mAnimation as ChromaSDKAnimation2D).Device);
                    int maxColumn = ChromaUtils.GetMaxColumn((_mAnimation as ChromaSDKAnimation2D).Device);
                    DisplayRenderTexture((int)rect.y, maxColumn, maxRow);
                    for (int k = 1; (k * maxColumn) < position.width && (rect.y + rect.height) <= position.height; k *= 2)
                    {
                        DisplayRenderTexture((int)rect.y, maxColumn * k, maxRow * k);
                        rect.y += maxRow * k + padding;
                    }
                }
            }
        }

        Repaint();
    }
    private void CaptureFrame()
    {
        if (_mAnimation && _mRenderTexture && _mRenderCamera)
        {
            if (_mAnimation is ChromaSDKAnimation1D)
            {
                ChromaSDKAnimation1D animation = (ChromaSDKAnimation1D)_mAnimation;
                animation.Unload();
                int maxLeds = ChromaUtils.GetMaxLeds(animation.Device);

                _mTempTexture        = new Texture2D(RENDER_TEXTURE_SIZE, RENDER_TEXTURE_SIZE, TextureFormat.RGB24, false);
                RenderTexture.active = _mRenderTexture;
                _mRenderCamera.Render();
                DisplayRenderTexture(0, maxLeds, 1);
                _mTempTexture.ReadPixels(new Rect(0, 0, _mTempTexture.width, _mTempTexture.height), 0, 0, false);
                _mTempTexture.Apply();
                TextureScale.Bilinear(_mTempTexture, maxLeds, 1);
                _mTempTexture.Apply();
                RenderTexture.active = null;
                Color[] pixels = _mTempTexture.GetPixels();
                List <EffectArray1dInput> frames = animation.Frames;
                EffectArray1dInput        frame  = ChromaUtils.CreateColors1D(animation.Device);
                int index = 0;
                if (frame.Count > 0)
                {
                    for (int i = 0; i < maxLeds; ++i)
                    {
                        Color color = pixels[index];
                        frame[i] = ChromaUtils.ToBGR(color);
                        ++index;
                    }
                }
#if !SHOW_TEMP_TEXTURE
                DestroyImmediate(_mTempTexture);
#endif
                frames.Add(frame);
                animation.Frames = frames;
                ChromaSDKAnimationBaseEditor.GoToLastFrame();
            }
            else if (_mAnimation is ChromaSDKAnimation2D)
            {
                ChromaSDKAnimation2D animation = (ChromaSDKAnimation2D)_mAnimation;
                animation.Unload();
                int maxRow    = ChromaUtils.GetMaxRow(animation.Device);
                int maxColumn = ChromaUtils.GetMaxColumn(animation.Device);

                _mTempTexture        = new Texture2D(RENDER_TEXTURE_SIZE, RENDER_TEXTURE_SIZE, TextureFormat.RGB24, false);
                RenderTexture.active = _mRenderTexture;
                _mRenderCamera.Render();
                DisplayRenderTexture(0, maxColumn, maxRow);
                _mTempTexture.ReadPixels(new Rect(0, 0, _mTempTexture.width, _mTempTexture.height), 0, 0, false);
                _mTempTexture.Apply();
                TextureScale.Bilinear(_mTempTexture, maxColumn, maxRow);
                _mTempTexture.Apply();
                RenderTexture.active = null;
                Color[] pixels = _mTempTexture.GetPixels();
                List <EffectArray2dInput> frames = animation.Frames;
                EffectArray2dInput        frame  = ChromaUtils.CreateColors2D(animation.Device);
                int index = 0;
                for (int i = maxRow - 1; i >= 0; --i)
                {
                    List <int> row = frame[i];
                    for (int j = 0; j < maxColumn; ++j)
                    {
                        Color color = pixels[index];
                        row[j] = ChromaUtils.ToBGR(color);
                        ++index;
                    }
                }
#if !SHOW_TEMP_TEXTURE
                DestroyImmediate(_mTempTexture);
#endif
                frames.Add(frame);
                animation.Frames = frames;
                ChromaSDKAnimationBaseEditor.GoToLastFrame();
            }
        }
    }