Merge pull request #9920 from pchote/label-truncation

Truncate long user-defined strings.
This commit is contained in:
Pavel Penev
2015-11-08 17:21:19 +02:00
9 changed files with 120 additions and 35 deletions

View File

@@ -227,6 +227,22 @@ namespace OpenRA.Widgets
return text;
}
public static string TruncateText(string text, int width, SpriteFont font)
{
var trimmedWidth = font.Measure(text).X;
if (trimmedWidth <= width)
return text;
var trimmed = text;
while (trimmedWidth > width && trimmed.Length > 3)
{
trimmed = text.Substring(0, trimmed.Length - 4) + "...";
trimmedWidth = font.Measure(trimmed).X;
}
return trimmed;
}
public static Action Once(Action a) { return () => { if (a != null) { a(); a = null; } }; }
public static string ChooseInitialMap(string initialUid)
@@ -242,6 +258,32 @@ namespace OpenRA.Widgets
}
}
public class CachedTransform<T, U>
{
readonly Func<T, U> transform;
bool initialized;
T lastInput;
U lastOutput;
public CachedTransform(Func<T, U> transform)
{
this.transform = transform;
}
public U Update(T input)
{
if (initialized && ((input == null && lastInput == null) || input.Equals(lastInput)))
return lastOutput;
lastInput = input;
lastOutput = transform(input);
initialized = true;
return lastOutput;
}
}
[Flags]
public enum PanelSides
{

View File

@@ -8,6 +8,7 @@
*/
#endregion
using System;
using OpenRA.Network;
using OpenRA.Widgets;
@@ -28,17 +29,25 @@ namespace OpenRA.Mods.Common.Widgets.Logic
preview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint(orderManager, preview, lobby.Map, mi);
preview.SpawnOccupants = () => LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, lobby.Map);
var title = available.GetOrNull<LabelWidget>("MAP_TITLE");
if (title != null)
title.GetText = () => lobby.Map.Title;
var titleLabel = available.GetOrNull<LabelWidget>("MAP_TITLE");
if (titleLabel != null)
{
var font = Game.Renderer.Fonts[titleLabel.Font];
var title = new CachedTransform<MapPreview, string>(m => WidgetUtils.TruncateText(m.Title, titleLabel.Bounds.Width, font));
titleLabel.GetText = () => title.Update(lobby.Map);
}
var type = available.GetOrNull<LabelWidget>("MAP_TYPE");
if (type != null)
type.GetText = () => lobby.Map.Type;
var typeLabel = available.GetOrNull<LabelWidget>("MAP_TYPE");
if (typeLabel != null)
typeLabel.GetText = () => lobby.Map.Type;
var author = available.GetOrNull<LabelWidget>("MAP_AUTHOR");
if (author != null)
author.GetText = () => "Created by {0}".F(lobby.Map.Author);
var authorLabel = available.GetOrNull<LabelWidget>("MAP_AUTHOR");
if (authorLabel != null)
{
var font = Game.Renderer.Fonts[authorLabel.Font];
var author = new CachedTransform<MapPreview, string>(m => WidgetUtils.TruncateText("Created by {0}".F(lobby.Map.Author), authorLabel.Bounds.Width, font));
authorLabel.GetText = () => author.Update(lobby.Map);
}
}
var invalid = widget.GetOrNull("MAP_INVALID");

View File

@@ -291,7 +291,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
public static void SetupNameWidget(Widget parent, Session.Slot s, Session.Client c)
{
var name = parent.Get<LabelWidget>("NAME");
name.GetText = () => c.Name;
var font = Game.Renderer.Fonts[name.Font];
var label = WidgetUtils.TruncateText(c.Name, name.Bounds.Width, font);
name.GetText = () => label;
}
public static void SetupEditableSlotWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, Ruleset rules)

View File

@@ -235,7 +235,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
item.IsVisible = () => item.RenderBounds.IntersectsWith(scrollpanels[tab].RenderBounds);
var titleLabel = item.Get<LabelWidget>("TITLE");
titleLabel.GetText = () => preview.Title;
if (titleLabel != null)
{
var font = Game.Renderer.Fonts[titleLabel.Font];
var title = WidgetUtils.TruncateText(preview.Title, titleLabel.Bounds.Width, font);
titleLabel.GetText = () => title;
}
var previewWidget = item.Get<MapPreviewWidget>("PREVIEW");
previewWidget.Preview = () => preview;
@@ -246,7 +251,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var authorWidget = item.GetOrNull<LabelWidget>("AUTHOR");
if (authorWidget != null)
authorWidget.GetText = () => "Created by {0}".F(preview.Author);
{
var font = Game.Renderer.Fonts[authorWidget.Font];
var author = WidgetUtils.TruncateText("Created by {0}".F(preview.Author), authorWidget.Bounds.Width, font);
authorWidget.GetText = () => author;
}
var sizeWidget = item.GetOrNull<LabelWidget>("SIZE");
if (sizeWidget != null)

View File

@@ -198,7 +198,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var mapTitle = widget.GetOrNull<LabelWidget>("SELECTED_MAP");
if (mapTitle != null)
mapTitle.GetText = () => currentMap != null ? currentMap.Title : "No Server Selected";
{
var font = Game.Renderer.Fonts[mapTitle.Font];
var title = new CachedTransform<MapPreview, string>(m => m == null ? "No Server Selected" :
WidgetUtils.TruncateText(m.Title, mapTitle.Bounds.Width, font));
mapTitle.GetText = () => title.Update(currentMap);
}
var ip = widget.GetOrNull<LabelWidget>("SELECTED_IP");
if (ip != null)
@@ -219,8 +224,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (modVersion != null)
{
modVersion.IsVisible = () => currentServer != null;
modVersion.GetText = () => currentServer.ModLabel;
modVersion.GetColor = () => currentServer.IsCompatible ? modVersion.TextColor : incompatibleVersionColor;
var font = Game.Renderer.Fonts[modVersion.Font];
var version = new CachedTransform<GameServer, string>(s => WidgetUtils.TruncateText(s.ModLabel, mapTitle.Bounds.Width, font));
modVersion.GetText = () => version.Update(currentServer);
}
var players = widget.GetOrNull<LabelWidget>("SELECTED_PLAYERS");
@@ -358,7 +366,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var title = item.GetOrNull<LabelWidget>("TITLE");
if (title != null)
{
title.GetText = () => game.Name;
var font = Game.Renderer.Fonts[title.Font];
var label = WidgetUtils.TruncateText(game.Name, title.Bounds.Width, font);
title.GetText = () => label;
title.GetColor = () => canJoin ? title.TextColor : incompatibleGameColor;
}

View File

@@ -71,9 +71,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic
preview.SpawnOccupants = () => selectedSpawns;
preview.Preview = () => selectedReplay != null ? selectedReplay.GameInfo.MapPreview : null;
var title = panel.GetOrNull<LabelWidget>("MAP_TITLE");
if (title != null)
title.GetText = () => selectedReplay != null ? selectedReplay.GameInfo.MapPreview.Title : null;
var titleLabel = panel.GetOrNull<LabelWidget>("MAP_TITLE");
if (titleLabel != null)
{
titleLabel.IsVisible = () => selectedReplay != null;
var font = Game.Renderer.Fonts[titleLabel.Font];
var title = new CachedTransform<MapPreview, string>(m => WidgetUtils.TruncateText(m.Title, titleLabel.Bounds.Width, font));
titleLabel.GetText = () => title.Update(selectedReplay.GameInfo.MapPreview);
}
var type = panel.GetOrNull<LabelWidget>("MAP_TYPE");
if (type != null)

View File

@@ -52,7 +52,14 @@ namespace OpenRA.Mods.Common.Widgets.Logic
};
panel.Get<MapPreviewWidget>("MAP_PREVIEW").Preview = () => preview;
panel.Get<LabelWidget>("MAP_NAME").GetText = () => preview.Title;
var mapTitle = panel.Get<LabelWidget>("MAP_NAME");
if (mapTitle != null)
{
var font = Game.Renderer.Fonts[mapTitle.Font];
var title = new CachedTransform<MapPreview, string>(m => WidgetUtils.TruncateText(m.Title, mapTitle.Bounds.Width, font));
mapTitle.GetText = () => title.Update(preview);
}
}
var serverName = panel.Get<TextFieldWidget>("SERVER_NAME");

View File

@@ -89,25 +89,25 @@ Container@MAPCHOOSER_PANEL:
IgnoreMouseOver: true
IgnoreMouseInput: true
Label@TITLE:
X: 2
X: 4
Y: PARENT_BOTTOM-48
Width: PARENT_RIGHT-4
Width: PARENT_RIGHT-8
Align: Center
Label@DETAILS:
Width: PARENT_RIGHT-4
X: 2
Width: PARENT_RIGHT-8
X: 4
Y: PARENT_BOTTOM-34
Align: Center
Font: Tiny
Label@AUTHOR:
Width: PARENT_RIGHT-4
X: 2
Width: PARENT_RIGHT-8
X: 4
Y: PARENT_BOTTOM-22
Align: Center
Font: Tiny
Label@SIZE:
Width: PARENT_RIGHT-4
X: 2
Width: PARENT_RIGHT-8
X: 4
Y: PARENT_BOTTOM-10
Align: Center
Font: Tiny

View File

@@ -60,25 +60,25 @@ Background@MAPCHOOSER_PANEL:
IgnoreMouseOver: true
IgnoreMouseInput: true
Label@TITLE:
X: 2
X: 4
Y: PARENT_BOTTOM-53
Width: PARENT_RIGHT-4
Width: PARENT_RIGHT-8
Align: Center
Label@DETAILS:
Width: PARENT_RIGHT-4
X: 2
Width: PARENT_RIGHT-8
X: 4
Y: PARENT_BOTTOM-37
Align: Center
Font: Tiny
Label@AUTHOR:
Width: PARENT_RIGHT-4
X: 2
Width: PARENT_RIGHT-8
X: 4
Y: PARENT_BOTTOM-25
Align: Center
Font: Tiny
Label@SIZE:
Width: PARENT_RIGHT-4
X: 2
Width: PARENT_RIGHT-8
X: 4
Y: PARENT_BOTTOM-13
Align: Center
Font: Tiny