diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj
index 6cf977a09a..a6f99c8a59 100644
--- a/OpenRA.Game/OpenRA.Game.csproj
+++ b/OpenRA.Game/OpenRA.Game.csproj
@@ -223,6 +223,7 @@
+
diff --git a/OpenRA.Game/Widgets/ClientTooltipRegionWidget.cs b/OpenRA.Game/Widgets/ClientTooltipRegionWidget.cs
new file mode 100644
index 0000000000..d487ea51ae
--- /dev/null
+++ b/OpenRA.Game/Widgets/ClientTooltipRegionWidget.cs
@@ -0,0 +1,67 @@
+#region Copyright & License Information
+/*
+ * Copyright 2007-2011 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.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Threading;
+using OpenRA.FileFormats;
+using OpenRA.Graphics;
+using OpenRA.Network;
+
+namespace OpenRA.Widgets
+{
+ public class ClientTooltipRegionWidget : Widget
+ {
+ public readonly string Template;
+ public readonly string TooltipContainer;
+ Lazy tooltipContainer;
+ OrderManager orderManager;
+ int clientIndex;
+
+ public ClientTooltipRegionWidget() : base()
+ {
+ tooltipContainer = Lazy.New(() => Ui.Root.Get(TooltipContainer));
+ }
+
+ protected ClientTooltipRegionWidget(ClientTooltipRegionWidget other)
+ : base(other)
+ {
+ Template = other.Template;
+ TooltipContainer = other.TooltipContainer;
+ tooltipContainer = Lazy.New(() => Ui.Root.Get(TooltipContainer));
+ orderManager = other.orderManager;
+ clientIndex = other.clientIndex;
+ }
+
+ public override Widget Clone() { return new ClientTooltipRegionWidget(this); }
+
+ public void Bind(OrderManager orderManager, int clientIndex)
+ {
+ this.orderManager = orderManager;
+ this.clientIndex = clientIndex;
+ }
+
+ public override void MouseEntered()
+ {
+ if (TooltipContainer == null)
+ return;
+ tooltipContainer.Value.SetTooltip(Template, new WidgetArgs() {{"orderManager", orderManager}, {"clientIndex", clientIndex}});
+ }
+
+ public override void MouseExited()
+ {
+ if (TooltipContainer == null)
+ return;
+ tooltipContainer.Value.RemoveTooltip();
+ }
+ }
+}
diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
index 328a098d0b..d19315ef96 100644
--- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
+++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
@@ -431,6 +431,7 @@
+
diff --git a/OpenRA.Mods.RA/Widgets/Logic/ClientTooltipLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ClientTooltipLogic.cs
new file mode 100644
index 0000000000..847704bf92
--- /dev/null
+++ b/OpenRA.Mods.RA/Widgets/Logic/ClientTooltipLogic.cs
@@ -0,0 +1,64 @@
+#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.RA.Widgets.Logic
+{
+ public class ClientTooltipLogic
+ {
+ [ObjectCreator.UseCtor]
+ public ClientTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, OrderManager orderManager, int clientIndex)
+ {
+ var admin = widget.Get("ADMIN");
+ var adminFont = Game.Renderer.Fonts[admin.Font];
+
+ var latency = widget.Get("LATENCY");
+ var latencyFont = Game.Renderer.Fonts[latency.Font];
+
+ var ip = widget.Get("IP");
+ var ipFont = Game.Renderer.Fonts[ip.Font];
+
+ var ipOffset = ip.Bounds.Y;
+ var latencyOffset = latency.Bounds.Y;
+ var tooltipHeight = widget.Bounds.Height;
+
+ var margin = widget.Bounds.Width;
+ tooltipContainer.BeforeRender = () =>
+ {
+ var width = Math.Max(adminFont.Measure(admin.GetText()).X, Math.Max(ipFont.Measure(ip.GetText()).X, latencyFont.Measure(latency.GetText()).X));
+ widget.Bounds.Width = width + 2*margin;
+ latency.Bounds.Width = widget.Bounds.Width;
+ ip.Bounds.Width = widget.Bounds.Width;
+ admin.Bounds.Width = widget.Bounds.Width;
+
+ ip.Bounds.Y = ipOffset;
+ latency.Bounds.Y = latencyOffset;
+ widget.Bounds.Height = tooltipHeight;
+
+ if (admin.IsVisible())
+ {
+ ip.Bounds.Y += admin.Bounds.Height;
+ latency.Bounds.Y += admin.Bounds.Height;
+ widget.Bounds.Height += admin.Bounds.Height;
+ }
+ };
+
+ admin.IsVisible = () => orderManager.LobbyInfo.ClientWithIndex(clientIndex).IsAdmin;
+ latency.GetText = () => "Latency: {0}".F(LobbyUtils.LatencyDescription(orderManager.LobbyInfo.ClientWithIndex(clientIndex).Latency));
+ ip.GetText = () => orderManager.LobbyInfo.ClientWithIndex(clientIndex).IpAddress;
+ }
+ }
+}
+
diff --git a/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs b/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs
index 922a0df210..09659d261e 100644
--- a/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs
+++ b/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs
@@ -158,7 +158,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
}
}
- static Color LatencyColor(int latency)
+ public static Color LatencyColor(int latency)
{
// Levels set relative to the default order lag of 3 net ticks (360ms)
// TODO: Adjust this once dynamic lag is implemented
@@ -171,7 +171,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
return Color.Red;
}
- static string LatencyDescription(int latency)
+ public static string LatencyDescription(int latency)
{
if (latency < 0)
return "Unknown";
@@ -190,6 +190,10 @@ namespace OpenRA.Mods.RA.Widgets.Logic
if (visible)
block.Get("LATENCY_COLOR").GetColor = () => LatencyColor(c.Latency);
+
+ var tooltip = parent.Get("CLIENT_REGION");
+ tooltip.IsVisible = () => visible;
+ tooltip.Bind(orderManager, c.Index);
}
public static void SetupEditableNameWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager)
diff --git a/mods/cnc/chrome/lobby.yaml b/mods/cnc/chrome/lobby.yaml
index bf1e029182..6c64204219 100644
--- a/mods/cnc/chrome/lobby.yaml
+++ b/mods/cnc/chrome/lobby.yaml
@@ -86,6 +86,11 @@ Container@SERVER_LOBBY:
Y:2
Width:PARENT_RIGHT-4
Height:PARENT_BOTTOM-4
+ ClientTooltipRegion@CLIENT_REGION:
+ TooltipContainer:TOOLTIP_CONTAINER
+ Template:CLIENT_TOOLTIP
+ Width:11
+ Height:25
TextField@NAME:
Text:Name
X:15
@@ -174,6 +179,11 @@ Container@SERVER_LOBBY:
Y:2
Width:PARENT_RIGHT-4
Height:PARENT_BOTTOM-4
+ ClientTooltipRegion@CLIENT_REGION:
+ TooltipContainer:TOOLTIP_CONTAINER
+ Template:CLIENT_TOOLTIP
+ Width:11
+ Height:25
Label@NAME:
Text:Name
Width:185
@@ -276,6 +286,11 @@ Container@SERVER_LOBBY:
Y:2
Width:PARENT_RIGHT-4
Height:PARENT_BOTTOM-4
+ ClientTooltipRegion@CLIENT_REGION:
+ TooltipContainer:TOOLTIP_CONTAINER
+ Template:CLIENT_TOOLTIP
+ Width:11
+ Height:25
TextField@NAME:
Text:Name
X:15
@@ -332,6 +347,11 @@ Container@SERVER_LOBBY:
Y:2
Width:PARENT_RIGHT-4
Height:PARENT_BOTTOM-4
+ ClientTooltipRegion@CLIENT_REGION:
+ TooltipContainer:TOOLTIP_CONTAINER
+ Template:CLIENT_TOOLTIP
+ Width:11
+ Height:25
Label@NAME:
Text:Name
Width:185
diff --git a/mods/cnc/chrome/tooltips.yaml b/mods/cnc/chrome/tooltips.yaml
index 49644b4746..7393067200 100644
--- a/mods/cnc/chrome/tooltips.yaml
+++ b/mods/cnc/chrome/tooltips.yaml
@@ -123,3 +123,27 @@ Background@SPAWN_TOOLTIP:
Height:15
Font:TinyBold
Align:center
+
+Background@CLIENT_TOOLTIP:
+ Logic:ClientTooltipLogic
+ Background:panel-black
+ Height:35
+ Width:5
+ Children:
+ Label@ADMIN:
+ Y:2
+ Height:18
+ Font:Bold
+ Text:Game Admin
+ Align:Center
+ Label@IP:
+ Y:5
+ Width:5
+ Height:10
+ Font:TinyBold
+ Align:Center
+ Label@LATENCY:
+ Y:17
+ Height:10
+ Font:TinyBold
+ Align:Center
diff --git a/mods/d2k/chrome/lobby.yaml b/mods/d2k/chrome/lobby.yaml
index d5645d4a28..352a73a78f 100644
--- a/mods/d2k/chrome/lobby.yaml
+++ b/mods/d2k/chrome/lobby.yaml
@@ -66,6 +66,11 @@ Background@SERVER_LOBBY:
Y:2
Width:PARENT_RIGHT-4
Height:PARENT_BOTTOM-4
+ ClientTooltipRegion@CLIENT_REGION:
+ TooltipContainer:TOOLTIP_CONTAINER
+ Template:CLIENT_TOOLTIP
+ Width:11
+ Height:25
TextField@NAME:
Text:Name
X:15
@@ -152,6 +157,11 @@ Background@SERVER_LOBBY:
Y:2
Width:PARENT_RIGHT-4
Height:PARENT_BOTTOM-4
+ ClientTooltipRegion@CLIENT_REGION:
+ TooltipContainer:TOOLTIP_CONTAINER
+ Template:CLIENT_TOOLTIP
+ Width:11
+ Height:25
Label@NAME:
Text:Name
Width:130
@@ -252,6 +262,11 @@ Background@SERVER_LOBBY:
Y:2
Width:PARENT_RIGHT-4
Height:PARENT_BOTTOM-4
+ ClientTooltipRegion@CLIENT_REGION:
+ TooltipContainer:TOOLTIP_CONTAINER
+ Template:CLIENT_TOOLTIP
+ Width:11
+ Height:25
TextField@NAME:
Text:Name
X:15
@@ -314,6 +329,11 @@ Background@SERVER_LOBBY:
Y:2
Width:PARENT_RIGHT-4
Height:PARENT_BOTTOM-4
+ ClientTooltipRegion@CLIENT_REGION:
+ TooltipContainer:TOOLTIP_CONTAINER
+ Template:CLIENT_TOOLTIP
+ Width:11
+ Height:25
Label@NAME:
Text:Name
Width:130
diff --git a/mods/d2k/chrome/tooltips.yaml b/mods/d2k/chrome/tooltips.yaml
index c8b88119c5..25ee4544b7 100644
--- a/mods/d2k/chrome/tooltips.yaml
+++ b/mods/d2k/chrome/tooltips.yaml
@@ -20,4 +20,28 @@ Background@SPAWN_TOOLTIP:
Y:28
Height:15
Font:TinyBold
- Align:center
\ No newline at end of file
+ Align:center
+
+Background@CLIENT_TOOLTIP:
+ Logic:ClientTooltipLogic
+ Background:dialog3
+ Height:39
+ Width:7
+ Children:
+ Label@ADMIN:
+ Y:4
+ Height:18
+ Font:Bold
+ Text:Game Admin
+ Align:Center
+ Label@IP:
+ Y:7
+ Width:5
+ Height:10
+ Font:TinyBold
+ Align:Center
+ Label@LATENCY:
+ Y:19
+ Height:10
+ Font:TinyBold
+ Align:Center
diff --git a/mods/ra/chrome/lobby.yaml b/mods/ra/chrome/lobby.yaml
index f67699e16b..22115f69b3 100644
--- a/mods/ra/chrome/lobby.yaml
+++ b/mods/ra/chrome/lobby.yaml
@@ -66,6 +66,11 @@ Background@SERVER_LOBBY:
Y:2
Width:PARENT_RIGHT-4
Height:PARENT_BOTTOM-4
+ ClientTooltipRegion@CLIENT_REGION:
+ TooltipContainer:TOOLTIP_CONTAINER
+ Template:CLIENT_TOOLTIP
+ Width:11
+ Height:25
TextField@NAME:
Text:Name
X:15
@@ -152,6 +157,11 @@ Background@SERVER_LOBBY:
Y:2
Width:PARENT_RIGHT-4
Height:PARENT_BOTTOM-4
+ ClientTooltipRegion@CLIENT_REGION:
+ TooltipContainer:TOOLTIP_CONTAINER
+ Template:CLIENT_TOOLTIP
+ Width:11
+ Height:25
Label@NAME:
Text:Name
Width:130
@@ -252,6 +262,11 @@ Background@SERVER_LOBBY:
Y:2
Width:PARENT_RIGHT-4
Height:PARENT_BOTTOM-4
+ ClientTooltipRegion@CLIENT_REGION:
+ TooltipContainer:TOOLTIP_CONTAINER
+ Template:CLIENT_TOOLTIP
+ Width:11
+ Height:25
TextField@NAME:
Text:Name
X:15
@@ -314,6 +329,11 @@ Background@SERVER_LOBBY:
Y:2
Width:PARENT_RIGHT-4
Height:PARENT_BOTTOM-4
+ ClientTooltipRegion@CLIENT_REGION:
+ TooltipContainer:TOOLTIP_CONTAINER
+ Template:CLIENT_TOOLTIP
+ Width:11
+ Height:25
Label@NAME:
Text:Name
Width:130
diff --git a/mods/ra/chrome/tooltips.yaml b/mods/ra/chrome/tooltips.yaml
index 03904d5d69..2d948ffef7 100644
--- a/mods/ra/chrome/tooltips.yaml
+++ b/mods/ra/chrome/tooltips.yaml
@@ -20,4 +20,28 @@ Background@SPAWN_TOOLTIP:
Y:23
Height:15
Font:TinyBold
- Align:center
\ No newline at end of file
+ Align:center
+
+Background@CLIENT_TOOLTIP:
+ Logic:ClientTooltipLogic
+ Background:dialog4
+ Height:39
+ Width:7
+ Children:
+ Label@ADMIN:
+ Y:4
+ Height:18
+ Font:Bold
+ Text:Game Admin
+ Align:Center
+ Label@IP:
+ Y:7
+ Width:5
+ Height:10
+ Font:TinyBold
+ Align:Center
+ Label@LATENCY:
+ Y:19
+ Height:10
+ Font:TinyBold
+ Align:Center