Overhaul the lobby faction dropdown for ra
This commit is contained in:
@@ -18,6 +18,12 @@ namespace OpenRA.Traits
|
||||
[Desc("This is the internal name for owner checks.")]
|
||||
public readonly string Race = null;
|
||||
|
||||
[Desc("The side that the country belongs to. For example, England belongs to the 'Allies' side.")]
|
||||
public readonly string Side = null;
|
||||
|
||||
[Translate]
|
||||
public readonly string Description = null;
|
||||
|
||||
public readonly bool Selectable = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ namespace OpenRA.Widgets
|
||||
public readonly string TooltipContainer;
|
||||
public readonly string TooltipTemplate = "BUTTON_TOOLTIP";
|
||||
[Translate] public string TooltipText;
|
||||
public Func<string> GetTooltipText;
|
||||
|
||||
// Equivalent to OnMouseUp, but without an input arg
|
||||
public Action OnClick = () => {};
|
||||
@@ -68,6 +69,7 @@ namespace OpenRA.Widgets
|
||||
OnKeyPress = _ => OnClick();
|
||||
IsDisabled = () => Disabled;
|
||||
IsHighlighted = () => Highlighted;
|
||||
GetTooltipText = () => TooltipText;
|
||||
tooltipContainer = Exts.Lazy(() =>
|
||||
Ui.Root.Get<TooltipContainerWidget>(TooltipContainer));
|
||||
}
|
||||
@@ -102,6 +104,7 @@ namespace OpenRA.Widgets
|
||||
|
||||
TooltipTemplate = other.TooltipTemplate;
|
||||
TooltipText = other.TooltipText;
|
||||
GetTooltipText = other.GetTooltipText;
|
||||
TooltipContainer = other.TooltipContainer;
|
||||
tooltipContainer = Exts.Lazy(() =>
|
||||
Ui.Root.Get<TooltipContainerWidget>(TooltipContainer));
|
||||
@@ -177,19 +180,23 @@ namespace OpenRA.Widgets
|
||||
|
||||
public override void MouseEntered()
|
||||
{
|
||||
if (TooltipContainer == null) return;
|
||||
if (TooltipContainer == null || GetTooltipText() == null)
|
||||
return;
|
||||
|
||||
tooltipContainer.Value.SetTooltip(TooltipTemplate,
|
||||
new WidgetArgs() {{ "button", this }});
|
||||
new WidgetArgs { { "button", this } });
|
||||
}
|
||||
|
||||
public override void MouseExited()
|
||||
{
|
||||
if (TooltipContainer == null) return;
|
||||
if (TooltipContainer == null || !tooltipContainer.IsValueCreated)
|
||||
return;
|
||||
|
||||
tooltipContainer.Value.RemoveTooltip();
|
||||
}
|
||||
|
||||
public override int2 ChildOrigin { get { return RenderOrigin +
|
||||
((Depressed) ? new int2(VisualHeight, VisualHeight) : new int2(0, 0)); } }
|
||||
(Depressed ? new int2(VisualHeight, VisualHeight) : new int2(0, 0)); } }
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
|
||||
@@ -19,12 +19,19 @@ namespace OpenRA.Widgets
|
||||
{
|
||||
Widget panel;
|
||||
MaskWidget fullscreenMask;
|
||||
Widget panelRoot;
|
||||
|
||||
public string PanelRoot;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public DropDownButtonWidget(Ruleset modRules)
|
||||
: base(modRules) { }
|
||||
|
||||
protected DropDownButtonWidget(DropDownButtonWidget widget) : base(widget) { }
|
||||
protected DropDownButtonWidget(DropDownButtonWidget widget)
|
||||
: base(widget)
|
||||
{
|
||||
PanelRoot = widget.PanelRoot;
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
@@ -34,7 +41,7 @@ namespace OpenRA.Widgets
|
||||
var image = ChromeProvider.GetImage("scrollbar", IsDisabled() ? "down_pressed" : "down_arrow");
|
||||
var rb = RenderBounds;
|
||||
var color = GetColor();
|
||||
var colordisabled = GetColorDisabled();
|
||||
var colorDisabled = GetColorDisabled();
|
||||
|
||||
WidgetUtils.DrawRGBA( image,
|
||||
stateOffset + new float2( rb.Right - rb.Height + 4,
|
||||
@@ -42,7 +49,7 @@ namespace OpenRA.Widgets
|
||||
|
||||
WidgetUtils.FillRectWithColor(new Rectangle(stateOffset.X + rb.Right - rb.Height,
|
||||
stateOffset.Y + rb.Top + 3, 1, rb.Height - 6),
|
||||
IsDisabled() ? colordisabled : color);
|
||||
IsDisabled() ? colorDisabled : color);
|
||||
}
|
||||
|
||||
public override Widget Clone() { return new DropDownButtonWidget(this); }
|
||||
@@ -61,8 +68,8 @@ namespace OpenRA.Widgets
|
||||
if (panel == null)
|
||||
return;
|
||||
|
||||
Ui.Root.RemoveChild(fullscreenMask);
|
||||
Ui.Root.RemoveChild(panel);
|
||||
panelRoot.RemoveChild(fullscreenMask);
|
||||
panelRoot.RemoveChild(panel);
|
||||
panel = fullscreenMask = null;
|
||||
}
|
||||
|
||||
@@ -80,11 +87,17 @@ namespace OpenRA.Widgets
|
||||
if (onCancel != null)
|
||||
fullscreenMask.OnMouseDown += _ => onCancel();
|
||||
|
||||
Ui.Root.AddChild(fullscreenMask);
|
||||
panelRoot = PanelRoot == null ? Ui.Root : Ui.Root.Get(PanelRoot);
|
||||
|
||||
panelRoot.AddChild(fullscreenMask);
|
||||
|
||||
var oldBounds = panel.Bounds;
|
||||
panel.Bounds = new Rectangle(RenderOrigin.X, RenderOrigin.Y + Bounds.Height, oldBounds.Width, oldBounds.Height);
|
||||
Ui.Root.AddChild(panel);
|
||||
panel.Bounds = new Rectangle(
|
||||
RenderOrigin.X - panelRoot.RenderOrigin.X,
|
||||
RenderOrigin.Y + Bounds.Height - panelRoot.RenderOrigin.Y,
|
||||
oldBounds.Width,
|
||||
oldBounds.Height);
|
||||
panelRoot.AddChild(panel);
|
||||
}
|
||||
|
||||
public void ShowDropDown<T>(string panelTemplate, int maxHeight, IEnumerable<T> options, Func<T, ScrollItemWidget, ScrollItemWidget> setupItem)
|
||||
@@ -116,14 +129,14 @@ namespace OpenRA.Widgets
|
||||
var panel = (ScrollPanelWidget)Ui.LoadWidget(panelTemplate, null, new WidgetArgs()
|
||||
{{ "substitutions", substitutions }});
|
||||
|
||||
var headerTemplate = panel.Get<ScrollItemWidget>("HEADER");
|
||||
var headerTemplate = panel.GetOrNull<ScrollItemWidget>("HEADER");
|
||||
var itemTemplate = panel.Get<ScrollItemWidget>("TEMPLATE");
|
||||
panel.RemoveChildren();
|
||||
|
||||
foreach (var kv in groups)
|
||||
{
|
||||
var group = kv.Key;
|
||||
if (group.Length > 0)
|
||||
if (group.Length > 0 && headerTemplate != null)
|
||||
{
|
||||
var header = ScrollItemWidget.Setup(headerTemplate, () => true, () => {});
|
||||
header.Get<LabelWidget>("LABEL").GetText = () => group;
|
||||
|
||||
@@ -221,6 +221,7 @@
|
||||
<Compile Include="Widgets\Logic\AssetBrowserLogic.cs" />
|
||||
<Compile Include="Widgets\Logic\ButtonTooltipLogic.cs" />
|
||||
<Compile Include="Widgets\Logic\ColorPickerLogic.cs" />
|
||||
<Compile Include="Widgets\Logic\CountryTooltipLogic.cs" />
|
||||
<Compile Include="Widgets\Logic\DisconnectWatcherLogic.cs" />
|
||||
<Compile Include="Widgets\Logic\Ingame\IngameRadarDisplayLogic.cs" />
|
||||
<Compile Include="Widgets\Logic\Ingame\LoadIngamePlayerOrObserverUILogic.cs" />
|
||||
|
||||
@@ -19,9 +19,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
var label = widget.Get<LabelWidget>("LABEL");
|
||||
var font = Game.Renderer.Fonts[label.Font];
|
||||
var labelWidth = font.Measure(button.TooltipText).X;
|
||||
var text = button.GetTooltipText();
|
||||
var labelWidth = font.Measure(text).X;
|
||||
|
||||
label.GetText = () => button.TooltipText;
|
||||
label.GetText = () => text;
|
||||
label.Bounds.Width = labelWidth;
|
||||
widget.Bounds.Width = 2 * label.Bounds.X + labelWidth;
|
||||
|
||||
|
||||
52
OpenRA.Mods.Common/Widgets/Logic/CountryTooltipLogic.cs
Normal file
52
OpenRA.Mods.Common/Widgets/Logic/CountryTooltipLogic.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 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.Linq;
|
||||
using OpenRA.Widgets;
|
||||
|
||||
namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
public class CountryTooltipLogic
|
||||
{
|
||||
[ObjectCreator.UseCtor]
|
||||
public CountryTooltipLogic(Widget widget, ButtonWidget button)
|
||||
{
|
||||
var lines = button.GetTooltipText().Replace("\\n", "\n").Split('\n');
|
||||
|
||||
var header = widget.Get<LabelWidget>("HEADER");
|
||||
var headerLine = lines[0];
|
||||
var headerFont = Game.Renderer.Fonts[header.Font];
|
||||
var headerSize = headerFont.Measure(headerLine);
|
||||
header.Bounds.Width += headerSize.X;
|
||||
header.Bounds.Height += headerSize.Y;
|
||||
header.GetText = () => headerLine;
|
||||
|
||||
if (lines.Length > 1)
|
||||
{
|
||||
var description = widget.Get<LabelWidget>("DESCRIPTION");
|
||||
var descriptionLines = lines.Skip(1).ToArray();
|
||||
var descriptionFont = Game.Renderer.Fonts[description.Font];
|
||||
description.Bounds.Y += header.Bounds.Y + header.Bounds.Height;
|
||||
description.Bounds.Width += descriptionLines.Select(l => descriptionFont.Measure(l).X).Max();
|
||||
description.Bounds.Height += descriptionFont.Measure(descriptionLines.First()).Y * descriptionLines.Length;
|
||||
description.GetText = () => string.Join("\n", descriptionLines);
|
||||
|
||||
widget.Bounds.Width = Math.Max(header.Bounds.X + header.Bounds.Width, description.Bounds.X + description.Bounds.Width);
|
||||
widget.Bounds.Height = description.Bounds.Y + description.Bounds.Height;
|
||||
}
|
||||
else
|
||||
{
|
||||
widget.Bounds.Width = header.Bounds.X + header.Bounds.Width;
|
||||
widget.Bounds.Height = header.Bounds.Y + header.Bounds.Height;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,8 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
readonly Widget chatTemplate;
|
||||
|
||||
readonly ScrollPanelWidget players;
|
||||
readonly Dictionary<string, string> countryNames;
|
||||
|
||||
readonly Dictionary<string, LobbyCountry> countries = new Dictionary<string, LobbyCountry>();
|
||||
|
||||
readonly ColorPreviewManagerWidget colorPreview;
|
||||
|
||||
@@ -142,10 +143,9 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
colorPreview = lobby.Get<ColorPreviewManagerWidget>("COLOR_MANAGER");
|
||||
colorPreview.Color = Game.Settings.Player.Color;
|
||||
|
||||
countryNames = modRules.Actors["world"].Traits.WithInterface<CountryInfo>()
|
||||
.Where(c => c.Selectable)
|
||||
.ToDictionary(a => a.Race, a => a.Name);
|
||||
countryNames.Add("random", "Any");
|
||||
countries.Add("random", new LobbyCountry { Name = "Any" });
|
||||
foreach (var c in modRules.Actors["world"].Traits.WithInterface<CountryInfo>().Where(c => c.Selectable))
|
||||
countries.Add(c.Race, new LobbyCountry { Name = c.Name, Side = c.Side, Description = c.Description });
|
||||
|
||||
var gameStarting = false;
|
||||
Func<bool> configurationDisabled = () => !Game.IsHost || gameStarting ||
|
||||
@@ -691,7 +691,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
LobbyUtils.SetupEditableNameWidget(template, slot, client, orderManager);
|
||||
|
||||
LobbyUtils.SetupEditableColorWidget(template, slot, client, orderManager, colorPreview);
|
||||
LobbyUtils.SetupEditableFactionWidget(template, slot, client, orderManager, countryNames);
|
||||
LobbyUtils.SetupEditableFactionWidget(template, slot, client, orderManager, countries);
|
||||
LobbyUtils.SetupEditableTeamWidget(template, slot, client, orderManager, Map);
|
||||
LobbyUtils.SetupEditableSpawnWidget(template, slot, client, orderManager, Map);
|
||||
LobbyUtils.SetupEditableReadyWidget(template, slot, client, orderManager, Map);
|
||||
@@ -707,7 +707,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
LobbyUtils.SetupKickWidget(template, slot, client, orderManager, lobby,
|
||||
() => panel = PanelType.Kick, () => panel = PanelType.Players);
|
||||
LobbyUtils.SetupColorWidget(template, slot, client);
|
||||
LobbyUtils.SetupFactionWidget(template, slot, client, countryNames);
|
||||
LobbyUtils.SetupFactionWidget(template, slot, client, countries);
|
||||
LobbyUtils.SetupTeamWidget(template, slot, client);
|
||||
LobbyUtils.SetupSpawnWidget(template, slot, client);
|
||||
LobbyUtils.SetupReadyWidget(template, slot, client);
|
||||
@@ -810,4 +810,11 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
public Action OnClick;
|
||||
}
|
||||
}
|
||||
|
||||
public class LobbyCountry
|
||||
{
|
||||
public string Name;
|
||||
public string Description;
|
||||
public string Side;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,21 +105,25 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
}
|
||||
|
||||
public static void ShowRaceDropDown(DropDownButtonWidget dropdown, Session.Client client,
|
||||
OrderManager orderManager, Dictionary<string, string> countryNames)
|
||||
OrderManager orderManager, Dictionary<string, LobbyCountry> countries)
|
||||
{
|
||||
Func<string, ScrollItemWidget, ScrollItemWidget> setupItem = (race, itemTemplate) =>
|
||||
{
|
||||
var item = ScrollItemWidget.Setup(itemTemplate,
|
||||
() => client.Country == race,
|
||||
() => orderManager.IssueOrder(Order.Command("race {0} {1}".F(client.Index, race))));
|
||||
item.Get<LabelWidget>("LABEL").GetText = () => countryNames[race];
|
||||
var country = countries[race];
|
||||
item.Get<LabelWidget>("LABEL").GetText = () => country.Name;
|
||||
var flag = item.Get<ImageWidget>("FLAG");
|
||||
flag.GetImageCollection = () => "flags";
|
||||
flag.GetImageName = () => race;
|
||||
item.GetTooltipText = () => country.Description;
|
||||
return item;
|
||||
};
|
||||
|
||||
dropdown.ShowDropDown("RACE_DROPDOWN_TEMPLATE", 150, countryNames.Keys, setupItem);
|
||||
var options = countries.GroupBy(c => c.Value.Side).ToDictionary(g => g.Key ?? "", g => g.Select(c => c.Key));
|
||||
|
||||
dropdown.ShowDropDown("RACE_DROPDOWN_TEMPLATE", 150, options, setupItem);
|
||||
}
|
||||
|
||||
public static void ShowColorDropDown(DropDownButtonWidget color, Session.Client client,
|
||||
@@ -389,21 +393,25 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
color.GetColor = () => c.Color.RGB;
|
||||
}
|
||||
|
||||
public static void SetupEditableFactionWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, Dictionary<string,string> countryNames)
|
||||
public static void SetupEditableFactionWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager,
|
||||
Dictionary<string, LobbyCountry> countries)
|
||||
{
|
||||
var dropdown = parent.Get<DropDownButtonWidget>("FACTION");
|
||||
dropdown.IsDisabled = () => s.LockRace || orderManager.LocalClient.IsReady;
|
||||
dropdown.OnMouseDown = _ => ShowRaceDropDown(dropdown, c, orderManager, countryNames);
|
||||
SetupFactionWidget(dropdown, s, c, countryNames);
|
||||
dropdown.OnMouseDown = _ => ShowRaceDropDown(dropdown, c, orderManager, countries);
|
||||
var factionDescription = countries[c.Country].Description;
|
||||
dropdown.GetTooltipText = () => factionDescription;
|
||||
SetupFactionWidget(dropdown, s, c, countries);
|
||||
}
|
||||
|
||||
public static void SetupFactionWidget(Widget parent, Session.Slot s, Session.Client c, Dictionary<string,string> countryNames)
|
||||
public static void SetupFactionWidget(Widget parent, Session.Slot s, Session.Client c,
|
||||
Dictionary<string, LobbyCountry> countries)
|
||||
{
|
||||
var factionname = parent.Get<LabelWidget>("FACTIONNAME");
|
||||
factionname.GetText = () => countryNames[c.Country];
|
||||
var factionflag = parent.Get<ImageWidget>("FACTIONFLAG");
|
||||
factionflag.GetImageName = () => c.Country;
|
||||
factionflag.GetImageCollection = () => "flags";
|
||||
var factionName = parent.Get<LabelWidget>("FACTIONNAME");
|
||||
factionName.GetText = () => countries[c.Country].Name;
|
||||
var factionFlag = parent.Get<ImageWidget>("FACTIONFLAG");
|
||||
factionFlag.GetImageName = () => c.Country;
|
||||
factionFlag.GetImageCollection = () => "flags";
|
||||
}
|
||||
|
||||
public static void SetupEditableTeamWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, MapPreview map)
|
||||
|
||||
@@ -61,6 +61,9 @@ ScrollPanel@LOBBY_PLAYER_BIN:
|
||||
X: 280
|
||||
Width: 130
|
||||
Height: 25
|
||||
TooltipContainer: TOOLTIP_CONTAINER
|
||||
TooltipTemplate: FACTION_DESCRIPTION_TOOLTIP
|
||||
PanelRoot: FACTION_DROPDOWN_PANEL_ROOT # ensure that tooltips for the options are on top of the dropdown panel
|
||||
Children:
|
||||
Image@FACTIONFLAG:
|
||||
Width: 30
|
||||
@@ -326,12 +329,27 @@ ScrollPanel@LOBBY_PLAYER_BIN:
|
||||
ScrollPanel@RACE_DROPDOWN_TEMPLATE:
|
||||
Width: DROPDOWN_WIDTH
|
||||
Children:
|
||||
ScrollItem@HEADER:
|
||||
BaseName: scrollheader
|
||||
Width: PARENT_RIGHT-27
|
||||
Height: 13
|
||||
X: 2
|
||||
Y: 0
|
||||
Visible: false
|
||||
Children:
|
||||
Label@LABEL:
|
||||
Font: TinyBold
|
||||
Width: PARENT_RIGHT
|
||||
Height: 10
|
||||
Align: Center
|
||||
ScrollItem@TEMPLATE:
|
||||
Width: PARENT_RIGHT-27
|
||||
Height: 25
|
||||
X: 2
|
||||
Y: 0
|
||||
Visible: false
|
||||
TooltipContainer: TOOLTIP_CONTAINER
|
||||
TooltipTemplate: FACTION_DESCRIPTION_TOOLTIP
|
||||
Children:
|
||||
Image@FLAG:
|
||||
X: 5
|
||||
@@ -342,4 +360,3 @@ ScrollPanel@RACE_DROPDOWN_TEMPLATE:
|
||||
X: 40
|
||||
Width: 60
|
||||
Height: 25
|
||||
|
||||
|
||||
@@ -141,5 +141,5 @@ Background@SERVER_LOBBY:
|
||||
Text: Disconnect
|
||||
Font: Bold
|
||||
Key: escape
|
||||
Container@FACTION_DROPDOWN_PANEL_ROOT:
|
||||
TooltipContainer@TOOLTIP_CONTAINER:
|
||||
|
||||
|
||||
@@ -186,3 +186,22 @@ Background@SUPPORT_POWER_TOOLTIP:
|
||||
Y: 22
|
||||
Font: TinyBold
|
||||
VAlign: Top
|
||||
|
||||
Background@FACTION_DESCRIPTION_TOOLTIP:
|
||||
Logic: CountryTooltipLogic
|
||||
Background: dialog4
|
||||
Children:
|
||||
Label@HEADER:
|
||||
X: 7
|
||||
Y: 6
|
||||
Width: 8
|
||||
Height: 12
|
||||
Font: Bold
|
||||
VAlign: Top
|
||||
Label@DESCRIPTION:
|
||||
X: 14
|
||||
Y: 0
|
||||
Width: 15
|
||||
Height: 14
|
||||
Font: TinyBold
|
||||
VAlign: Top
|
||||
@@ -95,24 +95,38 @@ World:
|
||||
Country@0:
|
||||
Name: Allies
|
||||
Race: allies
|
||||
Side: Allies
|
||||
Description: Allies: Deception\nSpecial Ability: Can build fake structures
|
||||
Country@1:
|
||||
Name: England
|
||||
Race: england
|
||||
Side: Allies
|
||||
Description: England: Espionage\nSpecial Unit: British Spy\nSpecial Unit: Phase Transport
|
||||
Country@2:
|
||||
Name: France
|
||||
Race: france
|
||||
Side: Allies
|
||||
Description: France: Concealment\nSpecial Structure: Advanced Gap Generator\nSpecial Unit: Mobile Gap Generator
|
||||
Country@3:
|
||||
Name: Germany
|
||||
Race: germany
|
||||
Side: Allies
|
||||
Description: Germany: Technology\nSpecial Structure: Advanced Chronosphere\nSpecial Unit: Chrono Tank
|
||||
Country@4:
|
||||
Name: Soviet
|
||||
Race: soviet
|
||||
Side: Soviet
|
||||
Description: Soviet: Infantry\nSpecial Ability: Paradrop\nSpecial Ability: Spy Plane
|
||||
Country@5:
|
||||
Name: Russia
|
||||
Race: russia
|
||||
Side: Soviet
|
||||
Description: Russia: Tanks\nSpecial Ability: Armor Airdrop\nSpecial Unit: MAD Tank
|
||||
Country@6:
|
||||
Name: Ukraine
|
||||
Race: ukraine
|
||||
Side: Soviet
|
||||
Description: Ukraine: Demolitions\nSpecial Ability: Parabombs\nSpecial Unit: Demolition Truck
|
||||
DomainIndex:
|
||||
SmudgeLayer@SCORCH:
|
||||
Type: Scorch
|
||||
|
||||
Reference in New Issue
Block a user