1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-06-24 08:29:29 +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:
Andy McFadden 2019-06-16 09:29:54 -07:00
parent 1a0a229b9b
commit d3230ef0d6
5 changed files with 164 additions and 2 deletions

View File

@ -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;
}
}
}
}

View File

@ -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);
}

View File

@ -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>

View File

@ -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}"/>

View File

@ -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 &lt; 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 &lt; 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