public void RecreateFrameContents()
            {
                var info = CharacterInfo;

                HeadSelectionList = null;
                parentComponent.ClearChildren();
                ClearSprites();

                float contentWidth = HasIcon ? 0.75f : 1.0f;
                var   listBox      = new GUIListBox(
                    new RectTransform(new Vector2(contentWidth, 1.0f), parentComponent.RectTransform,
                                      Anchor.CenterLeft))
                {
                    CanBeFocused = false, CanTakeKeyBoardFocus = false
                };
                var content = listBox.Content;

                info.LoadHeadAttachments();
                if (HasIcon)
                {
                    info.CreateIcon(
                        new RectTransform(new Vector2(0.25f, 1.0f), parentComponent.RectTransform, Anchor.CenterRight)
                    {
                        RelativeOffset = new Vector2(-0.01f, 0.0f)
                    });
                }

                RectTransform createItemRectTransform(string labelTag, float width = 0.6f)
                {
                    var layoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.166f), content.RectTransform));

                    var label = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), layoutGroup.RectTransform),
                                                 TextManager.Get(labelTag), font: GUI.SubHeadingFont);

                    var bottomItem = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.5f), layoutGroup.RectTransform),
                                                  style: null);

                    return(new RectTransform(new Vector2(width, 1.0f), bottomItem.RectTransform, Anchor.Center));
                }

                RectTransform genderItemRT = createItemRectTransform("Gender", 1.0f);

                GUILayoutGroup genderContainer =
                    new GUILayoutGroup(genderItemRT, isHorizontal: true)
                {
                    Stretch         = true,
                    RelativeSpacing = 0.05f
                };

                void createGenderButton(Gender gender)
                {
                    new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), genderContainer.RectTransform),
                                  TextManager.Get(gender.ToString()), style: "ListBoxElement")
                    {
                        UserData  = gender,
                        OnClicked = OpenHeadSelection,
                        Selected  = info.Gender == gender
                    };
                }

                createGenderButton(Gender.Male);
                createGenderButton(Gender.Female);

                int countAttachmentsOfType(WearableType wearableType)
                => info.FilterByTypeAndHeadID(
                    info.FilterElementsByGenderAndRace(info.Wearables, info.Head.gender, info.Head.race),
                    wearableType, info.HeadSpriteId).Count();

                List <GUIScrollBar> attachmentSliders = new List <GUIScrollBar>();

                void createAttachmentSlider(int initialValue, WearableType wearableType)
                {
                    int attachmentCount = countAttachmentsOfType(wearableType);

                    if (attachmentCount > 0)
                    {
                        var labelTag = wearableType == WearableType.FaceAttachment
                            ? "FaceAttachment.Accessories"
                            : $"FaceAttachment.{wearableType}";
                        var sliderItemRT = createItemRectTransform(labelTag);
                        var slider       =
                            new GUIScrollBar(sliderItemRT, style: "GUISlider")
                        {
                            Range      = new Vector2(0, attachmentCount),
                            StepValue  = 1,
                            OnMoved    = (bar, scroll) => SwitchAttachment(bar, wearableType),
                            OnReleased = OnSliderReleased,
                            BarSize    = 1.0f / (float)(attachmentCount + 1)
                        };
                        slider.BarScrollValue = initialValue;
                        attachmentSliders.Add(slider);
                    }
                }

                createAttachmentSlider(info.HairIndex, WearableType.Hair);
                createAttachmentSlider(info.BeardIndex, WearableType.Beard);
                createAttachmentSlider(info.MoustacheIndex, WearableType.Moustache);
                createAttachmentSlider(info.FaceAttachmentIndex, WearableType.FaceAttachment);

                void createColorSelector(string labelTag, IEnumerable <(Color Color, float Commonness)> options, Func <Color> getter,
                                         Action <Color> setter)
                {
                    var selectorItemRT = createItemRectTransform(labelTag, 0.4f);
                    var dropdown       =
                        new GUIDropDown(selectorItemRT)
                    {
                        AllowNonText = true
                    };

                    var listBoxSize = dropdown.ListBox.RectTransform.RelativeSize;

                    dropdown.ListBox.RectTransform.RelativeSize = new Vector2(listBoxSize.X * 1.75f, listBoxSize.Y);
                    var dropdownButton = dropdown.GetChild <GUIButton>();
                    var buttonFrame    =
                        new GUIFrame(
                            new RectTransform(Vector2.One * 0.7f, dropdownButton.RectTransform, Anchor.CenterLeft)
                    {
                        RelativeOffset = new Vector2(0.05f, 0.0f)
                    }, style: null);
                    Color?previewingColor = null;

                    dropdown.OnSelected = (component, color) =>
                    {
                        previewingColor = null;
                        setter((Color)color);
                        buttonFrame.Color      = getter();
                        buttonFrame.HoverColor = getter();
                        return(true);
                    };
                    buttonFrame.Color      = getter();
                    buttonFrame.HoverColor = getter();

                    dropdown.ListBox.UseGridLayout = true;
                    foreach (var option in options)
                    {
                        var optionElement =
                            new GUIFrame(
                                new RectTransform(new Vector2(0.25f, 1.0f / 3.0f),
                                                  dropdown.ListBox.Content.RectTransform),
                                style: "ListBoxElement")
                        {
                            UserData     = option.Color,
                            CanBeFocused = true
                        };
                        var colorElement =
                            new GUIFrame(
                                new RectTransform(Vector2.One * 0.75f, optionElement.RectTransform, Anchor.Center,
                                                  scaleBasis: ScaleBasis.Smallest),
                                style: null)
                        {
                            Color        = option.Color,
                            HoverColor   = option.Color,
                            OutlineColor = Color.Lerp(Color.Black, option.Color, 0.5f),
                            CanBeFocused = false
                        };
                    }

                    var childToSelect = dropdown.ListBox.Content.FindChild(c => (Color)c.UserData == getter());

                    dropdown.Select(dropdown.ListBox.Content.GetChildIndex(childToSelect));

                    //The following exists to track mouseover to preview colors before selecting them
                    new GUICustomComponent(new RectTransform(Vector2.One, buttonFrame.RectTransform),
                                           onUpdate: (deltaTime, component) =>
                    {
                        if (GUI.MouseOn is GUIFrame {
                            Parent: { } p
                        } hoveredFrame&& dropdown.ListBox.Content.IsParentOf(hoveredFrame))
                        {
                            previewingColor ??= getter();
                            Color color = (Color)(dropdown.ListBox.Content.FindChild(c =>
                                                                                     c == hoveredFrame || c.IsParentOf(hoveredFrame))?.UserData ?? dropdown.SelectedData ?? getter());
                            setter(color);
                            buttonFrame.Color      = getter();
                            buttonFrame.HoverColor = getter();
                        }
        public CampaignSetupUI(bool isMultiplayer, GUIComponent newGameContainer, GUIComponent loadGameContainer, IEnumerable <SubmarineInfo> submarines, IEnumerable <string> saveFiles = null)
        {
            this.isMultiplayer     = isMultiplayer;
            this.newGameContainer  = newGameContainer;
            this.loadGameContainer = loadGameContainer;

            var columnContainer = new GUILayoutGroup(new RectTransform(Vector2.One, newGameContainer.RectTransform), isHorizontal: true)
            {
                Stretch         = true,
                RelativeSpacing = isMultiplayer ? 0.0f : 0.02f
            };

            var leftColumn = new GUILayoutGroup(new RectTransform(Vector2.One, columnContainer.RectTransform))
            {
                Stretch         = true,
                RelativeSpacing = 0.015f
            };

            var rightColumn = new GUILayoutGroup(new RectTransform(isMultiplayer ? Vector2.Zero : new Vector2(1.5f, 1.0f), columnContainer.RectTransform))
            {
                Stretch         = true,
                RelativeSpacing = 0.015f
            };

            columnContainer.Recalculate();

            // New game left side
            new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform)
            {
                MinSize = new Point(0, 20)
            }, TextManager.Get("SaveName"), font: GUI.SubHeadingFont);
            saveNameBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform)
            {
                MinSize = new Point(0, 20)
            }, string.Empty)
            {
                textFilterFunction = (string str) => { return(ToolBox.RemoveInvalidFileNameChars(str)); }
            };

            new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform)
            {
                MinSize = new Point(0, 20)
            }, TextManager.Get("MapSeed"), font: GUI.SubHeadingFont);
            seedBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform)
            {
                MinSize = new Point(0, 20)
            }, ToolBox.RandomSeed(8));

            if (!isMultiplayer)
            {
                new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform)
                {
                    MinSize = new Point(0, 20)
                }, TextManager.Get("SelectedSub"), font: GUI.SubHeadingFont);

                var moddedDropdown = new GUIDropDown(new RectTransform(new Vector2(1f, 0.02f), leftColumn.RectTransform), "", 3);
                moddedDropdown.AddItem(TextManager.Get("clientpermission.all"), CategoryFilter.All);
                moddedDropdown.AddItem(TextManager.Get("servertag.modded.false"), CategoryFilter.Vanilla);
                moddedDropdown.AddItem(TextManager.Get("customrank"), CategoryFilter.Custom);
                moddedDropdown.Select(0);

                var filterContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform), isHorizontal: true)
                {
                    Stretch = true
                };

                subList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.65f), leftColumn.RectTransform))
                {
                    ScrollBarVisible = true
                };

                var searchTitle = new GUITextBlock(new RectTransform(new Vector2(0.001f, 1.0f), filterContainer.RectTransform), TextManager.Get("serverlog.filter"), textAlignment: Alignment.CenterLeft, font: GUI.Font);
                var searchBox   = new GUITextBox(new RectTransform(new Vector2(1.0f, 1.0f), filterContainer.RectTransform, Anchor.CenterRight), font: GUI.Font, createClearButton: true);
                filterContainer.RectTransform.MinSize = searchBox.RectTransform.MinSize;
                searchBox.OnSelected    += (sender, userdata) => { searchTitle.Visible = false; };
                searchBox.OnDeselected  += (sender, userdata) => { searchTitle.Visible = true; };
                searchBox.OnTextChanged += (textBox, text) => { FilterSubs(subList, text); return(true); };

                moddedDropdown.OnSelected = (component, data) =>
                {
                    searchBox.Text = string.Empty;
                    subFilter      = (CategoryFilter)data;
                    UpdateSubList(SubmarineInfo.SavedSubmarines);
                    return(true);
                };

                subList.OnSelected = OnSubSelected;
            }
            else // Spacing to fix the multiplayer campaign setup layout
            {
                CreateMultiplayerCampaignSubList(leftColumn.RectTransform);

                //spacing
                //new GUIFrame(new RectTransform(new Vector2(1.0f, 0.25f), leftColumn.RectTransform), style: null);
            }

            // New game right side
            subPreviewContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), rightColumn.RectTransform))
            {
                Stretch = true
            };

            var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.12f),
                                                                       (isMultiplayer ? leftColumn : rightColumn).RectTransform)
            {
                MaxSize = new Point(int.MaxValue, 60)
            }, childAnchor: Anchor.BottomRight, isHorizontal: true);

            if (!isMultiplayer)
            {
                buttonContainer.IgnoreLayoutGroups = true;
            }

            StartButton = new GUIButton(new RectTransform(new Vector2(0.4f, 1f), buttonContainer.RectTransform, Anchor.BottomRight)
            {
                MaxSize = new Point(350, 60)
            }, TextManager.Get("StartCampaignButton"))
            {
                OnClicked = (GUIButton btn, object userData) =>
                {
                    if (string.IsNullOrWhiteSpace(saveNameBox.Text))
                    {
                        saveNameBox.Flash(GUI.Style.Red);
                        return(false);
                    }

                    SubmarineInfo selectedSub = null;

                    if (!isMultiplayer)
                    {
                        if (!(subList.SelectedData is SubmarineInfo))
                        {
                            return(false);
                        }
                        selectedSub = subList.SelectedData as SubmarineInfo;
                    }
                    else
                    {
                        if (GameMain.NetLobbyScreen.SelectedSub == null)
                        {
                            return(false);
                        }
                        selectedSub = GameMain.NetLobbyScreen.SelectedSub;
                    }

                    if (selectedSub.SubmarineClass == SubmarineClass.Undefined)
                    {
                        new GUIMessageBox(TextManager.Get("error"), TextManager.Get("undefinedsubmarineselected"));
                        return(false);
                    }

                    if (string.IsNullOrEmpty(selectedSub.MD5Hash.Hash))
                    {
                        ((GUITextBlock)subList.SelectedComponent).TextColor = Color.DarkRed * 0.8f;
                        subList.SelectedComponent.CanBeFocused = false;
                        subList.Deselect();
                        return(false);
                    }

                    string savePath = SaveUtil.CreateSavePath(isMultiplayer ? SaveUtil.SaveType.Multiplayer : SaveUtil.SaveType.Singleplayer, saveNameBox.Text);
                    bool   hasRequiredContentPackages = selectedSub.RequiredContentPackagesInstalled;

                    if (selectedSub.HasTag(SubmarineTag.Shuttle) || !hasRequiredContentPackages)
                    {
                        if (!hasRequiredContentPackages)
                        {
                            var msgBox = new GUIMessageBox(TextManager.Get("ContentPackageMismatch"),
                                                           TextManager.GetWithVariable("ContentPackageMismatchWarning", "[requiredcontentpackages]", string.Join(", ", selectedSub.RequiredContentPackages)),
                                                           new string[] { TextManager.Get("Yes"), TextManager.Get("No") });

                            msgBox.Buttons[0].OnClicked  = msgBox.Close;
                            msgBox.Buttons[0].OnClicked += (button, obj) =>
                            {
                                if (GUIMessageBox.MessageBoxes.Count == 0)
                                {
                                    StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text);
                                    if (isMultiplayer)
                                    {
                                        CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup");
                                    }
                                }
                                return(true);
                            };

                            msgBox.Buttons[1].OnClicked = msgBox.Close;
                        }

                        if (selectedSub.HasTag(SubmarineTag.Shuttle))
                        {
                            var msgBox = new GUIMessageBox(TextManager.Get("ShuttleSelected"),
                                                           TextManager.Get("ShuttleWarning"),
                                                           new string[] { TextManager.Get("Yes"), TextManager.Get("No") });

                            msgBox.Buttons[0].OnClicked = (button, obj) =>
                            {
                                StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text);
                                if (isMultiplayer)
                                {
                                    CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup");
                                }
                                return(true);
                            };
                            msgBox.Buttons[0].OnClicked += msgBox.Close;

                            msgBox.Buttons[1].OnClicked = msgBox.Close;
                            return(false);
                        }
                    }
                    else
                    {
                        StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text);
                        if (isMultiplayer)
                        {
                            CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup");
                        }
                    }

                    return(true);
                }
            };

            InitialMoneyText = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1f), buttonContainer.RectTransform), "",
                                                font: isMultiplayer ? GUI.Style.SmallFont : GUI.Style.Font, textColor: GUI.Style.Green)
            {
                TextGetter = () =>
                {
                    int initialMoney = CampaignMode.InitialMoney;
                    if (isMultiplayer)
                    {
                        if (GameMain.NetLobbyScreen.SelectedSub != null)
                        {
                            initialMoney -= GameMain.NetLobbyScreen.SelectedSub.Price;
                        }
                    }
                    else if (subList.SelectedData is SubmarineInfo subInfo)
                    {
                        initialMoney -= subInfo.Price;
                    }
                    initialMoney = Math.Max(initialMoney, isMultiplayer ? MultiPlayerCampaign.MinimumInitialMoney : 0);
                    return(TextManager.GetWithVariable("campaignstartingmoney", "[money]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", initialMoney)));
                }
            };

            if (!isMultiplayer)
            {
                var disclaimerBtn = new GUIButton(new RectTransform(new Vector2(1.0f, 0.8f), rightColumn.RectTransform, Anchor.TopRight)
                {
                    AbsoluteOffset = new Point(5)
                }, style: "GUINotificationButton")
                {
                    IgnoreLayoutGroups = true,
                    OnClicked          = (btn, userdata) => { GameMain.Instance.ShowCampaignDisclaimer(); return(true); }
                };
                disclaimerBtn.RectTransform.MaxSize = new Point((int)(30 * GUI.Scale));
            }

            columnContainer.Recalculate();
            leftColumn.Recalculate();
            rightColumn.Recalculate();

            if (submarines != null)
            {
                UpdateSubList(submarines);
            }
            UpdateLoadMenu(saveFiles);
        }
Exemple #3
0
        private void CreateFirstPage(GUILayoutGroup firstPageLayout, IEnumerable <SubmarineInfo> submarines)
        {
            firstPageLayout.RelativeSpacing = 0.02f;

            var columnContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.9f), firstPageLayout.RectTransform), isHorizontal: true)
            {
                Stretch         = true,
                RelativeSpacing = 0.02f
            };

            var leftColumn = new GUILayoutGroup(new RectTransform(Vector2.One, columnContainer.RectTransform))
            {
                Stretch         = true,
                RelativeSpacing = 0.015f
            };

            var rightColumn = new GUILayoutGroup(new RectTransform(new Vector2(1.5f, 1.0f), columnContainer.RectTransform))
            {
                Stretch         = true,
                RelativeSpacing = 0.015f
            };

            columnContainer.Recalculate();

            // New game left side
            new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform)
            {
                MinSize = new Point(0, 20)
            }, TextManager.Get("SaveName"), font: GUI.SubHeadingFont);
            saveNameBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform)
            {
                MinSize = new Point(0, 20)
            }, string.Empty)
            {
                textFilterFunction = (string str) => { return(ToolBox.RemoveInvalidFileNameChars(str)); }
            };

            new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform)
            {
                MinSize = new Point(0, 20)
            }, TextManager.Get("MapSeed"), font: GUI.SubHeadingFont);
            seedBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform)
            {
                MinSize = new Point(0, 20)
            }, ToolBox.RandomSeed(8));

            new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform)
            {
                MinSize = new Point(0, 20)
            }, TextManager.Get("SelectedSub"), font: GUI.SubHeadingFont);

            var moddedDropdown = new GUIDropDown(new RectTransform(new Vector2(1f, 0.02f), leftColumn.RectTransform), "", 3);

            moddedDropdown.AddItem(TextManager.Get("clientpermission.all"), CategoryFilter.All);
            moddedDropdown.AddItem(TextManager.Get("servertag.modded.false"), CategoryFilter.Vanilla);
            moddedDropdown.AddItem(TextManager.Get("customrank"), CategoryFilter.Custom);
            moddedDropdown.Select(0);

            var filterContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform), isHorizontal: true)
            {
                Stretch = true
            };

            subList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.65f), leftColumn.RectTransform))
            {
                ScrollBarVisible = true
            };

            var searchTitle = new GUITextBlock(new RectTransform(new Vector2(0.001f, 1.0f), filterContainer.RectTransform), TextManager.Get("serverlog.filter"), textAlignment: Alignment.CenterLeft, font: GUI.Font);
            var searchBox   = new GUITextBox(new RectTransform(new Vector2(1.0f, 1.0f), filterContainer.RectTransform, Anchor.CenterRight), font: GUI.Font, createClearButton: true);

            filterContainer.RectTransform.MinSize = searchBox.RectTransform.MinSize;
            searchBox.OnSelected    += (sender, userdata) => { searchTitle.Visible = false; };
            searchBox.OnDeselected  += (sender, userdata) => { searchTitle.Visible = true; };
            searchBox.OnTextChanged += (textBox, text) => { FilterSubs(subList, text); return(true); };

            moddedDropdown.OnSelected = (component, data) =>
            {
                searchBox.Text = string.Empty;
                subFilter      = (CategoryFilter)data;
                UpdateSubList(SubmarineInfo.SavedSubmarines);
                return(true);
            };

            subList.OnSelected = OnSubSelected;

            // New game right side
            subPreviewContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), rightColumn.RectTransform))
            {
                Stretch = true
            };

            var firstPageButtonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.08f),
                                                                                firstPageLayout.RectTransform), childAnchor: Anchor.BottomLeft, isHorizontal: true)
            {
                RelativeSpacing = 0.025f
            };

            InitialMoneyText = new GUITextBlock(new RectTransform(new Vector2(0.3f, 1f), firstPageButtonContainer.RectTransform), "", font: GUI.Style.Font, textColor: GUI.Style.Green, textAlignment: Alignment.CenterLeft)
            {
                TextGetter = () =>
                {
                    int initialMoney = CampaignMode.InitialMoney;
                    if (subList.SelectedData is SubmarineInfo subInfo)
                    {
                        initialMoney -= subInfo.Price;
                    }
                    initialMoney = Math.Max(initialMoney, 0);
                    return(TextManager.GetWithVariable("campaignstartingmoney", "[money]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", initialMoney)));
                }
            };

            CampaignCustomizeButton = new GUIButton(new RectTransform(new Vector2(0.25f, 1f), firstPageButtonContainer.RectTransform, Anchor.CenterLeft), TextManager.Get("SettingsButton"))
            {
                OnClicked = (tb, userdata) =>
                {
                    CreateCustomizeWindow();
                    return(true);
                }
            };

            nextButton = new GUIButton(new RectTransform(new Vector2(0.4f, 1f), firstPageButtonContainer.RectTransform, Anchor.BottomRight), TextManager.Get("Next"))
            {
                OnClicked = (GUIButton btn, object userData) =>
                {
                    SetPage(1);
                    return(false);
                }
            };

            var disclaimerBtn = new GUIButton(new RectTransform(new Vector2(1.0f, 0.8f), rightColumn.RectTransform, Anchor.TopRight)
            {
                AbsoluteOffset = new Point(5)
            }, style: "GUINotificationButton")
            {
                IgnoreLayoutGroups = true,
                OnClicked          = (btn, userdata) => { GameMain.Instance.ShowCampaignDisclaimer(); return(true); }
            };

            disclaimerBtn.RectTransform.MaxSize = new Point((int)(30 * GUI.Scale));

            columnContainer.Recalculate();
            leftColumn.Recalculate();
            rightColumn.Recalculate();

            if (submarines != null)
            {
                UpdateSubList(submarines);
            }
        }
Exemple #4
0
        public static void Init()
        {
            backgroundFrame = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas), style: null)
            {
                Color         = Color.Black * 0.5f,
                HoverColor    = Color.Black * 0.5f,
                SelectedColor = Color.Black * 0.5f,
                PressedColor  = Color.Black * 0.5f,
            };

            window = new GUIFrame(new RectTransform(Vector2.One * 0.8f, backgroundFrame.RectTransform, Anchor.Center));

            var horizontalLayout = new GUILayoutGroup(new RectTransform(Vector2.One * 0.9f, window.RectTransform, Anchor.Center), true);

            sidebar = new GUIListBox(new RectTransform(new Vector2(0.29f, 1.0f), horizontalLayout.RectTransform));

            var drives = DriveInfo.GetDrives();

            foreach (var drive in drives)
            {
                if (drive.DriveType == DriveType.Ram)
                {
                    continue;
                }
                if (ignoredDrivePrefixes.Any(p => drive.Name.StartsWith(p)))
                {
                    continue;
                }
                new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), sidebar.Content.RectTransform), drive.Name.Replace('\\', '/'));
            }

            sidebar.OnSelected = (child, userdata) =>
            {
                CurrentDirectory = (child as GUITextBlock).Text;

                return(false);
            };

            //spacing between sidebar and fileListLayout
            new GUIFrame(new RectTransform(new Vector2(0.01f, 1.0f), horizontalLayout.RectTransform), style: null);

            var fileListLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.7f, 1.0f), horizontalLayout.RectTransform));
            var firstRow       = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.04f), fileListLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);

            new GUIButton(new RectTransform(new Vector2(0.05f, 1.0f), firstRow.RectTransform), "^")
            {
                OnClicked = MoveToParentDirectory
            };
            directoryBox = new GUITextBox(new RectTransform(new Vector2(0.7f, 1.0f), firstRow.RectTransform))
            {
                OverflowClip   = true,
                OnEnterPressed = (tb, txt) =>
                {
                    if (Directory.Exists(txt))
                    {
                        CurrentDirectory = txt;
                        return(true);
                    }
                    else
                    {
                        tb.Text = CurrentDirectory;
                        return(false);
                    }
                }
            };
            filterBox = new GUITextBox(new RectTransform(new Vector2(0.25f, 1.0f), firstRow.RectTransform))
            {
                OverflowClip = true
            };
            firstRow.RectTransform.MinSize = new Point(0, firstRow.RectTransform.Children.Max(c => c.MinSize.Y));

            filterBox.OnTextChanged += (txtbox, txt) =>
            {
                RefreshFileList();
                return(true);
            };
            //spacing between rows
            new GUIFrame(new RectTransform(new Vector2(1.0f, 0.01f), fileListLayout.RectTransform), style: null);

            fileList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.85f), fileListLayout.RectTransform))
            {
                OnSelected = (child, userdata) =>
                {
                    if (userdata == null)
                    {
                        return(false);
                    }

                    var fileName = (child as GUITextBlock).Text;
                    fileBox.Text = fileName;
                    if (PlayerInput.DoubleClicked())
                    {
                        bool isDir = (userdata as bool?).Value;
                        if (isDir)
                        {
                            CurrentDirectory += fileName;
                        }
                        else
                        {
                            OnFileSelected?.Invoke(CurrentDirectory + fileName);
                            Open = false;
                        }
                    }

                    return(true);
                }
            };

            //spacing between rows
            new GUIFrame(new RectTransform(new Vector2(1.0f, 0.01f), fileListLayout.RectTransform), style: null);

            var thirdRow = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.04f), fileListLayout.RectTransform), true);

            fileBox = new GUITextBox(new RectTransform(new Vector2(0.7f, 1.0f), thirdRow.RectTransform))
            {
                OnEnterPressed = (tb, txt) => openButton?.OnClicked?.Invoke(openButton, null) ?? false
            };

            fileTypeDropdown = new GUIDropDown(new RectTransform(new Vector2(0.3f, 1.0f), thirdRow.RectTransform), dropAbove: true)
            {
                OnSelected = (child, userdata) =>
                {
                    currentFileTypePattern = (child as GUITextBlock).UserData as string;
                    RefreshFileList();

                    return(true);
                }
            };

            fileTypeDropdown.Select(4);

            //spacing between rows
            new GUIFrame(new RectTransform(new Vector2(1.0f, 0.01f), fileListLayout.RectTransform), style: null);
            var fourthRow = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.04f), fileListLayout.RectTransform), true);

            //padding for open/cancel buttons
            new GUIFrame(new RectTransform(new Vector2(0.7f, 1.0f), fourthRow.RectTransform), style: null);

            openButton = new GUIButton(new RectTransform(new Vector2(0.15f, 1.0f), fourthRow.RectTransform), TextManager.Get("opensubbutton"))
            {
                OnClicked = (btn, obj) =>
                {
                    if (Directory.Exists(Path.Combine(CurrentDirectory, fileBox.Text)))
                    {
                        CurrentDirectory += fileBox.Text;
                    }
                    if (!File.Exists(CurrentDirectory + fileBox.Text))
                    {
                        return(false);
                    }
                    OnFileSelected?.Invoke(CurrentDirectory + fileBox.Text);
                    Open = false;
                    return(false);
                }
            };
            new GUIButton(new RectTransform(new Vector2(0.15f, 1.0f), fourthRow.RectTransform), TextManager.Get("cancel"))
            {
                OnClicked = (btn, obj) =>
                {
                    Open = false;
                    return(false);
                }
            };

            CurrentDirectory = Directory.GetCurrentDirectory();
        }