diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index 6f7b5cbd0c..19947ca9e6 100644 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -217,6 +217,7 @@ + diff --git a/OpenRA.Game/Widgets/MapPreviewWidget.cs b/OpenRA.Game/Widgets/MapPreviewWidget.cs index 664a1a8961..667343798c 100644 --- a/OpenRA.Game/Widgets/MapPreviewWidget.cs +++ b/OpenRA.Game/Widgets/MapPreviewWidget.cs @@ -15,27 +15,39 @@ using System.Linq; using System.Threading; using OpenRA.FileFormats; using OpenRA.Graphics; +using OpenRA.Network; namespace OpenRA.Widgets { public class MapPreviewWidget : Widget { public Func Map = () => null; - public Func> SpawnColors = () => new Dictionary(); + public Func> SpawnClients = () => new Dictionary(); public Action OnMouseDown = _ => {}; public Action OnTooltip = (_, __) => { }; public bool IgnoreMouseInput = false; public bool ShowSpawnPoints = true; - public MapPreviewWidget() : base() { } + public readonly string TooltipContainer; + public readonly string TooltipTemplate = "SPAWN_TOOLTIP"; + Lazy tooltipContainer; + public int TooltipSpawnIndex = -1; + + public MapPreviewWidget() : base() + { + tooltipContainer = Lazy.New(() => Ui.Root.Get(TooltipContainer)); + } protected MapPreviewWidget(MapPreviewWidget other) : base(other) { lastMap = other.lastMap; Map = other.Map; - SpawnColors = other.SpawnColors; + SpawnClients = other.SpawnClients; ShowSpawnPoints = other.ShowSpawnPoints; + TooltipTemplate = other.TooltipTemplate; + TooltipContainer = other.TooltipContainer; + tooltipContainer = Lazy.New(() => Ui.Root.Get(TooltipContainer)); } public override Widget Clone() { return new MapPreviewWidget(this); } @@ -52,6 +64,18 @@ namespace OpenRA.Widgets return true; } + public override void MouseEntered() + { + if (TooltipContainer == null) return; + tooltipContainer.Value.SetTooltip(TooltipTemplate, new WidgetArgs() {{ "preview", this }}); + } + + public override void MouseExited() + { + if (TooltipContainer == null) return; + tooltipContainer.Value.RemoveTooltip(); + } + public int2 ConvertToPreview(int2 point) { var map = Map(); @@ -104,9 +128,10 @@ namespace OpenRA.Widgets new float2(MapRect.Location), new float2(MapRect.Size)); + TooltipSpawnIndex = -1; if (ShowSpawnPoints) { - var colors = SpawnColors(); + var colors = SpawnClients().ToDictionary(c => c.Key, c => c.Value.ColorRamp.GetColor(0)); var spawnPoints = map.GetSpawnPoints().ToList(); foreach (var p in spawnPoints) @@ -123,7 +148,11 @@ namespace OpenRA.Widgets if ((pos - Viewport.LastMousePos).LengthSquared < 64) { - OnTooltip(spawnPoints.IndexOf(p) + 1, pos); + TooltipSpawnIndex = spawnPoints.IndexOf(p) + 1; + + // Legacy tooltip behavior + if (TooltipContainer == null) + OnTooltip(TooltipSpawnIndex, pos); } } } diff --git a/OpenRA.Mods.Cnc/Widgets/TooltipContainerWidget.cs b/OpenRA.Game/Widgets/TooltipContainerWidget.cs similarity index 96% rename from OpenRA.Mods.Cnc/Widgets/TooltipContainerWidget.cs rename to OpenRA.Game/Widgets/TooltipContainerWidget.cs index 1901bfc5c8..5d0827a425 100755 --- a/OpenRA.Mods.Cnc/Widgets/TooltipContainerWidget.cs +++ b/OpenRA.Game/Widgets/TooltipContainerWidget.cs @@ -13,11 +13,10 @@ using System.Drawing; using System.Linq; using OpenRA.FileFormats; using OpenRA.Graphics; -using OpenRA.Mods.RA; using OpenRA.Widgets; using System; -namespace OpenRA.Mods.Cnc.Widgets +namespace OpenRA.Widgets { public class TooltipContainerWidget : Widget { diff --git a/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj b/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj index 067b709c02..687c921db7 100644 --- a/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj +++ b/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj @@ -111,10 +111,10 @@ - + diff --git a/OpenRA.Mods.Cnc/Widgets/Logic/SpawnSelectorTooltipLogic.cs b/OpenRA.Mods.Cnc/Widgets/Logic/SpawnSelectorTooltipLogic.cs new file mode 100644 index 0000000000..6ad7f65538 --- /dev/null +++ b/OpenRA.Mods.Cnc/Widgets/Logic/SpawnSelectorTooltipLogic.cs @@ -0,0 +1,79 @@ +#region Copyright & License Information +/* + * Copyright 2007-2013 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. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.Drawing; +using System.Linq; +using OpenRA.Widgets; +using OpenRA.Network; + +namespace OpenRA.Mods.Cnc.Widgets.Logic +{ + public class SpawnSelectorTooltipLogic + { + [ObjectCreator.UseCtor] + public SpawnSelectorTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, MapPreviewWidget preview) + { + widget.IsVisible = () => preview.TooltipSpawnIndex != -1; + var label = widget.Get("LABEL"); + var flag = widget.Get("FLAG"); + var team = widget.Get("TEAM"); + + var ownerFont = Game.Renderer.Fonts[label.Font]; + var teamFont = Game.Renderer.Fonts[team.Font]; + var cachedWidth = 0; + var labelText = ""; + string playerCountry = null; + var playerTeam = -1; + + tooltipContainer.BeforeRender = () => + { + var client = preview.SpawnClients().Values.FirstOrDefault(c => c.SpawnPoint == preview.TooltipSpawnIndex); + + var teamWidth = 0; + if (client == null) + { + labelText = "Available spawn"; + playerCountry = null; + playerTeam = 0; + widget.Bounds.Height = 25; + } + else + { + labelText = client.Name; + playerCountry = client.Country; + playerTeam = client.Team; + widget.Bounds.Height = playerTeam > 0 ? 40 : 25; + teamWidth = teamFont.Measure(team.GetText()).X; + } + + label.Bounds.X = playerCountry != null ? flag.Bounds.Right + 5 : 5; + + var textWidth = ownerFont.Measure(labelText).X; + if (textWidth != cachedWidth) + { + label.Bounds.Width = textWidth; + widget.Bounds.Width = 2*label.Bounds.X + textWidth; + } + + widget.Bounds.Width = Math.Max(teamWidth + 10, label.Bounds.Right + 5); + team.Bounds.Width = widget.Bounds.Width; + }; + + label.GetText = () => labelText; + flag.IsVisible = () => playerCountry != null; + flag.GetImageCollection = () => "flags"; + flag.GetImageName = () => playerCountry; + team.GetText = () => "Team {0}".F(playerTeam); + team.IsVisible = () => playerTeam > 0; + } + } +} + diff --git a/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs index b5877f9ea5..69d4892d65 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs @@ -113,7 +113,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic mapPreview.Map = () => Map; mapPreview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint( orderManager, mapPreview, Map, mi ); mapPreview.OnTooltip = (spawnPoint, pos) => LobbyUtils.ShowSpawnPointTooltip(orderManager, spawnPoint, pos); - mapPreview.SpawnColors = () => LobbyUtils.GetSpawnColors(orderManager, Map); + mapPreview.SpawnClients = () => LobbyUtils.GetSpawnClients(orderManager, Map); var mapTitle = lobby.GetOrNull("MAP_TITLE"); if (mapTitle != null) diff --git a/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs b/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs index 12d792dd00..dbae7c10f1 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs @@ -149,14 +149,14 @@ namespace OpenRA.Mods.RA.Widgets.Logic color.AttachPanel(colorChooser); } - public static Dictionary GetSpawnColors(OrderManager orderManager, Map map) + public static Dictionary GetSpawnClients(OrderManager orderManager, Map map) { var spawns = map.GetSpawnPoints(); return orderManager.LobbyInfo.Clients - .Where( c => c.SpawnPoint != 0) - .ToDictionary( - c => spawns[c.SpawnPoint - 1], - c => c.ColorRamp.GetColor(0)); + .Where(c => c.SpawnPoint != 0) + .ToDictionary( + c => spawns[c.SpawnPoint - 1], + c => c); } public static void SelectSpawnPoint(OrderManager orderManager, MapPreviewWidget mapPreview, Map map, MouseInput mi) diff --git a/mods/cnc/chrome/lobby.yaml b/mods/cnc/chrome/lobby.yaml index a4365ec99c..a040f5f7b7 100644 --- a/mods/cnc/chrome/lobby.yaml +++ b/mods/cnc/chrome/lobby.yaml @@ -32,6 +32,7 @@ Container@SERVER_LOBBY: Y:1 Width:192 Height:192 + TooltipContainer:TOOLTIP_CONTAINER Label@MAP_TITLE: X:PARENT_RIGHT-15-WIDTH Y:227 @@ -403,6 +404,7 @@ Container@SERVER_LOBBY: Height:25 Align:Right Text:Chat: + TooltipContainer@TOOLTIP_CONTAINER: Button@DISCONNECT_BUTTON: X:0 Y:499 diff --git a/mods/cnc/chrome/tooltips.yaml b/mods/cnc/chrome/tooltips.yaml index 6860027c99..ed35e8ddb3 100644 --- a/mods/cnc/chrome/tooltips.yaml +++ b/mods/cnc/chrome/tooltips.yaml @@ -99,3 +99,23 @@ Background@SUPPORT_POWER_TOOLTIP: Y:20 Font:TinyBold VAlign:Top + +Background@SPAWN_TOOLTIP: + Logic:SpawnSelectorTooltipLogic + Background:panel-black + Width:141 + Children: + Label@LABEL: + X:5 + Height:23 + Font:Bold + Image@FLAG: + X:5 + Y:5 + Width:32 + Height:16 + Label@TEAM: + Y:21 + Height:15 + Font:TinyBold + Align:center \ No newline at end of file