1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-06-25 05:29:31 +00:00

Update editors to work with local variables

The table editor is now editing the table, and the DefSymbol editor
now asks for the Width data when editing a local var.

This also moves EditDefSymbol closer to proper WPF style, with
bound properties for the input fields.

No changes yet to serialization or analysis.
This commit is contained in:
Andy McFadden 2019-08-25 17:25:15 -07:00
parent 5fe032c93a
commit 1cc9d2bd70
9 changed files with 370 additions and 80 deletions

View File

@ -24,6 +24,8 @@ namespace SourceGen {
/// </summary>
public class DefSymbol : Symbol {
public const int NO_WIDTH = -1;
public const int MIN_WIDTH = 1;
public const int MAX_WIDTH = 4;
/// <summary>
/// Data format descriptor.
@ -93,6 +95,25 @@ namespace SourceGen {
Tag = tag;
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="label">Symbol's label.</param>
/// <param name="value">Symbol's value.</param>
/// <param name="source">Symbol source (general point of origin).</param>
/// <param name="type">Symbol type.</param>
/// <param name="formatSubType">Format descriptor sub-type, so we know how the
/// user wants the value to be displayed.</param>
/// <param name="comment">End-of-line comment.</param>
/// <param name="tag">Symbol tag, used for grouping platform symbols.</param>
/// <param name="width">Variable width.</param>
public DefSymbol(string label, int value, Source source, Type type,
FormatDescriptor.SubType formatSubType, string comment, string tag, int width)
: this(label, value, source, type, formatSubType, comment, tag) {
Debug.Assert(width == NO_WIDTH || (width >= MIN_WIDTH && width <= MAX_WIDTH));
Width = width;
}
/// <summary>
/// Constructs a DefSymbol from a Symbol and a format descriptor. This is used
/// for project symbols.

View File

@ -15,18 +15,23 @@
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace SourceGen {
/// <summary>
/// Table of redefinable variables. A project may have several of these, at different
/// offsets. The contents of later tables overwrite the contents of earlier tables.
///
/// The class is mutable, but may only be modified by the LvTable editor (which makes
/// changes to a work object that moves through the undo/redo buffer) or the
/// deserializer.
/// </summary>
public class LocalVariableTable {
/// <summary>
/// List of variables. The symbol's label must be unique within a table, so we sort
/// on that.
/// </summary>
private SortedList<string, DefSymbol> mVariables;
public SortedList<string, DefSymbol> Variables;
/// <summary>
/// If set, all values from previous VariableTables should be discarded when this
@ -40,25 +45,65 @@ namespace SourceGen {
/// </remarks>
public bool ClearPrevious { get; set; }
/// <summary>
/// Indexer.
/// </summary>
/// <param name="key">Symbol's label.</param>
/// <returns>Matching symbol. Throws an exception if not found.</returns>
public DefSymbol this[string key] {
get {
return mVariables[key];
}
set {
mVariables[key] = value;
}
}
/// <summary>
/// Constructs an empty table.
/// </summary>
public LocalVariableTable() {
mVariables = new SortedList<string, DefSymbol>();
Variables = new SortedList<string, DefSymbol>();
}
/// <summary>
/// Copy constructor.
/// </summary>
/// <param name="src">Object to clone.</param>
public LocalVariableTable(LocalVariableTable src) : this() {
ClearPrevious = src.ClearPrevious;
foreach (KeyValuePair<string, DefSymbol> kvp in src.Variables) {
Variables[kvp.Key] = kvp.Value;
}
Debug.Assert(this == src);
}
public static bool operator ==(LocalVariableTable a, LocalVariableTable 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.
if (a.ClearPrevious != b.ClearPrevious) {
return false;
}
if (a.Variables.Count != b.Variables.Count) {
return false;
}
// Compare all list entries.
for (int i = 0; i < a.Variables.Count; i++) {
if (a.Variables.Values[i] != b.Variables.Values[i]) {
return false;
}
}
return true;
}
public static bool operator !=(LocalVariableTable a, LocalVariableTable b) {
return !(a == b);
}
public override bool Equals(object obj) {
return obj is LocalVariableTable && this == (LocalVariableTable)obj;
}
public override int GetHashCode() {
int hashCode = 0;
foreach (KeyValuePair<string, DefSymbol> kvp in Variables) {
hashCode ^= kvp.Value.GetHashCode();
}
if (ClearPrevious) {
hashCode++;
}
return hashCode;
}
}
}

View File

@ -1689,12 +1689,15 @@ namespace SourceGen {
return true; // TODO
}
private LocalVariableTable lvt = new LocalVariableTable();
public void EditLocalVariableTable() {
// TODO
EditLocalVariableTable dlg = new EditLocalVariableTable(mMainWin);
EditLocalVariableTable dlg = new EditLocalVariableTable(mMainWin, mProject.SymbolTable,
mOutputFormatter, lvt);
if (dlg.ShowDialog() != true) {
return;
}
lvt = dlg.NewTable;
}
public bool CanEditLongComment() {
@ -1937,12 +1940,11 @@ namespace SourceGen {
Debug.Assert(origDefSym.SymbolSource == Symbol.Source.Project);
EditDefSymbol dlg = new EditDefSymbol(mMainWin, mOutputFormatter,
mProject.ProjectProps.ProjectSyms);
dlg.DefSym = origDefSym;
mProject.ProjectProps.ProjectSyms, origDefSym);
if (dlg.ShowDialog() == true) {
ProjectProperties newProps = new ProjectProperties(mProject.ProjectProps);
newProps.ProjectSyms.Remove(origDefSym.Label);
newProps.ProjectSyms[dlg.DefSym.Label] = dlg.DefSym;
newProps.ProjectSyms[dlg.NewSym.Label] = dlg.NewSym;
UndoableChange uc = UndoableChange.CreateProjectPropertiesChange(
mProject.ProjectProps, newProps);

View File

@ -20,7 +20,8 @@ namespace SourceGen {
/// <summary>
/// A collection of project properties.
///
/// The class is mutable, but may only be modified by DisasmProject.ApplyChanges or
/// The class is mutable, but may only be modified by the property editor (which updates
/// a work object that gets put into the project by DisasmProject.ApplyChanges) or
/// the deserializer.
///
/// All fields are explicitly handled by the ProjectFile serializer.

View File

@ -36,40 +36,47 @@ limitations under the License.
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Text="Label:"/>
<StackPanel Grid.Column="1" Grid.Row="0">
<TextBox Name="labelTextBox" Margin="0,1,0,0"
FontFamily="{StaticResource GeneralMonoFont}"
TextChanged="LabelTextBox_TextChanged"/>
<TextBox Name="labelTextBox" Margin="0,1,0,0" Text="{Binding Label, UpdateSourceTrigger=PropertyChanged}"
FontFamily="{StaticResource GeneralMonoFont}"/>
<TextBlock Name="labelNotesLabel" Text="• 2+ alphanumerics, starting with letter" Margin="0,4,0,0"/>
<TextBlock Name="labelUniqueLabel" Text="• Unique among project symbols" Margin="0,4,0,16"/>
<TextBlock Name="projectLabelUniqueLabel" Text="• Unique among project symbols" Margin="0,4,0,16"/>
<TextBlock Name="labelUniqueLabel" Text="• Unique" Margin="0,4,0,16"/>
</StackPanel>
<TextBlock Grid.Column="0" Grid.Row="1" Text="Value:"/>
<StackPanel Grid.Column="1" Grid.Row="1">
<TextBox Name="valueTextBox" Margin="0,1,0,0"
FontFamily="{StaticResource GeneralMonoFont}"
TextChanged="ValueTextBox_TextChanged"/>
<TextBox Margin="0,1,0,0" Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}"
FontFamily="{StaticResource GeneralMonoFont}"/>
<TextBlock Name="valueNotesLabel" Text="• Decimal, hex ($), or binary (%)" Margin="0,4,0,16"/>
</StackPanel>
<TextBlock Grid.Column="0" Grid.Row="2" Text="Comment:" Margin="0,0,8,0"/>
<StackPanel Grid.Column="1" Grid.Row="2">
<TextBox Name="commentTextBox" Margin="0,1,0,0"
<TextBlock Name="widthEntry1" Grid.Column="0" Grid.Row="2" Text="Width:"/>
<StackPanel Name="widthEntry2" Grid.Column="1" Grid.Row="2">
<TextBox Margin="0,1,0,0" Text="{Binding VarWidth, UpdateSourceTrigger=PropertyChanged}"
FontFamily="{StaticResource GeneralMonoFont}"/>
<TextBlock Name="widthNotesLabel" Text="• Decimal, 1-4" Margin="0,4,0,16"/>
</StackPanel>
<TextBlock Grid.Column="0" Grid.Row="3" Text="Comment:" Margin="0,0,8,0"/>
<StackPanel Grid.Column="1" Grid.Row="3">
<TextBox Margin="0,1,0,0" Text="{Binding Comment, UpdateSourceTrigger=PropertyChanged}"
FontFamily="{StaticResource GeneralMonoFont}"/>
<TextBlock Text="• Optional" Margin="0,4,0,16"/>
</StackPanel>
<GroupBox Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2" Header="Symbol Type" Padding="4">
<GroupBox Grid.Column="0" Grid.Row="4" Grid.ColumnSpan="2" Header="Symbol Type" Padding="4">
<StackPanel Orientation="Horizontal">
<RadioButton Name="addressRadioButton" Content="Address"/>
<RadioButton Name="constantRadioButton" Content="Constant" Margin="24,0,0,0"/>
</StackPanel>
</GroupBox>
<StackPanel Grid.Column="1" Grid.Row="4" Margin="0,16,0,0"
<StackPanel Grid.Column="1" Grid.Row="5" Margin="0,16,0,0"
Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="OK" Width="70" IsDefault="True" IsEnabled="{Binding IsValid}"
Click="OkButton_Click"/>

View File

@ -30,33 +30,63 @@ namespace SourceGen.WpfGui {
/// </summary>
public partial class EditDefSymbol : Window, INotifyPropertyChanged {
/// <summary>
/// Set to previous value before calling; may be null if creating a new symbol.
/// Will be set to new value on OK result.
/// Result; will be set non-null on OK.
/// </summary>
public DefSymbol DefSym { get; set; }
public DefSymbol NewSym { get; private set; }
/// <summary>
/// Set to true when all fields are valid. Controls whether the OK button is enabled.
/// </summary>
public bool IsValid {
get { return mIsValid; }
set {
mIsValid = value;
OnPropertyChanged();
}
set { mIsValid = value; OnPropertyChanged(); }
}
private bool mIsValid;
public string Label {
get { return mLabel; }
set { mLabel = value; OnPropertyChanged(); UpdateControls(); }
}
private string mLabel;
public string Value {
get { return mValue; }
set { mValue = value; OnPropertyChanged(); UpdateControls(); }
}
private string mValue;
public string VarWidth {
get { return mWidth; }
set { mWidth = value; OnPropertyChanged(); UpdateControls(); }
}
private string mWidth;
public string Comment {
get { return mComment; }
set { mComment = value; OnPropertyChanged(); }
}
private string mComment;
/// <summary>
/// Format object to use when formatting addresses and constants.
/// </summary>
private Formatter mNumFormatter;
/// <summary>
/// Old symbol value. May be null.
/// </summary>
private DefSymbol mOldSym;
/// <summary>
/// List of existing symbols, for uniqueness check. The list will not be modified.
/// </summary>
private SortedList<string, DefSymbol> mDefSymbolList;
/// <summary>
/// Full symbol table, for extended uniqueness check.
/// </summary>
private SymbolTable mSymbolTable;
// Saved off at dialog load time.
private Brush mDefaultLabelColor;
@ -67,26 +97,50 @@ namespace SourceGen.WpfGui {
}
/// <summary>
/// Constructor, for editing a project symbol.
/// </summary>
public EditDefSymbol(Window owner, Formatter formatter,
SortedList<string, DefSymbol> defList) {
SortedList<string, DefSymbol> defList, DefSymbol defSym) {
InitializeComponent();
Owner = owner;
DataContext = this;
mNumFormatter = formatter;
mDefSymbolList = defList;
mOldSym = defSym;
Label = Value = VarWidth = Comment = string.Empty;
widthEntry1.Visibility = widthEntry2.Visibility = labelUniqueLabel.Visibility =
Visibility.Collapsed;
projectLabelUniqueLabel.Visibility = Visibility.Visible;
}
/// <summary>
/// Constructor, for editing a local variable.
/// </summary>
public EditDefSymbol(Window owner, Formatter formatter,
SortedList<string, DefSymbol> defList, DefSymbol defSym,
SymbolTable symbolTable) : this(owner, formatter, defList, defSym) {
mSymbolTable = symbolTable;
widthEntry1.Visibility = widthEntry2.Visibility = labelUniqueLabel.Visibility =
Visibility.Visible;
projectLabelUniqueLabel.Visibility = Visibility.Collapsed;
}
private void Window_Loaded(object sender, RoutedEventArgs e) {
mDefaultLabelColor = labelNotesLabel.Foreground;
if (DefSym != null) {
labelTextBox.Text = DefSym.Label;
valueTextBox.Text = mNumFormatter.FormatValueInBase(DefSym.Value,
DefSym.DataDescriptor.NumBase);
commentTextBox.Text = DefSym.Comment;
if (mOldSym != null) {
Label = mOldSym.Label;
Value = mNumFormatter.FormatValueInBase(mOldSym.Value,
mOldSym.DataDescriptor.NumBase);
VarWidth = mOldSym.Width.ToString();
Comment = mOldSym.Comment;
if (DefSym.SymbolType == Symbol.Type.Constant) {
if (mOldSym.SymbolType == Symbol.Type.Constant) {
constantRadioButton.IsChecked = true;
} else {
addressRadioButton.IsChecked = true;
@ -100,37 +154,55 @@ namespace SourceGen.WpfGui {
}
private void UpdateControls() {
bool labelValid, labelUnique, valueValid;
if (!IsLoaded) {
return;
}
// Label must be valid and not already exist in project symbol list. (It's okay
// if it exists elsewhere.)
labelValid = Asm65.Label.ValidateLabel(labelTextBox.Text);
// Label must be valid and not already exist in project symbol list. (For project
// symbols, it's okay if an identical label exists elsewhere.)
bool labelValid = Asm65.Label.ValidateLabel(Label);
bool labelUnique;
if (mDefSymbolList.TryGetValue(labelTextBox.Text, out DefSymbol existing)) {
if (mDefSymbolList.TryGetValue(Label, out DefSymbol existing)) {
// It's okay if it's the same object.
labelUnique = (existing == DefSym);
labelUnique = (existing == mOldSym);
} else {
labelUnique = true;
}
// For local variables, do a secondary uniqueness check.
if (labelUnique && mSymbolTable != null) {
labelUnique = !mSymbolTable.TryGetValue(Label, out Symbol sym);
}
// Value must be blank, meaning "erase any earlier definition", or valid value.
// (Hmm... don't currently have a way to specify "no symbol" in DefSymbol.)
//if (!string.IsNullOrEmpty(valueTextBox.Text)) {
valueValid = ParseValue(out int unused1, out int unused2);
bool valueValid = ParseValue(out int unused1, out int unused2);
//} else {
// valueValid = true;
//}
bool widthValid = true;
if (widthEntry1.Visibility == Visibility.Visible) {
if (!int.TryParse(VarWidth, out int width) ||
width < DefSymbol.MIN_WIDTH || width > DefSymbol.MAX_WIDTH) {
widthValid = false;
}
}
// TODO(maybe): do this the XAML way, with properties and Styles
labelNotesLabel.Foreground = labelValid ? mDefaultLabelColor : Brushes.Red;
labelUniqueLabel.Foreground = labelUnique ? mDefaultLabelColor : Brushes.Red;
labelUniqueLabel.Foreground = projectLabelUniqueLabel.Foreground =
labelUnique ? mDefaultLabelColor : Brushes.Red;
valueNotesLabel.Foreground = valueValid ? mDefaultLabelColor : Brushes.Red;
widthNotesLabel.Foreground = widthValid ? mDefaultLabelColor : Brushes.Red;
IsValid = labelValid && labelUnique && valueValid;
IsValid = labelValid && labelUnique && valueValid && widthValid;
}
private bool ParseValue(out int value, out int numBase) {
string str = valueTextBox.Text;
string str = Value;
if (str.IndexOf('/') >= 0) {
// treat as address
numBase = 16;
@ -145,19 +217,16 @@ namespace SourceGen.WpfGui {
ParseValue(out int value, out int numBase);
FormatDescriptor.SubType subType = FormatDescriptor.GetSubTypeForBase(numBase);
DefSym = new DefSymbol(labelTextBox.Text, value, Symbol.Source.Project,
int width = DefSymbol.NO_WIDTH;
if (!string.IsNullOrEmpty(VarWidth)) {
width = int.Parse(VarWidth);
}
NewSym = new DefSymbol(Label, value, Symbol.Source.Project,
isConstant ? Symbol.Type.Constant : Symbol.Type.ExternalAddr,
subType, commentTextBox.Text, string.Empty);
subType, Comment, string.Empty, width);
DialogResult = true;
}
private void LabelTextBox_TextChanged(object sender, TextChangedEventArgs e) {
UpdateControls();
}
private void ValueTextBox_TextChanged(object sender, TextChangedEventArgs e) {
UpdateControls();
}
}
}

View File

@ -72,11 +72,11 @@ limitations under the License.
Click="RemoveSymbolButton_Click"/>
</StackPanel>
<CheckBox Grid.Column="0" Grid.Row="2" Margin="0,4" Click="DeleteTableButton_Click"
<CheckBox Grid.Column="0" Grid.Row="2" Margin="0,4" IsChecked="{Binding ClearPrevious}"
Content="Clear values from previous tables"/>
<DockPanel Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2" Margin="0,8,0,0" LastChildFill="False">
<Button DockPanel.Dock="Left" Content="Delete Table" Width="120"/>
<Button DockPanel.Dock="Left" Content="Delete Table" Width="120" Click="DeleteTableButton_Click"/>
<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"/>

View File

@ -24,12 +24,21 @@ using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using Asm65;
using CommonWPF;
namespace SourceGen.WpfGui {
/// <summary>
/// Edit a LocalVariableTable.
/// </summary>
public partial class EditLocalVariableTable : Window {
// Item for the symbol list view.
/// <summary>
/// Result. Will be null if the table was deleted, or if cancel was hit while
/// creating a new table.
/// </summary>
public LocalVariableTable NewTable { get; private set; }
// Item for the symbol list view ItemsSource.
public class FormattedSymbol {
public string Label { get; private set; }
public string Value { get; private set; }
@ -49,35 +58,171 @@ namespace SourceGen.WpfGui {
public ObservableCollection<FormattedSymbol> Variables { get; private set; } =
new ObservableCollection<FormattedSymbol>();
public EditLocalVariableTable(Window owner) {
public bool ClearPrevious {
get { return mWorkTable.ClearPrevious; }
set { mWorkTable.ClearPrevious = value; OnPropertyChanged(); }
}
/// <summary>
/// Working set. Used internally to hold state.
/// </summary>
private LocalVariableTable mWorkTable;
/// <summary>
/// Symbol table for uniqueness check.
/// </summary>
private SymbolTable mSymbolTable;
/// <summary>
/// Format object to use when formatting addresses and constants.
/// </summary>
private Formatter mFormatter;
// INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = "") {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public EditLocalVariableTable(Window owner, SymbolTable symbolTable, Formatter formatter,
LocalVariableTable lvt) {
InitializeComponent();
Owner = owner;
DataContext = this;
mSymbolTable = symbolTable;
mFormatter = formatter;
if (lvt != null) {
mWorkTable = new LocalVariableTable(lvt);
} else {
mWorkTable = new LocalVariableTable();
}
LoadVariables();
}
public void Window_Loaded(object sender, RoutedEventArgs e) {
UpdateControls();
}
/// <summary>
/// Loads entries from the work table into the items source.
/// </summary>
private void LoadVariables() {
Variables.Clear();
foreach (KeyValuePair<string, DefSymbol> kvp in mWorkTable.Variables) {
DefSymbol defSym = kvp.Value;
string typeStr;
if (defSym.SymbolType == Symbol.Type.Constant) {
typeStr = Res.Strings.ABBREV_CONSTANT;
} else {
typeStr = Res.Strings.ABBREV_ADDRESS;
}
FormattedSymbol fsym = new FormattedSymbol(
defSym.Label,
mFormatter.FormatValueInBase(defSym.Value, defSym.DataDescriptor.NumBase),
typeStr,
defSym.Width == DefSymbol.NO_WIDTH ?
string.Empty : defSym.Width.ToString(),
defSym.Comment);
Variables.Add(fsym);
}
}
private void UpdateControls() {
// Enable or disable the edit/remove buttons based on how many items are selected.
// (We're currently configured for single-select, so this is really just a != 0 test.)
int symSelCount = symbolsListView.SelectedItems.Count;
removeSymbolButton.IsEnabled = (symSelCount == 1);
editSymbolButton.IsEnabled = (symSelCount == 1);
}
private void OkButton_Click(object sender, RoutedEventArgs e) {
NewTable = mWorkTable;
DialogResult = true;
}
private void DeleteTableButton_Click(object sender, RoutedEventArgs e) {
// TODO - get confirmation, then set result=true with LvTable=null
}
private void SymbolsListView_SelectionChanged(object sender, SelectionChangedEventArgs e) {
UpdateControls();
}
private void SymbolsListView_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
ListViewItem lvi = symbolsListView.GetClickedItem(e);
if (lvi == null) {
return;
}
FormattedSymbol item = (FormattedSymbol)lvi.Content;
DefSymbol defSym = mWorkTable.Variables[item.Label];
DoEditSymbol(defSym);
}
private void NewSymbolButton_Click(object sender, RoutedEventArgs e) {
EditDefSymbol dlg = new EditDefSymbol(this, mFormatter, mWorkTable.Variables, null,
mSymbolTable);
dlg.ShowDialog();
if (dlg.DialogResult == true) {
Debug.WriteLine("ADD: " + dlg.NewSym);
mWorkTable.Variables[dlg.NewSym.Label] = dlg.NewSym;
// Reload the contents. This loses the selection, but that shouldn't be an
// issue when adding new symbols. To do this incrementally we'd need to add
// the symbol at the correct sorted position.
LoadVariables();
UpdateControls();
}
}
private void EditSymbolButton_Click(object sender, EventArgs e) {
// Single-select list view, button dimmed when no selection.
Debug.Assert(symbolsListView.SelectedItems.Count == 1);
FormattedSymbol item = (FormattedSymbol)symbolsListView.SelectedItems[0];
DefSymbol defSym = mWorkTable.Variables[item.Label];
DoEditSymbol(defSym);
}
private void DoEditSymbol(DefSymbol defSym) {
EditDefSymbol dlg = new EditDefSymbol(this, mFormatter, mWorkTable.Variables, defSym,
mSymbolTable);
dlg.ShowDialog();
if (dlg.DialogResult == true) {
// Label might have changed, so remove old before adding new.
mWorkTable.Variables.Remove(defSym.Label);
mWorkTable.Variables[dlg.NewSym.Label] = dlg.NewSym;
LoadVariables();
UpdateControls();
}
}
private void RemoveSymbolButton_Click(object sender, RoutedEventArgs e) {
// Single-select list view, button dimmed when no selection.
Debug.Assert(symbolsListView.SelectedItems.Count == 1);
int selectionIndex = symbolsListView.SelectedIndex;
FormattedSymbol item = (FormattedSymbol)symbolsListView.SelectedItems[0];
DefSymbol defSym = mWorkTable.Variables[item.Label];
mWorkTable.Variables.Remove(defSym.Label);
LoadVariables();
UpdateControls();
// Restore selection to the item that used to come after the one we just deleted,
// so you can hit "Remove" repeatedly to delete multiple items.
int newCount = symbolsListView.Items.Count;
if (selectionIndex >= newCount) {
selectionIndex = newCount - 1;
}
if (selectionIndex >= 0) {
symbolsListView.SelectedIndex = selectionIndex;
removeSymbolButton.Focus();
}
}
}
}

View File

@ -157,10 +157,10 @@ namespace SourceGen.WpfGui {
NewProps = new ProjectProperties(mWorkProps);
DialogResult = true;
GridView view = (GridView)projectSymbolsListView.View;
foreach (GridViewColumn header in view.Columns) {
Debug.WriteLine("WIDTH " + header.ActualWidth);
}
//GridView view = (GridView)projectSymbolsListView.View;
//foreach (GridViewColumn header in view.Columns) {
// Debug.WriteLine("WIDTH " + header.ActualWidth);
//}
}
private void UpdateControls() {
@ -431,11 +431,11 @@ namespace SourceGen.WpfGui {
}
private void NewSymbolButton_Click(object sender, RoutedEventArgs e) {
EditDefSymbol dlg = new EditDefSymbol(this, mFormatter, mWorkProps.ProjectSyms);
EditDefSymbol dlg = new EditDefSymbol(this, mFormatter, mWorkProps.ProjectSyms, null);
dlg.ShowDialog();
if (dlg.DialogResult == true) {
Debug.WriteLine("ADD: " + dlg.DefSym);
mWorkProps.ProjectSyms[dlg.DefSym.Label] = dlg.DefSym;
Debug.WriteLine("ADD: " + dlg.NewSym);
mWorkProps.ProjectSyms[dlg.NewSym.Label] = dlg.NewSym;
IsDirty = true;
// Reload the contents. This loses the selection, but that shouldn't be an
@ -466,13 +466,13 @@ namespace SourceGen.WpfGui {
}
private void DoEditSymbol(DefSymbol defSym) {
EditDefSymbol dlg = new EditDefSymbol(this, mFormatter, mWorkProps.ProjectSyms);
dlg.DefSym = defSym;
EditDefSymbol dlg = new EditDefSymbol(this, mFormatter, mWorkProps.ProjectSyms,
defSym);
dlg.ShowDialog();
if (dlg.DialogResult == true) {
// Label might have changed, so remove old before adding new.
mWorkProps.ProjectSyms.Remove(defSym.Label);
mWorkProps.ProjectSyms[dlg.DefSym.Label] = dlg.DefSym;
mWorkProps.ProjectSyms[dlg.NewSym.Label] = dlg.NewSym;
IsDirty = true;
LoadProjectSymbols();
UpdateControls();