1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-11-05 06:04:36 +00:00
6502bench/SourceGen/WpfGui/EditLvTableLocation.xaml.cs

197 lines
6.9 KiB
C#
Raw Normal View History

/*
* 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.
private Brush mDefaultLabelColor = SystemColors.WindowTextBrush;
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);
}
}
}