public void GroupSelectedBlocks() { if (!SelectedBlocks.Any()) { return; } var relatedSegments = Enumerable.Select(SelectedBlocks, b => b.SegmentContext).Distinct().ToList(); MusicSegment segmentForGroup = (relatedSegments.Count == 1 ? relatedSegments.Single().GetModel() : model.MusicSegments[0]); var group = new LoopBlock(model); group.SegmentContext = segmentForGroup; group.StartTime = SelectedBlocks.Min(b => b.StartTime); foreach (var b in SelectedBlocks) { // create an independent copy of the block so transforming its time to local reference frame does not screw up undo Block newChild = Block.FromXML(model, b.GetModel().ToXML()); group.AddChild(newChild, true); } using (ActionManager.CreateTransaction()) { DeleteSelectedBlocks(); ActionManager.RecordAdd(model.Blocks, group); } SelectBlock(BlockViewModel.FromModel(this, group), CompositionMode.None); }
// type may be null, then the target will be auto-inferred based on currently selected blocks public void ConvertSelectedBlocksTo(string type) { bool rampsToColors = (type == "color"); bool colorsToRamps = (type == "ramp"); if (!rampsToColors && !colorsToRamps) { colorsToRamps = SelectedBlocks.Any(b => b is ColorBlockViewModel); rampsToColors = SelectedBlocks.Any(b => b is RampBlockViewModel); if (colorsToRamps && rampsToColors) { throw new ArgumentException("type needs to be given when both color and ramp blocks are selected"); } } using (ActionManager.CreateTransaction()) { for (int i = 0; i < SelectedBlocks.Count; i++) { var block = SelectedBlocks[i].GetModel(); Block convertedBlock; if (rampsToColors && block is RampBlock rampBlock) { convertedBlock = new ColorBlock(model, rampBlock.Tracks.ToArray()) { Color = (rampBlock.StartColor == GloColor.Black ? rampBlock.EndColor : rampBlock.StartColor) }; } else if (colorsToRamps && block is ColorBlock colorBlock) { convertedBlock = new RampBlock(model, colorBlock.Tracks.ToArray()) { StartColor = colorBlock.Color, EndColor = (colorBlock.Color == GloColor.White ? GloColor.Black : GloColor.White) }; } else { continue; } // copy generic properties convertedBlock.StartTime = block.StartTime; convertedBlock.Duration = block.Duration; convertedBlock.SegmentContext = block.SegmentContext; ActionManager.RecordReplace(model.Blocks, block, convertedBlock); SelectedBlocks[i] = BlockViewModel.FromModel(this, convertedBlock); } } }