(d9829ac) v0.9.4.0
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user