Ejemplo n.º 1
0
 // Constructor
 public ControllerCallbacks()
 {
     // out
     // nanoKontrol: 1
     // Launchpad: 3
     lpd = new Launchpad(MIDIs.Get(3));
 }
Ejemplo n.º 2
0
        public static void Create(Launchpad launchpad, Window owner)
        {
            if (launchpad.Window == null)
            {
                launchpad.Window = new LaunchpadWindow(launchpad);

                if (owner == null || owner.WindowState == WindowState.Minimized)
                {
                    launchpad.Window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
                }
                else
                {
                    launchpad.Window.Owner = owner;
                }

                launchpad.Window.Show();
                launchpad.Window.Owner = null;
            }
            else
            {
                launchpad.Window.WindowState = WindowState.Normal;
                launchpad.Window.Activate();
            }

            launchpad.Window.Topmost = true;
            launchpad.Window.Topmost = Preferences.AlwaysOnTop;
        }
Ejemplo n.º 3
0
    static public void Buttons(MonoBehaviour owner, Launchpad launchpad)
    {
        if (launchpad == null || launchpad.pads == null)
        {
            return;
        }

        var buttonOption = GUILayout.Width(64);

        for (var i = 0; i < launchpad.pads.Length; i++)
        {
            var pad    = launchpad.pads [i];
            var column = i % launchpad.padsPerLine;

            if (column == 0)
            {
                EditorGUILayout.BeginHorizontal();
            }

            if (GUILayout.Button(pad.DisplayName, buttonOption) && EditorApplication.isPlaying)
            {
                launchpad.Launch(owner, pad);
            }

            if (column == launchpad.padsPerLine - 1 || i == launchpad.pads.Length - 1)
            {
                EditorGUILayout.EndHorizontal();
            }
        }
    }
Ejemplo n.º 4
0
        public bool DisplayWarning(Window sender, bool dispatcher = false)
        {
            if (State != PortWarningType.Show)
            {
                return(false);
            }

            State = PortWarningType.Done;

            Action DisplayMessage = async() => {
                string[] actions = options.Select(i => i.action).ToArray();
                int      result;

                if ((result = Array.IndexOf(actions, await MessageWindow.Create(message, actions.Append("Ignore").ToArray(), sender))) != -1)
                {
                    App.URL(options[result].url);
                }

                Launchpad.DisplayWarnings(sender);
            };

            if (dispatcher)
            {
                Dispatcher.UIThread.Post(DisplayMessage, DispatcherPriority.MinValue);
            }
            else
            {
                DisplayMessage.Invoke();
            }

            return(true);
        }
Ejemplo n.º 5
0
        public LaunchpadInfo(Launchpad launchpad)
        {
            InitializeComponent();

            _launchpad      = launchpad;
            _launchpad.Info = this;

            this.Get <TextBlock>("Name").Text = _launchpad.Name.Trim();

            Rotation.SelectedIndex            = (int)_launchpad.Rotation;
            InputFormatSelector.SelectedIndex = (int)_launchpad.InputFormat;

            Popout.IsVisible = _launchpad.Window == null;

            if (_launchpad.GetType() != typeof(Launchpad))
            {
                Reconnect.IsVisible       = false;
                Rotation.IsHitTestVisible = InputFormatSelector.IsHitTestVisible = false;
                Rotation.Opacity          = InputFormatSelector.Opacity = 0;
            }

            if (_launchpad is VirtualLaunchpad vlp)
            {
                LockToggle.IsVisible = true;
                LockToggle.SetState(Preferences.VirtualLaunchpads.Contains(vlp.VirtualIndex));
            }

            if (_launchpad is AbletonLaunchpad)
            {
                TargetPortSelector.IsVisible = true;

                UpdatePorts();
                MIDI.DevicesUpdated += HandlePorts;
            }
        }
Ejemplo n.º 6
0
        public LaunchpadWindow(Launchpad launchpad)
        {
            InitializeComponent();
            #if DEBUG
            this.AttachDevTools();
            #endif

            UpdateTopmost(Preferences.AlwaysOnTop);
            Preferences.AlwaysOnTopChanged += UpdateTopmost;

            _launchpad = launchpad;

            Title = TitleText.Text = TitleCenter.Text = _launchpad.Name;

            for (int i = 0; i < 100; i++)
            {
                Grid.SetColor(LaunchpadGrid.SignalToGrid(i), launchpad.GetColor(i).ToScreenBrush());
            }

            observables.Add(Grid.GetObservable(Visual.BoundsProperty).Subscribe(Grid_Updated));

            observables.Add(this.GetObservable(Visual.BoundsProperty).Subscribe(Bounds_Updated));
            observables.Add(TitleText.GetObservable(Visual.BoundsProperty).Subscribe(Bounds_Updated));
            observables.Add(TitleCenter.GetObservable(Visual.BoundsProperty).Subscribe(Bounds_Updated));
            observables.Add(CenteringLeft.GetObservable(Visual.BoundsProperty).Subscribe(Bounds_Updated));
            observables.Add(CenteringRight.GetObservable(Visual.BoundsProperty).Subscribe(Bounds_Updated));
        }
Ejemplo n.º 7
0
 void Port_Changed(Launchpad selected)
 {
     if (selected != null && _track.Launchpad != selected)
     {
         _track.Launchpad = selected;
     }
 }
Ejemplo n.º 8
0
        public LaunchpadInfo(Launchpad launchpad)
        {
            InitializeComponent();

            _launchpad = launchpad;

            this.Get <TextBlock>("Name").Text = _launchpad.Name.Trim();

            Rotation.SelectedIndex            = (int)_launchpad.Rotation;
            InputFormatSelector.SelectedIndex = (int)_launchpad.InputFormat;

            if (_launchpad.GetType() != typeof(Launchpad))
            {
                Rotation.IsEnabled = InputFormatSelector.IsEnabled = false;
                Rotation.Opacity   = Rotation.Width = InputFormatSelector.Opacity = InputFormatSelector.Width = 0;
            }

            if (_launchpad.GetType() == typeof(VirtualLaunchpad))
            {
                Popout.IsEnabled = false;
                Popout.Opacity   = Popout.Width = 0;
            }

            if (_launchpad.GetType() == typeof(AbletonLaunchpad))
            {
                TargetPortSelector.IsEnabled = true;
                TargetPortSelector.Opacity   = 1;

                UpdatePorts();
                MIDI.DevicesUpdated += HandlePorts;
            }
        }
Ejemplo n.º 9
0
        public bool DisplayWarning(Window sender, bool dispatcher = false)
        {
            if (State != PortWarningType.Show)
            {
                return(false);
            }

            State = PortWarningType.Done;

            Action DisplayMessage = async() => {
                if (await MessageWindow.Create(message, new string[] { action, "OK" }, sender) == action)
                {
                    App.URL(url);
                }

                Launchpad.DisplayWarnings(sender);
            };

            if (dispatcher)
            {
                Dispatcher.UIThread.Post(DisplayMessage, DispatcherPriority.MinValue);
            }
            else
            {
                DisplayMessage.Invoke();
            }

            return(true);
        }
Ejemplo n.º 10
0
        public async Task Launchpads_Get_By_Id_Mock()
        {
            // arrange
            var mockService = new Mock <ILaunchDataService>();

            Launchpad launchpad = new Launchpad
            {
                Id     = "xxx-yyyy-zzz",
                Name   = "Test Launchpad",
                Status = "active"
            };

            mockService.Setup(s => s.GetLaunchpadDataById("xxx-yyyy-zzz"))
            .Returns(Task.FromResult(launchpad));

            var controller = new LaunchesController(mockService.Object);

            // act
            var result = await controller.GetLaunchpadById("xxx-yyyy-zzz");

            // assert
            var okResult = result.Should().BeOfType <OkObjectResult>().Subject;
            var actual   = okResult.Value.Should().BeAssignableTo <Launchpad>().Subject;

            actual.Id.Should().Be("xxx-yyyy-zzz");
        }
Ejemplo n.º 11
0
        private void TargetPort_Changed(object sender, SelectionChangedEventArgs e)
        {
            Launchpad selected = (Launchpad)TargetPortSelector.SelectedItem;

            if (_launchpad is AbletonLaunchpad abletonLaunchpad && selected != null && abletonLaunchpad.Target != selected)
            {
                abletonLaunchpad.Target = selected;
            }
        }
Ejemplo n.º 12
0
        // TODO: move to mapping package (e.g.: automapper) based on performance/need
        LaunchpadViewModel ConvertToLaunchpadViewModel(Launchpad launchpad)
        {
            var l = new LaunchpadViewModel()
            {
                Id = launchpad.id, Name = launchpad.full_name, Status = launchpad.status
            };

            return(string.IsNullOrEmpty(l.Id) ? null : l);
        }
Ejemplo n.º 13
0
        void Unloaded(object sender, VisualTreeAttachmentEventArgs e)
        {
            if (_launchpad.GetType() == typeof(AbletonLaunchpad))
            {
                MIDI.DevicesUpdated -= HandlePorts;
            }

            _launchpad = null;
        }
Ejemplo n.º 14
0
        // Constructor
        public ControllerCallbacks()
        {
            MIDIs.ListAll();
            lpd = new Launchpad(MIDIs.Get("MIDIOUT2"));

            Thread th = new Thread(SyncScreen);

            th.IsBackground = true;
            th.Start();
        }
Ejemplo n.º 15
0
        // Constructor
        public ControllerCallbacks()
        {
            Logger.Log("Profile Running.");

            // Load Launchpad (Helper class) from MIDIout#2
            if (MIDIs.Get(2) != null)
            {
                lpd = new Launchpad(MIDIs.Get(2));                      // lame but the only pain
            }
        }
Ejemplo n.º 16
0
        private void Unloaded(object sender, EventArgs e)
        {
            _launchpad.Window = null;

            Preferences.AlwaysOnTopChanged -= UpdateTopmost;

            if (_launchpad.GetType() == typeof(VirtualLaunchpad))
            {
                MIDI.Disconnect(_launchpad);
            }

            _launchpad = null;
        }
Ejemplo n.º 17
0
        static void Encode(BinaryWriter writer, Launchpad o)
        {
            EncodeID(writer, typeof(Launchpad));

            if (o == MIDI.NoOutput)
            {
                writer.Write("");
            }
            else
            {
                writer.Write(o.Name);
                writer.Write((int)o.InputFormat);
                writer.Write((int)o.Rotation);
            }
        }
Ejemplo n.º 18
0
        // Constructor
        public ControllerCallbacks()
        {
            Logger.Log("Profile Running");

            Keyboard.FullScanCodeMode = true;   // virtual key codes might not works to some game settings, so scan mode instead.

            if (MIDIs.Get(2) != null)
            {
                lpd = new Launchpad(MIDIs.Get(2));                     // lame but the only pain
            }
            Thread th = new Thread(Shift);

            th.IsBackground = true;
            th.Start();
        }
Ejemplo n.º 19
0
        void TargetPort_Changed(Launchpad selected)
        {
            if (_launchpad is AbletonLaunchpad abletonLaunchpad)
            {
                if (selected != null && abletonLaunchpad.Target != selected && abletonLaunchpad.PatternWindow == null && _launchpad.PatternWindow == null)
                {
                    abletonLaunchpad.Target = selected;
                }

                else
                {
                    TargetPortSelector.SelectedItem = abletonLaunchpad.Target;
                }
            }
        }
Ejemplo n.º 20
0
        void TargetPort_Changed(object sender, SelectionChangedEventArgs e)
        {
            Launchpad selected = (Launchpad)TargetPortSelector.SelectedItem;

            if (_launchpad is AbletonLaunchpad abletonLaunchpad)
            {
                if (selected != null && abletonLaunchpad.Target != selected && abletonLaunchpad.PatternWindow == null && _launchpad.PatternWindow == null)
                {
                    abletonLaunchpad.Target = selected;
                }

                else
                {
                    TargetPortSelector.SelectedItem = abletonLaunchpad.Target;
                }
            }
        }
Ejemplo n.º 21
0
 public static void Create(Launchpad launchpad, Window owner)
 {
     if (launchpad.Window == null)
     {
         launchpad.Window = new LaunchpadWindow(launchpad)
         {
             Owner = owner
         };
         launchpad.Window.Show();
         launchpad.Window.Owner = null;
     }
     else
     {
         launchpad.Window.WindowState = WindowState.Normal;
         launchpad.Window.Activate();
     }
 }
Ejemplo n.º 22
0
        void Port_Changed(object sender, SelectionChangedEventArgs e)
        {
            Launchpad selected = (Launchpad)PortSelector.SelectedItem;

            if (selected != null && _track.Launchpad != selected)
            {
                Launchpad u    = _track.Launchpad;
                Launchpad r    = selected;
                int       path = _track.ParentIndex.Value;

                Program.Project.Undo.Add($"{_track.ProcessedName} Launchpad Changed to {selected.Name}", () => {
                    Program.Project[path].Launchpad = u;
                }, () => {
                    Program.Project[path].Launchpad = r;
                });

                _track.Launchpad = selected;
            }
        }
Ejemplo n.º 23
0
        public override void Initiate(Launchpad launchpad)
        {
            this.launchpad = launchpad as LaunchpadMk2;
            try
            {
                CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() =>
                {
                    using (var fileStream = File.OpenText(@"Animations\initiate0.piskel"))
                    {
                        var contents = fileStream.ReadToEnd();
                        piskelFile   = new PiskelFile(contents);
                    }

                    var pngData = piskelFile.Layers.First().Chunks.First().Data;
                    bitmap      = SKBitmap.Decode(pngData);

                    var totalFrames = piskelFile.Layers.First().FrameCount;
                    var frameWidth  = bitmap.Width / totalFrames;

                    for (var frameIndex = 0; frameIndex < totalFrames; frameIndex++)
                    {
                        var frame   = new Color[frameWidth, bitmap.Height];
                        var xOffset = frameIndex * frameWidth;
                        for (var y = 0; y < bitmap.Height; y++)
                        {
                            for (var x = 0; x < frameWidth; x++)
                            {
                                var pixel   = bitmap.Pixels[bitmap.Width * y + (x + xOffset)];
                                frame[x, y] = Color.FromArgb(pixel.Alpha, pixel.Red, pixel.Green, pixel.Blue);
                            }
                        }
                        frames.Add(frame);
                    }


                    isInitiated = true;
                });
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
        }
Ejemplo n.º 24
0
        async void Loaded(object sender, EventArgs e)
        {
            Position = new PixelPoint(Position.X, Math.Max(0, Position.Y));

            if (Launchpad.CFWIncompatible == CFWIncompatibleState.Show)
            {
                Launchpad.CFWError(this);
            }

            if (Program.Args?.Length > 0)
            {
                ReadFile(Program.Args[0]);
            }

            Program.Args = null;

            UpdateBlogpost();
            UpdateRelease();

            if (IsVisible && !openDialog && await Github.ShouldUpdate())
            {
                Window[] windows = Application.Current.Windows.ToArray();

                foreach (Window window in windows)
                {
                    if (window.GetType() != typeof(MessageWindow))
                    {
                        window.Close();
                    }
                }

                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    Program.LaunchAdmin = true;
                }
                else
                {
                    UpdateWindow.Create(this);
                }
            }
        }
Ejemplo n.º 25
0
        void Loaded(object sender, EventArgs e)
        {
            Position = new PixelPoint(Position.X, Math.Max(0, Position.Y));

            Launchpad.DisplayWarnings(this);

            if (App.Args?.Length > 0)
            {
                ReadFile(App.Args[0]);
            }

            App.Args = null;

            UpdateBlogpost();
            UpdateRelease();

            if (!Program.HadCrashed)
            {
                CheckUpdate();
            }
        }
Ejemplo n.º 26
0
        public LaunchpadWindow(Launchpad launchpad)
        {
            InitializeComponent();
            #if DEBUG
            this.AttachDevTools();
            #endif

            UpdateTopmost(Preferences.AlwaysOnTop);
            Preferences.AlwaysOnTopChanged += UpdateTopmost;

            _launchpad = launchpad;

            Title = this.Get <TextBlock>("Title").Text = _launchpad.Name;

            for (int i = 0; i < 100; i++)
            {
                Grid.SetColor(LaunchpadGrid.SignalToGrid(i), launchpad.GetColor(i).ToScreenBrush());
            }

            Grid.GetObservable(Visual.BoundsProperty).Subscribe(Bounds_Updated);
        }
Ejemplo n.º 27
0
        public void UpdatePorts()
        {
            List <Launchpad> ports = (from i in MIDI.Devices where i.Available && i.Type != LaunchpadType.Unknown && i.GetType() != typeof(AbletonLaunchpad) select i).ToList();

            Launchpad target = null;

            if (_launchpad is AbletonLaunchpad abletonLaunchpad)
            {
                target = abletonLaunchpad.Target;
                if (target != null && (!target.Available || target.Type == LaunchpadType.Unknown))
                {
                    ports.Add(target);
                }
            }

            ports.Add(MIDI.NoOutput);

            TargetPortSelector.Items         = ports;
            TargetPortSelector.SelectedIndex = -1;
            TargetPortSelector.SelectedItem  = target;
        }
Ejemplo n.º 28
0
        void Unloaded(object sender, CancelEventArgs e)
        {
            _launchpad.Window = null;

            Preferences.AlwaysOnTopChanged -= UpdateTopmost;

            _launchpad.Info?.SetPopout(true);

            if (_launchpad is VirtualLaunchpad lp && !Preferences.VirtualLaunchpads.Contains(lp.VirtualIndex))
            {
                MIDI.Disconnect(_launchpad);
            }

            _launchpad = null;

            foreach (IDisposable observable in observables)
            {
                observable.Dispose();
            }

            this.Content = null;
        }
Ejemplo n.º 29
0
    public static void Buttons(MonoBehaviour owner, Launchpad launchpad)
    {
        if (launchpad == null || launchpad.pads == null)
            return;

        var buttonOption = GUILayout.Width (64);

        for (var i = 0; i < launchpad.pads.Length; i++)
        {
            var pad = launchpad.pads [i];
            var column = i % launchpad.padsPerLine;

            if (column == 0)
                EditorGUILayout.BeginHorizontal ();

            if (GUILayout.Button (pad.DisplayName, buttonOption) && EditorApplication.isPlaying)
                launchpad.Launch (owner, pad);

            if (column == launchpad.padsPerLine - 1 || i == launchpad.pads.Length - 1)
                EditorGUILayout.EndHorizontal ();
        }
    }
Ejemplo n.º 30
0
 public Launchpad ToDomain()
 {
     return(Launchpad.Reconstitute(Id, Full_Name, Status, Details));
 }
Ejemplo n.º 31
0
        static dynamic Decode(BinaryReader reader, int version, Type ensure = null, bool root = false)
        {
            Type t = DecodeID(reader);

            if (ensure != null && ensure != t)
            {
                throw new InvalidDataException();
            }

            if (t == typeof(Preferences) && root)
            {
                Preferences.AlwaysOnTop         = reader.ReadBoolean();
                Preferences.CenterTrackContents = reader.ReadBoolean();

                if (version >= 9)
                {
                    Preferences.LaunchpadStyle = (LaunchpadStyles)reader.ReadInt32();
                }

                if (version >= 14)
                {
                    Preferences.LaunchpadGridRotation = reader.ReadInt32() > 0;
                }

                Preferences.AutoCreateKeyFilter  = reader.ReadBoolean();
                Preferences.AutoCreatePageFilter = reader.ReadBoolean();

                if (version >= 11)
                {
                    Preferences.AutoCreatePattern = reader.ReadBoolean();
                }

                Preferences.FadeSmoothness    = reader.ReadDouble();
                Preferences.CopyPreviousFrame = reader.ReadBoolean();

                if (version >= 7)
                {
                    Preferences.CaptureLaunchpad = reader.ReadBoolean();
                }

                Preferences.EnableGestures = reader.ReadBoolean();

                if (version >= 7)
                {
                    Preferences.PaletteName   = reader.ReadString();
                    Preferences.CustomPalette = new Palette((from i in Enumerable.Range(0, 128) select(Color) Decode(reader, version)).ToArray());
                    Preferences.ImportPalette = (Palettes)reader.ReadInt32();

                    Preferences.Theme = (Themes)reader.ReadInt32();
                }

                if (version >= 10)
                {
                    Preferences.Backup   = reader.ReadBoolean();
                    Preferences.Autosave = reader.ReadBoolean();
                }

                if (version >= 12)
                {
                    Preferences.UndoLimit = reader.ReadBoolean();
                }

                if (version <= 0)
                {
                    Preferences.DiscordPresence = true;
                    reader.ReadBoolean();
                }
                else
                {
                    Preferences.DiscordPresence = reader.ReadBoolean();
                }

                Preferences.DiscordFilename = reader.ReadBoolean();

                ColorHistory.Set(
                    (from i in Enumerable.Range(0, reader.ReadInt32()) select(Color) Decode(reader, version)).ToList()
                    );

                if (version >= 2)
                {
                    MIDI.Devices = (from i in Enumerable.Range(0, reader.ReadInt32()) select(Launchpad) Decode(reader, version)).ToList();
                }

                if (version >= 15)
                {
                    Preferences.Recents   = (from i in Enumerable.Range(0, reader.ReadInt32()) select reader.ReadString()).ToList();
                    Preferences.CrashName = reader.ReadString();
                    Preferences.CrashPath = reader.ReadString();
                }

                if (version >= 16)
                {
                    Preferences.CheckForUpdates = reader.ReadBoolean();
                }

                if (version >= 17)
                {
                    Preferences.BaseTime = reader.ReadInt64();
                }

                return(null);
            }
            else if (t == typeof(Copyable))
            {
                return(new Copyable()
                {
                    Contents = (from i in Enumerable.Range(0, reader.ReadInt32()) select(ISelect) Decode(reader, version)).ToList()
                });
            }
            else if (t == typeof(Project))
            {
                int          bpm    = reader.ReadInt32();
                int          page   = reader.ReadInt32();
                List <Track> tracks = (from i in Enumerable.Range(0, reader.ReadInt32()) select(Track) Decode(reader, version)).ToList();

                string author  = "";
                long   time    = 0;
                long   started = 0;

                if (version >= 17)
                {
                    author  = reader.ReadString();
                    time    = reader.ReadInt64();
                    started = reader.ReadInt64();
                }

                return(new Project(bpm, page, tracks, author, time, started));
            }
            else if (t == typeof(Track))
            {
                Chain     chain = (Chain)Decode(reader, version);
                Launchpad lp    = (Launchpad)Decode(reader, version);
                string    name  = reader.ReadString();

                bool enabled = true;
                if (version >= 8)
                {
                    enabled = reader.ReadBoolean();
                }

                return(new Track(chain, lp, name)
                {
                    Enabled = enabled
                });
            }
            else if (t == typeof(Chain))
            {
                List <Device> devices = (from i in Enumerable.Range(0, reader.ReadInt32()) select(Device) Decode(reader, version)).ToList();
                string        name    = reader.ReadString();

                bool enabled = true;
                if (version >= 6)
                {
                    enabled = reader.ReadBoolean();
                }

                return(new Chain(devices, name)
                {
                    Enabled = enabled
                });
            }
            else if (t == typeof(Device))
            {
                bool collapsed = false;
                if (version >= 5)
                {
                    collapsed = reader.ReadBoolean();
                }

                bool enabled = true;
                if (version >= 5)
                {
                    enabled = reader.ReadBoolean();
                }

                Device ret = (Device)Decode(reader, version);
                ret.Collapsed = collapsed;
                ret.Enabled   = enabled;

                return(ret);
            }
            else if (t == typeof(Launchpad))
            {
                string name = reader.ReadString();
                if (name == "")
                {
                    return(MIDI.NoOutput);
                }

                InputType format = InputType.DrumRack;
                if (version >= 2)
                {
                    format = (InputType)reader.ReadInt32();
                }

                RotationType rotation = RotationType.D0;
                if (version >= 9)
                {
                    rotation = (RotationType)reader.ReadInt32();
                }

                foreach (Launchpad lp in MIDI.Devices)
                {
                    if (lp.Name == name)
                    {
                        if (lp.GetType() == typeof(Launchpad))
                        {
                            lp.InputFormat = format;
                            lp.Rotation    = rotation;
                        }
                        return(lp);
                    }
                }

                Launchpad ret;
                if (name.Contains("Virtual Launchpad "))
                {
                    ret = new VirtualLaunchpad(name);
                }
                else if (name.Contains("Ableton Connector "))
                {
                    ret = new AbletonLaunchpad(name);
                }
                else
                {
                    ret = new Launchpad(name, format, rotation);
                }

                MIDI.Devices.Add(ret);

                return(ret);
            }
            else if (t == typeof(Group))
            {
                return(new Group(
                           (from i in Enumerable.Range(0, reader.ReadInt32()) select(Chain) Decode(reader, version)).ToList(),
                           reader.ReadBoolean()? (int?)reader.ReadInt32() : null
                           ));
            }

            else if (t == typeof(Choke))
            {
                return(new Choke(
                           reader.ReadInt32(),
                           (Chain)Decode(reader, version)
                           ));
            }

            else if (t == typeof(Clear))
            {
                return(new Clear(
                           (ClearType)reader.ReadInt32()
                           ));
            }

            else if (t == typeof(ColorFilter))
            {
                return(new ColorFilter(
                           reader.ReadDouble(),
                           reader.ReadDouble(),
                           reader.ReadDouble(),
                           reader.ReadDouble(),
                           reader.ReadDouble(),
                           reader.ReadDouble()
                           ));
            }

            else if (t == typeof(Copy))
            {
                Time time;
                if (version <= 2)
                {
                    time = new Time(
                        reader.ReadBoolean(),
                        Decode(reader, version),
                        reader.ReadInt32()
                        );
                }
                else
                {
                    time = Decode(reader, version);
                }

                double gate;
                if (version <= 13)
                {
                    gate = (double)reader.ReadDecimal();
                }
                else
                {
                    gate = reader.ReadDouble();
                }

                return(new Copy(
                           time,
                           gate,
                           (CopyType)reader.ReadInt32(),
                           (GridType)reader.ReadInt32(),
                           reader.ReadBoolean(),
                           (from i in Enumerable.Range(0, reader.ReadInt32()) select(Offset) Decode(reader, version)).ToList()
                           ));
            }
            else if (t == typeof(Delay))
            {
                Time time;
                if (version <= 2)
                {
                    time = new Time(
                        reader.ReadBoolean(),
                        Decode(reader, version),
                        reader.ReadInt32()
                        );
                }
                else
                {
                    time = Decode(reader, version);
                }

                double gate;
                if (version <= 13)
                {
                    gate = (double)reader.ReadDecimal();
                }
                else
                {
                    gate = reader.ReadDouble();
                }

                return(new Delay(time, gate));
            }
            else if (t == typeof(Fade))
            {
                Time time;
                if (version <= 2)
                {
                    time = new Time(
                        reader.ReadBoolean(),
                        Decode(reader, version),
                        reader.ReadInt32()
                        );
                }
                else
                {
                    time = Decode(reader, version);
                }

                double gate;
                if (version <= 13)
                {
                    gate = (double)reader.ReadDecimal();
                }
                else
                {
                    gate = reader.ReadDouble();
                }

                FadePlaybackType playmode = (FadePlaybackType)reader.ReadInt32();

                int           count;
                List <Color>  colors    = (from i in Enumerable.Range(0, count = reader.ReadInt32()) select(Color) Decode(reader, version)).ToList();
                List <double> positions = (from i in Enumerable.Range(0, count) select(version <= 13)? (double)reader.ReadDecimal() : reader.ReadDouble()).ToList();

                return(new Fade(time, gate, playmode, colors, positions));
            }
            else if (t == typeof(Flip))
            {
                return(new Flip(
                           (FlipType)reader.ReadInt32(),
                           reader.ReadBoolean()
                           ));
            }

            else if (t == typeof(Hold))
            {
                Time time;
                if (version <= 2)
                {
                    time = new Time(
                        reader.ReadBoolean(),
                        Decode(reader, version),
                        reader.ReadInt32()
                        );
                }
                else
                {
                    time = Decode(reader, version);
                }

                double gate;
                if (version <= 13)
                {
                    gate = (double)reader.ReadDecimal();
                }
                else
                {
                    gate = reader.ReadDouble();
                }

                return(new Hold(
                           time,
                           gate,
                           reader.ReadBoolean(),
                           reader.ReadBoolean()
                           ));
            }
            else if (t == typeof(KeyFilter))
            {
                bool[] filter;
                if (version <= 18)
                {
                    List <bool> oldFilter = (from i in Enumerable.Range(0, 100) select reader.ReadBoolean()).ToList();
                    oldFilter.Insert(99, false);
                    filter = oldFilter.ToArray();
                }
                else
                {
                    filter = (from i in Enumerable.Range(0, 101) select reader.ReadBoolean()).ToArray();
                }

                return(new KeyFilter(filter));
            }
            else if (t == typeof(Layer))
            {
                int target = reader.ReadInt32();

                BlendingType blending = BlendingType.Normal;
                if (version >= 5)
                {
                    if (version == 5)
                    {
                        blending = (BlendingType)reader.ReadInt32();
                        if ((int)blending == 2)
                        {
                            blending = BlendingType.Mask;
                        }
                    }
                    else
                    {
                        blending = (BlendingType)reader.ReadInt32();
                    }
                }

                int range = 200;
                if (version >= 21)
                {
                    range = reader.ReadInt32();
                }

                return(new Layer(target, blending, range));
            }
            else if (t == typeof(Move))
            {
                return(new Move(
                           Decode(reader, version),
                           (GridType)reader.ReadInt32(),
                           reader.ReadBoolean()
                           ));
            }

            else if (t == typeof(Multi))
            {
                return(new Multi(
                           Decode(reader, version),
                           (from i in Enumerable.Range(0, reader.ReadInt32()) select(Chain) Decode(reader, version)).ToList(),
                           reader.ReadBoolean()? (int?)reader.ReadInt32() : null,
                           (MultiType)reader.ReadInt32()
                           ));
            }

            else if (t == typeof(Output))
            {
                return(new Output(
                           reader.ReadInt32()
                           ));
            }

            else if (t == typeof(PageFilter))
            {
                return(new PageFilter(
                           (from i in Enumerable.Range(0, 100) select reader.ReadBoolean()).ToArray()
                           ));
            }

            else if (t == typeof(Paint))
            {
                return(new Paint(
                           Decode(reader, version)
                           ));
            }

            else if (t == typeof(Pattern))
            {
                int repeats = 1;
                if (version >= 11)
                {
                    repeats = reader.ReadInt32();
                }

                double gate;
                if (version <= 13)
                {
                    gate = (double)reader.ReadDecimal();
                }
                else
                {
                    gate = reader.ReadDouble();
                }

                List <Frame> frames = (from i in Enumerable.Range(0, reader.ReadInt32()) select(Frame) Decode(reader, version)).ToList();
                PlaybackType mode   = (PlaybackType)reader.ReadInt32();

                bool chokeenabled = false;
                int  choke        = 8;

                if (version <= 10)
                {
                    chokeenabled = reader.ReadBoolean();

                    if (version <= 0)
                    {
                        if (chokeenabled)
                        {
                            choke = reader.ReadInt32();
                        }
                    }
                    else
                    {
                        choke = reader.ReadInt32();
                    }
                }

                bool infinite = false;
                if (version >= 4)
                {
                    infinite = reader.ReadBoolean();
                }

                int?rootkey = null;
                if (version >= 12)
                {
                    rootkey = reader.ReadBoolean()? (int?)reader.ReadInt32() : null;
                }

                bool wrap = false;
                if (version >= 13)
                {
                    wrap = reader.ReadBoolean();
                }

                int expanded = reader.ReadInt32();

                Pattern ret = new Pattern(repeats, gate, frames, mode, infinite, rootkey, wrap, expanded);

                if (chokeenabled)
                {
                    return(new Choke(choke, new Chain(new List <Device>()
                    {
                        ret
                    })));
                }

                return(ret);
            }
            else if (t == typeof(Preview))
            {
                return(new Preview());
            }

            else if (t == typeof(Rotate))
            {
                return(new Rotate(
                           (RotateType)reader.ReadInt32(),
                           reader.ReadBoolean()
                           ));
            }

            else if (t == typeof(Switch))
            {
                int page = reader.ReadInt32();

                if (18 <= version && version <= 21 && reader.ReadBoolean())
                {
                    return(new Group(new List <Chain>()
                    {
                        new Chain(new List <Device>()
                        {
                            new Switch(page), new Clear(ClearType.Multi)
                        }, "Switch Reset")
                    }));
                }

                return(new Switch(page));
            }
            else if (t == typeof(Tone))
            {
                return(new Tone(
                           reader.ReadDouble(),
                           reader.ReadDouble(),
                           reader.ReadDouble(),
                           reader.ReadDouble(),
                           reader.ReadDouble()
                           ));
            }

            else if (t == typeof(Color))
            {
                return(new Color(
                           reader.ReadByte(),
                           reader.ReadByte(),
                           reader.ReadByte()
                           ));
            }

            else if (t == typeof(Frame))
            {
                Time time;
                if (version <= 2)
                {
                    time = new Time(
                        reader.ReadBoolean(),
                        Decode(reader, version),
                        reader.ReadInt32()
                        );
                }
                else
                {
                    time = Decode(reader, version);
                }

                Color[] screen;
                if (version <= 19)
                {
                    List <Color> oldScreen = (from i in Enumerable.Range(0, 100) select(Color) Decode(reader, version)).ToList();
                    oldScreen.Insert(99, new Color(0));
                    screen = oldScreen.ToArray();
                }
                else
                {
                    screen = (from i in Enumerable.Range(0, 101) select(Color) Decode(reader, version)).ToArray();
                }

                return(new Frame(time, screen));
            }
            else if (t == typeof(Length))
            {
                return(new Length(
                           reader.ReadInt32()
                           ));
            }

            else if (t == typeof(Offset))
            {
                return(new Offset(
                           reader.ReadInt32(),
                           reader.ReadInt32()
                           ));
            }

            else if (t == typeof(Time))
            {
                return(new Time(
                           reader.ReadBoolean(),
                           Decode(reader, version),
                           reader.ReadInt32()
                           ));
            }

            throw new InvalidDataException();
        }