mirror of
https://github.com/haven1433/HexManiacAdvance.git
synced 2026-03-21 17:34:13 -05:00
truncate to 10 scripts showing at once in the map header
This commit is contained in:
parent
b65acc02d1
commit
14ae6b354b
|
|
@ -18,12 +18,14 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map {
|
|||
public bool Unloaded => address == 0;
|
||||
public ObservableCollection<MapScriptViewModel> Scripts { get; } = new();
|
||||
public bool CollectionExists => address > 0;
|
||||
public bool AllowAddMoreScripts { get; private set; } = true;
|
||||
|
||||
public event EventHandler<NewMapScriptsCreatedEventArgs> NewMapScriptsCreated;
|
||||
|
||||
public MapScriptCollection(IEditableViewPort viewPort) => this.viewPort = viewPort;
|
||||
|
||||
public void Load(ModelArrayElement owner) {
|
||||
foreach (var script in Scripts) script.DeleteMe -= HandleDelete;
|
||||
Scripts.Clear();
|
||||
this.owner = owner;
|
||||
if (owner == null) return;
|
||||
|
|
@ -31,12 +33,18 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map {
|
|||
if (address == Pointer.NULL) return;
|
||||
var model = viewPort.Model;
|
||||
var scriptStart = address;
|
||||
AllowAddMoreScripts = true;
|
||||
while (model[scriptStart] != 0) {
|
||||
if (Scripts.Count == 10) {
|
||||
Scripts.Add(new(viewPort, Pointer.NULL)); // 'UI is full' sentinel
|
||||
AllowAddMoreScripts = false;
|
||||
break;
|
||||
}
|
||||
Scripts.Add(new(viewPort, scriptStart));
|
||||
AddDeleteHandler(Scripts.Count - 1);
|
||||
scriptStart += 5;
|
||||
}
|
||||
NotifyPropertiesChanged(nameof(CollectionExists), nameof(Unloaded), nameof(Address));
|
||||
NotifyPropertiesChanged(nameof(CollectionExists), nameof(Unloaded), nameof(Address), nameof(AllowAddMoreScripts));
|
||||
}
|
||||
|
||||
public bool CanCreateCollection => address < 0;
|
||||
|
|
@ -71,9 +79,8 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map {
|
|||
model.UpdateArrayPointer(token, default, default, default, run.Start + run.Length - 5, newScript);
|
||||
model.ObserveRunWritten(token, run);
|
||||
model.ObserveRunWritten(token, new XSERun(newScript));
|
||||
Scripts.Add(new(viewPort, address + Scripts.Count * 5));
|
||||
AddDeleteHandler(Scripts.Count - 1);
|
||||
viewPort.ChangeHistory.ChangeCompleted();
|
||||
Load(owner); // do a full reload, in case we need to truncate scripts
|
||||
}
|
||||
|
||||
private void AddDeleteHandler(int index) {
|
||||
|
|
@ -88,16 +95,15 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map {
|
|||
var tableRun = model.GetNextRun(address) as ITableRun;
|
||||
if (tableRun == null) return;
|
||||
var table = new ModelTable(model, tableRun, () => token); // type. pointer<>
|
||||
for (int i = index; i < Scripts.Count - 1; i++) {
|
||||
for (int i = index; i < table.Count - 1; i++) {
|
||||
table[i].SetValue(0, table[i + 1].GetValue(0));
|
||||
table[i].SetAddress("pointer", table[i + 1].GetAddress("pointer"));
|
||||
}
|
||||
tableRun = tableRun.Append(token, -1);
|
||||
model.ObserveRunWritten(token, tableRun);
|
||||
Scripts[index].DeleteMe -= HandleDelete;
|
||||
Scripts.RemoveAt(index);
|
||||
e.Success = true;
|
||||
viewPort.ChangeHistory.ChangeCompleted();
|
||||
Load(owner); // do a reload, in case we were truncating scripts.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -114,6 +120,8 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map {
|
|||
public event EventHandler<MapScriptDeleteEventArgs> DeleteMe;
|
||||
|
||||
public bool HasSubScripts => scriptType == 2 || scriptType == 4;
|
||||
public bool MoreScriptsTruncated { get; } = false;
|
||||
public bool ShowMapScript => !MoreScriptsTruncated;
|
||||
|
||||
public ObservableCollection<VisualOption> ScriptOptions { get; } = new();
|
||||
public ObservableCollection<MapSubScriptViewModel> SubScripts { get; } = new();
|
||||
|
|
@ -122,6 +130,10 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map {
|
|||
this.viewPort = viewPort;
|
||||
var model = viewPort.Model;
|
||||
this.start = start;
|
||||
if (start == Pointer.NULL) {
|
||||
MoreScriptsTruncated = true;
|
||||
return;
|
||||
}
|
||||
this.scriptType = model[start];
|
||||
this.address = model.ReadPointer(start + 1);
|
||||
this.displayAddress = $"<{address:X6}>";
|
||||
|
|
@ -335,25 +347,31 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map {
|
|||
addressText = $"<{address:X6}>";
|
||||
}
|
||||
|
||||
public string Variable { get => variableText; set => Set(ref variableText, value, arg => {
|
||||
if (!variableText.TryParseHex(out int result)) return;
|
||||
variable = result;
|
||||
viewPort.Model.WriteMultiByteValue(start, 2, viewPort.ChangeHistory.CurrentChange, variable);
|
||||
}); }
|
||||
public string Variable {
|
||||
get => variableText; set => Set(ref variableText, value, arg => {
|
||||
if (!variableText.TryParseHex(out int result)) return;
|
||||
variable = result;
|
||||
viewPort.Model.WriteMultiByteValue(start, 2, viewPort.ChangeHistory.CurrentChange, variable);
|
||||
});
|
||||
}
|
||||
|
||||
public string Value { get => valueText; set => Set(ref valueText, value, arg => {
|
||||
if (!int.TryParse(valueText, out int result)) return;
|
||||
val = result;
|
||||
viewPort.Model.WriteMultiByteValue(start + 2, 2, viewPort.ChangeHistory.CurrentChange, val);
|
||||
}); }
|
||||
public string Value {
|
||||
get => valueText; set => Set(ref valueText, value, arg => {
|
||||
if (!int.TryParse(valueText, out int result)) return;
|
||||
val = result;
|
||||
viewPort.Model.WriteMultiByteValue(start + 2, 2, viewPort.ChangeHistory.CurrentChange, val);
|
||||
});
|
||||
}
|
||||
|
||||
public string Address { get => addressText; set => Set(ref addressText, value, arg => {
|
||||
var text = addressText.Trim("<> ".ToCharArray());
|
||||
if (!text.TryParseHex(out int result)) return;
|
||||
// do the same work that we do in the code tool, removing scripts that aren't needed
|
||||
address = result;
|
||||
viewPort.Model.UpdateArrayPointer(viewPort.ChangeHistory.CurrentChange, default, default, -1, start + 4, address);
|
||||
}); }
|
||||
public string Address {
|
||||
get => addressText; set => Set(ref addressText, value, arg => {
|
||||
var text = addressText.Trim("<> ".ToCharArray());
|
||||
if (!text.TryParseHex(out int result)) return;
|
||||
// do the same work that we do in the code tool, removing scripts that aren't needed
|
||||
address = result;
|
||||
viewPort.Model.UpdateArrayPointer(viewPort.ChangeHistory.CurrentChange, default, default, -1, start + 4, address);
|
||||
});
|
||||
}
|
||||
|
||||
public void Delete() {
|
||||
var args = new MapScriptDeleteEventArgs();
|
||||
|
|
|
|||
|
|
@ -564,7 +564,11 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Visitors {
|
|||
var name = newArray.Start.ToAddress();
|
||||
var anchorName = model.GetAnchorFromAddress(-1, newArray.Start);
|
||||
if (!string.IsNullOrWhiteSpace(anchorName)) name = anchorName;
|
||||
messageText = $"Table {name} was moved. Pointers have been updated.";
|
||||
if (newArray.Start != array.Start) {
|
||||
messageText = $"Table {name} was moved. Pointers have been updated.";
|
||||
} else {
|
||||
messageText = $"Table {name} was resized. Address has not changed.";
|
||||
}
|
||||
if (newArray.Length > array.Length && newArray.Start == array.Start) {
|
||||
model.ClearFormat(token, array.Start + array.Length, newArray.Length - array.Length);
|
||||
// edge case: if the run in this spot isn't the run we're about to add, clear that too
|
||||
|
|
|
|||
|
|
@ -1279,65 +1279,70 @@
|
|||
<ItemsControl ItemsSource="{Binding PrimaryMap.MapScriptCollection.Scripts}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel>
|
||||
<DockPanel Margin="2">
|
||||
<DockPanel.Resources>
|
||||
<DataTemplate DataType="{x:Type models:VisualOption}">
|
||||
<TextBlock Text="{Binding Option}">
|
||||
<TextBlock.ToolTip>
|
||||
<TextBlock>
|
||||
<Bold>
|
||||
<Run Text="{Binding ShortDescription}" />
|
||||
</Bold>
|
||||
<LineBreak /> <LineBreak />
|
||||
<Run Text="{Binding Description}" />
|
||||
<Grid>
|
||||
<StackPanel Visibility="{Binding ShowMapScript, Converter={StaticResource BoolToVisibility}}">
|
||||
<DockPanel Margin="2">
|
||||
<DockPanel.Resources>
|
||||
<DataTemplate DataType="{x:Type models:VisualOption}">
|
||||
<TextBlock Text="{Binding Option}">
|
||||
<TextBlock.ToolTip>
|
||||
<TextBlock>
|
||||
<Bold>
|
||||
<Run Text="{Binding ShortDescription}" />
|
||||
</Bold>
|
||||
<LineBreak /> <LineBreak />
|
||||
<Run Text="{Binding Description}" />
|
||||
</TextBlock>
|
||||
</TextBlock.ToolTip>
|
||||
</TextBlock>
|
||||
</TextBlock.ToolTip>
|
||||
</TextBlock>
|
||||
</DataTemplate>
|
||||
</DockPanel.Resources>
|
||||
<local:AngleButton Command="{res:MethodCommand Delete}" DockPanel.Dock="Left" Direction="Left" Padding="0" VerticalAlignment="Center" Height="18">
|
||||
<Path Fill="{DynamicResource Secondary}" Stretch="Uniform" Data="{res:Icon Exit}" Width="10" Height="20"/>
|
||||
</local:AngleButton>
|
||||
<local:AngleButton Command="{res:MethodCommand Goto}" DockPanel.Dock="Right" Direction="Right" Padding="0" Width="20" Height="18">
|
||||
<Path Fill="{DynamicResource Secondary}" Stretch="Fill" Data="{res:Icon RightAngleArrow}" Width="10" Height="12" />
|
||||
</local:AngleButton>
|
||||
<local:AngleComboBox SelectedIndex="{Binding ScriptTypeIndex}" ItemsSource="{Binding ScriptOptions}" Direction="Out" DockPanel.Dock="Left" Width="140" Height="18" />
|
||||
<local:AngleTextBox Direction="Right" TextBinding="{Binding Address, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</DockPanel>
|
||||
<ItemsControl Visibility="{Binding HasSubScripts, Converter={StaticResource BoolToVisibility}}" ItemsSource="{Binding SubScripts}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Margin="8,2">
|
||||
<!-- Do I need multiple lines for this? -->
|
||||
<!-- One line for Delete, Address, Goto -->
|
||||
<!-- One line for variable/value pair -->
|
||||
<DockPanel>
|
||||
<local:AngleButton Command="{res:MethodCommand Delete}" DockPanel.Dock="Left" Direction="Left" Padding="0" VerticalAlignment="Center" Height="18">
|
||||
<Path Fill="{DynamicResource Secondary}" Stretch="Uniform" Data="{res:Icon Exit}" Width="10" Height="20" />
|
||||
</local:AngleButton>
|
||||
<local:AngleButton Command="{res:MethodCommand Goto}" DockPanel.Dock="Right" Direction="Right" Padding="0" Width="20" Height="18">
|
||||
<Path Fill="{DynamicResource Secondary}" Stretch="Fill" Data="{res:Icon RightAngleArrow}" Width="10" Height="12" />
|
||||
</local:AngleButton>
|
||||
<local:AngleBorder Direction="Left" Content="Address:" Padding="2,0" />
|
||||
<local:AngleTextBox Direction="Out" TextBinding="{Binding Address, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</DockPanel>
|
||||
<UniformGrid Columns="4" Margin="20,0">
|
||||
<local:AngleBorder Direction="Out" Content="Var:" />
|
||||
<local:AngleTextBox Direction="Right" TextBinding="{Binding Variable, UpdateSourceTrigger=PropertyChanged}" Margin="0,0,2,0" />
|
||||
<local:AngleBorder Direction="Out" Content="Value:" Margin="2,0,0,0" />
|
||||
<local:AngleTextBox Direction="Right" TextBinding="{Binding Value, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</UniformGrid>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
<local:AngleButton Margin="8,2" Visibility="{Binding HasSubScripts, Converter={StaticResource BoolToVisibility}}" Command="{res:MethodCommand AddSubScript}" Direction="Out" Content="Add Table Script" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DockPanel.Resources>
|
||||
<local:AngleButton Command="{res:MethodCommand Delete}" DockPanel.Dock="Left" Direction="Left" Padding="0" VerticalAlignment="Center" Height="18">
|
||||
<Path Fill="{DynamicResource Secondary}" Stretch="Uniform" Data="{res:Icon Exit}" Width="10" Height="20"/>
|
||||
</local:AngleButton>
|
||||
<local:AngleButton Command="{res:MethodCommand Goto}" DockPanel.Dock="Right" Direction="Right" Padding="0" Width="20" Height="18">
|
||||
<Path Fill="{DynamicResource Secondary}" Stretch="Fill" Data="{res:Icon RightAngleArrow}" Width="10" Height="12" />
|
||||
</local:AngleButton>
|
||||
<local:AngleComboBox SelectedIndex="{Binding ScriptTypeIndex}" ItemsSource="{Binding ScriptOptions}" Direction="Out" DockPanel.Dock="Left" Width="140" Height="18" />
|
||||
<local:AngleTextBox Direction="Right" TextBinding="{Binding Address, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</DockPanel>
|
||||
<ItemsControl Visibility="{Binding HasSubScripts, Converter={StaticResource BoolToVisibility}}" ItemsSource="{Binding SubScripts}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Margin="8,2">
|
||||
<!-- Do I need multiple lines for this? -->
|
||||
<!-- One line for Delete, Address, Goto -->
|
||||
<!-- One line for variable/value pair -->
|
||||
<DockPanel>
|
||||
<local:AngleButton Command="{res:MethodCommand Delete}" DockPanel.Dock="Left" Direction="Left" Padding="0" VerticalAlignment="Center" Height="18">
|
||||
<Path Fill="{DynamicResource Secondary}" Stretch="Uniform" Data="{res:Icon Exit}" Width="10" Height="20" />
|
||||
</local:AngleButton>
|
||||
<local:AngleButton Command="{res:MethodCommand Goto}" DockPanel.Dock="Right" Direction="Right" Padding="0" Width="20" Height="18">
|
||||
<Path Fill="{DynamicResource Secondary}" Stretch="Fill" Data="{res:Icon RightAngleArrow}" Width="10" Height="12" />
|
||||
</local:AngleButton>
|
||||
<local:AngleBorder Direction="Left" Content="Address:" Padding="2,0" />
|
||||
<local:AngleTextBox Direction="Out" TextBinding="{Binding Address, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</DockPanel>
|
||||
<UniformGrid Columns="4" Margin="20,0">
|
||||
<local:AngleBorder Direction="Out" Content="Var:" />
|
||||
<local:AngleTextBox Direction="Right" TextBinding="{Binding Variable, UpdateSourceTrigger=PropertyChanged}" Margin="0,0,2,0" />
|
||||
<local:AngleBorder Direction="Out" Content="Value:" Margin="2,0,0,0" />
|
||||
<local:AngleTextBox Direction="Right" TextBinding="{Binding Value, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</UniformGrid>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
<local:AngleButton Margin="8,2" Visibility="{Binding HasSubScripts, Converter={StaticResource BoolToVisibility}}" Command="{res:MethodCommand AddSubScript}" Direction="Out" Content="Add Table Script" />
|
||||
</StackPanel>
|
||||
<TextBlock Visibility="{Binding MoreScriptsTruncated, Converter={StaticResource BoolToVisibility}}" FontStyle="Italic"
|
||||
Text="Further scripts truncated for performance. View the table data to see the remaining scripts." TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
<local:AngleButton DataContext="{Binding PrimaryMap.MapScriptCollection}" Content="Add New Script" Direction="Out" Margin="2" Command="{res:MethodCommand AddScript}" />
|
||||
<local:AngleButton DataContext="{Binding PrimaryMap.MapScriptCollection}" Content="Add New Script" Direction="Out" Margin="2" Command="{res:MethodCommand AddScript}"
|
||||
Visibility="{Binding AllowAddMoreScripts, Converter={StaticResource BoolToVisibility}}"/>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user