mirror of
https://github.com/fadden/6502bench.git
synced 2024-11-29 10:50:28 +00:00
Add a "move table" button
A simple if slightly awkward way to reposition a local variable table.
This commit is contained in:
parent
d542a809f8
commit
9a61a852ad
@ -104,6 +104,8 @@ namespace SourceGen {
|
||||
/// up in the symbol table, and the uniquifier isn't able to tell that the entry in the
|
||||
/// symbol table is itself. The logic is simpler if we just rename the label before
|
||||
/// the uniquifier ever sees it.
|
||||
///
|
||||
/// I feel like there has to be a simpler way to do this. This'll do for now.
|
||||
/// </remarks>
|
||||
private Dictionary<string, string> mDupRemap;
|
||||
|
||||
|
@ -1324,6 +1324,7 @@ namespace SourceGen {
|
||||
case LineListGen.Line.Type.EquDirective:
|
||||
case LineListGen.Line.Type.RegWidthDirective:
|
||||
case LineListGen.Line.Type.OrgDirective:
|
||||
case LineListGen.Line.Type.LocalVariableTable:
|
||||
if (format == ClipLineFormat.Disassembly) {
|
||||
if (!string.IsNullOrEmpty(parts.Addr)) {
|
||||
sb.Append(parts.Addr);
|
||||
@ -1706,21 +1707,37 @@ namespace SourceGen {
|
||||
public void EditLocalVariableTable() {
|
||||
int selIndex = mMainWin.CodeListView_GetFirstSelectedIndex();
|
||||
int offset = CodeLineList[selIndex].FileOffset;
|
||||
// Get existing table, if any.
|
||||
mProject.LvTables.TryGetValue(offset, out LocalVariableTable oldLvt);
|
||||
|
||||
EditLocalVariableTable dlg = new EditLocalVariableTable(mMainWin, mProject.SymbolTable,
|
||||
mOutputFormatter, oldLvt);
|
||||
EditLocalVariableTable dlg = new EditLocalVariableTable(mMainWin, mProject,
|
||||
mOutputFormatter, oldLvt, offset);
|
||||
if (dlg.ShowDialog() != true) {
|
||||
return;
|
||||
}
|
||||
if (oldLvt == dlg.NewTable) {
|
||||
if (offset != dlg.NewOffset) {
|
||||
// Table moved. We create two changes, one to delete the current table, one
|
||||
// to create a new table.
|
||||
Debug.Assert(!mProject.LvTables.TryGetValue(dlg.NewOffset,
|
||||
out LocalVariableTable unused));
|
||||
|
||||
UndoableChange rem = UndoableChange.CreateLocalVariableTableChange(offset,
|
||||
oldLvt, null);
|
||||
UndoableChange add = UndoableChange.CreateLocalVariableTableChange(dlg.NewOffset,
|
||||
null, dlg.NewTable);
|
||||
ChangeSet cs = new ChangeSet(2);
|
||||
cs.Add(rem);
|
||||
cs.Add(add);
|
||||
ApplyUndoableChanges(cs);
|
||||
} else if (oldLvt != dlg.NewTable) {
|
||||
// New table, edited in place, or deleted.
|
||||
UndoableChange uc = UndoableChange.CreateLocalVariableTableChange(offset,
|
||||
oldLvt, dlg.NewTable);
|
||||
ChangeSet cs = new ChangeSet(uc);
|
||||
ApplyUndoableChanges(cs);
|
||||
} else {
|
||||
Debug.WriteLine("LvTable unchanged");
|
||||
return;
|
||||
}
|
||||
UndoableChange uc = UndoableChange.CreateLocalVariableTableChange(offset,
|
||||
oldLvt, dlg.NewTable);
|
||||
ChangeSet cs = new ChangeSet(uc);
|
||||
ApplyUndoableChanges(cs);
|
||||
}
|
||||
|
||||
public bool CanEditLongComment() {
|
||||
|
@ -118,6 +118,9 @@
|
||||
<Compile Include="WpfGui\EditLongComment.xaml.cs">
|
||||
<DependentUpon>EditLongComment.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="WpfGui\EditLvTableLocation.xaml.cs">
|
||||
<DependentUpon>EditLvTableLocation.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="WpfGui\EditNote.xaml.cs">
|
||||
<DependentUpon>EditNote.xaml</DependentUpon>
|
||||
</Compile>
|
||||
@ -275,6 +278,10 @@
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="WpfGui\EditLvTableLocation.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="WpfGui\EditNote.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
@ -83,8 +83,10 @@ limitations under the License.
|
||||
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" IsEnabled="{Binding IsNotNewTable}"
|
||||
Click="DeleteTableButton_Click"/>
|
||||
<Button DockPanel.Dock="Left" Content="Delete Table" Width="120"
|
||||
IsEnabled="{Binding IsNotNewTable}" Click="DeleteTableButton_Click"/>
|
||||
<Button DockPanel.Dock="Left" Content="Move Table" Width="120" Margin="8,0,0,0"
|
||||
IsEnabled="{Binding IsNotNewTable}" Click="MoveTableButton_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"/>
|
||||
|
@ -14,7 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
@ -22,7 +21,6 @@ using System.Runtime.CompilerServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
|
||||
using Asm65;
|
||||
using CommonWPF;
|
||||
@ -31,13 +29,18 @@ namespace SourceGen.WpfGui {
|
||||
/// <summary>
|
||||
/// Edit a LocalVariableTable.
|
||||
/// </summary>
|
||||
public partial class EditLocalVariableTable : Window {
|
||||
public partial class EditLocalVariableTable : Window, INotifyPropertyChanged {
|
||||
/// <summary>
|
||||
/// Result. Will be null if the table was deleted, or if cancel was hit while
|
||||
/// Output. 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; }
|
||||
|
||||
/// <summary>
|
||||
/// Output. If the table was moved, the new offset will be different from the old.
|
||||
/// </summary>
|
||||
public int NewOffset { get; private set; }
|
||||
|
||||
// Item for the symbol list view ItemsSource.
|
||||
public class FormattedSymbol {
|
||||
public string Label { get; private set; }
|
||||
@ -82,15 +85,25 @@ namespace SourceGen.WpfGui {
|
||||
private LocalVariableTable mWorkTable;
|
||||
|
||||
/// <summary>
|
||||
/// Symbol table for uniqueness check.
|
||||
/// Project reference.
|
||||
/// </summary>
|
||||
private SymbolTable mSymbolTable;
|
||||
private DisasmProject mProject;
|
||||
|
||||
/// <summary>
|
||||
/// Format object to use when formatting addresses and constants.
|
||||
/// </summary>
|
||||
private Formatter mFormatter;
|
||||
|
||||
/// <summary>
|
||||
/// Symbol table for uniqueness check.
|
||||
/// </summary>
|
||||
private SymbolTable mSymbolTable;
|
||||
|
||||
/// <summary>
|
||||
/// Table offset, for move ops.
|
||||
/// </summary>
|
||||
private int mOffset;
|
||||
|
||||
// INotifyPropertyChanged implementation
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
private void OnPropertyChanged([CallerMemberName] string propertyName = "") {
|
||||
@ -101,14 +114,16 @@ namespace SourceGen.WpfGui {
|
||||
/// <summary>
|
||||
/// Constructor. lvt will be null when creating a new entry.
|
||||
/// </summary>
|
||||
public EditLocalVariableTable(Window owner, SymbolTable symbolTable, Formatter formatter,
|
||||
LocalVariableTable lvt) {
|
||||
public EditLocalVariableTable(Window owner, DisasmProject project, Formatter formatter,
|
||||
LocalVariableTable lvt, int offset) {
|
||||
InitializeComponent();
|
||||
Owner = owner;
|
||||
DataContext = this;
|
||||
|
||||
mSymbolTable = symbolTable;
|
||||
mProject = project;
|
||||
mFormatter = formatter;
|
||||
mSymbolTable = project.SymbolTable;
|
||||
mOffset = NewOffset = offset;
|
||||
|
||||
if (lvt != null) {
|
||||
mWorkTable = new LocalVariableTable(lvt);
|
||||
@ -173,6 +188,13 @@ namespace SourceGen.WpfGui {
|
||||
}
|
||||
}
|
||||
|
||||
private void MoveTableButton_Click(object sender, RoutedEventArgs e) {
|
||||
EditLvTableLocation dlg = new EditLvTableLocation(this, mProject, mOffset, NewOffset);
|
||||
if (dlg.ShowDialog() == true) {
|
||||
NewOffset = dlg.NewOffset;
|
||||
}
|
||||
}
|
||||
|
||||
private void SymbolsListView_SelectionChanged(object sender, SelectionChangedEventArgs e) {
|
||||
UpdateControls();
|
||||
}
|
||||
|
76
SourceGen/WpfGui/EditLvTableLocation.xaml
Normal file
76
SourceGen/WpfGui/EditLvTableLocation.xaml
Normal file
@ -0,0 +1,76 @@
|
||||
<!--
|
||||
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.EditLvTableLocation"
|
||||
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 Local Variable Table Location"
|
||||
SizeToContent="WidthAndHeight" ResizeMode="NoResize"
|
||||
ShowInTaskbar="False" WindowStartupLocation="CenterOwner"
|
||||
ContentRendered="Window_ContentRendered">
|
||||
|
||||
<Window.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
|
||||
</Window.Resources>
|
||||
|
||||
<DockPanel LastChildFill="False" Margin="8">
|
||||
<TextBlock DockPanel.Dock="Top" Text="Select new location for table" Margin="0,0,75,8"/>
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
|
||||
<TextBlock Text="File offset (hex): +"/>
|
||||
|
||||
<!-- up/down control, inspired by https://stackoverflow.com/a/5321605/294248 -->
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBox Name="offsetTextBox" Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Width="50" MaxLength="6"
|
||||
Text="{Binding OffsetStr, UpdateSourceTrigger=PropertyChanged, FallbackValue=012345}"/>
|
||||
<RepeatButton Grid.Column="1" Grid.Row="0" Content="5" FontSize="8" FontFamily="Marlett"
|
||||
VerticalContentAlignment="Center" HorizontalContentAlignment="Center"
|
||||
Click="OffsetUp_Click"/>
|
||||
<RepeatButton Grid.Column="1" Grid.Row="1" Content="6" FontSize="8" FontFamily="Marlett"
|
||||
VerticalContentAlignment="Center" HorizontalContentAlignment="Center"
|
||||
Click="OffsetDown_Click"/>
|
||||
</Grid>
|
||||
|
||||
</StackPanel>
|
||||
<DockPanel DockPanel.Dock="Bottom" LastChildFill="False" Margin="0,16,0,0">
|
||||
<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" IsEnabled="{Binding IsValid}" Click="OkButton_Click"/>
|
||||
</DockPanel>
|
||||
|
||||
<TextBlock DockPanel.Dock="Bottom" Margin="0,4,0,0"
|
||||
Text="• Offset must not already have a local variable table"
|
||||
Foreground="{Binding TableAlreadyPresentBrush}"/>
|
||||
<TextBlock DockPanel.Dock="Bottom" Margin="0,4,0,0"
|
||||
Text="• Offset must be the start of an instruction"
|
||||
Foreground="{Binding NotInstructionBrush}"/>
|
||||
<TextBlock DockPanel.Dock="Bottom" Margin="0,4,0,0"
|
||||
Text="• Offset value must be valid"
|
||||
Foreground="{Binding InvalidOffsetBrush}"/>
|
||||
</DockPanel>
|
||||
</Window>
|
196
SourceGen/WpfGui/EditLvTableLocation.xaml.cs
Normal file
196
SourceGen/WpfGui/EditLvTableLocation.xaml.cs
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
* 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.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace SourceGen.WpfGui {
|
||||
/// <summary>
|
||||
/// Allows repositioning of a local variable table.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This would be better implemented as cut/copy/paste, allowing parts of tables to be
|
||||
/// freely duplicated and copied around, but that's a bunch of work for something that
|
||||
/// I'm not yet convinced is important. (It might not be that much more work in and of
|
||||
/// itself, but once the action is possible people will expect it to work for comments
|
||||
/// and notes, and maybe want to paste operand formatting.)
|
||||
/// </remarks>
|
||||
public partial class EditLvTableLocation : Window, INotifyPropertyChanged {
|
||||
/// <summary>
|
||||
/// After a successful move, this will hold the new offset.
|
||||
/// </summary>
|
||||
public int NewOffset { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Project reference.
|
||||
/// </summary>
|
||||
private DisasmProject mProject;
|
||||
|
||||
/// <summary>
|
||||
/// File offset at which we are initially positioned.
|
||||
/// </summary>
|
||||
private int mCurrentOffset;
|
||||
|
||||
// Dialog label text color, saved off at dialog load time.
|
||||
private Brush mDefaultLabelColor = Brushes.Black;
|
||||
private Brush mErrorLabelColor = Brushes.Red;
|
||||
|
||||
public string OffsetStr {
|
||||
get { return mOffsetStr; }
|
||||
set { mOffsetStr = value; OnPropertyChanged(); ValidateOffset(); }
|
||||
}
|
||||
private string mOffsetStr;
|
||||
|
||||
public bool IsValid {
|
||||
get { return mIsValid; }
|
||||
set { mIsValid = value; OnPropertyChanged(); }
|
||||
}
|
||||
private bool mIsValid;
|
||||
|
||||
public Brush InvalidOffsetBrush {
|
||||
get { return mInvalidOffsetBrush; }
|
||||
set { mInvalidOffsetBrush = value; OnPropertyChanged(); }
|
||||
}
|
||||
private Brush mInvalidOffsetBrush;
|
||||
|
||||
public Brush NotInstructionBrush {
|
||||
get { return mNotInstructionBrush; }
|
||||
set { mNotInstructionBrush = value; OnPropertyChanged(); }
|
||||
}
|
||||
private Brush mNotInstructionBrush;
|
||||
|
||||
public Brush TableAlreadyPresentBrush {
|
||||
get { return mTableAlreadyPresentBrush; }
|
||||
set { mTableAlreadyPresentBrush = value; OnPropertyChanged(); }
|
||||
}
|
||||
private Brush mTableAlreadyPresentBrush;
|
||||
|
||||
// INotifyPropertyChanged implementation
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
private void OnPropertyChanged([CallerMemberName] string propertyName = "") {
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
|
||||
public EditLvTableLocation(Window owner, DisasmProject project, int curOffset,
|
||||
int initialOffset) {
|
||||
InitializeComponent();
|
||||
Owner = owner;
|
||||
DataContext = this;
|
||||
|
||||
mProject = project;
|
||||
mCurrentOffset = curOffset;
|
||||
|
||||
// curOffset is where the table actually is. initialOffset reflects changes
|
||||
// made on a previous invocation of this dialog.
|
||||
OffsetStr = initialOffset.ToString("x6");
|
||||
}
|
||||
|
||||
private void Window_ContentRendered(object sender, EventArgs e) {
|
||||
offsetTextBox.SelectAll();
|
||||
offsetTextBox.Focus();
|
||||
}
|
||||
|
||||
private void OkButton_Click(object sender, RoutedEventArgs e) {
|
||||
NewOffset = Convert.ToInt32(OffsetStr, 16);
|
||||
DialogResult = true;
|
||||
}
|
||||
|
||||
private void OffsetUp_Click(object sender, RoutedEventArgs e) {
|
||||
AdjustOffset(-1);
|
||||
}
|
||||
|
||||
private void OffsetDown_Click(object sender, RoutedEventArgs e) {
|
||||
AdjustOffset(1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the offset up or down enough to get it to the next instruction start that
|
||||
/// doesn't already have a local variable table.
|
||||
/// </summary>
|
||||
/// <param name="adj">Adjustment, should be +1 or -1.</param>
|
||||
private void AdjustOffset(int adj) {
|
||||
int offset;
|
||||
try {
|
||||
offset = Convert.ToInt32(OffsetStr, 16);
|
||||
} catch (Exception) {
|
||||
// string is garbage, just put the initial offset back in
|
||||
OffsetStr = mCurrentOffset.ToString("x6");
|
||||
return;
|
||||
}
|
||||
offset += adj;
|
||||
while (offset >= 0 && offset < mProject.FileDataLength) {
|
||||
if (mProject.GetAnattrib(offset).IsInstructionStart && !HasTableNotSelf(offset)) {
|
||||
// found a winner
|
||||
OffsetStr = offset.ToString("x6");
|
||||
return;
|
||||
}
|
||||
offset += adj;
|
||||
}
|
||||
}
|
||||
|
||||
private void ValidateOffset() {
|
||||
InvalidOffsetBrush = NotInstructionBrush = TableAlreadyPresentBrush =
|
||||
mDefaultLabelColor;
|
||||
|
||||
if (string.IsNullOrEmpty(OffsetStr)) {
|
||||
InvalidOffsetBrush = mErrorLabelColor;
|
||||
IsValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
int offset;
|
||||
try {
|
||||
offset = Convert.ToInt32(OffsetStr, 16);
|
||||
} catch (Exception) {
|
||||
InvalidOffsetBrush = mErrorLabelColor;
|
||||
IsValid = false;
|
||||
return;
|
||||
}
|
||||
if (offset < 0 || offset >= mProject.FileDataLength) {
|
||||
InvalidOffsetBrush = mErrorLabelColor;
|
||||
IsValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
Anattrib attr = mProject.GetAnattrib(offset);
|
||||
if (!attr.IsInstructionStart) {
|
||||
NotInstructionBrush = mErrorLabelColor;
|
||||
IsValid = false;
|
||||
return;
|
||||
}
|
||||
if (HasTableNotSelf(offset)) {
|
||||
TableAlreadyPresentBrush = mErrorLabelColor;
|
||||
IsValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
IsValid = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the specified offset is the start of an instruction, and doesn't
|
||||
/// have a local variable table unless the table is us.
|
||||
/// </summary>
|
||||
private bool HasTableNotSelf(int offset) {
|
||||
return offset != mCurrentOffset &&
|
||||
mProject.LvTables.TryGetValue(offset, out LocalVariableTable unused);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user