mirror of
https://github.com/fadden/6502bench.git
synced 2024-11-26 06:49:19 +00:00
Add addr/label target highlight
When you select a line that references a label within the file, we highlight the address and label fields of the target offset.
This commit is contained in:
parent
1a0a229b9b
commit
d3230ef0d6
@ -285,6 +285,9 @@ namespace SourceGenWPF {
|
||||
SelectedIndices = new DisplayListSelection(size);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List elements. Instances are immutable.
|
||||
/// </summary>
|
||||
public class FormattedParts {
|
||||
public string Offset { get; private set; }
|
||||
public string Addr { get; private set; }
|
||||
@ -297,11 +300,29 @@ namespace SourceGenWPF {
|
||||
public string Comment { get; private set; }
|
||||
public bool IsLongComment { get; private set; }
|
||||
|
||||
// Set to true if we want to highlight the address and label fields.
|
||||
public bool HasAddrLabelHighlight { get; private set; }
|
||||
|
||||
public int ListIndex { get; set; } = -1;
|
||||
|
||||
// Private constructor -- create instances with factory methods.
|
||||
private FormattedParts() { }
|
||||
|
||||
/// <summary>
|
||||
/// Clones the specified object.
|
||||
/// </summary>
|
||||
private static FormattedParts Clone(FormattedParts orig) {
|
||||
FormattedParts newParts = FormattedParts.Create(orig.Offset, orig.Addr,
|
||||
orig.Bytes, orig.Flags, orig.Attr, orig.Label, orig.Opcode, orig.Operand,
|
||||
orig.Comment);
|
||||
|
||||
newParts.IsLongComment = orig.IsLongComment;
|
||||
newParts.HasAddrLabelHighlight = orig.HasAddrLabelHighlight;
|
||||
|
||||
newParts.ListIndex = orig.ListIndex;
|
||||
return newParts;
|
||||
}
|
||||
|
||||
public static FormattedParts Create(string offset, string addr, string bytes,
|
||||
string flags, string attr, string label, string opcode, string operand,
|
||||
string comment) {
|
||||
@ -348,6 +369,18 @@ namespace SourceGenWPF {
|
||||
parts.Comment = comment;
|
||||
return parts;
|
||||
}
|
||||
|
||||
public static FormattedParts AddSelectionHighlight(FormattedParts orig) {
|
||||
FormattedParts newParts = Clone(orig);
|
||||
newParts.HasAddrLabelHighlight = true;
|
||||
return newParts;
|
||||
}
|
||||
|
||||
public static FormattedParts RemoveSelectionHighlight(FormattedParts orig) {
|
||||
FormattedParts newParts = Clone(orig);
|
||||
newParts.HasAddrLabelHighlight = false;
|
||||
return newParts;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1057,6 +1057,7 @@ namespace SourceGenWPF {
|
||||
|
||||
UpdateReferencesPanel();
|
||||
UpdateInfoPanel();
|
||||
UpdateSelectionHighlight();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1256,6 +1257,49 @@ namespace SourceGenWPF {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the selection highlight. When a code item with an operand offset is
|
||||
/// selected, such as a branch, we want to highlight the address and label of the
|
||||
/// target.
|
||||
/// </summary>
|
||||
private void UpdateSelectionHighlight() {
|
||||
int targetIndex = FindSelectionHighlight();
|
||||
|
||||
if (mTargetHighlightIndex != targetIndex) {
|
||||
mMainWin.CodeListView_RemoveSelectionHighlight(mTargetHighlightIndex);
|
||||
mMainWin.CodeListView_AddSelectionHighlight(targetIndex);
|
||||
|
||||
mTargetHighlightIndex = targetIndex;
|
||||
Debug.WriteLine("Selection highlight now " + targetIndex);
|
||||
}
|
||||
}
|
||||
|
||||
private int FindSelectionHighlight() {
|
||||
if (mMainWin.CodeListView_GetSelectionCount() != 1) {
|
||||
return -1;
|
||||
}
|
||||
int selIndex = mMainWin.CodeListView_GetFirstSelectedIndex();
|
||||
LineListGen.Line line = CodeListGen[selIndex];
|
||||
if (!line.IsCodeOrData) {
|
||||
return -1;
|
||||
}
|
||||
Debug.Assert(line.FileOffset >= 0);
|
||||
|
||||
// Does this have an operand with an in-file target offset?
|
||||
Anattrib attr = mProject.GetAnattrib(line.FileOffset);
|
||||
if (attr.OperandOffset >= 0) {
|
||||
return CodeListGen.FindCodeDataIndexByOffset(attr.OperandOffset);
|
||||
} else if (attr.IsDataStart || attr.IsInlineDataStart) {
|
||||
// If it's an Address or Symbol, we can try to resolve
|
||||
// the value.
|
||||
int operandOffset = DataAnalysis.GetDataOperandOffset(mProject, line.FileOffset);
|
||||
if (operandOffset >= 0) {
|
||||
return CodeListGen.FindCodeDataIndexByOffset(operandOffset);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public bool CanUndo() {
|
||||
return (mProject != null && mProject.CanUndo);
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ See also https://github.com/fadden/DisasmUiTest
|
||||
<GridViewColumn Width="{Binding
|
||||
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListView}
|
||||
}, Path=View.Columns[4].ActualWidth}" DisplayMemberBinding="{Binding Attr}"/>
|
||||
<!-- This column holds the long comment. Leave the width unset. -->
|
||||
<GridViewColumn Header="two" DisplayMemberBinding="{Binding Path=Comment}"/>
|
||||
</GridViewColumnCollection>
|
||||
|
||||
@ -139,10 +140,49 @@ See also https://github.com/fadden/DisasmUiTest
|
||||
wrong place you'll feel like you clicked and nothing happened. -->
|
||||
<Setter Property="Margin" Value="0,-1,0,0"/>
|
||||
|
||||
<!-- This causes individual TextBoxes to stretch to fill the column. This is nice
|
||||
because the cell-highlight stuff will set the background on the full cell rather than
|
||||
just the bit with the text. -->
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Path=IsLongComment}" Value="True">
|
||||
<Setter Property="Template" Value="{StaticResource longCommentTemplate}"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<!-- Highlighting for individual cells. -->
|
||||
<DataTemplate x:Key="addrHighlightTemplate">
|
||||
<TextBlock>
|
||||
<TextBlock.Style>
|
||||
<Style>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Path=HasAddrLabelHighlight}" Value="True">
|
||||
<Setter Property="TextBlock.Background" Value="{StaticResource ListItemSelectedFill}"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
<TextBlock.Text>
|
||||
<Binding Path="Addr"/>
|
||||
</TextBlock.Text>
|
||||
</TextBlock>
|
||||
</DataTemplate>
|
||||
<DataTemplate x:Key="labelHighlightTemplate">
|
||||
<TextBlock>
|
||||
<TextBlock.Style>
|
||||
<Style>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Path=HasAddrLabelHighlight}" Value="True">
|
||||
<Setter Property="TextBlock.Background" Value="{StaticResource ListItemSelectedFill}"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
<TextBlock.Text>
|
||||
<Binding Path="Label"/>
|
||||
</TextBlock.Text>
|
||||
</TextBlock>
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
@ -350,11 +350,11 @@ limitations under the License.
|
||||
<ListView.View>
|
||||
<GridView AllowsColumnReorder="False">
|
||||
<GridViewColumn Header="Offset" DisplayMemberBinding="{Binding Offset}"/>
|
||||
<GridViewColumn Header="Addr" DisplayMemberBinding="{Binding Addr}"/>
|
||||
<GridViewColumn Header="Addr" CellTemplate="{StaticResource addrHighlightTemplate}"/>
|
||||
<GridViewColumn Header="Bytes" DisplayMemberBinding="{Binding Bytes}"/>
|
||||
<GridViewColumn Header="Flags" DisplayMemberBinding="{Binding Flags}"/>
|
||||
<GridViewColumn Header="Attr" DisplayMemberBinding="{Binding Attr}"/>
|
||||
<GridViewColumn Header="Label" DisplayMemberBinding="{Binding Label}"/>
|
||||
<GridViewColumn Header="Label" CellTemplate="{StaticResource labelHighlightTemplate}"/>
|
||||
<GridViewColumn Header="Opcode" DisplayMemberBinding="{Binding Opcode}"/>
|
||||
<GridViewColumn Header="Operand" DisplayMemberBinding="{Binding Operand}"/>
|
||||
<GridViewColumn Header="Comment" DisplayMemberBinding="{Binding Comment}"/>
|
||||
|
@ -413,11 +413,56 @@ namespace SourceGenWPF.ProjWin {
|
||||
codeListView.ScrollToTopItem(CodeDisplayList[index]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scrolls the code list to ensure that the specified index is visible.
|
||||
/// </summary>
|
||||
/// <param name="index">Line index of item.</param>
|
||||
public void CodeListView_EnsureVisible(int index) {
|
||||
Debug.Assert(index >= 0 && index < CodeDisplayList.Count);
|
||||
codeListView.ScrollIntoView(CodeDisplayList[index]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an address/label selection highlight to the specified line.
|
||||
/// </summary>
|
||||
/// <param name="index">Line index. If < 0, method has no effect.</param>
|
||||
public void CodeListView_AddSelectionHighlight(int index) {
|
||||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
CodeListView_ReplaceEntry(index,
|
||||
DisplayList.FormattedParts.AddSelectionHighlight(CodeDisplayList[index]));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes an address/label selection highlight from the specified line.
|
||||
/// </summary>
|
||||
/// <param name="index">Line index. If < 0, method has no effect.</param>
|
||||
public void CodeListView_RemoveSelectionHighlight(int index) {
|
||||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
CodeListView_ReplaceEntry(index,
|
||||
DisplayList.FormattedParts.RemoveSelectionHighlight(CodeDisplayList[index]));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces an entry in the code list. If the item was selected, the selection is
|
||||
/// cleared and restored.
|
||||
/// </summary>
|
||||
/// <param name="index">List index.</param>
|
||||
/// <param name="newParts">Replacement parts.</param>
|
||||
private void CodeListView_ReplaceEntry(int index, DisplayList.FormattedParts newParts) {
|
||||
bool isSelected = CodeDisplayList.SelectedIndices[index];
|
||||
if (isSelected) {
|
||||
codeListView.SelectedItems.Remove(CodeDisplayList[index]);
|
||||
}
|
||||
CodeDisplayList[index] = newParts;
|
||||
if (isSelected) {
|
||||
codeListView.SelectedItems.Add(newParts);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Selection management
|
||||
|
||||
#region Can-execute handlers
|
||||
|
Loading…
Reference in New Issue
Block a user