1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-12-01 07:50:37 +00:00

Groundwork for visualization sets

Placeholder data structure plus menu command, undoable change, etc.
This commit is contained in:
Andy McFadden 2019-11-22 20:45:57 -08:00
parent d8170c50d3
commit ac30512ed3
11 changed files with 312 additions and 18 deletions

View File

@ -91,15 +91,20 @@ namespace SourceGen {
public Dictionary<int, Symbol> UserLabels { get; private set; } public Dictionary<int, Symbol> UserLabels { get; private set; }
/// <summary> /// <summary>
/// Local variable tables. /// Local variable tables. Uses file offset as key.
/// </summary> /// </summary>
public SortedList<int, LocalVariableTable> LvTables { get; private set; } public SortedList<int, LocalVariableTable> LvTables { get; private set; }
/// <summary> /// <summary>
/// Format descriptors for operands and data items; uses file offset as key. /// Format descriptors for operands and data items. Uses file offset as key.
/// </summary> /// </summary>
public SortedList<int, FormatDescriptor> OperandFormats { get; private set; } public SortedList<int, FormatDescriptor> OperandFormats { get; private set; }
/// <summary>
/// Visualization sets. Uses file offset as key.
/// </summary>
public SortedList<int, VisualizationSet> VisualizationSets { get; private set; }
/// <summary> /// <summary>
/// Project properties. Includes CPU type, platform symbol file names, project /// Project properties. Includes CPU type, platform symbol file names, project
/// symbols, etc. /// symbols, etc.
@ -243,6 +248,7 @@ namespace SourceGen {
UserLabels = new Dictionary<int, Symbol>(); UserLabels = new Dictionary<int, Symbol>();
OperandFormats = new SortedList<int, FormatDescriptor>(); OperandFormats = new SortedList<int, FormatDescriptor>();
LvTables = new SortedList<int, LocalVariableTable>(); LvTables = new SortedList<int, LocalVariableTable>();
VisualizationSets = new SortedList<int, VisualizationSet>();
ProjectProps = new ProjectProperties(); ProjectProps = new ProjectProperties();
SymbolTable = new SymbolTable(); SymbolTable = new SymbolTable();
@ -2248,6 +2254,22 @@ namespace SourceGen {
UndoableChange.ReanalysisScope.DataOnly); UndoableChange.ReanalysisScope.DataOnly);
} }
break; break;
case UndoableChange.ChangeType.SetVisualizationSet: {
VisualizationSets.TryGetValue(offset, out VisualizationSet current);
if (current != (VisualizationSet)oldValue) {
Debug.WriteLine("GLITCH: old visSet value mismatch: current=" +
current + " old=" + (VisualizationSet)oldValue);
Debug.Assert(false);
}
if (newValue == null) {
VisualizationSets.Remove(offset);
} else {
VisualizationSets[offset] = (VisualizationSet)newValue;
}
Debug.Assert(uc.ReanalysisRequired ==
UndoableChange.ReanalysisScope.DisplayOnly);
}
break;
default: default:
break; break;
} }

View File

@ -314,6 +314,8 @@ namespace SourceGen {
case LineListGen.Line.Type.Note: case LineListGen.Line.Type.Note:
TextUtil.AppendPaddedString(sb, parts.Comment, mColStart[(int)Col.Label]); TextUtil.AppendPaddedString(sb, parts.Comment, mColStart[(int)Col.Label]);
break; break;
case LineListGen.Line.Type.VisualizationSet:
break; // TODO(xyzzy)
case LineListGen.Line.Type.Blank: case LineListGen.Line.Type.Blank:
break; break;
default: default:
@ -617,6 +619,8 @@ namespace SourceGen {
colPos = AddSpacedString(sb, colPos, mColStart[(int)Col.Label], cstr, colPos = AddSpacedString(sb, colPos, mColStart[(int)Col.Label], cstr,
parts.Comment.Length); parts.Comment.Length);
break; break;
case LineListGen.Line.Type.VisualizationSet:
break; // TODO(xyzzy)
case LineListGen.Line.Type.Blank: case LineListGen.Line.Type.Blank:
break; break;
default: default:

View File

@ -30,7 +30,7 @@ namespace SourceGen {
/// </summary> /// </summary>
public class LineListGen { public class LineListGen {
/// <summary> /// <summary>
/// Color multiplier for Notes. /// Color multiplier for Notes. Used for "dark" mode.
/// </summary> /// </summary>
public float NoteColorMultiplier { get; set; } = 1.0f; public float NoteColorMultiplier { get; set; } = 1.0f;
@ -122,6 +122,7 @@ namespace SourceGen {
// Additional metadata. // Additional metadata.
LocalVariableTable = 1 << 8, LocalVariableTable = 1 << 8,
VisualizationSet = 1 << 9,
} }
/// <summary> /// <summary>
@ -504,6 +505,13 @@ namespace SourceGen {
case Line.Type.LocalVariableTable: case Line.Type.LocalVariableTable:
parts = GenerateLvTableLine(line.FileOffset, line.SubLineIndex); parts = GenerateLvTableLine(line.FileOffset, line.SubLineIndex);
break; break;
case Line.Type.VisualizationSet:
// TODO(xyzzy)
mProject.VisualizationSets.TryGetValue(line.FileOffset,
out VisualizationSet visSet);
parts = FormattedParts.CreateLongComment("!VISUALIZATION SET! " +
(visSet != null ? visSet.PlaceHolder : "???"));
break;
case Line.Type.Blank: case Line.Type.Blank:
// Nothing to do. // Nothing to do.
parts = FormattedParts.CreateBlankLine(); parts = FormattedParts.CreateBlankLine();
@ -971,6 +979,9 @@ namespace SourceGen {
StringListToLines(formatted, offset, Line.Type.LongComment, StringListToLines(formatted, offset, Line.Type.LongComment,
longComment.BackgroundColor, NoteColorMultiplier, lines); longComment.BackgroundColor, NoteColorMultiplier, lines);
} }
if (mProject.VisualizationSets.TryGetValue(offset, out VisualizationSet visSet)) {
lines.Add(new Line(offset, 0, Line.Type.VisualizationSet));
}
// Local variable tables come next. Defer rendering. // Local variable tables come next. Defer rendering.
if (mProject.LvTables.TryGetValue(offset, out LocalVariableTable lvt)) { if (mProject.LvTables.TryGetValue(offset, out LocalVariableTable lvt)) {

View File

@ -1491,6 +1491,11 @@ namespace SourceGen {
EditLocalVariableTable(); EditLocalVariableTable();
} }
break; break;
case LineListGen.Line.Type.VisualizationSet:
if (CanEditVisualizationSet()) {
EditVisualizationSet();
}
break;
case LineListGen.Line.Type.Code: case LineListGen.Line.Type.Code:
case LineListGen.Line.Type.Data: case LineListGen.Line.Type.Data:
@ -2058,6 +2063,25 @@ namespace SourceGen {
} }
} }
public void EditProjectProperties() {
string projectDir = string.Empty;
if (!string.IsNullOrEmpty(mProjectPathName)) {
projectDir = Path.GetDirectoryName(mProjectPathName);
}
EditProjectProperties dlg = new EditProjectProperties(mMainWin, mProject.ProjectProps,
projectDir, mOutputFormatter);
dlg.ShowDialog();
ProjectProperties newProps = dlg.NewProps;
// The dialog result doesn't matter, because the user might have hit "apply"
// before hitting "cancel".
if (newProps != null) {
UndoableChange uc = UndoableChange.CreateProjectPropertiesChange(
mProject.ProjectProps, newProps);
ApplyUndoableChanges(new ChangeSet(uc));
}
}
public bool CanEditProjectSymbol() { public bool CanEditProjectSymbol() {
if (SelectionAnalysis.mNumItemsSelected != 1) { if (SelectionAnalysis.mNumItemsSelected != 1) {
return false; return false;
@ -2119,22 +2143,37 @@ namespace SourceGen {
} }
} }
public void EditProjectProperties() { public bool CanEditVisualizationSet() {
string projectDir = string.Empty; if (SelectionAnalysis.mNumItemsSelected != 1) {
if (!string.IsNullOrEmpty(mProjectPathName)) { return false;
projectDir = Path.GetDirectoryName(mProjectPathName);
} }
EditProjectProperties dlg = new EditProjectProperties(mMainWin, mProject.ProjectProps, EntityCounts counts = SelectionAnalysis.mEntityCounts;
projectDir, mOutputFormatter); // Single line, must be a visualization set.
dlg.ShowDialog(); LineListGen.Line.Type lineType = SelectionAnalysis.mLineType;
ProjectProperties newProps = dlg.NewProps; return (lineType == LineListGen.Line.Type.VisualizationSet ||
lineType == LineListGen.Line.Type.Code ||
lineType == LineListGen.Line.Type.Data);
}
// The dialog result doesn't matter, because the user might have hit "apply" public void EditVisualizationSet() {
// before hitting "cancel". int selIndex = mMainWin.CodeListView_GetFirstSelectedIndex();
if (newProps != null) { int offset = CodeLineList[selIndex].FileOffset;
UndoableChange uc = UndoableChange.CreateProjectPropertiesChange( mProject.VisualizationSets.TryGetValue(offset, out VisualizationSet curVisSet);
mProject.ProjectProps, newProps);
ApplyUndoableChanges(new ChangeSet(uc)); EditVisualizationSet dlg = new EditVisualizationSet(mMainWin,
curVisSet);
if (dlg.ShowDialog() != true) {
return;
}
if (curVisSet != dlg.NewVisSet) {
// New table, edited in place, or deleted.
UndoableChange uc = UndoableChange.CreateVisualizationSetChange(offset,
curVisSet, dlg.NewVisSet);
Debug.WriteLine("Change " + curVisSet + " to " + dlg.NewVisSet);
ChangeSet cs = new ChangeSet(uc);
ApplyUndoableChanges(cs);
} else {
Debug.WriteLine("No change to VisualizationSet");
} }
} }
@ -3579,6 +3618,10 @@ namespace SourceGen {
lineTypeStr = "???"; lineTypeStr = "???";
} }
break; break;
case LineListGen.Line.Type.VisualizationSet:
// TODO(xyzzy)
lineTypeStr = "visualization set";
break;
default: default:
lineTypeStr = "???"; lineTypeStr = "???";
break; break;
@ -4007,7 +4050,9 @@ namespace SourceGen {
continue; continue;
} }
// Create a new user label symbol. // Create a new user label symbol. We should not be creating a duplicate name,
// because user labels have priority over platform symbols when populating
// the symbol table.
Symbol newSym = new Symbol(sym.Label, sym.Value, Symbol.Source.User, Symbol newSym = new Symbol(sym.Label, sym.Value, Symbol.Source.User,
Symbol.Type.GlobalAddr, Symbol.LabelAnnotation.None); Symbol.Type.GlobalAddr, Symbol.LabelAnnotation.None);
UndoableChange uc = UndoableChange.CreateLabelChange(offset, null, newSym); UndoableChange uc = UndoableChange.CreateLabelChange(offset, null, newSym);

View File

@ -96,6 +96,7 @@
<DependentUpon>ShowText.xaml</DependentUpon> <DependentUpon>ShowText.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="LocalVariableTable.cs" /> <Compile Include="LocalVariableTable.cs" />
<Compile Include="VisualizationSet.cs" />
<Compile Include="WpfGui\AboutBox.xaml.cs"> <Compile Include="WpfGui\AboutBox.xaml.cs">
<DependentUpon>AboutBox.xaml</DependentUpon> <DependentUpon>AboutBox.xaml</DependentUpon>
</Compile> </Compile>
@ -132,6 +133,9 @@
<Compile Include="WpfGui\EditProjectProperties.xaml.cs"> <Compile Include="WpfGui\EditProjectProperties.xaml.cs">
<DependentUpon>EditProjectProperties.xaml</DependentUpon> <DependentUpon>EditProjectProperties.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="WpfGui\EditVisualizationSet.xaml.cs">
<DependentUpon>EditVisualizationSet.xaml</DependentUpon>
</Compile>
<Compile Include="WpfGui\Export.xaml.cs"> <Compile Include="WpfGui\Export.xaml.cs">
<DependentUpon>Export.xaml</DependentUpon> <DependentUpon>Export.xaml</DependentUpon>
</Compile> </Compile>
@ -310,6 +314,10 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="WpfGui\EditVisualizationSet.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="WpfGui\Export.xaml"> <Page Include="WpfGui\Export.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>

View File

@ -105,6 +105,9 @@ namespace SourceGen {
// Adds, updates, or removes a local variable table. // Adds, updates, or removes a local variable table.
SetLocalVariableTable, SetLocalVariableTable,
// Adds, updates, or removes a visualization set.
SetVisualizationSet,
} }
/// <summary> /// <summary>
@ -478,6 +481,28 @@ namespace SourceGen {
return uc; return uc;
} }
/// <summary>
/// Creates an UndoableChange for a visualization set update.
/// </summary>
/// <param name="offset">Affected offset.</param>
/// <param name="oldVisSet">Old visualization set.</param>
/// <param name="newVisSet">New visualization set.</param>
/// <returns>Change record.</returns>
public static UndoableChange CreateVisualizationSetChange(int offset,
VisualizationSet oldVisSet, VisualizationSet newVisSet) {
if (oldVisSet == newVisSet) {
Debug.WriteLine("No-op visualization set change");
}
UndoableChange uc = new UndoableChange();
uc.Type = ChangeType.SetVisualizationSet;
uc.Offset = offset;
uc.OldValue = oldVisSet;
uc.NewValue = newVisSet;
uc.ReanalysisRequired = ReanalysisScope.DisplayOnly; // no change to code/data
return uc;
}
public override string ToString() { public override string ToString() {
return "[UC type=" + Type + " offset=+" + return "[UC type=" + Type + " offset=+" +
(HasOffset ? Offset.ToString("x6") : "N/A") + "]"; (HasOffset ? Offset.ToString("x6") : "N/A") + "]";

View File

@ -0,0 +1,56 @@
/*
* Copyright 2019 faddenSoft
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SourceGen {
public class VisualizationSet {
// TODO(xyzzy)
public string PlaceHolder { get; private set; }
public VisualizationSet(string placeHolder) {
PlaceHolder = placeHolder;
}
public override string ToString() {
return "[VS: " + PlaceHolder + "]";
}
public static bool operator ==(VisualizationSet a, VisualizationSet b) {
if (ReferenceEquals(a, b)) {
return true; // same object, or both null
}
if (ReferenceEquals(a, null) || ReferenceEquals(b, null)) {
return false; // one is null
}
// All fields must be equal.
return a.PlaceHolder == b.PlaceHolder;
}
public static bool operator !=(VisualizationSet a, VisualizationSet b) {
return !(a == b);
}
public override bool Equals(object obj) {
return obj is VisualizationSet && this == (VisualizationSet)obj;
}
public override int GetHashCode() {
return PlaceHolder.GetHashCode();
}
}
}

View File

@ -0,0 +1,43 @@
<!--
Copyright 2019 faddenSoft
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<Window x:Class="SourceGen.WpfGui.EditVisualizationSet"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SourceGen.WpfGui"
mc:Ignorable="d"
Title="Edit Visualization Set"
SizeToContent="WidthAndHeight" ResizeMode="NoResize"
ShowInTaskbar="False" WindowStartupLocation="CenterOwner"
Loaded="Window_Loaded">
<Grid Margin="8">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBox Grid.Column="0" Grid.Row="0" Text="{Binding PlaceHolder, UpdateSourceTrigger=PropertyChanged}"/>
<DockPanel Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" Margin="0,8,0,0" LastChildFill="False">
<Button DockPanel.Dock="Right" Content="Cancel" Width="70" Margin="8,0,0,0" IsCancel="True"/>
<Button DockPanel.Dock="Right" Grid.Column="1" Content="OK" Width="70"
IsDefault="True" Click="OkButton_Click"/>
</DockPanel>
</Grid>
</Window>

View File

@ -0,0 +1,68 @@
/*
* Copyright 2019 faddenSoft
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace SourceGen.WpfGui {
/// <summary>
/// Visualization set editor.
/// </summary>
public partial class EditVisualizationSet : Window, INotifyPropertyChanged {
public VisualizationSet NewVisSet { get; private set; }
public string PlaceHolder {
get { return mPlaceHolder; }
set { mPlaceHolder = value; OnPropertyChanged(); }
}
private string mPlaceHolder;
// INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = "") {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public EditVisualizationSet(Window owner, VisualizationSet curSet) {
InitializeComponent();
Owner = owner;
DataContext = this;
if (curSet != null) {
PlaceHolder = curSet.PlaceHolder;
} else {
PlaceHolder = "New!";
}
}
private void Window_Loaded(object sender, RoutedEventArgs e) {
}
private void OkButton_Click(object sender, RoutedEventArgs e) {
if (string.IsNullOrEmpty(PlaceHolder)) {
NewVisSet = null;
} else {
NewVisSet = new VisualizationSet(PlaceHolder);
}
DialogResult = true;
}
}
}

View File

@ -101,6 +101,7 @@ limitations under the License.
</RoutedUICommand> </RoutedUICommand>
<RoutedUICommand x:Key="EditProjectSymbolCmd" Text="Edit Project Symbol..."/> <RoutedUICommand x:Key="EditProjectSymbolCmd" Text="Edit Project Symbol..."/>
<RoutedUICommand x:Key="EditStatusFlagsCmd" Text="Override Status Flags..."/> <RoutedUICommand x:Key="EditStatusFlagsCmd" Text="Override Status Flags..."/>
<RoutedUICommand x:Key="EditVisualizationSetCmd" Text="Create/Edit Visualization Set..."/>
<RoutedUICommand x:Key="ExitCmd" Text="Exit"/> <RoutedUICommand x:Key="ExitCmd" Text="Exit"/>
<RoutedUICommand x:Key="ExportCmd" Text="Export..."/> <RoutedUICommand x:Key="ExportCmd" Text="Export..."/>
<RoutedUICommand x:Key="FindNextCmd" Text="Find Next"> <RoutedUICommand x:Key="FindNextCmd" Text="Find Next">
@ -225,6 +226,8 @@ limitations under the License.
CanExecute="CanEditProjectSymbol" Executed="EditProjectSymbolCmd_Executed"/> CanExecute="CanEditProjectSymbol" Executed="EditProjectSymbolCmd_Executed"/>
<CommandBinding Command="{StaticResource EditStatusFlagsCmd}" <CommandBinding Command="{StaticResource EditStatusFlagsCmd}"
CanExecute="CanEditStatusFlags" Executed="EditStatusFlagsCmd_Executed"/> CanExecute="CanEditStatusFlags" Executed="EditStatusFlagsCmd_Executed"/>
<CommandBinding Command="{StaticResource EditVisualizationSetCmd}"
CanExecute="CanEditVisualizationSet" Executed="EditVisualizationSetCmd_Executed"/>
<CommandBinding Command="{StaticResource ExitCmd}" <CommandBinding Command="{StaticResource ExitCmd}"
Executed="ExitCmd_Executed"/> Executed="ExitCmd_Executed"/>
<CommandBinding Command="{StaticResource ExportCmd}" <CommandBinding Command="{StaticResource ExportCmd}"
@ -368,6 +371,7 @@ limitations under the License.
<MenuItem Command="{StaticResource EditProjectSymbolCmd}"/> <MenuItem Command="{StaticResource EditProjectSymbolCmd}"/>
<MenuItem Command="{StaticResource CreateLocalVariableTableCmd}"/> <MenuItem Command="{StaticResource CreateLocalVariableTableCmd}"/>
<MenuItem Command="{StaticResource EditLocalVariableTableCmd}"/> <MenuItem Command="{StaticResource EditLocalVariableTableCmd}"/>
<MenuItem Command="{StaticResource EditVisualizationSetCmd}"/>
<Separator/> <Separator/>
<MenuItem Command="{StaticResource HintAsCodeEntryPointCmd}" InputGestureText="Ctrl+H, Ctrl+C"/> <MenuItem Command="{StaticResource HintAsCodeEntryPointCmd}" InputGestureText="Ctrl+H, Ctrl+C"/>
<MenuItem Command="{StaticResource HintAsDataStartCmd}" InputGestureText="Ctrl+H, Ctrl+D"/> <MenuItem Command="{StaticResource HintAsDataStartCmd}" InputGestureText="Ctrl+H, Ctrl+D"/>

View File

@ -1040,6 +1040,10 @@ namespace SourceGen.WpfGui {
e.CanExecute = IsProjectOpen() && mMainCtrl.CanEditStatusFlags(); e.CanExecute = IsProjectOpen() && mMainCtrl.CanEditStatusFlags();
} }
private void CanEditVisualizationSet(object sender, CanExecuteRoutedEventArgs e) {
e.CanExecute = IsProjectOpen() && mMainCtrl.CanEditVisualizationSet();
}
private void CanFormatAsWord(object sender, CanExecuteRoutedEventArgs e) { private void CanFormatAsWord(object sender, CanExecuteRoutedEventArgs e) {
e.CanExecute = IsProjectOpen() && mMainCtrl.CanFormatAsWord(); e.CanExecute = IsProjectOpen() && mMainCtrl.CanFormatAsWord();
} }
@ -1187,6 +1191,10 @@ namespace SourceGen.WpfGui {
mMainCtrl.EditStatusFlags(); mMainCtrl.EditStatusFlags();
} }
private void EditVisualizationSetCmd_Executed(object sender, ExecutedRoutedEventArgs e) {
mMainCtrl.EditVisualizationSet();
}
private void ExitCmd_Executed(object sender, ExecutedRoutedEventArgs e) { private void ExitCmd_Executed(object sender, ExecutedRoutedEventArgs e) {
Close(); Close();
} }