Esempio n. 1
0
        public virtual void ShiftTracks(int delta, GuiLabs.Undo.ActionManager am = null)
        {
            var oldIndices = Tracks.Select(t => t.GetIndex()).ToList();
            var newIndices = oldIndices.Select(i => i + delta).ToList();

            if (newIndices.Any(i => i < 0 || i >= timeline.Tracks.Count))
            {
                throw new ArgumentException("shifting tracks would move them out of range", "delta");
            }

            // runtime complexity is horrendeous, but we don't have that many tracks ...
            foreach (int i in newIndices)
            {
                if (!oldIndices.Contains(i))
                {
                    am.RecordAdd(Tracks, timeline.Tracks[i]);
                }
            }
            foreach (int i in oldIndices)
            {
                if (!newIndices.Contains(i))
                {
                    am.RecordRemove(Tracks, timeline.Tracks[i]);
                }
            }
        }
        public override void ExtendToTrack(Track fromTrack, Track toTrack, GuiLabs.Undo.ActionManager am = null)
        {
            foreach (var child in _children.Where(b => b.Tracks.Contains(fromTrack)))
            {
                am.RecordAdd(child.Tracks, toTrack);
            }

            RecalcTracks();
        }
Esempio n. 3
0
        public virtual void ExtendToTrack(Track fromTrack, Track toTrack, GuiLabs.Undo.ActionManager am = null)
        {
            if (Tracks.Contains(toTrack))
            {
                throw new InvalidOperationException("block is already part of track");
            }

            //Tracks.Add(toTrack);
            am.RecordAdd(Tracks, toTrack);
        }
        public override void ShiftTracks(int delta, GuiLabs.Undo.ActionManager am = null)
        {
            am.RecordAction(() => { }, RecalcTracks);

            foreach (var child in Children)
            {
                child.ShiftTracks(delta, am);
            }

            RecalcTracks();
        }
Esempio n. 5
0
        public virtual bool RemoveFromTrack(Track track, GuiLabs.Undo.ActionManager am = null)
        {
            if (Tracks.Count <= 1)
            {
                return(false);
            }
            if (!Tracks.Contains(track))
            {
                throw new InvalidOperationException("block is not part of track");
            }

            am.RecordRemove(Tracks, track);
            return(true);
        }
        public override bool RemoveFromTrack(Track track, GuiLabs.Undo.ActionManager am = null)
        {
            if (base.RemoveFromTrack(track, am))
            {
                foreach (var child in _children.Where(b => b.Tracks.Contains(track)).Reverse().ToArray())
                {
                    if (child.Tracks.Count > 1)
                    {
                        am.RecordRemove(child.Tracks, track);
                    }
                    else
                    {
                        am.RecordRemove(_children, child);
                    }
                }

                // since the base method already removed the track from the group block,
                // this call should in theory be redundant
                RecalcTracks();
                return(true);
            }
            return(false);
        }
        public SequencerViewModel(Timeline model)
        {
            this.model = model;

            ActionManager  = new GuiLabs.Undo.ActionManager();
            SelectedBlocks = new ObservableCollection <BlockViewModel>();
            SelectionData  = new SelectionProperties(this);
            Tracks         = model.Tracks.Select(g => new TrackViewModel(this, g));
            MusicSegments  = model.MusicSegments.Select(seg => new MusicSegmentViewModel(this, seg));
            AllBlocks      = model.Blocks.Select(b => BlockViewModel.FromModel(this, b));

            if (Tracks.Count > 0)
            {
                SelectedTrack = Tracks[0];
            }

            ActiveMusicSegment = MusicSegments[model.DefaultMusicSegment.GetIndex()];
            Playback           = new PlaybackViewModel(this);
            Visualization      = new VisualizationViewModel(this);
            Notes = new NotesViewModel(this);

            if (model.MusicFileName != null)
            {
                Playback.LoadFileAsync(model.MusicFileName).Forget();
            }

            Action <BlockViewModel> fn_SubscribeToBlock = bvm => ForwardPropertyEvents(nameof(bvm.EndTimeOccupied), bvm, nameof(TimelineLength));

            AllBlocks.ToList().ForEach(fn_SubscribeToBlock);
            AllBlocks.CollectionChanged += (_, e) =>
            {
                if (e.NewItems != null)
                {
                    e.NewItems.Cast <BlockViewModel>().ToList().ForEach(fn_SubscribeToBlock);
                }
                Notify(nameof(TimelineLength));
            };

            ForwardPropertyEvents(nameof(PipetteTarget), this, nameof(IsPipetteActive));
            ForwardPropertyEvents(nameof(CursorPosition), this,
                                  nameof(CursorPixelPosition), nameof(CursorPixelPositionOnViewport));
            ForwardPropertyEvents(nameof(TimePixelScale), this,
                                  nameof(CursorPixelPosition), nameof(CursorPixelPositionOnViewport),
                                  nameof(CurrentViewLeftPositionTime), nameof(CurrentViewRightPositionTime),
                                  nameof(TimelineWidth), nameof(GridInterval));
            ForwardPropertyEvents(nameof(ActiveMusicSegment), this,
                                  nameof(GridInterval));

            ForwardPropertyEvents(nameof(Playback.MusicDuration), Playback, nameof(TimelineLength));
            ForwardPropertyEvents(nameof(TimelineLength), this, nameof(TimelineWidth));

            ForwardCollectionEvents(SelectedBlocks,
                                    nameof(CanConvertToColor), nameof(CanConvertToRamp),
                                    nameof(CanConvertToAutoDeduced), nameof(ConvertAutoDeduceGestureText));

            Tracks.CollectionChanged += (_, e) =>
            {
                foreach (var b in AllBlocks)
                {
                    b.OnTracksCollectionChanged();
                }
            };

            // Disable pipette whenever the selection is modified.
            SelectedBlocks.CollectionChanged += (_, __) => PipetteTarget = null;
        }