Skip to content

Commit

Permalink
Feature: associate an address with various views.
Browse files Browse the repository at this point in the history
LineSpan.Tag property can be used to associate an address with lines in TextViews.
  • Loading branch information
uxmal committed Jun 7, 2022
1 parent 8ed6d1f commit 4cd1790
Show file tree
Hide file tree
Showing 19 changed files with 106 additions and 41 deletions.
1 change: 1 addition & 0 deletions src/Core/Block.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ public void WriteStatements(TextWriter writer)
int i = 0;
foreach (Statement s in Statements)
{
f.Begin(s.LinearAddress);
s.Instruction.Accept(cf);
++i;
}
Expand Down
4 changes: 4 additions & 0 deletions src/Core/Output/Dumper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,10 @@ public AsmCommentFormatter(string asmCommentPrefix, Formatter w)
this.needPrefix = true;
}

public override void Begin(object? tag)
{
}

public override void Terminate()
{
WritePrefix();
Expand Down
10 changes: 10 additions & 0 deletions src/Core/Output/Formatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ public virtual void Indent()
public int TabSize {get; set; }
public bool UseTabs { get; set; }

/// <summary>
/// Begin a new line.
/// </summary>
/// <param name="tag">Optional line-specific data object.</param>
public abstract void Begin(object? tag);

/// <summary>
/// Terminate a line.
/// </summary>
Expand Down Expand Up @@ -133,6 +139,10 @@ public void WriteSpaces(int n)

public class NullFormatter : Formatter
{
public override void Begin(object? tag)
{
}

public override void Terminate()
{
}
Expand Down
1 change: 1 addition & 0 deletions src/Core/Output/ProcedureFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public void WriteBlock(Block block, CodeFormatter writer)
}
foreach (var stm in block.Statements)
{
writer.InnerFormatter.Begin(stm.LinearAddress);
stm.Instruction.Accept(writer);
}
}
Expand Down
9 changes: 9 additions & 0 deletions src/Core/Output/TextFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ public TextFormatter(TextWriter writer)
public TextWriter TextWriter { get; private set; }
public string Terminator { get; set; }

/// <summary>
/// Signals the start of a line with an object (which is ignored)
/// </summary>
/// <param name="tag"></param>
public override void Begin(object? tag)
{
}


/// <summary>
/// Terminate a line using the terminator string.
/// </summary>
Expand Down
3 changes: 2 additions & 1 deletion src/Gui/Controls/INavigableControl.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#region License
#region License
/*
* Copyright (C) 1999-2022 John Källén.
*
Expand Down Expand Up @@ -36,6 +36,7 @@ public interface INavigableControl<T>
IButton BackButton { get; }
IButton ForwardButton { get; }
T CurrentAddress { get; set; }

event EventHandler CurrentAddressChanged; // This event is fired when Back/Forward is pressed.
}
}
4 changes: 2 additions & 2 deletions src/UserInterfaces/WindowsForms/CombinedCodeViewInteractor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ private Address MixedCodeDataView_GetAnchorAddress()
{
addr = blockItem.Block.Procedure.EntryAddress;
}
else if (!(item.DataType is UnknownType))
else if (item.DataType is not UnknownType)
{
addr = item.Address;
}
Expand Down Expand Up @@ -558,7 +558,7 @@ void CombinedCodeView_CurrentAddressChanged(object sender, EventArgs e)

private void MixedCodeDataView_TopAddressChanged()
{
if (!(combinedCodeView.MixedCodeDataView.Model is MixedCodeDataModel mixedCodeDataModel))
if (combinedCodeView.MixedCodeDataView.Model is not MixedCodeDataModel mixedCodeDataModel)
return;

var topAddress = combinedCodeView.MixedCodeDataView.TopAddress;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ public static LineSpan RenderAsmLine(
var dfmt = new DisassemblyFormatter(program, arch, instr, line);
instr.Render(dfmt, options);
dfmt.NewLine();
return new LineSpan(position, line.ToArray());
return new LineSpan(position, addr, line.ToArray());
}

private Address Align(Address addr)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ private bool TryReadComment(out LineSpan line)
{
line = new LineSpan(
curPos,
curPos.Address,
new MemoryTextSpan(
$"; {commentLines[curPos.Offset]}",
UiStyles.CodeComment));
Expand Down Expand Up @@ -228,7 +229,7 @@ public override (ModelPosition, LineSpan)? GenerateSpan()
var addr = this.position.Address;
var rdr = program.CreateImageReader(program.Architecture, addr, item.EndAddress);
mem.Formatter.RenderLine(rdr, program.TextEncoding, this);
var memLine = new LineSpan(position, line.ToArray());
var memLine = new LineSpan(position, addr, line.ToArray());
line.Clear();

this.position = Pos(rdr.Address);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ public LineSpan[] GetLineSpans(int count)
count = count - sub.Length;
spans.AddRange(sub.Select(ls => new LineSpan(
new Location(i, ls.Position),
ls.Tag,
ls.TextSpans)));
position = new Location(i, model.CurrentPosition);
}
Expand Down
14 changes: 8 additions & 6 deletions src/UserInterfaces/WindowsForms/Controls/ProcedureCodeModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
using Reko.Core;
using Reko.Core.Output;
using System;
using System.Diagnostics;

namespace Reko.UserInterfaces.WindowsForms.Controls
{
Expand All @@ -29,9 +30,9 @@ namespace Reko.UserInterfaces.WindowsForms.Controls
/// </summary>
public class ProcedureCodeModel : TextViewModel
{
private Procedure proc;
int position;
private TextSpan[][] lines;
private readonly Procedure proc;
private int position;
private LineSpan[] lines; // The procedure, rendered into line spans
private int numLines;

public ProcedureCodeModel(Procedure proc)
Expand Down Expand Up @@ -65,12 +66,13 @@ public LineSpan[] GetLineSpans(int count)
var spans = new LineSpan[c];
for (int i = 0; i < c; ++i)
{
TextSpan[] line;
LineSpan line;
if ((p + i) < lines.Length)
line = lines[p + i];
else
line = new TextSpan[] { new EmptyTextSpan() };
spans[i] = new LineSpan(p + i, line);
line = new LineSpan(p + i, null, new TextSpan[] { new EmptyTextSpan() });
Debug.Assert((int) line.Position == p + i);
spans[i] = line;
}
position = p + c;
return spans;
Expand Down
34 changes: 26 additions & 8 deletions src/UserInterfaces/WindowsForms/Controls/TextView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ public partial class TextView : Control
public event EventHandler<SpanEventArgs> SpanEnter;
public event EventHandler<SpanEventArgs> SpanLeave;


private StringFormat stringFormat;
private TextViewLayout layout;
private bool ignoreScroll;
Expand Down Expand Up @@ -231,12 +230,12 @@ protected override void OnMouseMove(MouseEventArgs e)
{
if (spanHover != null)
{
SpanLeave.Fire(this, new SpanEventArgs(spanHover));
SpanLeave?.Invoke(this, new SpanEventArgs(spanHover));
}
spanHover = span;
if (span != null)
{
SpanEnter.Fire(this, new SpanEventArgs(span));
SpanEnter?.Invoke(this, new SpanEventArgs(span));
}
}
}
Expand Down Expand Up @@ -265,7 +264,7 @@ protected override void OnMouseUp(MouseEventArgs e)
var span = GetSpan(e.Location);
if (span != null && span.Tag != null)
{
Navigate.Fire(this, new EditorNavigationArgs(span.Tag));
Navigate?.Invoke(this, new EditorNavigationArgs(span.Tag));
}
}
SelectionChanged.Fire(this);
Expand Down Expand Up @@ -406,7 +405,7 @@ public Point GetAnchorMiddlePoint()
/// Returns the span located at the point <paramref name="pt"/>.
/// </summary>
/// <param name="pt">Location specified in client coordinates.</param>
/// <returns></returns>
/// <returns>The span containing the given point.</returns>
protected LayoutSpan GetSpan(Point pt)
{
foreach (var line in this.layout.LayoutLines)
Expand All @@ -417,6 +416,21 @@ protected LayoutSpan GetSpan(Point pt)
return null;
}

/// <summary>
/// Returns the LayoutLine containing the point <paramref name="pt"/>.
/// </summary>
/// <param name="pt">Location specified in client coordinates.</param>
/// <returns>The span containing the given point.</returns>
protected LayoutLine GetLine(Point pt)
{
foreach (var line in this.layout.LayoutLines)
{
if (line.Extent.Contains(pt))
return line;
}
return null;
}

private LayoutSpan FindSpan(Point ptClient, LayoutLine line)
{
foreach (var span in line.Spans)
Expand Down Expand Up @@ -480,9 +494,13 @@ protected void ChangeLayout()
public object GetTagFromPoint(Point ptClient)
{
var span = GetSpan(ptClient);
if (span == null)
return null;
return span.Tag;
return span?.Tag;
}

public object GetLineTagFromPoint(Point ptClient)
{
var line = GetLine(ptClient);
return line?.Tag;
}

private int GetFullyVisibleLines()
Expand Down
9 changes: 7 additions & 2 deletions src/UserInterfaces/WindowsForms/Controls/TextViewLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ public void AddLayoutLine(LineSpan line, ref RectangleF rcLine /* put in state *
float cyLine = MeasureLineHeight(line);
rcLine.Height = cyLine;
var spans = ComputeSpanLayouts(line.TextSpans, rcLine);
var ll = new LayoutLine(line.Position)
var ll = new LayoutLine(line.Position, line.Tag)
{
Extent = LineExtent(rcLine, spans),
Spans = spans,
Expand Down Expand Up @@ -349,8 +349,13 @@ public TextViewLayout Build()
/// </summary>
public class LayoutLine
{
public LayoutLine(object Position) { this.Position = Position; }
public LayoutLine(object Position, object tag) {
this.Position = Position;
this.Tag = tag;
}

public object Position;
public object Tag; // extra object for this line.
public RectangleF Extent;
public LayoutSpan[] Spans;
}
Expand Down
6 changes: 5 additions & 1 deletion src/UserInterfaces/WindowsForms/Controls/TextViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,15 @@ public struct LineSpan
{
public readonly object Position;
public readonly TextSpan[] TextSpans;
public readonly object Tag;

public LineSpan(object position, params TextSpan[] textSpans)
public LineSpan(object position, object tag, params TextSpan[] textSpans)
{
this.Position = position;
this.TextSpans = textSpans;
if (textSpans is null || textSpans.Length == 0)
_ = textSpans; //$DEBUG
this.Tag = tag;
}
}
}
3 changes: 2 additions & 1 deletion src/UserInterfaces/WindowsForms/Controls/TextViewPainter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#region License
#region License
/*
* Copyright (C) 1999-2022 John Källén.
*
Expand Down Expand Up @@ -125,6 +125,7 @@ private void PaintLine(LayoutLine line)
outer.ComparePositions(selStart, pos) <= 0 &&
outer.ComparePositions(pos, selEnd) < 0;

var hasTag = line.Tag != null;
this.fg = styleStack.GetForegroundColor(defaultFgColor);
this.bg = styleStack.GetBackground(defaultBgColor);
this.font = styleStack.GetFont(defaultFont);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ public DiagnosticsInteractor()

public DiagnosticFilters Filter { get; set; }

public void Attach(ListView listView, ToolStripButton? btnFilter)
public void Attach(ListView listView, ToolStripButton btnFilter)
{
if (listView == null)
throw new ArgumentNullException("listView");
throw new ArgumentNullException(nameof(listView));
syncCtx = SynchronizationContext.Current;
this.listView = listView;
listView.DoubleClick += listView_DoubleClick;
Expand Down
9 changes: 4 additions & 5 deletions src/UserInterfaces/WindowsForms/StyleStack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ private IEnumerable<UiStyle> GetStyles(string[] styles)
{
foreach (var styleName in styles)
{
UiStyle style;
if (uiPrefSvc.Styles.TryGetValue(styleName, out style))
if (uiPrefSvc.Styles.TryGetValue(styleName, out UiStyle style))
yield return style;
}
}
Expand Down Expand Up @@ -142,9 +141,9 @@ public Font GetFont(Font defaultFont)
for (int i = stack.Count - 1; i >= 0; --i)
{
var styles = GetStyles(stack[i]);
var font = styles.Select(s => s.Font).LastOrDefault(f => f != null);
if (font != null)
return (Font)font;
var oFont = styles.Select(s => s.Font).LastOrDefault(f => f != null);
if (oFont is Font font)
return font;
}
return defaultFont;
}
Expand Down
Loading

0 comments on commit 4cd1790

Please sign in to comment.