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, string iconStyle = "", Sprite backgroundIcon = null) : base(new RectTransform(GUI.Canvas.RelativeSize, GUI.Canvas, Anchor.Center), style: GUI.Style.GetComponentStyle("GUIMessageBox." + type) != null ? "GUIMessageBox." + type : "GUIMessageBox") { int width = (int)(DefaultWidth * (type == Type.Default ? 1.0f : 1.5f)), height = 0; if (relativeSize.HasValue) { width = (int)(GameMain.GraphicsWidth * relativeSize.Value.X); height = (int)(GameMain.GraphicsHeight * relativeSize.Value.Y); } if (minSize.HasValue) { width = Math.Max(width, minSize.Value.X); if (height > 0) { height = Math.Max(height, minSize.Value.Y); } } if (backgroundIcon != null) { BackgroundIcon = new GUIImage(new RectTransform(backgroundIcon.size.ToPoint(), RectTransform), backgroundIcon) { IgnoreLayoutGroups = true, Color = Color.Transparent }; } Anchor anchor = type switch { Type.InGame => Anchor.TopCenter, Type.Vote => Anchor.TopRight, _ => Anchor.Center }; InnerFrame = new GUIFrame(new RectTransform(new Point(width, height), RectTransform, anchor) { IsFixedSize = false }, style: null); if (type == Type.Vote) { int offset = GUI.IntScale(64); InnerFrame.RectTransform.ScreenSpaceOffset = new Point(-offset, offset); CanBeFocused = false; } GUI.Style.Apply(InnerFrame, "", this); this.type = type; Tag = tag; if (type == Type.Default || type == Type.Vote) { 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, font: GUI.SubHeadingFont, textAlignment: Alignment.Center, 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); Text.RectTransform.NonScaledSize = Text.RectTransform.MinSize = Text.RectTransform.MaxSize = new Point(Text.Rect.Width, Text.Rect.Height); Text.RectTransform.IsFixedSize = true; } var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), Content.RectTransform, Anchor.BottomCenter), childAnchor: Anchor.TopCenter) { AbsoluteSpacing = 5, IgnoreLayoutGroups = true }; int buttonSize = 35; var buttonStyle = GUI.Style.GetComponentStyle("GUIButton"); if (buttonStyle != null && buttonStyle.Height.HasValue) { buttonSize = buttonStyle.Height.Value; } buttonContainer.RectTransform.NonScaledSize = buttonContainer.RectTransform.MinSize = buttonContainer.RectTransform.MaxSize = new Point(buttonContainer.Rect.Width, (int)((buttonSize + 5) * buttons.Length)); 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 + 20; 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(0.6f, 1.0f / buttons.Length), buttonContainer.RectTransform), buttons[i]); Buttons.Add(button); } } else if (type == Type.InGame) { InnerFrame.RectTransform.AbsoluteOffset = new Point(0, GameMain.GraphicsHeight); alwaysVisible = true; CanBeFocused = false; AutoClose = true; 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); } else if (iconStyle != string.Empty) { Icon = new GUIImage(new RectTransform(new Vector2(0.2f, 0.95f), horizontalLayoutGroup.RectTransform), iconStyle, 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.3f, 0.5f), buttonContainer.RectTransform, Anchor.Center), style: "UIToggleButton") { OnClicked = Close } }; InputType?closeInput = null; if (GameMain.Config.KeyBind(InputType.Use).MouseButton == MouseButton.None) { closeInput = InputType.Use; } else if (GameMain.Config.KeyBind(InputType.Select).MouseButton == MouseButton.None) { closeInput = InputType.Select; } if (closeInput.HasValue) { Buttons[0].ToolTip = TextManager.ParseInputTypes($"{TextManager.Get("Close")} ([InputType.{closeInput.Value}])"); Buttons[0].OnAddedToGUIUpdateList += (GUIComponent component) => { if (!closing && openState >= 1.0f && PlayerInput.KeyHit(closeInput.Value)) { GUIButton btn = component as GUIButton; btn?.OnClicked(btn, btn.UserData); btn?.Flash(GUI.Style.Green); } }; } 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 (string.IsNullOrWhiteSpace(headerText)) { Content.ChildAnchor = Anchor.Center; } } 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((int)(0.4f * Buttons[0].Rect.Y), Buttons[0].Rect.Y); } MessageBoxes.Add(this); }
void AssignActionsToButtons(List <GUIButton> optionButtons, GUIMessageBox target) { if (!options.Any()) { GUIButton closeButton = new GUIButton(new RectTransform(Vector2.One, target.InnerFrame.RectTransform, Anchor.BottomRight, scaleBasis: ScaleBasis.Smallest) { MaxSize = new Point(GUI.IntScale(24)), MinSize = new Point(24), AbsoluteOffset = new Point(GUI.IntScale(48), GUI.IntScale(16)) }, style: "GUIButtonVerticalArrow") { UserData = "ContinueButton", IgnoreLayoutGroups = true, Bounce = true, OnClicked = (btn, userdata) => { if (actionInstance != null) { actionInstance.selectedOption = 0; } else if (actionId.HasValue) { SendResponse(actionId.Value, 0); } if (!continueConversation) { target.Close(); } else { btn.Frame.FadeOut(0.33f, true); } return(true); } }; double allowCloseTime = Timing.TotalTime + 0.5; closeButton.Children.ForEach(child => child.SpriteEffects = SpriteEffects.FlipVertically); closeButton.Frame.FadeIn(0.5f, 0.5f); closeButton.SlideIn(0.5f, 0.33f, 16, SlideDirection.Down); InputType?closeInput = null; if (GameMain.Config.KeyBind(InputType.Use).MouseButton == MouseButton.None) { closeInput = InputType.Use; } else if (GameMain.Config.KeyBind(InputType.Select).MouseButton == MouseButton.None) { closeInput = InputType.Select; } if (closeInput.HasValue) { closeButton.ToolTip = TextManager.ParseInputTypes($"{TextManager.Get("Close")} ([InputType.{closeInput.Value}])"); closeButton.OnAddedToGUIUpdateList += (GUIComponent component) => { if (Timing.TotalTime > allowCloseTime && PlayerInput.KeyHit(closeInput.Value)) { GUIButton btn = component as GUIButton; btn?.OnClicked(btn, btn.UserData); btn?.Flash(GUI.Style.Green); } }; } } for (int i = 0; i < optionButtons.Count; i++) { optionButtons[i].UserData = i; optionButtons[i].OnClicked += (btn, userdata) => { int selectedOption = (userdata as int?) ?? 0; if (actionInstance != null) { actionInstance.selectedOption = selectedOption; foreach (GUIButton otherButton in optionButtons) { otherButton.CanBeFocused = false; if (otherButton != btn) { otherButton.TextBlock.OverrideTextColor(Color.DarkGray * 0.8f); } } btn.ExternalHighlight = true; return(true); } if (actionId.HasValue) { SendResponse(actionId.Value, selectedOption); btn.CanBeFocused = false; btn.ExternalHighlight = true; foreach (GUIButton otherButton in optionButtons) { otherButton.CanBeFocused = false; if (otherButton != btn) { otherButton.TextBlock.OverrideTextColor(Color.DarkGray * 0.8f); } } return(true); } //should not happen return(false); }; if (closingOptions.Contains(i)) { optionButtons[i].OnClicked += target.Close; } } }