diff --git a/OpenRA.Mods.Common/Widgets/LabelWidget.cs b/OpenRA.Mods.Common/Widgets/LabelWidget.cs index ef90f420e2..9baf17e6f6 100644 --- a/OpenRA.Mods.Common/Widgets/LabelWidget.cs +++ b/OpenRA.Mods.Common/Widgets/LabelWidget.cs @@ -98,7 +98,11 @@ namespace OpenRA.Mods.Common.Widgets if (WordWrap) text = WidgetUtils.WrapText(text, Bounds.Width, font); - var color = GetColor(); + DrawInner(text, font, GetColor(), position); + } + + protected virtual void DrawInner(string text, SpriteFont font, Color color, int2 position) + { var bgDark = GetContrastColorDark(); var bgLight = GetContrastColorLight(); if (Contrast) diff --git a/OpenRA.Mods.Common/Widgets/LabelWithHighlightWidget.cs b/OpenRA.Mods.Common/Widgets/LabelWithHighlightWidget.cs new file mode 100644 index 0000000000..3e7cd8c76b --- /dev/null +++ b/OpenRA.Mods.Common/Widgets/LabelWithHighlightWidget.cs @@ -0,0 +1,90 @@ +#region Copyright & License Information +/* + * Copyright 2007-2020 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. For more + * information, see COPYING. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using OpenRA.Graphics; +using OpenRA.Primitives; +using OpenRA.Widgets; + +namespace OpenRA.Mods.Common.Widgets +{ + public class LabelWithHighlightWidget : LabelWidget + { + public Color HighlightColor = ChromeMetrics.Get("TextHighlightColor"); + readonly CachedTransform[]> textComponents; + + [ObjectCreator.UseCtor] + public LabelWithHighlightWidget() + : base() + { + textComponents = new CachedTransform[]>(MakeComponents); + } + + protected LabelWithHighlightWidget(LabelWithHighlightWidget other) + : base(other) + { + HighlightColor = other.HighlightColor; + textComponents = new CachedTransform[]>(MakeComponents); + } + + Pair[] MakeComponents(string text) + { + List> components = new List>(); + foreach (var l in text.Split(new[] { "\\n" }, StringSplitOptions.None)) + { + var line = l; + + while (line.Length > 0) + { + var highlightStart = line.IndexOf('{'); + var highlightEnd = line.IndexOf('}', 0); + + if (highlightStart > 0 && highlightEnd > highlightStart) + { + if (highlightStart > 0) + { + // Normal line segment before highlight + var lineNormal = line.Substring(0, highlightStart); + components.Add(Pair.New(lineNormal, false)); + } + + // Highlight line segment + var lineHighlight = line.Substring(highlightStart + 1, highlightEnd - highlightStart - 1); + components.Add(Pair.New(lineHighlight, true)); + line = line.Substring(highlightEnd + 1); + } + else + { + // Final normal line segment + components.Add(Pair.New(line, false)); + break; + } + } + } + + return components.ToArray(); + } + + protected override void DrawInner(string text, SpriteFont font, Color color, int2 position) + { + var advance = 0; + foreach (var c in textComponents.Update(text)) + { + base.DrawInner(c.First, font, c.Second ? HighlightColor : color, position + new int2(advance, 0)); + advance += font.Measure(c.First).X; + } + } + + public override Widget Clone() { return new LabelWithHighlightWidget(this); } + } +} diff --git a/OpenRA.Mods.Common/Widgets/Logic/ButtonTooltipWithDescHighlightLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/ButtonTooltipWithDescHighlightLogic.cs deleted file mode 100644 index 3f88d112c6..0000000000 --- a/OpenRA.Mods.Common/Widgets/Logic/ButtonTooltipWithDescHighlightLogic.cs +++ /dev/null @@ -1,123 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2020 The OpenRA Developers (see AUTHORS) - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. For more - * information, see COPYING. - */ -#endregion - -using System; -using System.Collections.Generic; -using OpenRA.Primitives; -using OpenRA.Widgets; - -namespace OpenRA.Mods.Common.Widgets.Logic -{ - public class ButtonTooltipWithDescHighlightLogic : ChromeLogic - { - [ObjectCreator.UseCtor] - public ButtonTooltipWithDescHighlightLogic(Widget widget, ButtonWidget button, Dictionary logicArgs) - { - var label = widget.Get("LABEL"); - var font = Game.Renderer.Fonts[label.Font]; - var text = button.GetTooltipText(); - var labelWidth = font.Measure(text).X; - var key = button.Key.GetValue(); - - label.GetText = () => text; - label.Bounds.Width = labelWidth; - widget.Bounds.Width = 2 * label.Bounds.X + labelWidth; - - if (key.IsValid()) - { - var hotkey = widget.Get("HOTKEY"); - hotkey.Visible = true; - - var hotkeyLabel = "({0})".F(key.DisplayString()); - hotkey.GetText = () => hotkeyLabel; - hotkey.Bounds.X = labelWidth + 2 * label.Bounds.X; - - widget.Bounds.Width = hotkey.Bounds.X + label.Bounds.X + font.Measure(hotkeyLabel).X; - } - - var desc = button.GetTooltipDesc(); - if (!string.IsNullOrEmpty(desc)) - { - var descTemplate = widget.Get("DESC"); - var highlightColor = FieldLoader.GetValue("Highlight", logicArgs["Highlight"].Value); - widget.RemoveChild(descTemplate); - - var descFont = Game.Renderer.Fonts[descTemplate.Font]; - var descWidth = 0; - var descOffset = descTemplate.Bounds.Y; - - foreach (var l in desc.Split(new[] { "\\n" }, StringSplitOptions.None)) - { - var line = l; - var lineWidth = 0; - - while (line.Length > 0) - { - var highlightStart = line.IndexOf('{'); - var highlightEnd = line.IndexOf('}', 0); - - if (highlightStart > 0 && highlightEnd > highlightStart) - { - if (highlightStart > 0) - { - // Normal line segment before highlight - var lineNormal = line.Substring(0, highlightStart); - var lineNormalWidth = descFont.Measure(lineNormal).X; - var lineNormalLabel = (LabelWidget)descTemplate.Clone(); - lineNormalLabel.GetText = () => lineNormal; - lineNormalLabel.Bounds.X = descTemplate.Bounds.X + lineWidth; - lineNormalLabel.Bounds.Y = descOffset; - lineNormalLabel.Bounds.Width = lineNormalWidth; - widget.AddChild(lineNormalLabel); - - lineWidth += lineNormalWidth; - } - - // Highlight line segment - var lineHighlight = line.Substring(highlightStart + 1, highlightEnd - highlightStart - 1); - var lineHighlightWidth = descFont.Measure(lineHighlight).X; - var lineHighlightLabel = (LabelWidget)descTemplate.Clone(); - lineHighlightLabel.GetText = () => lineHighlight; - lineHighlightLabel.GetColor = () => highlightColor; - lineHighlightLabel.Bounds.X = descTemplate.Bounds.X + lineWidth; - lineHighlightLabel.Bounds.Y = descOffset; - lineHighlightLabel.Bounds.Width = lineHighlightWidth; - widget.AddChild(lineHighlightLabel); - - lineWidth += lineHighlightWidth; - line = line.Substring(highlightEnd + 1); - } - else - { - // Final normal line segment - var lineLabel = (LabelWidget)descTemplate.Clone(); - var width = descFont.Measure(line).X; - lineLabel.GetText = () => line; - lineLabel.Bounds.X = descTemplate.Bounds.X + lineWidth; - lineLabel.Bounds.Y = descOffset; - widget.AddChild(lineLabel); - - lineWidth += width; - break; - } - } - - descWidth = Math.Max(descWidth, lineWidth); - - descOffset += descTemplate.Bounds.Height; - } - - widget.Bounds.Width = Math.Max(widget.Bounds.Width, descTemplate.Bounds.X * 2 + descWidth); - widget.Bounds.Height += descOffset - descTemplate.Bounds.Y + descTemplate.Bounds.X; - } - } - } -} diff --git a/mods/cnc/chrome/tooltips.yaml b/mods/cnc/chrome/tooltips.yaml index 67824a1c30..a4ed6bb304 100644 --- a/mods/cnc/chrome/tooltips.yaml +++ b/mods/cnc/chrome/tooltips.yaml @@ -73,8 +73,7 @@ Background@BUTTON_TOOLTIP_FACTIONSUFFIX: VAlign: Top Background@BUTTON_WITH_DESC_HIGHLIGHT_TOOLTIP: - Logic: ButtonTooltipWithDescHighlightLogic - Highlight: FFFF00 + Logic: ButtonTooltipLogic Background: panel-black Height: 26 Children: @@ -89,7 +88,7 @@ Background@BUTTON_WITH_DESC_HIGHLIGHT_TOOLTIP: TextColor: FFFF00 Height: 23 Font: Bold - Label@DESC: + LabelWithHighlight@DESC: X: 5 Y: 26 Height: 12 @@ -97,8 +96,7 @@ Background@BUTTON_WITH_DESC_HIGHLIGHT_TOOLTIP: VAlign: Top Background@BUTTON_WITH_DESC_HIGHLIGHT_TOOLTIP_FACTIONSUFFIX: - Logic: ButtonTooltipWithDescHighlightLogic, AddFactionSuffixLogic - Highlight: FFFF00 + Logic: ButtonTooltipLogic, AddFactionSuffixLogic Background: panel-black Height: 26 Children: @@ -113,7 +111,7 @@ Background@BUTTON_WITH_DESC_HIGHLIGHT_TOOLTIP_FACTIONSUFFIX: TextColor: FFFF00 Height: 23 Font: Bold - Label@DESC: + LabelWithHighlight@DESC: X: 5 Y: 26 Height: 12 diff --git a/mods/common/chrome/tooltips.yaml b/mods/common/chrome/tooltips.yaml index 51ade8983f..f54c32ebe7 100644 --- a/mods/common/chrome/tooltips.yaml +++ b/mods/common/chrome/tooltips.yaml @@ -36,8 +36,7 @@ Background@BUTTON_TOOLTIP: VAlign: Top Background@BUTTON_WITH_DESC_HIGHLIGHT_TOOLTIP: - Logic: ButtonTooltipWithDescHighlightLogic - Highlight: FFFF00 + Logic: ButtonTooltipLogic Background: dialog4 Height: 29 Children: @@ -52,7 +51,7 @@ Background@BUTTON_WITH_DESC_HIGHLIGHT_TOOLTIP: TextColor: FFFF00 Height: 23 Font: Bold - Label@DESC: + LabelWithHighlight@DESC: X: 7 Y: 27 Height: 12 diff --git a/mods/common/metrics.yaml b/mods/common/metrics.yaml index a8473104fa..376c3a56f2 100644 --- a/mods/common/metrics.yaml +++ b/mods/common/metrics.yaml @@ -29,6 +29,7 @@ Metrics: SpawnFont: TinyBold SpawnLabelOffset: 0,1 TextColor: FFFFFF + TextHighlightColor: FFFF00 TextContrast: false TextContrastColorDark: 000000 TextContrastColorLight: 7F7F7F diff --git a/mods/d2k/chrome/tooltips.yaml b/mods/d2k/chrome/tooltips.yaml index dee9331733..0ab2f896d4 100644 --- a/mods/d2k/chrome/tooltips.yaml +++ b/mods/d2k/chrome/tooltips.yaml @@ -36,7 +36,7 @@ Background@BUTTON_TOOLTIP: VAlign: Top Background@BUTTON_WITH_DESC_HIGHLIGHT_TOOLTIP: - Logic: ButtonTooltipWithDescHighlightLogic + Logic: ButtonTooltipLogic Highlight: FFFF00 Background: dialog3 Height: 31 @@ -52,7 +52,7 @@ Background@BUTTON_WITH_DESC_HIGHLIGHT_TOOLTIP: TextColor: FFFF00 Height: 23 Font: Bold - Label@DESC: + LabelWithHighlight@DESC: X: 5 Y: 29 Height: 12