Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaClient/ClientSource/Steam/ItemList.cs
T
2022-03-17 01:25:04 +09:00

695 lines
33 KiB
C#

#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Barotrauma.Extensions;
using Barotrauma.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using ItemOrPackage = Barotrauma.Either<Steamworks.Ugc.Item, Barotrauma.ContentPackage>;
namespace Barotrauma.Steam
{
public partial class WorkshopMenu
{
private string ExtractTitle(ItemOrPackage itemOrPackage)
=> itemOrPackage.TryGet(out ContentPackage package)
? package.Name
: ((Steamworks.Ugc.Item)itemOrPackage).Title;
private void CreateWorkshopItemDetailContainer(
GUIFrame parent,
out GUIListBox outerContainer,
Action<ItemOrPackage, GUIFrame> onSelected,
Action onDeselected,
out Action<ItemOrPackage> select,
out Action deselect)
{
ItemOrPackage? selectedItemOrPackage = null;
GUIListBox outContainer = new GUIListBox(new RectTransform(Vector2.One, parent.RectTransform),
isHorizontal: true,
style: null)
{
ScrollBarEnabled = false,
ScrollBarVisible = false,
HoverCursor = CursorState.Default
};
outerContainer = outContainer;
var selectedLayout =
new GUILayoutGroup(new RectTransform(Vector2.One, outerContainer.Content.RectTransform));
var selectedHeaderLayout =
new GUILayoutGroup(new RectTransform((1.0f, 0.05f), selectedLayout.RectTransform),
isHorizontal: true,
childAnchor: Anchor.CenterLeft);
void deselectMethod()
{
if (selectedItemOrPackage is null) { return; }
selectedItemOrPackage = null;
onDeselected();
}
deselect = deselectMethod;
var backButton =
new GUIButton(new RectTransform((0.04f, 1.0f), selectedHeaderLayout.RectTransform),
style: "GUIButtonToggleLeft")
{
OnClicked = (button, o) =>
{
deselectMethod();
return false;
}
};
var padding = new GUIFrame(new RectTransform((1.0f, 0.005f), selectedLayout.RectTransform), style: null);
var selectedFrame = new GUIFrame(new RectTransform((1.0f, 0.945f), selectedLayout.RectTransform),
style: null);
var selectionScroller = new GUICustomComponent(
new RectTransform(Vector2.Zero, outerContainer.Parent.RectTransform),
onUpdate: (deltaTime, component) =>
{
float targetScroll = selectedItemOrPackage is null
? 0.0f
: 1.0f;
outContainer.ScrollBar.BarScroll
= MathUtils.NearlyEqual(targetScroll, outContainer.ScrollBar.BarScroll)
? targetScroll
: MathHelper.Lerp(outContainer.ScrollBar.BarScroll, targetScroll, 0.3f);
});
select = itemOrPackage =>
{
//showInSteamButton.Visible = itemOrPackage.TryGet(out Steamworks.Ugc.Item _);
//selectedItem = itemOrPackage;
//selectedTitle.Text = ExtractTitle(itemOrPackage);
selectedFrame.ClearChildren();
//Jank to fix mouserect not clamping properly
//when shifting all elements to the left
var dropdowns = outContainer.Content.GetAllChildren<GUIDropDown>().ToArray();
var allChildren = outContainer.Content.GetAllChildren()
.Concat(selectedFrame.GetAllChildren());
allChildren.ForEach(c =>
{
//c.CascadingMouseRectClamp = !dropdowns.Any(dd => dd.IsParentOf(c) || dd.ListBox.IsParentOf(c));
//c.CanBeFocused = c.CanBeFocused || !c.CascadingMouseRectClamp;
c.ClampMouseRectToParent = !(c.Parent?.Parent is GUIDropDown);
}
);
selectedItemOrPackage = itemOrPackage;
onSelected(itemOrPackage, selectedFrame);
};
}
private void CreateWorkshopItemList(
GUIFrame parent,
out GUIListBox outerContainer,
out GUIListBox workshopItemList,
Action<Steamworks.Ugc.Item, GUIFrame> onSelected)
=> CreateWorkshopItemOrPackageList(
parent,
out outerContainer,
out workshopItemList,
onSelected: (ItemOrPackage itemOrPackage, GUIFrame frame)
=> onSelected((Steamworks.Ugc.Item)itemOrPackage, frame));
private GUIButton CreateShowInSteamButton(Steamworks.Ugc.Item workshopItem, RectTransform rectT)
=> new GUIButton(
rectT,
TextManager.Get("WorkshopShowItemInSteam"), style: "GUIButtonSmall")
{
OnClicked = (button, o) =>
{
SteamManager.OverlayCustomURL(workshopItem.Url);
return false;
}
};
private GUIButton? CreateShowInSteamButton(ItemOrPackage itemOrPackage)
=> itemOrPackage.TryGet(out Steamworks.Ugc.Item workshopItem)
? CreateShowInSteamButton(workshopItem)
: null;
private void CreateWorkshopItemOrPackageList(
GUIFrame parent,
out GUIListBox outerContainer,
out GUIListBox workshopItemList,
Action<ItemOrPackage, GUIFrame> onSelected)
{
GUIListBox? itemList = null;
CreateWorkshopItemDetailContainer(
parent,
out outerContainer,
onSelected: onSelected,
onDeselected: () => itemList?.Deselect(),
out var select, out var deselect);
itemList = new GUIListBox(new RectTransform(Vector2.One, outerContainer.Content.RectTransform));
itemList.RectTransform.SetAsFirstChild();
workshopItemList = itemList;
var deselectCarrier
= CreateActionCarrier(outerContainer.Content, nameof(deselect).ToIdentifier(), deselect);
itemList.OnSelected = (component, userData) =>
{
//Don't select if hitting the subscribe button
if (GUI.MouseOn.Parent != itemList.Content) { return false; }
if (!(userData is ItemOrPackage itemOrPackage)) { return false; }
select(itemOrPackage);
return true;
};
}
private void AddUnpublishedMods(ISet<Steamworks.Ugc.Item> workshopItems)
{
//Users that don't have a proper license cannot publish Workshop items
//(see https://partner.steamgames.com/doc/features/workshop#15)
void clearWithMessage(LocalizedString message)
{
selfModsList.ClearChildren();
var messageFrame = new GUIFrame(new RectTransform(Vector2.One, selfModsList.Content.RectTransform),
style: null)
{
CanBeFocused = false
};
new GUITextBlock(new RectTransform((0.5f, 1.0f), messageFrame.RectTransform, Anchor.Center),
text: message,
textAlignment: Alignment.Center,
wrap: true,
font: GUIStyle.Font);
}
if (SteamManager.IsFreeWeekend())
{
clearWithMessage(TextManager.Get("FreeWeekendCantPublish"));
return;
}
if (SteamManager.IsFamilyShared())
{
clearWithMessage(TextManager.Get("FamilySharedCantPublish"));
return;
}
DateTime getEditTime(ContentPackage p)
=> File.GetLastWriteTime(Path.GetDirectoryName(p.Path)!);
//Find local packages associated with the Workshop items if available
(Steamworks.Ugc.Item WorkshopItem, ContentPackage? LocalPackage)[] publishedItems = workshopItems
.Select(item => (item,
(ContentPackage?)ContentPackageManager.LocalPackages.FirstOrDefault(p
=> p.SteamWorkshopId != 0 && p.SteamWorkshopId == item.Id)))
//Sort the pairs by last local edit time if available
.OrderBy(t => t.Item2 == null)
.ThenByDescending(t => t.Item2 is { } p ? getEditTime(p) : t.Item1.LatestUpdateTime)
.ToArray();
int indexOfUserDataInPublishedItemsArray(object userData)
=> publishedItems.IndexOf(t
=> t.WorkshopItem.Id == ((Steamworks.Ugc.Item)(userData as ItemOrPackage)).Id);
//Take the existing GUI items that are in the list and sort to match the order of publishedItems
var publishedGuiComponents = selfModsList.Content.Children.OrderBy(c => indexOfUserDataInPublishedItemsArray(c.UserData)).ToArray();
//Get mods that haven't been published and add them to the list
var unpublishedMods = ContentPackageManager.LocalPackages
.Where(p => p.SteamWorkshopId == 0 || !publishedItems.Any(item => item.WorkshopItem.Id == p.SteamWorkshopId))
.OrderByDescending(getEditTime).ToArray();
if (unpublishedMods.Any())
{
var unpublishedHeader
= new GUITextBlock(new RectTransform((1.0f, 1.0f / 11.0f), selfModsList.Content.RectTransform),
TextManager.Get("UnpublishedModsHeader"), font: GUIStyle.SubHeadingFont) { CanBeFocused = false };
}
foreach (var unpublishedMod in unpublishedMods)
{
var unpublishedFrame = new GUIFrame(
new RectTransform((1.0f, 1.0f / 5.5f), selfModsList.Content.RectTransform),
style: "ListBoxElement")
{
UserData = (ItemOrPackage)unpublishedMod
};
var unpublishedLayout
= new GUILayoutGroup(new RectTransform(Vector2.One, unpublishedFrame.RectTransform),
isHorizontal: true)
{
Stretch = true,
RelativeSpacing = 0.02f
};
var unpublishedPadding
= new GUIFrame(
new RectTransform(Vector2.One, unpublishedLayout.RectTransform,
scaleBasis: ScaleBasis.BothHeight), style: null)
{
CanBeFocused = false
};
var unpublishedTextBlock
= new GUITextBlock(new RectTransform(Vector2.One, unpublishedLayout.RectTransform),
$"{unpublishedMod.Name}\n\n" +
TextManager.GetWithVariable("LastLocalEditTime",
"[datetime]",
getEditTime(unpublishedMod).ToString()),
font: GUIStyle.Font)
{
CanBeFocused = false
};
}
if (publishedGuiComponents.Any())
{
var publishedHeader
= new GUITextBlock(new RectTransform((1.0f, 1.0f / 11.0f), selfModsList.Content.RectTransform),
TextManager.Get("PublishedModsHeader"), font: GUIStyle.SubHeadingFont) { CanBeFocused = false };
}
foreach (var c in publishedGuiComponents)
{
c.SetAsLastChild();
var textBlock = (c.FindChild(b => b is GUITextBlock, recursive: true) as GUITextBlock)!;
textBlock.Text += $"\n";
int index = indexOfUserDataInPublishedItemsArray(c.UserData);
(Steamworks.Ugc.Item workshopItem, ContentPackage? localMod) = publishedItems[index];
if (localMod != null)
{
textBlock.Text += $"\n" + TextManager.GetWithVariable("LastLocalEditTime", "[datetime]", getEditTime(localMod).ToString());
}
textBlock.Text += $"\n" + TextManager.GetWithVariable("LatestPublishTime", "[datetime]", workshopItem.LatestUpdateTime.ToLocalTime().ToString());
}
}
private static (GUIButton Button, GUIFrame Sprite) CreatePaddedButton(RectTransform rectT, string style, float spriteScale)
{
var button = new GUIButton(
rectT,
style: null);
var sprite = new GUIFrame(
new RectTransform(Vector2.One * spriteScale, button.RectTransform, Anchor.Center),
style: style)
{
CanBeFocused = false
};
return (button, sprite);
}
private static void CreateSubscribeButton(Steamworks.Ugc.Item workshopItem, RectTransform rectT, float spriteScale)
{
const string plusButton = "GUIPlusButton";
const string minusButton = "GUIMinusButton";
LocalizedString subscribeTooltip = TextManager.Get("DownloadButton");
LocalizedString unsubscribeTooptip = TextManager.Get("WorkshopItemUnsubscribe");
var (subscribeButton, subscribeButtonSprite) = CreatePaddedButton(rectT, plusButton, spriteScale);
subscribeButton.ToolTip = subscribeTooltip;
subscribeButton.OnClicked = (button, o) =>
{
if (!workshopItem.IsSubscribed)
{
workshopItem.Subscribe();
TaskPool.Add($"DownloadSubscribedItem{workshopItem.Id}",
SteamManager.Workshop.ForceRedownload(workshopItem),
t => { });
}
else
{
workshopItem.Unsubscribe();
SteamManager.Workshop.Uninstall(workshopItem);
}
return false;
};
var buttonStyleUpdater = new GUICustomComponent(
new RectTransform(Vector2.Zero, subscribeButton.RectTransform),
onUpdate: (deltaTime, component) =>
{
if (subscribeButtonSprite.Style is { Identifier: { } styleId })
{
if (workshopItem.IsSubscribed && styleId != minusButton)
{
subscribeButtonSprite.ApplyStyle(GUIStyle.GetComponentStyle(minusButton));
subscribeButton.ToolTip = unsubscribeTooptip;
}
if (!workshopItem.IsSubscribed && styleId != plusButton)
{
subscribeButtonSprite.ApplyStyle(GUIStyle.GetComponentStyle(plusButton));
subscribeButton.ToolTip = subscribeTooltip;
}
}
});
float displayedDownloadAmount = workshopItem.DownloadAmount;
var downloadProgressBar = new GUICustomComponent(
new RectTransform((1.22f, 1.22f), subscribeButtonSprite.RectTransform, Anchor.Center),
onDraw: (spriteBatch, component) =>
{
bool visible = workshopItem.IsSubscribed
&& (workshopItem.IsDownloading
|| workshopItem.IsDownloadPending
|| !MathUtils.NearlyEqual(workshopItem.DownloadAmount, displayedDownloadAmount));
if (!visible) { return; }
void drawSection(float amount, Color color, float thickness)
=> GUI.DrawDonutSection(
spriteBatch,
component.Rect.Center.ToVector2() + (0, 1),
new Range<float>(component.Rect.Width * 0.55f - thickness * 0.5f, component.Rect.Width * 0.55f + thickness * 0.5f),
amount * MathF.PI * 2.0f,
color);
void drawSectionFuzzy(float amount, Color color, float thickness)
{
drawSection(amount, color, thickness);
drawSection(amount, color * 0.6f, thickness + 0.5f);
drawSection(amount, color * 0.3f, thickness + 1.0f);
}
drawSectionFuzzy(1.0f, Color.Lerp(Color.Black, GUIStyle.Blue, 0.2f), component.Rect.Width * 0.25f);
drawSectionFuzzy(1.0f, Color.Black, component.Rect.Width * 0.15f);
drawSectionFuzzy(displayedDownloadAmount, GUIStyle.Green, component.Rect.Width * 0.08f);
},
onUpdate: (deltaTime, component) =>
{
displayedDownloadAmount = Math.Min(
workshopItem.DownloadAmount,
MathHelper.Lerp(displayedDownloadAmount, workshopItem.DownloadAmount, 0.05f));
})
{
CanBeFocused = false
};
}
private void PopulateItemList(GUIListBox itemListBox, Task<ISet<Steamworks.Ugc.Item>> items, bool includeSubscribeButton, Action<ISet<Steamworks.Ugc.Item>>? onFill = null)
{
itemListBox.ClearChildren();
itemListBox.Deselect();
itemListBox.ScrollBar.BarScroll = 0.0f;
TaskPool.Add("PopulateTabWithItemList", items,
(t) =>
{
taskCancelSrc = taskCancelSrc.IsCancellationRequested ? new CancellationTokenSource() : taskCancelSrc;
itemListBox.ClearChildren();
var workshopItems = ((Task<ISet<Steamworks.Ugc.Item>>)t).Result;
foreach (var workshopItem in workshopItems)
{
var itemFrame = new GUIFrame(
new RectTransform((1.0f, 1.0f / 5.5f), itemListBox.Content.RectTransform),
style: "ListBoxElement")
{
UserData = (ItemOrPackage)workshopItem
};
var itemLayout = new GUILayoutGroup(
new RectTransform(Vector2.One, itemFrame.RectTransform),
isHorizontal: true, childAnchor: Anchor.CenterLeft)
{
Stretch = true
};
var thumbnailContainer
= CreateThumbnailContainer(itemLayout, Vector2.One, ScaleBasis.BothHeight);
CreateItemThumbnail(workshopItem, taskCancelSrc.Token, thumbnailContainer);
thumbnailContainer.CanBeFocused = false;
thumbnailContainer.GetAllChildren().ForEach(c => c.CanBeFocused = false);
var title = new GUITextBlock(
new RectTransform(Vector2.One, itemLayout.RectTransform),
workshopItem.Title, font: GUIStyle.Font)
{
CanBeFocused = false
};
if (includeSubscribeButton)
{
CreateSubscribeButton(workshopItem, new RectTransform(Vector2.One, itemLayout.RectTransform, scaleBasis: ScaleBasis.BothHeight), spriteScale: 0.4f);
}
}
onFill?.Invoke(workshopItems);
});
}
private GUIFrame CreateThumbnailContainer(
GUIComponent parent,
Vector2 relativeSize,
ScaleBasis scaleBasis)
=> new GUIFrame(new RectTransform(relativeSize, parent.RectTransform, scaleBasis: scaleBasis),
style: "GUIFrameListBox");
private SteamManager.Workshop.ItemThumbnail CreateItemThumbnail(
in Steamworks.Ugc.Item workshopItem,
CancellationToken cancellationToken,
GUIFrame thumbnailContainer)
{
var thumbnail = new SteamManager.Workshop.ItemThumbnail(workshopItem, cancellationToken);
itemThumbnails.Add(thumbnail);
CreateAsyncThumbnailComponent(thumbnailContainer, () => thumbnail.Texture, () => thumbnail.Loading);
return thumbnail;
}
private GUICustomComponent CreateAsyncThumbnailComponent(GUIFrame thumbnailContainer, Func<Texture2D?> textureGetter, Func<bool> throbberEnabled)
{
int randomThrobberOffset = Rand.Range(0, 10, Rand.RandSync.Unsynced);
return new GUICustomComponent(
new RectTransform(Vector2.One, thumbnailContainer.RectTransform, Anchor.Center),
onDraw: (spriteBatch, component) =>
{
Rectangle rect = component.Rect;
Texture2D? texture = textureGetter();
if (texture != null)
{
rect.Location += (4, 4);
rect.Size -= (8, 8);
Point destinationSizeMaxWidth = (rect.Width, rect.Width * texture.Height / texture.Width);
Point destinationSizeMaxHeight = (rect.Height * texture.Width / texture.Height, rect.Height);
Point destinationSize = destinationSizeMaxHeight.X > rect.Width
? destinationSizeMaxWidth
: destinationSizeMaxHeight;
Rectangle destinationRectangle = new Rectangle(
rect.Center.X - destinationSize.X / 2,
rect.Center.Y - destinationSize.Y / 2,
destinationSize.X,
destinationSize.Y);
spriteBatch.Draw(texture, destinationRectangle, Color.White);
}
else if (throbberEnabled())
{
var sheet = GUIStyle.GenericThrobber;
Vector2 pos = rect.Center.ToVector2() - Vector2.One * rect.Height * 0.4f;
sheet.Draw(spriteBatch, ((int)Math.Floor(Timing.TotalTime * 24.0f) + randomThrobberOffset) % sheet.FrameCount, pos, Color.White,
origin: Vector2.Zero, rotate: 0.0f,
scale: Vector2.One * component.Rect.Height / sheet.FrameSize.ToVector2() * 0.8f);
}
});
}
private GUIListBox CreateTagsList(IEnumerable<Identifier> tags, RectTransform rectT, bool canBeFocused)
{
var tagsList
= new GUIListBox(rectT, style: null, isHorizontal: false)
{
UseGridLayout = true,
ScrollBarEnabled = false,
ScrollBarVisible = false,
HideChildrenOutsideFrame = false,
Spacing = GUI.IntScale(4)
};
tagsList.Content.ClampMouseRectToParent = false;
foreach (Identifier tag in tags)
{
var tagBtn = new GUIButton(
new RectTransform(new Vector2(0.25f, 1.0f / 8.0f), tagsList.Content.RectTransform,
anchor: Anchor.TopLeft),
TextManager.Get($"workshop.contenttag.{tag.Value.RemoveWhitespace()}")
.Fallback(tag.Value.CapitaliseFirstInvariant()), style: "GUIButtonRound")
{
CanBeFocused = canBeFocused,
Selected = !canBeFocused,
UserData = tag
};
tagBtn.RectTransform.NonScaledSize
= tagBtn.Font.MeasureString(tagBtn.Text).ToPoint() + new Point(GUI.IntScale(15), GUI.IntScale(5));
tagBtn.RectTransform.IsFixedSize = true;
tagBtn.ClampMouseRectToParent = false;
}
return tagsList;
}
private void PopulateFrameWithItemInfo(Steamworks.Ugc.Item workshopItem, GUIFrame parentFrame)
{
taskCancelSrc = taskCancelSrc.IsCancellationRequested ? new CancellationTokenSource() : taskCancelSrc;
var verticalLayout = new GUILayoutGroup(new RectTransform(Vector2.One, parentFrame.RectTransform));
var headerLayout = new GUILayoutGroup(new RectTransform((1.0f, 0.1f), verticalLayout.RectTransform),
isHorizontal: true) { Stretch = true };
var titleAndAuthorLayout = new GUILayoutGroup(new RectTransform(Vector2.One, headerLayout.RectTransform));
var selectedTitle =
new GUITextBlock(new RectTransform((1.0f, 0.5f), titleAndAuthorLayout.RectTransform), workshopItem.Title,
font: GUIStyle.LargeFont);
var author = workshopItem.Owner;
var authorButton = new GUIButton(new RectTransform((1.0f, 0.5f),
titleAndAuthorLayout.RectTransform),
style: null,
textAlignment: Alignment.CenterLeft)
{
ForceUpperCase = ForceUpperCase.No,
Font = GUIStyle.SubHeadingFont,
TextColor = GUIStyle.TextColorNormal,
HoverTextColor = Color.White,
SelectedTextColor = GUIStyle.TextColorNormal,
OnClicked = (button, o) =>
{
SteamManager.OverlayCustomURL(
$"https://steamcommunity.com/profiles/{author.Id}/myworkshopfiles/?appid={SteamManager.AppID}");
return false;
}
};
var authorPadding = authorButton.GetChild<GUITextBlock>().Padding;
RectTransform rightSideButtonRectT()
=> new RectTransform(Vector2.One, headerLayout.RectTransform, scaleBasis: ScaleBasis.BothHeight);
var (reinstallButton, reinstallSprite) = CreatePaddedButton(
rightSideButtonRectT(),
"GUIReloadButton",
spriteScale: 0.8f);
reinstallButton.ToolTip = TextManager.Get("WorkshopItemReinstall");
reinstallButton.OnClicked += (button, o) =>
{
SteamManager.Workshop.Uninstall(workshopItem);
TaskPool.Add($"Reinstall{workshopItem.Id}", SteamManager.Workshop.ForceRedownload(workshopItem), t => { });
return false;
};
var reinstallButtonUpdater = new GUICustomComponent(
new RectTransform(Vector2.Zero, reinstallButton.RectTransform),
onUpdate: (f, component) =>
{
reinstallButton.Visible = workshopItem.IsSubscribed;
reinstallButton.Enabled = !workshopItem.IsDownloading && !workshopItem.IsDownloadPending &&
!SteamManager.Workshop.IsInstalling(workshopItem);
reinstallSprite.Color = reinstallButton.Enabled
? reinstallSprite.Style.Color
: Color.DimGray;
});
CreateSubscribeButton(workshopItem,
rightSideButtonRectT(),
spriteScale: 0.8f);
var padding = new GUIFrame(new RectTransform((1.0f, 0.015f), verticalLayout.RectTransform), style: null);
var horizontalLayout = new GUILayoutGroup(new RectTransform((1.0f, 0.45f), verticalLayout.RectTransform),
isHorizontal: true)
{
Stretch = true
};
TaskPool.Add($"Request username for {author.Id}", author.RequestInfoAsync(), (t) =>
{
authorButton.Text = author.Name;
authorButton.RectTransform.NonScaledSize =
((int)(authorButton.Font.MeasureString(author.Name).X + authorPadding.X + authorPadding.Z),
authorButton.RectTransform.NonScaledSize.Y);
});
var thumbnailSuperContainer = new GUIFrame(
new RectTransform(Vector2.One, horizontalLayout.RectTransform, scaleBasis: ScaleBasis.BothHeight),
style: null);
GUIFrame thumbnailContainer = CreateThumbnailContainer(thumbnailSuperContainer, Vector2.One,
scaleBasis: ScaleBasis.BothHeight);
CreateItemThumbnail(workshopItem, taskCancelSrc.Token, thumbnailContainer);
thumbnailContainer.RectTransform.Anchor = Anchor.Center;
thumbnailContainer.RectTransform.Pivot = Pivot.Center;
var statsBox = new GUIFrame(new RectTransform((0.6f, 1.0f), horizontalLayout.RectTransform),
style: "GUIFrameListBox");
#region Stats box
var statsHorizontalLayout = new GUILayoutGroup(new RectTransform(Vector2.One, statsBox.RectTransform), isHorizontal: true);
var statsVertical0
= new GUILayoutGroup(new RectTransform((1.0f, 1.0f), statsHorizontalLayout.RectTransform), childAnchor: Anchor.TopCenter);
statFrame("", ""); //padding
var scoreFrame = new GUIFrame(new RectTransform((1.0f, 0.12f), statsVertical0.RectTransform), style: null);
var scoreLabel = new GUITextBlock(new RectTransform((0.4f, 1.0f), scoreFrame.RectTransform),
TextManager.Get("WorkshopItemScore"), font: GUIStyle.SubHeadingFont);
var scoreStarContainer
= new GUILayoutGroup(
new RectTransform((0.6f, 1.0f), scoreFrame.RectTransform, Anchor.CenterRight),
isHorizontal: true,
childAnchor: Anchor.CenterLeft) { Stretch = true };
var starColor = Color.Lerp(
Color.Lerp(Color.Red, Color.Yellow, Math.Min(workshopItem.Score * 2.0f, 1.0f)),
Color.Lime, Math.Max(0.0f, (workshopItem.Score - 0.5f) * 2.0f));
for (int i = 0; i < 5; i++)
{
bool isStarLit = i <= Round(workshopItem.Score * 5.0f);
var star = new GUIFrame(new RectTransform(Vector2.One, scoreStarContainer.RectTransform, scaleBasis: ScaleBasis.BothHeight),
style: isStarLit ? "GUIStarIconBright" : "GUIStarIconDark");
if (isStarLit)
{
star.Color = starColor;
star.HoverColor = starColor;
star.SelectedColor = starColor;
}
}
var scoreVoteCountPadding = new GUIFrame(new RectTransform((0.5f, 1.0f), scoreStarContainer.RectTransform, scaleBasis: ScaleBasis.BothHeight),
style: null);
var scoreVoteCount = new GUITextBlock(
new RectTransform(Vector2.One, scoreStarContainer.RectTransform),
TextManager.GetWithVariable("WorkshopItemVotes", "[VoteCount]",
(workshopItem.VotesUp + workshopItem.VotesDown).ToString()), textAlignment: Alignment.CenterLeft)
{
Padding = Vector4.Zero
};
void statFrame(LocalizedString labelText, LocalizedString dataText)
{
var frame = new GUIFrame(new RectTransform((1.0f, 0.12f), statsVertical0!.RectTransform), style: null);
var label = new GUITextBlock(new RectTransform((0.4f, 1.0f), frame.RectTransform),
labelText, font: GUIStyle.SubHeadingFont);
var data = new GUITextBlock(new RectTransform((0.6f, 1.0f), frame.RectTransform, Anchor.CenterRight),
dataText, font: GUIStyle.Font)
{
Padding = Vector4.Zero
};
}
statFrame(TextManager.Get("WorkshopItemFileSize"), MathUtils.GetBytesReadable(workshopItem.SizeOfFileInBytes));
statFrame(TextManager.Get("WorkshopItemCreationDate"), workshopItem.Created.ToShortDateString());
statFrame(TextManager.Get("WorkshopItemModificationDate"), workshopItem.Updated.ToShortDateString());
var tagsLabel = new GUITextBlock(new RectTransform((1.0f, 0.12f), statsVertical0.RectTransform),
TextManager.Get("WorkshopItemTags"), font: GUIStyle.SubHeadingFont);
CreateTagsList(workshopItem.Tags.ToIdentifiers(), new RectTransform((0.97f, 0.3f), statsVertical0.RectTransform), canBeFocused: false);
#endregion
var descriptionListBox = new GUIListBox(new RectTransform((1.0f, 0.38f), verticalLayout.RectTransform));
CreateBBCodeElement(workshopItem.Description, descriptionListBox);
var showInSteamContainer
= new GUIFrame(new RectTransform((1.0f, 0.05f), verticalLayout.RectTransform), style: null);
CreateShowInSteamButton(workshopItem, new RectTransform((0.2f, 1.0f), showInSteamContainer.RectTransform, Anchor.CenterRight));
}
}
}