Add text pointer content to tool.

This commit is contained in:
Benjamin Popp
2019-05-27 14:01:09 -05:00
parent 3e00051cb5
commit 76df0b7bb0
4 changed files with 76 additions and 0 deletions

View File

@@ -215,4 +215,49 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Tools {
}
}
}
public class TextStreamArrayElementViewModel : ViewModelCore, IArrayElementViewModel {
private readonly ChangeHistory<ModelDelta> history;
private readonly IDataModel model;
private readonly string name;
private readonly int start;
public bool IsInError => !string.IsNullOrEmpty(ErrorText);
public string ErrorText { get; private set; }
public event EventHandler DataChanged;
public event EventHandler<(int originalStart, int newStart)> DataMoved;
string content;
public string Content {
get => content;
set {
if (TryUpdate(ref content, value)) {
var destination = model.ReadPointer(start);
var run = model.GetNextRun(destination);
var data = PCSString.Convert(content);
var newRun = model.RelocateForExpansion(history.CurrentChange, run, data.Count);
if (run.Start != newRun.Start) DataMoved?.Invoke(this, (run.Start, newRun.Start));
run = newRun;
for (int i = 0; i < data.Count; i++) history.CurrentChange.ChangeData(model, run.Start + i, data[i]);
for (int i = data.Count; i < run.Length; i++) history.CurrentChange.ChangeData(model, run.Start + i, 0xFF);
DataChanged?.Invoke(this, EventArgs.Empty);
model.ObserveRunWritten(history.CurrentChange, new PCSRun(run.Start, data.Count));
}
}
}
public TextStreamArrayElementViewModel(ChangeHistory<ModelDelta> history, IDataModel model, string name, int start) {
this.history = history;
this.model = model;
this.name = name;
this.start = start;
var destination = model.ReadPointer(start);
// by the time we get this far, we're guaranteed that this will be a PCSRun.
// if it's not a PCSRun, we shouldn't have asked to construct this object.
var run = (PCSRun)model.GetNextRun(destination);
content = PCSString.Convert(model, run.Start, run.Length);
}
}
}

View File

@@ -161,10 +161,23 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Tools {
}
Children.Add(viewModel);
viewModel.DataChanged += ForwardModelChanged;
if (item is ArrayRunPointerSegment pointerSegment) {
if (pointerSegment.DestinationDataMatchesPointerFormat(model, history.CurrentChange, model.ReadPointer(itemAddress))) {
if (pointerSegment.InnerFormat == $"{PCSRun.StringDelimeter}{PCSRun.StringDelimeter}") {
var streamElement = new TextStreamArrayElementViewModel(history, model, item.Name, itemAddress);
streamElement.DataChanged += ForwardModelChanged;
streamElement.DataMoved += ForwardModelDataMoved;
Children.Add(streamElement);
} else {
throw new NotImplementedException();
}
}
}
itemAddress += item.Length;
}
}
private void ForwardModelChanged(object sender, EventArgs e) => ModelDataChanged?.Invoke(this, model.GetNextRun(Address));
private void ForwardModelDataMoved(object sender, (int originalStart, int newStart) e) => ModelDataMoved?.Invoke(this, e);
}
}

View File

@@ -2,6 +2,7 @@
using HavenSoft.HexManiac.Core.Models.Runs;
using HavenSoft.HexManiac.Core.ViewModels;
using HavenSoft.HexManiac.Core.ViewModels.DataFormats;
using HavenSoft.HexManiac.Core.ViewModels.Tools;
using System.Collections.Generic;
using Xunit;
@@ -122,5 +123,19 @@ namespace HavenSoft.HexManiac.Tests {
Assert.IsType<None>(viewPort[1, 1].Format); // no PCS format was added
}
[Fact]
public void TableToolAllowsEditingTextContent() {
viewPort.Edit("FF"); // have to put the FF first, or trying to create a text run will fail
viewPort.MoveSelectionStart.Execute(Direction.Left);
viewPort.Edit("^text\"\" Some Text\"");
viewPort.SelectionStart = new Point(0, 4);
viewPort.Edit("^table[description<\"\">]4 <000000>"); // note that this auto-scrolls, since a table was created
viewPort.FollowLink(0, 0);
Assert.Equal(2, viewPort.Tools.TableTool.Children.Count);
Assert.IsType<TextStreamArrayElementViewModel>(viewPort.Tools.TableTool.Children[1]);
}
}
}

View File

@@ -129,6 +129,9 @@
<ComboBox SelectedIndex="{Binding SelectedIndex}" ItemsSource="{Binding Options}" Grid.Column="1"/>
</Grid>
</DataTemplate>
<DataTemplate DataType="{x:Type hsg3hvmtr:TextStreamArrayElementViewModel}">
<TextBox Text="{Binding Content, UpdateSourceTrigger=PropertyChanged}" Margin="20,2,2,2" AcceptsReturn="True"/>
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
</StackPanel>