public void AddChange(UndoEntry entry) { if (m_UndoPos < m_UndoBuffer.Count) { for (int i = 0, e = m_UndoBuffer.Count; i < e; ++i) { m_CurrentCost -= GetEntryCost(m_UndoBuffer[i]); } m_UndoBuffer.RemoveRange(m_UndoPos, m_UndoBuffer.Count - m_UndoPos); } m_UndoBuffer.Add(entry); ++m_UndoPos; m_CurrentCost += GetEntryCost(entry); if (m_CurrentCost > MAX_UNDO_BUFFER_COST) { int entries_to_remove; for (entries_to_remove = 0; entries_to_remove < m_UndoPos - 1; ++entries_to_remove) { m_CurrentCost -= GetEntryCost(m_UndoBuffer[entries_to_remove]); if (m_CurrentCost <= MAX_UNDO_BUFFER_COST) { entries_to_remove++; break; } } m_UndoBuffer.RemoveRange(0, entries_to_remove); m_UndoPos -= entries_to_remove; } }
public UndoEntryInfo(UndoEntry entry) { InitializeComponent(); _entry = entry; this.Get <TextBlock>("Description").Text = _entry.Description; }
// Undo the last move void UndoMove() { if (this.canUndo) { AudioController.MoveCard(); UndoEntry entry = _undoManager.Pop(); Card card = RemoveCardAtLocation(entry.toLocation, entry.toIndex); MoveCardToLocation(card, entry.fromLocation, entry.fromIndex, true); UpdateScore(); } }
public void Contents_Insert(int index, UndoEntry entry) { UndoEntryInfo viewer = new UndoEntryInfo(entry); viewer.Selected += UndoEntry_Select; Contents.Children.Insert(index, viewer); if (index <= current) { current++; } if (index <= saved) { saved++; } Dispatcher.UIThread.Post(() => ScrollViewer.Offset = ScrollViewer.Offset.WithY(Contents.Bounds.Height), DispatcherPriority.Background); }
void DetectAndSaveChange(string new_text, int new_sel_start, int new_sel_length) { if (m_PrevText != null) { // We are doing brutalforce change detection as we will work with at most a few hundred kilobytes of text in this project. int max_len = Math.Min(m_PrevText.Length, new_text.Length); // The Math.Min(m_PrevSelStart, max_len) is there to fix a bug that detected wrongly the actual location of // multiple pasted lines. If we pasted lines that are equivalent to the lines starting at the actual paste // location then this change detector found our newly pasted text as unchanged text and detected the next // block as the change. This caused problems especially in case of the optimized syntax highlighter. int common_prefix_len = FindCommonPrefixLength(m_PrevText, new_text, Math.Min(m_PrevSelStart, max_len)); if (m_PrevText.Length == new_text.Length && new_text.Length == common_prefix_len) { return; } int common_postfix_len = common_prefix_len >= max_len ? 0 : FindCommonPostfixLen(m_PrevText, new_text, max_len - common_prefix_len); UndoEntry entry = new UndoEntry(); entry.Id = m_NextUndoEntryId++; entry.PrevCaretPos = m_PrevSelStart + m_PrevSelLength; entry.NewCaretPos = new_sel_start + new_sel_length; entry.Pos = common_prefix_len; entry.CutText = m_PrevText.Substring(common_prefix_len, m_PrevText.Length - common_prefix_len - common_postfix_len); entry.PastedText = new_text.Substring(common_prefix_len, new_text.Length - common_prefix_len - common_postfix_len); m_UndoBuffer.AddChange(entry); if (UndoEntryAdded != null) { UndoEntryAdded(entry); } } m_PrevText = new_text; m_PrevSelStart = new_sel_start; m_PrevSelLength = new_sel_length; }
void DetectAndSaveChange(string new_text, int new_sel_start, int new_sel_length) { if (m_PrevText != null) { // We are doing brutalforce change detection as we will work with at most a few hundred kilobytes of text in this project. int max_len = Math.Min(m_PrevText.Length, new_text.Length); // The Math.Min(m_PrevSelStart, max_len) is there to fix a bug that detected wrongly the actual location of // multiple pasted lines. If we pasted lines that are equivalent to the lines starting at the actual paste // location then this change detector found our newly pasted text as unchanged text and detected the next // block as the change. This caused problems especially in case of the optimized syntax highlighter. int common_prefix_len = FindCommonPrefixLength(m_PrevText, new_text, Math.Min(m_PrevSelStart, max_len)); if (m_PrevText.Length == new_text.Length && new_text.Length == common_prefix_len) return; int common_postfix_len = common_prefix_len >= max_len ? 0 : FindCommonPostfixLen(m_PrevText, new_text, max_len - common_prefix_len); UndoEntry entry = new UndoEntry(); entry.Id = m_NextUndoEntryId++; entry.PrevCaretPos = m_PrevSelStart + m_PrevSelLength; entry.NewCaretPos = new_sel_start + new_sel_length; entry.Pos = common_prefix_len; entry.CutText = m_PrevText.Substring(common_prefix_len, m_PrevText.Length - common_prefix_len - common_postfix_len); entry.PastedText = new_text.Substring(common_prefix_len, new_text.Length - common_prefix_len - common_postfix_len); m_UndoBuffer.AddChange(entry); if (UndoEntryAdded != null) UndoEntryAdded(entry); } m_PrevText = new_text; m_PrevSelStart = new_sel_start; m_PrevSelLength = new_sel_length; }
private static int GetEntryCost(UndoEntry entry) { return FIX_COST_PER_ENTRY + entry.CutText.Length*2 + entry.PastedText.Length*2; }
public void Undo(out UndoEntry entry) { Debug.Assert(CanUndo()); --m_UndoPos; entry = m_UndoBuffer[m_UndoPos]; }
public void Redo(out UndoEntry entry) { Debug.Assert(CanRedo()); entry = m_UndoBuffer[m_UndoPos]; ++m_UndoPos; }
public void AddChange(UndoEntry entry) { if (m_UndoPos < m_UndoBuffer.Count) { for (int i=0,e=m_UndoBuffer.Count; i<e; ++i) m_CurrentCost -= GetEntryCost(m_UndoBuffer[i]); m_UndoBuffer.RemoveRange(m_UndoPos, m_UndoBuffer.Count - m_UndoPos); } m_UndoBuffer.Add(entry); ++m_UndoPos; m_CurrentCost += GetEntryCost(entry); if (m_CurrentCost > MAX_UNDO_BUFFER_COST) { int entries_to_remove; for (entries_to_remove=0; entries_to_remove<m_UndoPos-1; ++entries_to_remove) { m_CurrentCost -= GetEntryCost(m_UndoBuffer[entries_to_remove]); if (m_CurrentCost <= MAX_UNDO_BUFFER_COST) { entries_to_remove++; break; } } m_UndoBuffer.RemoveRange(0, entries_to_remove); m_UndoPos -= entries_to_remove; } }
private static int GetEntryCost(UndoEntry entry) { return(FIX_COST_PER_ENTRY + entry.CutText.Length * 2 + entry.PastedText.Length * 2); }
void Unloaded(object sender, VisualTreeAttachmentEventArgs e) { Selected = null; _entry = null; }
static dynamic Decode(BinaryReader reader, int version, Type ensure = null) { Type t = DecodeID(reader); if (ensure != null && ensure != t) { throw new InvalidDataException(); } if (t == typeof(Copyable)) { return new Copyable() { Contents = Enumerable.Range(0, reader.ReadInt32()).Select(i => Decode <ISelect>(reader, version)).ToList() } } ; else if (t == typeof(Project)) { int bpm = reader.ReadInt32(); int[] macros = (version >= 25)? Enumerable.Range(0, 4).Select(i => reader.ReadInt32()).ToArray() : new int[4] { reader.ReadInt32(), 1, 1, 1 }; List <Track> tracks = Enumerable.Range(0, reader.ReadInt32()).Select(i => Decode <Track>(reader, version)).ToList(); string author = ""; long time = 0; long started = 0; if (version >= 17) { author = reader.ReadString(); time = reader.ReadInt64(); started = reader.ReadInt64(); } UndoManager undo = null; if (version >= 30) { undo = Decode <UndoManager>(reader, version); } return(new Project(bpm, macros, tracks, author, time, started, undo)); } else if (t == typeof(Track)) { Chain chain = Decode <Chain>(reader, version); Launchpad lp = Decode <Launchpad>(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 = Enumerable.Range(0, reader.ReadInt32()).Select(i => Decode <Device>(reader, version)).ToList(); string name = reader.ReadString(); bool enabled = true; if (version >= 6) { enabled = reader.ReadBoolean(); } bool[] filter = null; if (version >= 29) { filter = Enumerable.Range(0, 101).Select(i => reader.ReadBoolean()).ToArray(); } return(new Chain(devices, name, filter) { 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); // This needs to be a cast! 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, Convert.ToInt32(name.Substring(18))); } 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( Enumerable.Range(0, reader.ReadInt32()).Select(i => Decode <Chain>(reader, version)).ToList(), reader.ReadBoolean()? (int?)reader.ReadInt32() : null )); } else if (t == typeof(Choke)) { return(new Choke( reader.ReadInt32(), Decode <Chain>(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(); } double pinch = 0; if (version >= 26) { pinch = reader.ReadDouble(); } bool bilateral = false; if (version >= 28) { bilateral = reader.ReadBoolean(); } bool reverse = false; if (version >= 26) { reverse = reader.ReadBoolean(); } bool infinite = false; if (version >= 27) { infinite = reader.ReadBoolean(); } CopyType copyType = (CopyType)reader.ReadInt32(); GridType gridType = (GridType)reader.ReadInt32(); bool wrap = reader.ReadBoolean(); int count; List <Offset> offsets = Enumerable.Range(0, count = reader.ReadInt32()).Select(i => Decode <Offset>(reader, version)).ToList(); List <int> angles = Enumerable.Range(0, count).Select(i => (version >= 25)? reader.ReadInt32() : 0).ToList(); return(new Copy(time, gate, pinch, bilateral, reverse, infinite, copyType, gridType, wrap, offsets, angles)); } 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 = Enumerable.Range(0, count = reader.ReadInt32()).Select(i => Decode <Color>(reader, version)).ToList(); List <double> positions = Enumerable.Range(0, count).Select(i => (version <= 13)? (double)reader.ReadDecimal() : reader.ReadDouble()).ToList(); List <FadeType> types = Enumerable.Range(0, count - 1).Select(i => (version <= 24) ? FadeType.Linear : (FadeType)reader.ReadInt32()).ToList(); int?expanded = null; if (version >= 23) { expanded = reader.ReadBoolean()? (int?)reader.ReadInt32() : null; } return(new Fade(time, gate, playmode, colors, positions, types, expanded)); } 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(); } HoldType holdmode; if (version <= 31) { holdmode = reader.ReadBoolean()? HoldType.Infinite : HoldType.Trigger; } else { holdmode = (HoldType)reader.ReadInt32(); } return(new Hold( time, gate, holdmode, reader.ReadBoolean() )); } else if (t == typeof(KeyFilter)) { bool[] filter; if (version <= 18) { List <bool> oldFilter = Enumerable.Range(0, 100).Select(i => reader.ReadBoolean()).ToList(); oldFilter.Insert(99, false); filter = oldFilter.ToArray(); } else { filter = Enumerable.Range(0, 101).Select(i => 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(LayerFilter)) { return(new LayerFilter( reader.ReadInt32(), reader.ReadInt32() )); } else if (t == typeof(Loop)) { return(new Loop( Decode(reader, version), reader.ReadDouble(), reader.ReadInt32(), reader.ReadBoolean() )); } else if (t == typeof(Move)) { return(new Move( Decode(reader, version), (GridType)reader.ReadInt32(), reader.ReadBoolean() )); } else if (t == typeof(Multi)) { Chain preprocess = Decode(reader, version); int count = reader.ReadInt32(); List <Chain> init = Enumerable.Range(0, count).Select(i => Decode <Chain>(reader, version)).ToList(); if (version == 28) { List <bool[]> filters = Enumerable.Range(0, count).Select(i => Enumerable.Range(0, 101).Select(i => reader.ReadBoolean()).ToArray() ).ToList(); for (int i = 0; i < count; i++) { init[i].SecretMultiFilter = filters[i]; } } int? expanded = reader.ReadBoolean()? (int?)reader.ReadInt32() : null; MultiType mode = (MultiType)reader.ReadInt32(); return(new Multi(preprocess, init, expanded, mode)); } else if (t == typeof(Output)) { return(new Output( reader.ReadInt32() )); } else if (t == typeof(MacroFilter)) { return(new MacroFilter( (version >= 25)? reader.ReadInt32() : 1, Enumerable.Range(0, 100).Select(i => 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(); } double pinch = 0; if (version >= 24) { pinch = reader.ReadDouble(); } bool bilateral = false; if (version >= 28) { bilateral = reader.ReadBoolean(); } List <Frame> frames = Enumerable.Range(0, reader.ReadInt32()).Select(i => Decode <Frame>(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, pinch, bilateral, 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(Refresh)) { return(new Refresh( Enumerable.Range(0, 4).Select(i => reader.ReadBoolean()).ToArray() )); } else if (t == typeof(Switch)) { int target = (version >= 25)? reader.ReadInt32() : 1; int value = reader.ReadInt32(); if (18 <= version && version <= 21 && reader.ReadBoolean()) { return(new Group(new List <Chain>() { new Chain(new List <Device>() { new Switch(1, value), new Clear(ClearType.Multi) }, "Switch Reset") })); } return(new Switch(target, value)); } else if (t == typeof(Tone)) { return(new Tone( reader.ReadDouble(), reader.ReadDouble(), reader.ReadDouble(), reader.ReadDouble(), reader.ReadDouble() )); } else if (t == typeof(Color)) { byte red = reader.ReadByte(); byte green = reader.ReadByte(); byte blue = reader.ReadByte(); if (version == 24) { if (red > 0) { red = (byte)((red - 1) * 62.0 / 126 + 1); } if (green > 0) { green = (byte)((green - 1) * 62.0 / 126 + 1); } if (blue > 0) { blue = (byte)((blue - 1) * 62.0 / 126 + 1); } } return(new Color(red, green, blue)); } 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 = Enumerable.Range(0, 100).Select(i => Decode <Color>(reader, version)).ToList(); oldScreen.Insert(99, new Color(0)); screen = oldScreen.ToArray(); } else { screen = Enumerable.Range(0, 101).Select(i => Decode <Color>(reader, version)).ToArray(); } return(new Frame(time, screen)); } else if (t == typeof(Length)) { return(new Length( reader.ReadInt32() )); } else if (t == typeof(Offset)) { int x = reader.ReadInt32(); int y = reader.ReadInt32(); bool absolute = false; int ax = 5; int ay = 5; if (version >= 25) { absolute = reader.ReadBoolean(); ax = reader.ReadInt32(); ay = reader.ReadInt32(); } return(new Offset(x, y, absolute, ax, ay)); } else if (t == typeof(Time)) { return(new Time( reader.ReadBoolean(), Decode(reader, version), reader.ReadInt32() )); } else if (t == typeof(UndoManager)) { int undoVersion = reader.ReadInt32(); int size = reader.ReadInt32(); if (undoVersion == UndoBinary.Version) { return(new UndoManager( Enumerable.Range(0, reader.ReadInt32()).Select(i => UndoEntry.DecodeEntry(reader, version)).ToList(), reader.ReadInt32() )); } reader.ReadBytes(size); return(new UndoManager()); } throw new InvalidDataException(); }