示例#1
0
        /// <summary>
        /// Adds the cell below row.
        /// </summary>
        protected void AddCellBelowRow()
        {
            Cell cell = new Cell(Row);

            // get the value string
            StringBuilder val = new StringBuilder();

            int ltmFactor = 1;

            CellTreeNode c = Row.Cells.Min;

            while (c != FirstSelected)
            {
                if (!string.IsNullOrEmpty(c.Cell.Reference))
                {
                    c = c.Next();
                    continue;
                }

                AddCellValueToAccumulator(c.Cell, Row.Cells.Min.Cell, FirstSelected.Cell, val, ref ltmFactor);
                c = c.Next();
            }

            val.Append('0').Append(BeatCell.MultiplyTerms(BeatCell.Invert(DrawingView.Instance.GridSpacingString), NumIntervals));

            cell.Value = BeatCell.Invert(BeatCell.SimplifyValue(val.ToString()));

            // does having negative positions like this cause problems?
            cell.Position = FirstSelected.Cell.Position - DrawingView.Instance.GridSpacing * NumIntervals;
            Row.Cells.Insert(cell);
            RightIndexBoundOfTransform = -1;
            Row.OffsetValue            = BeatCell.Subtract(Row.OffsetValue, cell.Value);  // don't mult group factor this
        }
示例#2
0
        /// <summary>
        /// Adds the cell to the other cell's groups when applicable
        /// </summary>
        /// <param name="cell">Cell.</param>
        /// <param name="below">Below.</param>
        private static void AddToGroups(Cell cell, Cell below)
        {
            foreach (Repeat rg in below.RepeatGroups.Where(x => x.ActualPosition + x.Length > cell.Position))
            {
                //rg.Cells.Last.Value.GroupActions.Remove();
                cell.RepeatGroups.AddLast(rg);

                // transfer actions if below was last cell of group
                if (rg.ExclusiveCells.Last.Value == below)
                {
                    below.GroupActions.Remove((false, rg));
                    cell.GroupActions.AddLast((false, rg));
                }
            }
            foreach (Multiply mg in below.MultGroups.Where(x => x.ActualPosition + x.Length > cell.Position))
            {
                cell.MultGroups.AddLast(mg);
                if (UserSettings.GetSettings().DrawMultToScale)
                {
                    cell.MultFactor = BeatCell.MultiplyTerms(cell.MultFactor, mg.FactorValue);
                }

                if (mg.ExclusiveCells.Last.Value == below)
                {
                    below.GroupActions.Remove((false, mg));
                    cell.GroupActions.AddLast((false, mg));
                }
            }
        }
示例#3
0
        public string GetValueDividedByMultFactor(string value, bool ignoreSetting = false)
        {
            if (string.IsNullOrEmpty(value) || (!ignoreSetting && !UserSettings.GetSettings().DrawMultToScale))
            {
                return(value);
            }

            return(BeatCell.DivideTerms(value, MultFactor));
        }
        public override void Redo()
        {
            base.Redo();

            if (ChangeOffset)
            {
                Row.Offset     += Duration;
                Row.OffsetValue = BeatCell.Add(Row.OffsetValue, BeatCodeDuration);
            }
        }
        public override void Undo()
        {
            base.Undo();

            if (ChangeOffset)
            {
                Row.Offset     -= Duration;
                Row.OffsetValue = BeatCell.Subtract(Row.OffsetValue, BeatCodeDuration);
            }
        }
示例#6
0
        /// <summary>
        /// Gets the ltm with mult factor.
        /// </summary>
        /// <returns>The ltm with mult factor.</returns>
        public string GetLtmWithMultFactor(bool ignoreSettings = false)
        {
            if (string.IsNullOrEmpty(LastTermModifier) || (!ignoreSettings && !UserSettings.GetSettings().DrawMultToScale))
            {
                return(LastTermModifier);
            }

            if (string.IsNullOrEmpty(MultedLtm))
            {
                MultedLtm = BeatCell.MultiplyTerms(LastTermModifier, MultFactor);
            }

            return(MultedLtm);
        }
示例#7
0
        public override bool CanPerform()
        {
            var prev = Row.Cells.LookupIndex(Cells.First().Index).Prev();

            // can't move if directly above a reference.
            if (prev != null && !string.IsNullOrEmpty(prev.Cell.Reference) && !prev.Cell.IsSelected)
            {
                return(false);
            }

            double increment = BeatCell.Parse(Increment) * Times;

            if (ShiftingRight)
            {
                if (Cells.Last().Index == Row.Cells.Count - 1)
                {
                    return(true);
                }

                if (Row.Cells.Count == 1)
                {
                    return(true);                      // can always move single cell right
                }
                var next = Row.Cells.LookupIndex(Cells.Last().Index).Next();

                return(next.Cell.Position > Cells.Last().Position + increment);
            }

            if (Cells.First().Index == 0)
            {
                return(Row.Offset >= increment);
            }


            return(prev.Cell.Position < Cells[0].Position - increment);
        }
示例#8
0
        /// <summary>
        /// Adds the cell to row below selection.
        /// </summary>
        protected void AddCellToRowBelowSelection()
        {
            Cell         cell     = new Cell(Row);
            CellTreeNode cellNode = new CellTreeNode(cell);

            cell.Position = FirstSelected.Cell.Position - DrawingView.Instance.GridSpacing * NumIntervals;

            if (Row.Cells.Insert(cellNode))
            {
                Cell below = cellNode.Prev().Cell;
                RightIndexBoundOfTransform = below.Index;

                // add to applicable groups
                AddToGroups(cell, below);

                // see if the cell is being added to a rep group's LTM zone
                Repeat repWithLtmToMod = null;
                foreach (Repeat rg in below.RepeatGroups.Where(
                             x => x.ExclusiveCells.Last.Value == below && Position > below.Position + below.Duration))
                {
                    repWithLtmToMod = rg;
                }

                // get new value string for below
                StringBuilder val = new StringBuilder();

                var sequence = cell.RepeatGroups
                               .Where(x => !FirstSelected.Cell.RepeatGroups.Contains(x) && x.Cells.First.Value != cell)
                               .Reverse()
                               .Select(x => x.Times);
                int ltmFactor = sequence.Any() ? sequence.Aggregate((x, y) => x * y) : 1;

                CellTreeNode c = cellNode;

                while (c != FirstSelected)
                {
                    if (!string.IsNullOrEmpty(c.Cell.Reference))
                    {
                        c = c.Next();
                        continue;
                    }

                    AddCellValueToAccumulator(c.Cell, cell, FirstSelected.Cell, val, ref ltmFactor);

                    c = c.Next();
                }

                val.Append('0').Append(BeatCell.MultiplyTerms(BeatCell.Invert(DrawingView.Instance.GridSpacingString), NumIntervals));

                cell.Value = BeatCell.SimplifyValue(cell.GetValueDividedByMultFactors(BeatCell.Invert(val.ToString())));

                string newValue = BeatCell.SimplifyValue(val.ToString());

                if (repWithLtmToMod == null)
                {
                    below.Value = below.GetValueDividedByMultFactors(BeatCell.Add(below.Value, newValue));//newValue);
                    below.Value = BeatCell.SimplifyValue(below.Value);
                }
                else
                {
                    repWithLtmToMod.LastTermModifier =
                        repWithLtmToMod.GetValueDividedByMultFactor(
                            BeatCell.Subtract(repWithLtmToMod.LastTermModifier, newValue));
                    repWithLtmToMod.LastTermModifier = BeatCell.SimplifyValue(repWithLtmToMod.LastTermModifier);
                }
            }
        }
示例#9
0
        /// <summary>
        /// Adds the cell to row above selection.
        /// </summary>
        protected void AddCellToRowAboveSelection()
        {
            Cell cell = new Cell(Row);

            CellTreeNode node = new CellTreeNode(cell);

            cell.Position = LastSelected.Cell.Position + NumIntervals * DrawingView.Instance.GridSpacing;

            if (Row.Cells.Insert(node))
            {
                CellTreeNode belowNode = node.Prev();
                Cell         below     = belowNode.Cell;
                RightIndexBoundOfTransform = below.Index + 1;

                // add to applicable groups
                AddToGroups(cell, below);

                // is new cell placed in the LTM zone of a rep group?
                Repeat repWithLtmToMod = null;
                foreach (Repeat rg in below.RepeatGroups.Where(
                             x => x.ExclusiveCells.Last.Value == below && Position > below.Position + below.ActualDuration))
                {
                    repWithLtmToMod = rg;
                }

                // determine new value for the below cell
                StringBuilder val = new StringBuilder();

                var sequence = LastSelected.Cell.RepeatGroups
                               .Where(x => !cell.RepeatGroups.Contains(x) && x.Cells.First.Value != LastSelected.Cell)
                               .Reverse()
                               .Select(x => x.Times);
                int ltmFactor = sequence.Any() ? sequence.Aggregate((x, y) => x * y) : 1;

                CellTreeNode c = LastSelected;

                // we subtract all values up to the "whitespace" below the new cell
                while (c != node)
                {
                    if (!string.IsNullOrEmpty(c.Cell.Reference))
                    {
                        c = c.Next();
                        continue;
                    }

                    AddCellValueToAccumulator(c.Cell, LastSelected.Cell, node.Cell, val, ref ltmFactor);

                    c = c.Next();
                }

                val.Append('0').Append(BeatCell.MultiplyTerms(BeatCell.Invert(DrawingView.Instance.GridSpacingString), NumIntervals));

                // get new cells value by subtracting old value of below cell by new value.
                string newVal = BeatCell.SimplifyValue(val.ToString());
                // placing a new cell on the beginning of a LTM is not illegal
                if (repWithLtmToMod != null && newVal == string.Empty)
                {
                    newVal = "0";
                }

                // assign the new cell's value
                cell.Value = BeatCell.SimplifyValue(cell.GetValueDividedByMultFactors(newVal));

                if (repWithLtmToMod == null)
                {
                    // change below cell's value
                    below.Value = below.GetValueDividedByMultFactors(
                        BeatCell.Subtract(below.Value, newVal));
                    below.Value = BeatCell.SimplifyValue(below.Value);

                    if (below.IsBreak)
                    {
                        below.IsBreak = false;
                        cell.IsBreak  = true;
                    }
                }
                else
                {
                    // changing a LTM value
                    repWithLtmToMod.LastTermModifier = BeatCell.SimplifyValue(
                        repWithLtmToMod.GetValueDividedByMultFactor(
                            BeatCell.Subtract(repWithLtmToMod.LastTermModifier, newVal)));
                }
            }
        }
示例#10
0
        /**
         * In order to have mult group resizing:
         * 1) Adding to a mult group from flat within that group,
         *    - the interval will need to be multiplied by the group factor
         *    - use the cell values that have said group's factor applied
         *
         * 2) adding from inside a mult group to outside that gorup
         *
         * 3) adding from before a mult group to after that group
         *
         * 4) adding from outside the group, into the group
         *    - like normal, use the actualValue inside of mult group. Multiply result by group factor to get
         *    base value.
         */

        /**
         * Add above row works like this:
         *    - if placed above all other cells, and above all rep group's LTMs,
         *    increase the previous last cell's or rep group LTM's duration
         *    * get the BPM value of the increment multiplied by how many ticks from last selected cell
         *    * to the new cell
         *    * Then subtract the accumulated value of all cells including rep groups from the total value.
         *    make new cell duration the increment value
         *
         * Add above selection, within row works like this:
         *    - Get the value of increment times # of ticks between last selected cell and new cell position
         *    - Subtract the accumulated values of all cells including rep groups to get the new value
         *    of the preceding cell OR a rep group's LTM if we are placing the cell inside of the LTM
         *    - The cells value is then the preceding cell's previous value minus it's new value.
         *
         * Add below row works like this:
         *    - Get the value of increment times # of ticks between first selected cell and new cell position
         *    - subtract the accumulated values of all cells and groups between selected cell and new cell
         *    to get the value of the new cell.
         *    - Subtract new cell value from row's offset to get the new offset
         *
         * add below section, within row works like this:
         *    - Get the increment * # of ticks value between the first selected cell and new cell postion
         *    - subtract the accumulated values of all cells and groups between selected cell and new cell
         *    to get the value of the new cell.
         *    - subtract new cell value from preceding cell / group LTM's old value to get value
         *
         */

        /**
         * Test Cases:
         *
         * 1) Above row
         * 2) Above row where last cell is in a repeat
         * 3) Above row and within the duration of the last cell
         * 4) Above selection and within row
         * 5) ^ Where selection is in a repeat and new cell is not
         * 6) ^ Where selection and new cell are in the same repeat
         * 7) ^ Where new cell is in a repeat group
         * 8) ^ Selection is in a repeat group that is nested
         * 9) ^ new cell is in a repeat group that is nested
         * 10) Below selection and within row
         * 11) ^ Where selection is in a repeat and new cell is not
         * 12) ^ Where selection and new cell are in the same repeat
         * 13) ^ Where new cell is in a repeat group
         * 14) ^ Selection is in a repeat group that is nested
         * 15) ^ new cell is in a repeat group that is nested
         * 16) Below the row, in offset area
         * 17) ^ selection is in a repeat group
         * 18) ^ there is a repeat group between the selection and the start
         */

        /// <summary>
        /// Adds the cell above row.
        /// </summary>
        protected void AddCellAboveRow()
        {
            Cell cell = new Cell(Row);

            if (cell != null)
            {
                cell.Value    = BeatCell.SimplifyValue(DrawingView.Instance.GridSpacingString);
                cell.Position = LastSelected.Cell.Position + DrawingView.Instance.GridSpacing * NumIntervals;
                // set new duration of previous cell

                Cell below = Row.Cells.Max.Cell;

                // if add above a reference, just drop it in and exit.
                if (below.IsReference)
                {
                    Row.Cells.Insert(cell);

                    return;
                }

                // find the value string
                StringBuilder val = new StringBuilder();

                int ltmFactor = LastSelected.Cell.RepeatGroups.Any() ?
                                LastSelected.Cell.RepeatGroups
                                .Reverse()
                                .Select(x => x.Times)
                                .Aggregate((x, y) => x * y) : 1;

                CellTreeNode c = LastSelected;

                while (c != null)
                {
                    if (!string.IsNullOrEmpty(c.Cell.Reference))
                    {
                        c = c.Next();
                        continue;
                    }

                    AddCellValueToAccumulator(c.Cell, LastSelected.Cell, cell, val, ref ltmFactor);

                    c = c.Next();
                }

                val.Append('0').Append(BeatCell.MultiplyTerms(BeatCell.Invert(DrawingView.Instance.GridSpacingString), NumIntervals));

                string valToAdd = BeatCell.Invert(BeatCell.SimplifyValue(val.ToString()));

                // if last cell is in a rep group, we need to increase the LTM for that group
                if (below.RepeatGroups.Any())
                {
                    var rg = below.RepeatGroups.First.Value;

                    // add to the bottom repeat group's LTM
                    rg.LastTermModifier = BeatCell.SimplifyValue(rg.GetValueDividedByMultFactor(valToAdd));
                }
                else
                {
                    // add to last cell's duration
                    below.Value = BeatCell.Add(below.GetValueDividedByMultFactors(valToAdd), below.Value);
                }

                Row.Cells.Insert(cell);

                ChangesViewWidth = true;
            }
        }
 protected override void Transformation()
 {
     Group.FactorValue = Factor;
     Group.Factor      = BeatCell.Parse(Factor);
     ChangesViewWidth  = true;
 }
示例#12
0
        public virtual void Undo()
        {
            // if no change, don't do anything
            if (AfterBeatCode == BeforeBeatCode)
            {
                return;
            }

            CellTree selectedCells = EditorViewController.Instance.DView.SelectedCells;

            // get current selection range if it's in this row
            int selectionStart = -1;
            int selectionEnd   = -1;

            // get selection indexes if there is a selection in the action's row
            if (selectedCells.Root != null && selectedCells.Root.Cell.Row == Row)
            {
                // find index of first selected cell
                selectionStart = selectedCells.Min.Cell.Index;

                selectionEnd = selectedCells.Max.Cell.Index;
            }

            bool selectFromBack = selectionEnd > RightIndexBoundOfTransform;

            if (selectFromBack)
            {
                // get index from back of list
                selectionStart = Row.Cells.Count - selectionStart;
                selectionEnd   = Row.Cells.Count - selectionEnd;
            }

            Row.FillFromBeatCode(BeforeBeatCode);
            if (BeforeOffset != AfterOffset)
            {
                Row.OffsetValue = BeforeOffset;
                Row.Offset      = BeatCell.Parse(BeforeOffset);
            }

            if (ChangesViewWidth)
            {
                double maxDur = DrawingView.Instance.Rows.Max(x => x.Duration);

                DrawingView.Instance.ResizeFrame(maxDur, false);
            }
            else
            {
                EditorViewController.Instance.DView.QueueRowToDraw(Row);

                RedrawReferencers();
            }

            EditorViewController.Instance.DView.ChangesApplied = false;

            // would be nice to only draw individual rows, but seems to be a problem
            //DrawingView.Instance.NeedsDisplay = true;


            if (selectionStart > -1)
            {
                if (selectFromBack)
                {
                    // convert back to forward indexed
                    selectionStart = Row.Cells.Count - selectionStart;
                    selectionEnd   = Row.Cells.Count - selectionEnd;
                }

                if (selectionStart < 0)
                {
                    selectionStart = 0;
                }
                if (selectionEnd >= Row.Cells.Count)
                {
                    selectionEnd = Row.Cells.Count - 1;
                }

                // make new selection
                CellTreeNode startNode = Row.Cells.LookupIndex(selectionStart);
                CellTreeNode endNode   = Row.Cells.LookupIndex(selectionEnd);

                EditorViewController.Instance.DView.SelectCell(startNode.Cell);

                if (startNode != endNode)
                {
                    EditorViewController.Instance.DView.SelectCell(endNode.Cell, true);
                }
            }
        }
示例#13
0
        protected override void Transformation()
        {
            string value = BeatCell.MultiplyTerms(Increment, Math.Abs(Times));

            Cell last  = Cells[Cells.Length - 1];
            Cell first = Cells[0];

            if (Row.Cells.Min.Cell == Cells[0])
            {
                // selection is at start of row, offset will be changed
                if (ShiftingRight)
                {
                    // add to offset
                    if (string.IsNullOrEmpty(Row.OffsetValue))
                    {
                        Row.OffsetValue = "0";
                    }
                    Row.OffsetValue = BeatCell.Add(Row.OffsetValue, first.GetValueDividedByMultFactors(value));
                    // subtract from last cell's value if not last cell of row
                    if (last != Row.Cells.Max.Cell)
                    {
                        last.Value = BeatCell.Subtract(last.Value, last.GetValueDividedByMultFactors(value));
                    }
                }
                else
                {
                    // subtract from offset
                    Row.OffsetValue = BeatCell.Subtract(Row.OffsetValue, first.GetValueDividedByMultFactors(value));
                    // zero becomes an empty string, make it zero.
                    if (string.IsNullOrEmpty(Row.OffsetValue))
                    {
                        Row.OffsetValue = "0";
                    }
                    // add to last cell's value if not last cell of row
                    if (last != Row.Cells.Max.Cell)
                    {
                        last.Value = BeatCell.Add(last.Value, last.GetValueDividedByMultFactors(value));
                    }
                }
            }
            else
            {
                Cell below = Row.Cells.LookupIndex(Cells[0].Index - 1).Cell;
                // if below is last cell of a repeat group, we instead operate on that group's LTM
                Repeat leftGroup    = below.RepeatGroups.Where(x => x.ExclusiveCells.Last.Value == below).FirstOrDefault();
                bool   useLeftGroup = leftGroup != default(Repeat);
                // if last cell in selection is last of a repeat group, operate on it's LTM
                Repeat rightGroup    = last.RepeatGroups.Where(x => x.ExclusiveCells.Last.Value == last).FirstOrDefault();
                bool   useRightGroup = rightGroup != default(Repeat);

                if (ShiftingRight)
                {
                    if (Cells.Last() == Row.Cells.Max.Cell)
                    {
                        ChangesViewWidth = true;
                    }

                    if (useLeftGroup)
                    {
                        // add to LTM
                        leftGroup.LastTermModifier = BeatCell.Add(leftGroup.LastTermModifier, leftGroup.GetValueDividedByMultFactor(value));
                    }
                    else
                    {
                        // add to below cell's value
                        below.Value = BeatCell.Add(below.Value, below.GetValueDividedByMultFactors(value));
                    }
                    // subtract from last cell's value if not last of row
                    if (last != Row.Cells.Max.Cell)
                    {
                        if (useRightGroup)
                        {
                            // subtract from LTM
                            rightGroup.LastTermModifier = BeatCell.Subtract(rightGroup.LastTermModifier, rightGroup.GetValueDividedByMultFactor(value));
                        }
                        else
                        {
                            last.Value = BeatCell.Subtract(last.Value, last.GetValueDividedByMultFactors(value));
                        }
                    }
                }
                else
                {
                    if (useLeftGroup)
                    {
                        // subtract from LTM
                        leftGroup.LastTermModifier = BeatCell.Subtract(leftGroup.LastTermModifier, leftGroup.GetValueDividedByMultFactor(value));
                    }
                    else
                    {
                        // subtract from below cell's value
                        below.Value = BeatCell.Subtract(below.Value, below.GetValueDividedByMultFactors(value));
                    }
                    // add to last cell's value if not last in row
                    if (last != Row.Cells.Max.Cell)
                    {
                        if (useRightGroup)
                        {
                            rightGroup.LastTermModifier = BeatCell.Add(rightGroup.LastTermModifier, rightGroup.GetValueDividedByMultFactor(value));
                        }
                        else
                        {
                            last.Value = BeatCell.Add(last.Value, last.GetValueDividedByMultFactors(value));
                        }
                    }
                }
            }

            Cells = null;
        }
示例#14
0
        public RemoveCells(CellTree cells) : base(cells.Root.Cell.Row, cells.Count > 1 ? "Remove Cells" : "Remove Cell")
        {
            Cells = cells;
            //Row = cells.Root.Cell.Row;
            //PreviousCellValue = previousCellValue;
            //Index = cells[0].Row.Cells.IndexOf(cells[0]);
            StartNode = Row.Cells.LookupIndex(cells.Min.Cell.Index);
            EndNode   = Row.Cells.LookupIndex(cells.Max.Cell.Index);

            StringBuilder duration = new StringBuilder();
            // find all groups that are encompassed by the selection
            HashSet <AbstractGroup> touchedGroups = new HashSet <AbstractGroup>();
            Repeat         groupBeingAppendedTo   = null;                 // a group who's LTM is actively being augmented
            Queue <Repeat> rgToAppendTo           = new Queue <Repeat>(); // RGs that may need to have their LTM added to

            //LinkedList<AbstractGroup> openedGroups = new LinkedList<AbstractGroup>();
            //LinkedList<AbstractGroup> closedGroups = new LinkedList<AbstractGroup>();

            foreach (Cell c in Cells)
            {
                //if (!string.IsNullOrEmpty(c.Reference)) continue;
                foreach ((bool begun, AbstractGroup group) in c.GroupActions)
                {
                    if (begun)
                    {
                        OpenedGroups.AddFirst(group);
                    }
                    else
                    {
                        ClosedGroups.AddFirst(group);
                    }
                }

                // add to the LTM of groups with a previous cell in the selection but not this cell
                if (rgToAppendTo.Any() && !c.RepeatGroups.Contains(rgToAppendTo.Peek()))
                {
                    groupBeingAppendedTo = rgToAppendTo.Dequeue();
                }
                if (groupBeingAppendedTo != null)
                {
                    groupBeingAppendedTo.LastTermModifier = BeatCell.Add(groupBeingAppendedTo.LastTermModifier, c.Value);
                }

                int times = 1;                 // times this cell gets repeated
                // track the times that each RG's LTM gets repeated
                Dictionary <Repeat, int> lcmTimes = new Dictionary <Repeat, int>();

                foreach (Repeat rg in c.RepeatGroups.Reverse())
                {
                    // remove cell from group
                    rg.ExclusiveCells.Remove(c);
                    rg.Cells.Remove(c);

                    // remove break cells
                    if (rg.BreakCell == c)
                    {
                        rg.BreakCell = null;
                    }

                    if (touchedGroups.Contains(rg))
                    {
                        continue;
                    }

                    rgToAppendTo.Enqueue(rg);
                    touchedGroups.Add(rg);

                    if (
                        (StartNode.Cell == rg.ExclusiveCells.First?.Value || rg.Position > StartNode.Cell.Position) &&
                        (EndNode.Cell == rg.ExclusiveCells.Last?.Value || rg.Position + rg.Length < EndNode.Cell.Position))
                    {
                        RepGroups.Add(rg);

                        bool cellAboveBreak = rg.BreakCell != null && c.Position > rg.BreakCell.Position;

                        times *= rg.Times - (cellAboveBreak ? 1 : 0);
                        // multiply all nested rgs' LTMs by this groups repeat times.
                        foreach (KeyValuePair <Repeat, int> kv in lcmTimes)
                        {
                            bool aboveBreak = rg.BreakCell != null && kv.Key.Position > rg.BreakCell.Position;

                            lcmTimes[kv.Key] *= rg.Times - (aboveBreak ? 1 : 0);
                        }
                        lcmTimes.Add(rg, 1);
                    }
                }

                foreach (Multiply mg in c.MultGroups)
                {
                    // remove cell from group
                    mg.ExclusiveCells.Remove(c);
                    if (touchedGroups.Contains(mg))
                    {
                        continue;
                    }
                    touchedGroups.Add(mg);
                    if (
                        (StartNode.Cell == mg.ExclusiveCells.First.Value || mg.Position > StartNode.Cell.Position) &&
                        (EndNode.Cell == mg.ExclusiveCells.Last.Value || mg.Position + mg.Length < EndNode.Cell.Position + EndNode.Cell.Duration))
                    {
                        MultGroups.Add(mg);
                    }
                }

                // get the double version of duration
                Duration += c.Duration * times;

                // get the string version of duration
                // add cell's repeat durations if this cell is in the same scope as the first cell.
                if ((!c.RepeatGroups.Any() && !StartNode.Cell.RepeatGroups.Any()) ||
                    c.RepeatGroups.Last?.Value == StartNode.Cell.RepeatGroups.Last?.Value)
                {
                    duration.Append("+0").Append(BeatCell.MultiplyTerms(c.Value, times));
                }
                // add any LTM's from repeat groups
                foreach (KeyValuePair <Repeat, int> kv in lcmTimes)
                {
                    duration.Append("+0").Append(BeatCell.MultiplyTerms(kv.Key.LastTermModifier, kv.Value));
                    Duration += BeatCell.Parse(kv.Key.LastTermModifier) * kv.Value;
                }
            }

            // Transfer group actions from deleted cells to the 2 cells outside the deleted group
            //CellTreeNode after = EndNode.Next();
            //CellTreeNode before = StartNode.Prev();
            //
            //if (after != null)
            //{
            //	foreach (AbstractGroup group in openedGroups)
            //	{
            //		if (group.ExclusiveCells.Count > 0)
            //		{
            //            after.Cell.GroupActions.AddFirst((true, group));
            //		}
            //	}
            //}
            //
            //if (before != null)
            //{
            //	foreach (AbstractGroup group in closedGroups)
            //	{
            //		if (group.ExclusiveCells.Count > 0)
            //		{
            //            before.Cell.GroupActions.AddFirst((false, group));
            //		}
            //	}
            //}

            BeatCodeDuration = BeatCell.SimplifyValue(duration.ToString());
        }
示例#15
0
        protected override void Transformation()
        {
            Cell firstCell = StartNode.Cell;

            // remove cells


            // remove groups
            foreach (Repeat rg in RepGroups)
            {
                Row.RepeatGroups.Remove(rg);
            }
            foreach (Multiply mg in MultGroups)
            {
                Row.MultGroups.Remove(mg);
            }

            // check if first cell of selection is not row's first cell
            if (firstCell.Index == 0)
            {
                // will be increasing the row offset, but only if
                // selection is not part of a rep group that is not
                // encompassed by the selection
                if (!firstCell.RepeatGroups.Any() || !RepGroups.Contains(firstCell.RepeatGroups.First.Value))
                {
                    // augment the row's offset
                    ChangeOffset = true;
                }
            }
            else
            {
                Cell prevCell = StartNode.Prev().Cell;
                if (prevCell != null)
                {
                    // if previous cell is the last cell of a rep group, increase rep groups offset

                    Repeat groupToAddTo = null;
                    foreach (Repeat rg in prevCell.RepeatGroups.Reverse())
                    {
                        if (!firstCell.RepeatGroups.Contains(rg))
                        {
                            groupToAddTo = rg;
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (groupToAddTo != null)
                    {
                        groupToAddTo.LastTermModifier = BeatCell.Add(groupToAddTo.LastTermModifier, BeatCodeDuration);
                    }
                    else if (!firstCell.RepeatGroups.Any() || prevCell.RepeatGroups.Contains(firstCell.RepeatGroups.Last.Value))
                    {
                        // otherwise, increase the prev cell's duration
                        // but only if it is not the cell prior to a repgroup for which first cell of select is first cell of the rep group.
                        prevCell.Value = BeatCell.Add(prevCell.Value, BeatCodeDuration);
                    }

                    // transfer the closing group actions to prev cell
                    foreach (AbstractGroup group in ClosedGroups)
                    {
                        if (RepGroups.Contains(group) || MultGroups.Contains(group))
                        {
                            continue;
                        }

                        if (prevCell.RepeatGroups.Contains(group) || prevCell.MultGroups.Contains(group))
                        {
                            prevCell.GroupActions.AddLast((false, group));
                        }
                    }
                }
            }

            // do the transition of group actions
            if (EndNode.Cell != Row.Cells.Max.Cell)
            {
                Cell nextCell = EndNode.Next().Cell;
                // need to transfer the repeat group creation point to the next cell (if not a 1 cell group)
                foreach (AbstractGroup group in OpenedGroups)
                {
                    if (RepGroups.Contains(group) || MultGroups.Contains(group))
                    {
                        continue;
                    }

                    if (nextCell.RepeatGroups.Contains(group) || nextCell.MultGroups.Contains(group))
                    {
                        nextCell.GroupActions.AddFirst((true, group));
                    }
                }
            }

            // remove cells from tree
            while (StartNode != null)
            {
                var next = StartNode.Next();
                Row.Cells.Remove(StartNode);
                if (StartNode == EndNode)
                {
                    break;
                }
                StartNode = next;
            }
            //foreach (CellTreeNode c in Row.Cells.GetRange(StartNode.Cell.Position, EndNode.Cell.Position))
            //{
            //	Row.Cells.Remove(c);
            //}

            DrawingView.Instance.DeselectCells();

            // no longer need these
            RepGroups  = null;
            MultGroups = null;
            Cells      = null;
            StartNode  = null;
            EndNode    = null;
        }
示例#16
0
        /// <summary>
        /// Add a cell's value to the accumulator the correct number of times
        /// </summary>
        /// <param name="target"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <param name="accumulator"></param>
        /// <param name="ltmFactor"></param>
        /// <param name="recursing"></param>
        protected void AddCellValueToAccumulator(Cell target, Cell start, Cell end, StringBuilder accumulator, ref int ltmFactor, bool recursing = false)
        {
            // subtract each value from the total
            if (!target.RepeatGroups.Any())
            {
                accumulator.Append(target.GetValueWithMultFactors()).Append('+');
                return;
            }

            int  timesDiff    = 1;
            int  ltmTimesDiff = 1;
            bool isBehind     = target.RepeatGroups.First.Value.Position + target.RepeatGroups.First.Value.FullDuration < start.Position;
            bool contains     = !isBehind;
            int  times        = 1;

            foreach (Repeat rg in target.RepeatGroups.TakeWhile(x => !end.RepeatGroups.Contains(x))) // iterate from innermost group
            {
                if (recursing)
                {
                    if (contains && rg.ExclusiveCells.Contains(start))
                    {
                        // this is the times to subtract because they occur before the starting point.
                        timesDiff = times;
                    }
                    else if (isBehind && rg.Cells.Contains(start))
                    {
                        // subtract a full cycle if this rep group exists all behind the target
                        ltmTimesDiff  = timesDiff = times;
                        ltmTimesDiff /= target.RepeatGroups.First().Times;
                        isBehind      = false;
                    }
                }

                // break cell(s) may decrease the factor
                if (rg.BreakCell != null)
                {
                    times *= rg.Times - (target == rg.BreakCell || target.Position < rg.BreakCell.Position ? 0 : 1);
                }
                else
                {
                    times *= rg.Times;
                }

                if (contains && recursing && rg.ExclusiveCells.Contains(start))
                {
                    ltmTimesDiff  = times;
                    ltmTimesDiff /= target.RepeatGroups.First().Times;
                }
            }

            // handle LTMs
            foreach ((bool opens, AbstractGroup rg) in target.GroupActions.Where(x => x.Item2 is Repeat && !end.RepeatGroups.Contains(x.Item2)))
            {
                if (!opens)
                {
                    ltmFactor /= ((Repeat)rg).Times;

                    // subtract out the LTM (if group doesn't contain the end point)
                    if (!string.IsNullOrEmpty((rg as Repeat).LastTermModifier))
                    {
                        accumulator.Append(
                            BeatCell.MultiplyTerms(
                                ((Repeat)rg).GetLtmWithMultFactor(), ltmFactor - (recursing ? ltmTimesDiff : 0))).Append('+');
                    }
                }
                else if (!end.RepeatGroups.Contains(rg))
                {
                    ltmFactor *= ((Repeat)rg).Times;
                }
            }

            // account for preceding cells if we are starting mid-way through a rep group
            if (recursing)
            {
                times -= timesDiff;
            }
            else if (target == start)
            {
                // find outermost rep group that doesn't contain the new cell
                Repeat rg = target.RepeatGroups.Reverse().SkipWhile(x => end.RepeatGroups.Contains(x)).FirstOrDefault();

                if (rg != null)
                {
                    int ltmFactorR = 1;//rg.Cells.First.Value == target ? 1 : rg.Times;
                    foreach (Cell c in rg.Cells.TakeWhile(x => x.Position < target.Position))
                    {
                        AddCellValueToAccumulator(c, start, end, accumulator, ref ltmFactorR, true);
                    }
                }
            }

            if (!string.IsNullOrEmpty(target.Value))
            {
                accumulator.Append(BeatCell.MultiplyTerms(target.GetValueWithMultFactors(), times)).Append('+');
            }
        }
示例#17
0
        public virtual void Redo()
        {
            CellTree selectedCells = EditorViewController.Instance.DView.SelectedCells;

            // get current selection range if it's in this row
            int selectionStart  = -1;
            int selectionEnd    = -1;
            int rowLengthBefore = Row.Cells.Count;

            // get selection indexes if there is a selection in the action's row
            if (selectedCells.Root != null && selectedCells.Root.Cell.Row == Row)
            {
                // find index of first selected cell

                selectionStart = selectedCells.Min.Cell.Index;

                selectionEnd = selectedCells.Max.Cell.Index;
            }

            if (string.IsNullOrEmpty(AfterBeatCode))
            {
                // perform the transform and get the new beat code
                Transformation();

                AfterBeatCode = Row.Stringify();
                AfterOffset   = Row.OffsetValue;
            }

            bool selectFromBack = selectionEnd > RightIndexBoundOfTransform;

            if (selectFromBack)
            {
                // get index from back of list
                selectionStart = rowLengthBefore - selectionStart;
                selectionEnd   = rowLengthBefore - selectionEnd;
            }

            Row.FillFromBeatCode(AfterBeatCode);
            if (BeforeOffset != AfterOffset)
            {
                Row.OffsetValue = AfterOffset;
                Row.Offset      = BeatCell.Parse(AfterOffset);
            }

            if (ChangesViewWidth)
            {
                double maxDur = DrawingView.Instance.Rows.Max(x => x.Duration);

                // change the view's width
                //var curFrame = DrawingView.Instance.Frame;
                //curFrame.Width = (System.nfloat)(maxDur * DrawingView.ScalingFactor + 550);
                //DrawingView.Instance.Frame = curFrame;

                // need to draw the end portion of other rows
                if (maxDur == Row.Duration)
                {
                    DrawingView.Instance.ResizeFrame(maxDur);
                }
                else
                {
                    ChangesViewWidth = false;
                }
            }

            DrawingView.Instance.QueueRowToDraw(Row);

            DrawingView.Instance.ChangesApplied = false;
            RedrawReferencers();

            if (selectionStart > -1)
            {
                if (selectFromBack)
                {
                    // convert back to forward indexed
                    selectionStart = Row.Cells.Count - selectionStart;
                    selectionEnd   = Row.Cells.Count - selectionEnd;
                }

                if (selectionStart < 0)
                {
                    selectionStart = 0;
                }
                if (selectionEnd >= Row.Cells.Count)
                {
                    selectionEnd = Row.Cells.Count - 1;
                }

                // make new selection

                CellTreeNode startNode = Row.Cells.LookupIndex(selectionStart);
                CellTreeNode endNode   = Row.Cells.LookupIndex(selectionEnd);

                if (startNode != null && endNode != null)
                {
                    EditorViewController.Instance.DView.SelectCell(startNode.Cell);
                    if (startNode != endNode)
                    {
                        EditorViewController.Instance.DView.SelectCell(endNode.Cell, true);
                    }
                }
            }
        }