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;
                    }
                }
            }
        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);
        }
Exemple #3
0
        public override void Draw(SpriteBatch spriteBatch)
        {
            if (overlayColor.A > 0)
            {
                if (overlaySprite != null)
                {
                    GUI.DrawRectangle(spriteBatch, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.Black * (overlayColor.A / 255.0f), isFilled: true);
                    float scale = Math.Max(GameMain.GraphicsWidth / overlaySprite.size.X, GameMain.GraphicsHeight / overlaySprite.size.Y);
                    overlaySprite.Draw(spriteBatch, new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight) / 2, overlayColor, overlaySprite.size / 2, scale: scale);
                }
                else
                {
                    GUI.DrawRectangle(spriteBatch, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), overlayColor, isFilled: true);
                }
                if (!string.IsNullOrEmpty(overlayText) && overlayTextColor.A > 0)
                {
                    var     backgroundSprite = GUI.Style.GetComponentStyle("CommandBackground").GetDefaultSprite();
                    Vector2 centerPos        = new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight) / 2;
                    string  wrappedText      = ToolBox.WrapText(overlayText, GameMain.GraphicsWidth / 3, GUI.Font);
                    Vector2 textSize         = GUI.Font.MeasureString(wrappedText);
                    Vector2 textPos          = centerPos - textSize / 2;
                    backgroundSprite.Draw(spriteBatch,
                                          centerPos,
                                          Color.White * (overlayTextColor.A / 255.0f),
                                          origin: backgroundSprite.size / 2,
                                          rotate: 0.0f,
                                          scale: new Vector2(GameMain.GraphicsWidth / 2 / backgroundSprite.size.X, textSize.Y / backgroundSprite.size.Y * 1.5f));

                    GUI.DrawString(spriteBatch, textPos + Vector2.One, wrappedText, Color.Black * (overlayTextColor.A / 255.0f));
                    GUI.DrawString(spriteBatch, textPos, wrappedText, overlayTextColor);

                    if (!string.IsNullOrEmpty(overlayTextBottom))
                    {
                        Vector2 bottomTextPos = centerPos + new Vector2(0.0f, textSize.Y / 2 + 40 * GUI.Scale) - GUI.Font.MeasureString(overlayTextBottom) / 2;
                        GUI.DrawString(spriteBatch, bottomTextPos + Vector2.One, overlayTextBottom, Color.Black * (overlayTextColor.A / 255.0f));
                        GUI.DrawString(spriteBatch, bottomTextPos, overlayTextBottom, overlayTextColor);
                    }
                }
            }

            if (GUI.DisableHUD || GUI.DisableUpperHUD || ForceMapUI || CoroutineManager.IsCoroutineRunning("LevelTransition"))
            {
                endRoundButton.Visible = false;
                if (ReadyCheckButton != null)
                {
                    ReadyCheckButton.Visible = false;
                }
                return;
            }
            if (Submarine.MainSub == null || Level.Loaded == null)
            {
                return;
            }

            endRoundButton.Visible = false;
            var    availableTransition = GetAvailableTransition(out _, out Submarine leavingSub);
            string buttonText          = "";

            switch (availableTransition)
            {
            case TransitionType.ProgressToNextLocation:
            case TransitionType.ProgressToNextEmptyLocation:
                if (Level.Loaded.EndOutpost == null || !Level.Loaded.EndOutpost.DockedTo.Contains(leavingSub))
                {
                    string textTag = availableTransition == TransitionType.ProgressToNextLocation ? "EnterLocation" : "EnterEmptyLocation";
                    buttonText             = TextManager.GetWithVariable(textTag, "[locationname]", Level.Loaded.EndLocation?.Name ?? "[ERROR]");
                    endRoundButton.Visible = !ForceMapUI && !ShowCampaignUI;
                }
                break;

            case TransitionType.LeaveLocation:
                buttonText             = TextManager.GetWithVariable("LeaveLocation", "[locationname]", Level.Loaded.StartLocation?.Name ?? "[ERROR]");
                endRoundButton.Visible = !ForceMapUI && !ShowCampaignUI;
                break;

            case TransitionType.ReturnToPreviousLocation:
            case TransitionType.ReturnToPreviousEmptyLocation:
                if (Level.Loaded.StartOutpost == null || !Level.Loaded.StartOutpost.DockedTo.Contains(leavingSub))
                {
                    string textTag = availableTransition == TransitionType.ReturnToPreviousLocation ? "EnterLocation" : "EnterEmptyLocation";
                    buttonText             = TextManager.GetWithVariable(textTag, "[locationname]", Level.Loaded.StartLocation?.Name ?? "[ERROR]");
                    endRoundButton.Visible = !ForceMapUI && !ShowCampaignUI;
                }

                break;

            case TransitionType.None:
            default:
                if (Level.Loaded.Type == LevelData.LevelType.Outpost &&
                    (Character.Controlled?.Submarine?.Info.Type == SubmarineType.Player || (Character.Controlled?.CurrentHull?.OutpostModuleTags.Contains("airlock") ?? false)))
                {
                    buttonText             = TextManager.GetWithVariable("LeaveLocation", "[locationname]", Level.Loaded.StartLocation?.Name ?? "[ERROR]");
                    endRoundButton.Visible = !ForceMapUI && !ShowCampaignUI;
                }
                else
                {
                    endRoundButton.Visible = false;
                }
                break;
            }

            if (ReadyCheckButton != null)
            {
                ReadyCheckButton.Visible = endRoundButton.Visible;
            }

            if (endRoundButton.Visible)
            {
                if (!AllowedToEndRound())
                {
                    buttonText = TextManager.Get("map");
                }
                else if (prevCampaignUIAutoOpenType != availableTransition &&
                         (availableTransition == TransitionType.ProgressToNextEmptyLocation || availableTransition == TransitionType.ReturnToPreviousEmptyLocation))
                {
                    HintManager.OnAvailableTransition(availableTransition);
                    //opening the campaign map pauses the game and prevents HintManager from running -> update it manually to get the hint to show up immediately
                    HintManager.Update();
                    Map.SelectLocation(-1);
                    endRoundButton.OnClicked(EndRoundButton, null);
                    prevCampaignUIAutoOpenType = availableTransition;
                }
                endRoundButton.Text = ToolBox.LimitString(buttonText, endRoundButton.Font, endRoundButton.Rect.Width - 5);
                if (endRoundButton.Text != buttonText)
                {
                    endRoundButton.ToolTip = buttonText;
                }
                if (Character.Controlled?.CharacterHealth?.SuicideButton?.Visible ?? false)
                {
                    endRoundButton.RectTransform.ScreenSpaceOffset = new Point(0, Character.Controlled.CharacterHealth.SuicideButton.Rect.Height);
                }
                else if (GameMain.Client != null && GameMain.Client.IsFollowSubTickBoxVisible)
                {
                    endRoundButton.RectTransform.ScreenSpaceOffset = new Point(0, HUDLayoutSettings.Padding + GameMain.Client.FollowSubTickBox.Rect.Height);
                }
                else
                {
                    endRoundButton.RectTransform.ScreenSpaceOffset = Point.Zero;
                }
            }
            endRoundButton.DrawManually(spriteBatch);
            if (this is MultiPlayerCampaign && ReadyCheckButton != null)
            {
                ReadyCheckButton.RectTransform.ScreenSpaceOffset = endRoundButton.RectTransform.ScreenSpaceOffset;
                ReadyCheckButton.DrawManually(spriteBatch);
            }
        }