diff --git a/src/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.Designer.cs b/src/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.Designer.cs index cb3c8f8543..64321a0b6d 100644 --- a/src/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.Designer.cs +++ b/src/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.Designer.cs @@ -89,7 +89,7 @@ namespace BizHawk.Client.EmuHawk this.MemoryViewerBox = new System.Windows.Forms.GroupBox(); this.HexScrollBar = new System.Windows.Forms.VScrollBar(); this.AddressLabel = new BizHawk.WinForms.Controls.LocLabelEx(); - this.AddressesLabel = new BizHawk.WinForms.Controls.LocLabelEx(); + this.AddressesLabel = new BizHawk.WinForms.Controls.HexLabelEx(); this.Header = new BizHawk.WinForms.Controls.LocLabelEx(); this.HexMenuStrip.SuspendLayout(); this.ViewerContextMenuStrip.SuspendLayout(); @@ -454,6 +454,7 @@ namespace BizHawk.Client.EmuHawk this.AddressesLabel.MouseLeave += new System.EventHandler(this.AddressesLabel_MouseLeave); this.AddressesLabel.MouseMove += new System.Windows.Forms.MouseEventHandler(this.AddressesLabel_MouseMove); this.AddressesLabel.MouseUp += new System.Windows.Forms.MouseEventHandler(this.AddressesLabel_MouseUp); + this.AddressesLabel.Paint += new System.Windows.Forms.PaintEventHandler(this.AddressesLabel_Paint); // // Header // @@ -511,7 +512,7 @@ namespace BizHawk.Client.EmuHawk private BizHawk.WinForms.Controls.ToolStripMenuItemEx AddToRamWatchMenuItem; private BizHawk.WinForms.Controls.ToolStripMenuItemEx FreezeAddressMenuItem; public System.Windows.Forms.GroupBox MemoryViewerBox; - private BizHawk.WinForms.Controls.LocLabelEx AddressesLabel; + private BizHawk.WinForms.Controls.HexLabelEx AddressesLabel; private System.Windows.Forms.VScrollBar HexScrollBar; private BizHawk.WinForms.Controls.ToolStripMenuItemEx UnfreezeAllMenuItem; private BizHawk.WinForms.Controls.ToolStripMenuItemEx UnfreezeAllContextItem; diff --git a/src/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs b/src/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs index 1fec01de63..46b3c698f7 100644 --- a/src/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs +++ b/src/BizHawk.Client.EmuHawk/tools/HexEditor/HexEditor.cs @@ -2055,6 +2055,54 @@ namespace BizHawk.Client.EmuHawk } } + private void AddressesLabel_Paint(object sender, PaintEventArgs e) + { + return; + + if (sender is not Label label) + return; + + char gap = ' '; + + //PointF point = new PointF(label.Location.X, label.Location.Y); + PointF point = new PointF(0, 0); + string text = label.Text; + Font font = label.Font; + + string[] lines = text.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None); + + Color color = label.ForeColor; + + foreach (string line in lines) + { + string[] words = line.Split(gap); + + foreach (string word in words) + { + if (word == "00") + { + color = Color.SlateGray; + } + else + { + color = label.ForeColor; + } + + SizeF size = e.Graphics.MeasureString(word, font); + + using (Brush brush = new SolidBrush(color)) + { + e.Graphics.DrawString(word, font, brush, point); + } + + point.X += size.Width + e.Graphics.MeasureString(gap.ToString(), font).Width; + } + + point.X = label.Location.X; + point.Y += e.Graphics.MeasureString(line, font).Height; + } + } + private void MemoryViewerBox_Paint(object sender, PaintEventArgs e) { var activeCheats = MainForm.CheatList.Where(x => x.Enabled); diff --git a/src/BizHawk.WinForms.Controls/BizHawk.WinForms.Controls.csproj b/src/BizHawk.WinForms.Controls/BizHawk.WinForms.Controls.csproj index 31744f1864..e26be95279 100644 --- a/src/BizHawk.WinForms.Controls/BizHawk.WinForms.Controls.csproj +++ b/src/BizHawk.WinForms.Controls/BizHawk.WinForms.Controls.csproj @@ -10,4 +10,9 @@ + + + Component + + diff --git a/src/BizHawk.WinForms.Controls/LabelEx/HexLabelEx.cs b/src/BizHawk.WinForms.Controls/LabelEx/HexLabelEx.cs new file mode 100644 index 0000000000..ab3e40a568 --- /dev/null +++ b/src/BizHawk.WinForms.Controls/LabelEx/HexLabelEx.cs @@ -0,0 +1,121 @@ +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using BizHawk.Common; + + +namespace BizHawk.WinForms.Controls +{ + /// + public class HexLabelEx : LabelExBase + { + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new bool AutoSize => base.AutoSize; + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public new Size Size => base.Size; + + public Color ZeroColor { get; set; } = Color.SlateGray; + + private float spacingHexModifier; + private float spacingPreDivider; + private float spacingPostDividerModifier; + private float spacingAscii; + private float spacingLineModifier; + + public HexLabelEx() + { + base.AutoSize = true; + this.BackColor = Color.Transparent; + + spacingHexModifier = 0.7F; + spacingPreDivider = 3.0F; + spacingPostDividerModifier = 3.5F; + spacingAscii = 7.0F; + spacingLineModifier = 0.56F; + + if (OSTailoredCode.IsUnixHost) + { + // TODO: spacing values will probably be different on linux + } + } + + protected override void OnPaint(PaintEventArgs e) + { + string text = this.Text; + Font font = this.Font; + PointF point = new PointF(0, 0); + char gap = ' '; + + string[] lines = text.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None); + + Color color00 = this.ForeColor; + Color color = this.ForeColor; + + foreach (string line in lines) + { + // split left and right panes + string[] panes = line.Split('|'); + + if (panes.Length < 2) + { + // skip - last line appears to be empty + continue; + } + + // hex pane + string[] words = panes[0].Split(gap); + foreach (var word in words) + { + SizeF size = e.Graphics.MeasureString(word, font); + + switch (word) + { + case "00": + color = ZeroColor; + break; + + default: + color = this.ForeColor; + break; + } + using (Brush brush = new SolidBrush(color)) + { + e.Graphics.DrawString(word, font, brush, point); + } + + point.X += size.Width + e.Graphics.MeasureString(gap.ToString(), font).Width + spacingHexModifier; + } + + // divider + string div = "|"; + point.X -= spacingPreDivider; + SizeF sizeDiv = e.Graphics.MeasureString(div, font); + using (Brush brush = new SolidBrush(this.ForeColor)) + { + e.Graphics.DrawString(div, font, brush, point); + } + + point.X += e.Graphics.MeasureString(gap.ToString(), font).Width + spacingPostDividerModifier; + + // ascii pane + char[] chars = panes[1].ToCharArray(); + foreach (var c in chars) + { + string str = c.ToString(); + + using (Brush brush = new SolidBrush(this.ForeColor)) + { + e.Graphics.DrawString(str, font, brush, point); + } + + // fixed size + point.X += spacingAscii; + } + + point.X = 0; + point.Y += e.Graphics.MeasureString(line, font).Height + spacingLineModifier; + } + } + } +}