(d9829ac) v0.9.4.0

This commit is contained in:
Regalis
2019-10-24 18:05:42 +02:00
parent 9aa12bcac2
commit b39922a074
319 changed files with 12516 additions and 6815 deletions
+33 -11
View File
@@ -1,3 +1,4 @@
using Barotrauma.CharacterEditor;
using Barotrauma.Extensions;
using Barotrauma.Sounds;
using Barotrauma.Tutorials;
@@ -8,6 +9,7 @@ using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma
{
@@ -154,19 +156,38 @@ namespace Barotrauma
public static void Init(GameWindow window, IEnumerable<ContentPackage> selectedContentPackages, GraphicsDevice graphicsDevice)
{
GUI.graphicsDevice = graphicsDevice;
var uiStyles = ContentPackage.GetFilesOfType(selectedContentPackages, ContentType.UIStyle).ToList();
if (uiStyles.Count == 0)
var files = ContentPackage.GetFilesOfType(selectedContentPackages, ContentType.UIStyle);
XElement selectedStyle = null;
foreach (var file in files)
{
XDocument doc = XMLExtensions.TryLoadXml(file);
if (doc == null) { continue; }
var mainElement = doc.Root;
if (doc.Root.IsOverride())
{
mainElement = doc.Root.FirstElement();
if (selectedStyle != null)
{
DebugConsole.NewMessage($"Overriding the ui styles with '{file}'", Color.Yellow);
}
}
else if (selectedStyle != null)
{
DebugConsole.ThrowError("Another ui style already loaded! Use <override></override> tags to override it.");
break;
}
selectedStyle = mainElement;
}
if (selectedStyle == null)
{
DebugConsole.ThrowError("No UI styles defined in the selected content package!");
return;
}
else if (uiStyles.Count > 1)
else
{
DebugConsole.ThrowError("Multiple UI styles defined in the selected content package! Selecting the first one.");
Style = new GUIStyle(selectedStyle, graphicsDevice);
}
Style = new GUIStyle(uiStyles[0], graphicsDevice);
if (CJKFont == null)
{
CJKFont = new ScalableFont("Content/Fonts/NotoSans/NotoSansCJKsc-Bold.otf",
@@ -407,6 +428,10 @@ namespace Barotrauma
{
debugDrawEvents = !debugDrawEvents;
}
if (MouseOn != null)
{
DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - 500, 20), $"Selected UI Element: {MouseOn.GetType().ToString()}", Color.LightGreen, Color.Black * 0.5f, 0, SmallFont);
}
}
if (HUDLayoutSettings.DebugDraw) HUDLayoutSettings.Draw(spriteBatch);
@@ -601,10 +626,7 @@ namespace Barotrauma
private static void HandlePersistingElements(float deltaTime)
{
if (GUIMessageBox.VisibleBox != null && GUIMessageBox.VisibleBox.UserData as string != "verificationprompt" && GUIMessageBox.VisibleBox.UserData as string != "bugreporter")
{
GUIMessageBox.VisibleBox.AddToGUIUpdateList();
}
GUIMessageBox.AddActiveToGUIUpdateList();
if (pauseMenuOpen)
{
@@ -1570,7 +1592,7 @@ namespace Barotrauma
button.OnClicked += (btn, userData) =>
{
var quitButton = button;
if (GameMain.GameSession != null || (Screen.Selected is CharacterEditorScreen charEditScreen || Screen.Selected is SubEditorScreen subEditScreen))
if (GameMain.GameSession != null || (Screen.Selected is CharacterEditorScreen || Screen.Selected is SubEditorScreen))
{
string text = GameMain.GameSession == null ? "PauseMenuQuitVerificationEditor" : "PauseMenuQuitVerification";
var msgBox = new GUIMessageBox("", TextManager.Get(text), new string[] { TextManager.Get("Yes"), TextManager.Get("Cancel") })
@@ -163,6 +163,12 @@ namespace Barotrauma
{
TextColor = this.style == null ? Color.Black : this.style.textColor
};
if (rectT.Rect.Height == 0 && !string.IsNullOrEmpty(text))
{
RectTransform.Resize(new Point(RectTransform.Rect.Width, (int)Font.MeasureString(textBlock.Text).Y));
RectTransform.MinSize = textBlock.RectTransform.MinSize = new Point(0, Rect.Height);
TextBlock.SetTextPos();
}
GUI.Style.Apply(textBlock, "", this);
Enabled = true;
}
@@ -4,6 +4,10 @@ using System.Collections.Generic;
using System.Linq;
using Barotrauma.Extensions;
using System;
using System.Xml.Linq;
using System.IO;
using RestSharp;
using System.Net;
namespace Barotrauma
{
@@ -596,5 +600,340 @@ namespace Barotrauma
this.style = style;
}
public static GUIComponent FromXML(XElement element, RectTransform parent)
{
GUIComponent component = null;
foreach (XElement subElement in element.Elements())
{
if (subElement.Name.ToString().ToLowerInvariant() == "conditional" &&
!CheckConditional(subElement))
{
return null;
}
}
switch (element.Name.ToString().ToLowerInvariant())
{
case "text":
case "guitextblock":
component = LoadGUITextBlock(element, parent);
break;
case "link":
component = LoadLink(element, parent);
break;
case "frame":
case "guiframe":
case "spacing":
component = LoadGUIFrame(element, parent);
break;
case "button":
case "guibutton":
component = LoadGUIButton(element, parent);
break;
case "listbox":
case "guilistbox":
component = LoadGUIListBox(element, parent);
break;
case "guilayoutgroup":
case "layoutgroup":
component = LoadGUILayoutGroup(element, parent);
break;
case "image":
case "guiimage":
component = LoadGUIImage(element, parent);
break;
case "accordion":
return LoadAccordion(element, parent);
case "gridtext":
LoadGridText(element, parent);
return null;
default:
throw new NotImplementedException("Loading GUI component \""+element.Name+"\" from XML is not implemented.");
}
if (component != null)
{
foreach (XElement subElement in element.Elements())
{
if (subElement.Name.ToString().ToLowerInvariant() == "conditional") { continue; }
FromXML(subElement, component is GUIListBox listBox ? listBox.Content.RectTransform : component.RectTransform);
}
if (element.GetAttributeBool("resizetofitchildren", false))
{
Vector2 relativeResizeScale = element.GetAttributeVector2("relativeresizescale", Vector2.One);
if (component is GUILayoutGroup layoutGroup)
{
layoutGroup.RectTransform.NonScaledSize =
layoutGroup.IsHorizontal ?
new Point(layoutGroup.Children.Sum(c => c.Rect.Width), layoutGroup.Rect.Height) :
component.RectTransform.MinSize = new Point(layoutGroup.Rect.Width, layoutGroup.Children.Sum(c => c.Rect.Height));
if (layoutGroup.CountChildren > 0)
{
layoutGroup.RectTransform.NonScaledSize +=
layoutGroup.IsHorizontal ?
new Point((int)((layoutGroup.CountChildren - 1) * (layoutGroup.AbsoluteSpacing + layoutGroup.Rect.Width * layoutGroup.RelativeSpacing)), 0) :
new Point(0, (int)((layoutGroup.CountChildren - 1) * (layoutGroup.AbsoluteSpacing + layoutGroup.Rect.Height * layoutGroup.RelativeSpacing)));
}
}
else if (component is GUIListBox listBox)
{
listBox.RectTransform.NonScaledSize =
listBox.ScrollBar.IsHorizontal ?
new Point(listBox.Children.Sum(c => c.Rect.Width + listBox.Spacing), listBox.Rect.Height) :
component.RectTransform.MinSize = new Point(listBox.Rect.Width, listBox.Children.Sum(c => c.Rect.Height + listBox.Spacing));
}
else
{
component.RectTransform.NonScaledSize =
new Point(
component.Children.Max(c => c.Rect.Right) - component.Children.Min(c => c.Rect.X),
component.Children.Max(c => c.Rect.Bottom) - component.Children.Min(c => c.Rect.Y));
}
component.RectTransform.NonScaledSize =
component.RectTransform.NonScaledSize.Multiply(relativeResizeScale);
}
}
return component;
}
private static bool CheckConditional(XElement element)
{
foreach (XAttribute attribute in element.Attributes())
{
switch (attribute.Name.ToString().ToLowerInvariant())
{
case "language":
string[] languages = element.GetAttributeStringArray(attribute.Name.ToString(), new string[0]);
if (!languages.Any(l => GameMain.Config.Language.ToLower() == l.ToLower())) { return false; }
break;
case "gameversion":
var version = new Version(attribute.Value);
if (GameMain.Version != version) { return false; }
break;
case "mingameversion":
var minVersion = new Version(attribute.Value);
if (GameMain.Version < minVersion) { return false; }
break;
case "maxgameversion":
var maxVersion = new Version(attribute.Value);
if (GameMain.Version > maxVersion) { return false; }
break;
}
}
return true;
}
private static GUITextBlock LoadGUITextBlock(XElement element, RectTransform parent, string overrideText = null, Anchor? anchor = null)
{
string text = element.Attribute("text") == null ?
element.ElementInnerText() :
element.GetAttributeString("text", "");
text = text.Replace(@"\n", "\n");
string style = element.GetAttributeString("style", "");
if (style == "null") { style = null; }
Color? color = null;
if (element.Attribute("color") != null) { color = element.GetAttributeColor("color", Color.White); }
float scale = element.GetAttributeFloat("scale", 1.0f);
bool wrap = element.GetAttributeBool("wrap", true);
Alignment alignment = Alignment.Center;
Enum.TryParse(element.GetAttributeString("alignment", "Center"), out alignment);
ScalableFont font = GUI.Font;
switch (element.GetAttributeString("font", "Font").ToLowerInvariant())
{
case "font":
font = GUI.Font;
break;
case "smallfont":
font = GUI.SmallFont;
break;
case "largefont":
font = GUI.LargeFont;
break;
case "videotitlefont":
font = GUI.VideoTitleFont;
break;
case "objectivetitlefont":
font = GUI.ObjectiveTitleFont;
break;
case "objectivenamefont":
font = GUI.ObjectiveNameFont;
break;
}
var textBlock = new GUITextBlock(RectTransform.Load(element, parent),
text, color, font, alignment, wrap: wrap, style: style)
{
TextScale = scale
};
if (anchor.HasValue) { textBlock.RectTransform.SetPosition(anchor.Value); }
textBlock.RectTransform.IsFixedSize = true;
textBlock.RectTransform.NonScaledSize = new Point(textBlock.Rect.Width, textBlock.Rect.Height);
return textBlock;
}
private static GUIButton LoadLink(XElement element, RectTransform parent)
{
var button = LoadGUIButton(element, parent);
string url = element.GetAttributeString("url", "");
button.OnClicked = (btn, userdata) =>
{
try
{
System.Diagnostics.Process.Start(url);
}
catch (Exception e)
{
DebugConsole.ThrowError("Failed to open url \""+url+"\".", e);
}
return true;
};
return button;
}
private static void LoadGridText(XElement element, RectTransform parent)
{
string text = element.Attribute("text") == null ?
element.ElementInnerText() :
element.GetAttributeString("text", "");
text = text.Replace(@"\n", "\n");
string[] elements = text.Split(',');
RectTransform lineContainer = null;
for (int i = 0; i < elements.Length; i++)
{
switch (i % 3)
{
case 0:
lineContainer = LoadGUITextBlock(element, parent, elements[i], Anchor.CenterLeft).RectTransform;
lineContainer.Anchor = Anchor.TopCenter;
lineContainer.Pivot = Pivot.TopCenter;
lineContainer.NonScaledSize = new Point((int)(parent.NonScaledSize.X * 0.7f), lineContainer.NonScaledSize.Y);
break;
case 1:
LoadGUITextBlock(element, lineContainer, elements[i], Anchor.Center).TextAlignment = Alignment.Center;
break;
case 2:
LoadGUITextBlock(element, lineContainer, elements[i], Anchor.CenterRight).TextAlignment = Alignment.CenterRight;
break;
}
}
}
private static GUIFrame LoadGUIFrame(XElement element, RectTransform parent)
{
string style = element.GetAttributeString("style", element.Name.ToString().ToLowerInvariant() == "spacing" ? null : "");
if (style == "null") { style = null; }
return new GUIFrame(RectTransform.Load(element, parent), style: style);
}
private static GUIButton LoadGUIButton(XElement element, RectTransform parent)
{
string style = element.GetAttributeString("style", "");
if (style == "null") { style = null; }
Alignment textAlignment = Alignment.Center;
Enum.TryParse(element.GetAttributeString("textalignment", "Center"), out textAlignment);
string text = element.Attribute("text") == null ?
element.ElementInnerText() :
element.GetAttributeString("text", "");
text = text.Replace(@"\n", "\n");
return new GUIButton(RectTransform.Load(element, parent),
text: text,
textAlignment: textAlignment,
style: style);
}
private static GUIListBox LoadGUIListBox(XElement element, RectTransform parent)
{
string style = element.GetAttributeString("style", "");
if (style == "null") { style = null; }
bool isHorizontal = element.GetAttributeBool("ishorizontal", !element.GetAttributeBool("isvertical", true));
return new GUIListBox(RectTransform.Load(element, parent), isHorizontal, style: style);
}
private static GUILayoutGroup LoadGUILayoutGroup(XElement element, RectTransform parent)
{
bool isHorizontal = element.GetAttributeBool("ishorizontal", !element.GetAttributeBool("isvertical", true));
Enum.TryParse(element.GetAttributeString("childanchor", "TopLeft"), out Anchor childAnchor);
return new GUILayoutGroup(RectTransform.Load(element, parent), isHorizontal, childAnchor)
{
Stretch = element.GetAttributeBool("stretch", false),
RelativeSpacing = element.GetAttributeFloat("relativespacing", 0.0f),
AbsoluteSpacing = element.GetAttributeInt("absolutespacing", 0),
};
}
private static GUIImage LoadGUIImage(XElement element, RectTransform parent)
{
Sprite sprite = null;
string url = element.GetAttributeString("url", "");
if (!string.IsNullOrEmpty(url))
{
string localFileName = Path.GetFileNameWithoutExtension(url.Replace("/", "").Replace(":", "").Replace("https", "").Replace("http", ""))
.Replace(".", "");
localFileName += Path.GetExtension(url);
string localFilePath = Path.Combine("Downloads", localFileName);
if (!File.Exists(localFilePath))
{
Uri baseAddress = new Uri(url);
Uri remoteDirectory = new Uri(baseAddress, ".");
string remoteFileName = Path.GetFileName(baseAddress.LocalPath);
IRestClient client = new RestClient(remoteDirectory);
var response = client.Execute(new RestRequest(remoteFileName, Method.GET));
if (response.ResponseStatus != ResponseStatus.Completed) { return null; }
if (response.StatusCode != HttpStatusCode.OK) { return null; }
if (!Directory.Exists("Downloads")) { Directory.CreateDirectory("Downloads"); }
File.WriteAllBytes(localFilePath, response.RawBytes);
}
sprite = new Sprite(element, "Downloads", localFileName);
}
else
{
sprite = new Sprite(element);
}
return new GUIImage(RectTransform.Load(element, parent), sprite, scaleToFit: true);
}
private static GUIButton LoadAccordion(XElement element, RectTransform parent)
{
var button = LoadGUIButton(element, parent);
List<GUIComponent> content = new List<GUIComponent>();
foreach (XElement subElement in element.Elements())
{
var contentElement = FromXML(subElement, parent);
if (contentElement != null)
{
contentElement.Visible = false;
contentElement.IgnoreLayoutGroups = true;
content.Add(contentElement);
}
}
button.OnClicked = (btn, userdata) =>
{
bool visible = content.FirstOrDefault()?.Visible ?? true;
foreach (GUIComponent contentElement in content)
{
contentElement.Visible = !visible;
contentElement.IgnoreLayoutGroups = !contentElement.Visible;
}
if (button.Parent is GUILayoutGroup layoutGroup)
{
layoutGroup.Recalculate();
}
return true;
};
return button;
}
}
}
@@ -14,6 +14,12 @@ namespace Barotrauma
get { return Math.Max(400, 400 * (GameMain.GraphicsWidth / 1920)); }
}
public enum Type
{
Default,
InGame
}
public List<GUIButton> Buttons { get; private set; } = new List<GUIButton>();
//public GUIFrame BackgroundFrame { get; private set; }
public GUILayoutGroup Content { get; private set; }
@@ -22,6 +28,29 @@ namespace Barotrauma
public GUITextBlock Text { get; private set; }
public string Tag { get; private set; }
public GUIImage Icon
{
get;
private set;
}
public Color IconColor
{
get { return Icon == null ? Color.White : Icon.Color; }
set
{
if (Icon == null) { return; }
Icon.Color = value;
}
}
private bool alwaysVisible;
private float openState;
private bool closing;
private Type type;
public static GUIComponent VisibleBox => MessageBoxes.LastOrDefault();
public GUIMessageBox(string headerText, string text, Vector2? relativeSize = null, Point? minSize = null)
@@ -29,12 +58,11 @@ namespace Barotrauma
{
this.Buttons[0].OnClicked = Close;
}
public GUIMessageBox(string headerText, string text, string[] buttons, Vector2? relativeSize = null, Point? minSize = null, Alignment textAlignment = Alignment.TopLeft, string tag = "")
: base(new RectTransform(Vector2.One, GUI.Canvas, Anchor.Center), style: "")
public GUIMessageBox(string headerText, string text, string[] buttons, Vector2? relativeSize = null, Point? minSize = null, Alignment textAlignment = Alignment.TopLeft, Type type = Type.Default, string tag = "", Sprite icon = null)
: base(new RectTransform(Vector2.One, GUI.Canvas, Anchor.Center), style: GUI.Style.GetComponentStyle("GUIMessageBox." + type) != null ? "GUIMessageBox." + type : "GUIMessageBox")
{
//int width = (int)(DefaultWidth * GUI.Scale), height = 0;
int width = DefaultWidth, height = 0;
int width = (int)(DefaultWidth * (type == Type.Default ? 1.0f : 1.5f)), height = 0;
if (relativeSize.HasValue)
{
width = (int)(GameMain.GraphicsWidth * relativeSize.Value.X);
@@ -49,137 +77,198 @@ namespace Barotrauma
}
}
InnerFrame = new GUIFrame(new RectTransform(new Point(width, height), RectTransform, Anchor.Center) { IsFixedSize = false }, style: null);
InnerFrame = new GUIFrame(new RectTransform(new Point(width, height), RectTransform, type == Type.InGame ? Anchor.TopCenter : Anchor.Center) { IsFixedSize = false }, style: null);
GUI.Style.Apply(InnerFrame, "", this);
Content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.85f), InnerFrame.RectTransform, Anchor.Center)) { AbsoluteSpacing = 5 };
this.type = type;
Tag = tag;
Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform),
headerText, textAlignment: Alignment.Center, wrap: true);
GUI.Style.Apply(Header, "", this);
Header.RectTransform.MinSize = new Point(0, Header.Rect.Height);
if (!string.IsNullOrWhiteSpace(text))
if (type == Type.Default)
{
Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform),
text, textAlignment: textAlignment, wrap: true);
GUI.Style.Apply(Text, "", this);
Text.RectTransform.NonScaledSize = Text.RectTransform.MinSize = Text.RectTransform.MaxSize =
new Point(Text.Rect.Width, Text.Rect.Height);
Text.RectTransform.IsFixedSize = true;
}
Content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.85f), InnerFrame.RectTransform, Anchor.Center)) { AbsoluteSpacing = 5 };
Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform),
headerText, textAlignment: Alignment.Center, wrap: true);
GUI.Style.Apply(Header, "", this);
Header.RectTransform.MinSize = new Point(0, Header.Rect.Height);
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), Content.RectTransform, Anchor.BottomCenter, maxSize: new Point(1000, 50)),
isHorizontal: true, childAnchor: buttons.Length > 1 ? Anchor.BottomLeft : Anchor.Center)
{
AbsoluteSpacing = 5,
IgnoreLayoutGroups = true
};
buttonContainer.RectTransform.NonScaledSize = buttonContainer.RectTransform.MinSize = buttonContainer.RectTransform.MaxSize =
new Point(buttonContainer.Rect.Width, (int)(30 * GUI.Scale));
buttonContainer.RectTransform.IsFixedSize = true;
if (height == 0)
{
height += Header.Rect.Height + Content.AbsoluteSpacing;
height += (Text == null ? 0 : Text.Rect.Height) + Content.AbsoluteSpacing;
height += buttonContainer.Rect.Height;
if (minSize.HasValue)
if (!string.IsNullOrWhiteSpace(text))
{
height = Math.Max(height, minSize.Value.Y);
Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true);
GUI.Style.Apply(Text, "", this);
Text.RectTransform.NonScaledSize = Text.RectTransform.MinSize = Text.RectTransform.MaxSize =
new Point(Text.Rect.Width, Text.Rect.Height);
Text.RectTransform.IsFixedSize = true;
}
InnerFrame.RectTransform.NonScaledSize =
new Point(InnerFrame.Rect.Width, (int)Math.Max(height / Content.RectTransform.RelativeSize.Y, height + (int)(50 * GUI.yScale)));
Content.RectTransform.NonScaledSize =
new Point(Content.Rect.Width, height);
}
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), Content.RectTransform, Anchor.BottomCenter, maxSize: new Point(1000, 50)),
isHorizontal: true, childAnchor: buttons.Length > 1 ? Anchor.BottomLeft : Anchor.Center)
{
AbsoluteSpacing = 5,
IgnoreLayoutGroups = true
};
buttonContainer.RectTransform.NonScaledSize = buttonContainer.RectTransform.MinSize = buttonContainer.RectTransform.MaxSize =
new Point(buttonContainer.Rect.Width, (int)(30 * GUI.Scale));
buttonContainer.RectTransform.IsFixedSize = true;
Buttons = new List<GUIButton>(buttons.Length);
for (int i = 0; i < buttons.Length; i++)
if (height == 0)
{
height += Header.Rect.Height + Content.AbsoluteSpacing;
height += (Text == null ? 0 : Text.Rect.Height) + Content.AbsoluteSpacing;
height += buttonContainer.Rect.Height;
if (minSize.HasValue) { height = Math.Max(height, minSize.Value.Y); }
InnerFrame.RectTransform.NonScaledSize =
new Point(InnerFrame.Rect.Width, (int)Math.Max(height / Content.RectTransform.RelativeSize.Y, height + (int)(50 * GUI.yScale)));
Content.RectTransform.NonScaledSize =
new Point(Content.Rect.Width, height);
}
Buttons = new List<GUIButton>(buttons.Length);
for (int i = 0; i < buttons.Length; i++)
{
var button = new GUIButton(new RectTransform(new Vector2(Math.Min(0.9f / buttons.Length, 0.5f), 1.0f), buttonContainer.RectTransform), buttons[i], style: "GUIButtonLarge");
Buttons.Add(button);
}
}
else if (type == Type.InGame)
{
var button = new GUIButton(new RectTransform(new Vector2(Math.Min(0.9f / buttons.Length, 0.5f), 1.0f), buttonContainer.RectTransform), buttons[i], style: "GUIButtonLarge");
Buttons.Add(button);
}
InnerFrame.RectTransform.AbsoluteOffset = new Point(0, GameMain.GraphicsHeight);
alwaysVisible = true;
CanBeFocused = false;
GUI.Style.Apply(InnerFrame, "", this);
var horizontalLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.98f, 0.95f), InnerFrame.RectTransform, Anchor.Center),
isHorizontal: true, childAnchor: Anchor.CenterLeft)
{
Stretch = true,
RelativeSpacing = 0.02f
};
if (icon != null)
{
Icon = new GUIImage(new RectTransform(new Vector2(0.2f, 0.95f), horizontalLayoutGroup.RectTransform), icon, scaleToFit: true);
}
Content = new GUILayoutGroup(new RectTransform(new Vector2(icon != null ? 0.65f : 0.85f, 1.0f), horizontalLayoutGroup.RectTransform));
var buttonContainer = new GUIFrame(new RectTransform(new Vector2(0.15f, 1.0f), horizontalLayoutGroup.RectTransform), style: null);
Buttons = new List<GUIButton>(1)
{
new GUIButton(new RectTransform(new Vector2(0.5f, 0.5f), buttonContainer.RectTransform, Anchor.Center),
style: GUI.Style.GetComponentStyle("GUIButtonSolidHorizontalArrow") != null ? "GUIButtonSolidHorizontalArrow" : "GUIButtonHorizontalArrow")
{
OnClicked = Close
}
};
Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), headerText, wrap: true);
GUI.Style.Apply(Header, "", this);
Header.RectTransform.MinSize = new Point(0, Header.Rect.Height);
if (!string.IsNullOrWhiteSpace(text))
{
Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true);
GUI.Style.Apply(Text, "", this);
/*Content.Recalculate();
Text.RectTransform.NonScaledSize = Text.RectTransform.MinSize = Text.RectTransform.MaxSize =
new Point(Text.Rect.Width, Text.Rect.Height);
Text.RectTransform.IsFixedSize = true;*/
}
if (height == 0)
{
height += Header.Rect.Height + Content.AbsoluteSpacing;
height += (Text == null ? 0 : Text.Rect.Height) + Content.AbsoluteSpacing;
if (minSize.HasValue) { height = Math.Max(height, minSize.Value.Y); }
InnerFrame.RectTransform.NonScaledSize =
new Point(InnerFrame.Rect.Width, (int)Math.Max(height / Content.RectTransform.RelativeSize.Y, height + (int)(50 * GUI.yScale)));
Content.RectTransform.NonScaledSize =
new Point(Content.Rect.Width, height);
}
Buttons[0].RectTransform.MaxSize = new Point(Math.Min(Buttons[0].Rect.Width, Buttons[0].Rect.Height));
}
MessageBoxes.Add(this);
}
///// <summary>
///// This is the new constructor.
///// TODO: for some reason the background does not prohibit input on the elements that are behind the box
///// TODO: allow providing buttons in the constructor
///// </summary>
/*public GUIMessageBox(RectTransform rectT, string headerText, string text, Alignment textAlignment = Alignment.TopCenter)
: base(rectT, "")
public static void AddActiveToGUIUpdateList()
{
//BackgroundFrame = new GUIFrame(new RectTransform(new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight), rectT, Anchor.Center), null, Color.Black * 0.5f);
float headerHeight = 0.2f;
float margin = 0.05f;
InnerFrame = new GUIFrame(rectT);
GUI.Style.Apply(InnerFrame, "", this);
Header = null;
if (!string.IsNullOrWhiteSpace(headerText))
for (int i = 0; i < MessageBoxes.Count; i++)
{
Header = new GUITextBlock(new RectTransform(new Vector2(1, headerHeight), InnerFrame.RectTransform, Anchor.TopCenter)
if (MessageBoxes[i] is GUIMessageBox alwaysVisibleMsgBox && alwaysVisibleMsgBox.alwaysVisible)
{
RelativeOffset = new Vector2(0, margin)
}, headerText, textAlignment: Alignment.Center);
GUI.Style.Apply(Header, "", this);
alwaysVisibleMsgBox.AddToGUIUpdateList();
break;
}
}
if (!string.IsNullOrWhiteSpace(text))
for (int i = MessageBoxes.Count - 1; i >= 0; i--)
{
float offset = headerHeight + margin;
var size = Header == null ? Vector2.One : new Vector2(1 - margin * 2, 1 - offset + margin);
Text = new GUITextBlock(new RectTransform(size, InnerFrame.RectTransform, Anchor.TopCenter)
if (MessageBoxes[i].UserData as string == "verificationprompt" ||
MessageBoxes[i].UserData as string == "bugreporter")
{
RelativeOffset = new Vector2(0, offset)
}, text, textAlignment: textAlignment, wrap: true);
GUI.Style.Apply(Text, "", this);
continue;
}
if (!(MessageBoxes[i] is GUIMessageBox msgBox) || !msgBox.alwaysVisible)
{
MessageBoxes[i].AddToGUIUpdateList();
break;
}
}
MessageBoxes.Add(this);
}*/
}
protected override void Update(float deltaTime)
{
if (type == Type.InGame)
{
Vector2 initialPos = new Vector2(0.0f, GameMain.GraphicsHeight);
Vector2 defaultPos = new Vector2(0.0f, HUDLayoutSettings.InventoryAreaLower.Y - InnerFrame.Rect.Height - 20 * GUI.Scale);
Vector2 endPos = new Vector2(GameMain.GraphicsWidth, defaultPos.Y);
/*for (int i = MessageBoxes.IndexOf(this); i >= 0; i--)
{
if (MessageBoxes[i] is GUIMessageBox otherMsgBox && otherMsgBox != this && otherMsgBox.type == type && !otherMsgBox.closing)
{
defaultPos = new Vector2(
Math.Max(otherMsgBox.InnerFrame.RectTransform.AbsoluteOffset.X + 10 * GUI.Scale, defaultPos.X),
Math.Max(otherMsgBox.InnerFrame.RectTransform.AbsoluteOffset.Y + 10 * GUI.Scale, defaultPos.Y));
}
}*/
if (!closing)
{
InnerFrame.RectTransform.AbsoluteOffset = Vector2.SmoothStep(initialPos, defaultPos, openState).ToPoint();
openState = Math.Min(openState + deltaTime * 2.0f, 1.0f);
}
else
{
openState += deltaTime * 2.0f;
InnerFrame.RectTransform.AbsoluteOffset = Vector2.SmoothStep(defaultPos, endPos, openState - 1.0f).ToPoint();
if (openState >= 2.0f)
{
if (Parent != null) { Parent.RemoveChild(this); }
if (MessageBoxes.Contains(this)) { MessageBoxes.Remove(this); }
}
}
}
}
//public override void AddToGUIUpdateList(bool ignoreChildren = false, bool updateLast = false)
//{
// base.AddToGUIUpdateList(ignoreChildren, updateLast);
//}
//public override void Draw(SpriteBatch spriteBatch, bool drawChildren = true)
//{
// if (RectTransform == null)
// {
// base.Draw(spriteBatch, drawChildren);
// }
// else
// {
// // Custom draw order so that the background is rendered behind the parent.
// if (drawChildren)
// {
// BackgroundFrame?.Draw(spriteBatch);
// }
// base.Draw(spriteBatch, false);
// if (drawChildren)
// {
// InnerFrame?.Draw(spriteBatch);
// Header?.Draw(spriteBatch);
// Text?.Draw(spriteBatch);
// Buttons.ForEach(b => b.Draw(spriteBatch));
// }
// }
//}
public void Close()
{
if (Parent != null) Parent.RemoveChild(this);
if (MessageBoxes.Contains(this)) MessageBoxes.Remove(this);
if (type == Type.InGame)
{
closing = true;
}
else
{
if (Parent != null) { Parent.RemoveChild(this); }
if (MessageBoxes.Contains(this)) { MessageBoxes.Remove(this); }
}
}
public bool Close(GUIButton button, object obj)
{
Close();
Close();
return true;
}
@@ -30,27 +30,12 @@ namespace Barotrauma
public SpriteSheet FocusIndicator { get; private set; }
public GUIStyle(string file, GraphicsDevice graphicsDevice)
public GUIStyle(XElement element, GraphicsDevice graphicsDevice)
{
this.graphicsDevice = graphicsDevice;
componentStyles = new Dictionary<string, GUIComponentStyle>();
XDocument doc;
try
{
ToolBox.IsProperFilenameCase(file);
doc = XDocument.Load(file, LoadOptions.SetBaseUri);
if (doc == null) { throw new Exception("doc is null"); }
if (doc.Root == null) { throw new Exception("doc.Root is null"); }
if (doc.Root.Elements() == null) { throw new Exception("doc.Root.Elements() is null"); }
}
catch (Exception e)
{
DebugConsole.ThrowError("Loading style \"" + file + "\" failed", e);
return;
}
configElement = doc.Root;
foreach (XElement subElement in doc.Root.Elements())
configElement = element;
foreach (XElement subElement in configElement.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
{
@@ -40,6 +40,8 @@ namespace Barotrauma
private float textDepth;
private ScalableFont originalFont;
public Vector2 TextOffset { get; set; }
private Vector4 padding;
@@ -62,7 +64,7 @@ namespace Barotrauma
set
{
if (base.Font == value) return;
base.Font = value;
base.Font = originalFont = value;
SetTextPos();
}
}
@@ -74,13 +76,23 @@ namespace Barotrauma
{
string newText = forceUpperCase ? value?.ToUpper() : value;
if (Text == newText) return;
if (Text == newText) { return; }
//reset scale, it gets recalculated in SetTextPos
if (autoScale) textScale = 1.0f;
if (autoScale) { textScale = 1.0f; }
text = newText;
wrappedText = newText;
if (TextManager.IsCJK(text))
{
//switch to fallback CJK font
if (!Font.IsCJK) { base.Font = GUI.CJKFont; }
}
else
{
if (Font == GUI.CJKFont) { base.Font = originalFont; }
}
SetTextPos();
}
}
@@ -208,8 +220,11 @@ namespace Barotrauma
//if the text is in chinese/korean/japanese and we're not using a CJK-compatible font,
//use the default CJK font as a fallback
var selectedFont = font ?? GUI.Font;
if (TextManager.IsCJK(text) && !selectedFont.IsCJK) { selectedFont = GUI.CJKFont; }
var selectedFont = originalFont = font ?? GUI.Font;
if (TextManager.IsCJK(text) && !selectedFont.IsCJK)
{
selectedFont = GUI.CJKFont;
}
this.Font = selectedFont;
this.textAlignment = textAlignment;
this.Wrap = wrap;
@@ -162,10 +162,11 @@ namespace Barotrauma
public override ScalableFont Font
{
get { return textBlock?.Font ?? base.Font; }
set
{
base.Font = value;
if (textBlock == null) return;
if (textBlock == null) { return; }
textBlock.Font = value;
}
}
@@ -32,7 +32,7 @@ namespace Barotrauma
{
rectT = rectT ?? new RectTransform(new Vector2(0.25f, 1f), GUI.Canvas) { MinSize = new Point(340, GameMain.GraphicsHeight) };
rectT.SetPosition(Anchor.TopRight);
Parent = new GUIFrame(rectT, null, new Color(20, 20, 20, 255));
Parent = new GUIFrame(rectT, null, Color);
EditorBox = new GUIListBox(new RectTransform(Vector2.One * 0.98f, rectT, Anchor.Center), color: Color.Black, style: null)
{
Spacing = 10
@@ -49,5 +49,7 @@ namespace Barotrauma
{
EditorBox = CreateEditorBox();
}
public static Color Color = new Color(20, 20, 20, 255);
}
}
@@ -358,9 +358,9 @@ namespace Barotrauma
parent?.ChildrenChanged?.Invoke(this);
}
public static RectTransform Load(XElement element, RectTransform parent)
public static RectTransform Load(XElement element, RectTransform parent, Anchor defaultAnchor = Anchor.TopLeft)
{
Enum.TryParse(element.GetAttributeString("anchor", "Center"), out Anchor anchor);
Enum.TryParse(element.GetAttributeString("anchor", defaultAnchor.ToString()), out Anchor anchor);
Enum.TryParse(element.GetAttributeString("pivot", anchor.ToString()), out Pivot pivot);
Point? minSize = null, maxSize = null;
@@ -368,11 +368,7 @@ namespace Barotrauma
//if (element.Attribute("maxsize") != null) maxSize = element.GetAttributePoint("maxsize", new Point(1000, 1000));
RectTransform rectTransform;
if (element.Attribute("relativesize") != null)
{
rectTransform = new RectTransform(element.GetAttributeVector2("relativesize", Vector2.One), parent, anchor, pivot, minSize, maxSize);
}
else
if (element.Attribute("absolutesize") != null)
{
rectTransform = new RectTransform(element.GetAttributePoint("absolutesize", new Point(1000, 1000)), parent, anchor, pivot)
{
@@ -380,6 +376,10 @@ namespace Barotrauma
maxSize = maxSize
};
}
else
{
rectTransform = new RectTransform(element.GetAttributeVector2("relativesize", Vector2.One), parent, anchor, pivot, minSize, maxSize);
}
rectTransform.RelativeOffset = element.GetAttributeVector2("relativeoffset", Vector2.Zero);
rectTransform.AbsoluteOffset = element.GetAttributePoint("absoluteoffset", Point.Zero);
return rectTransform;