private DialogGUIToggleButton[] CreateMissionListItems()
        {
            List <DialogGUIToggleButton> list = new List <DialogGUIToggleButton>();
            DialogGUIVerticalLayout      dialogGUIVerticalLayout;
            DialogGUIToggleButton        dialogGUIToggleButton;
            List <QuickLaunchMission>    missions = quickLaunchVessel.GetMissions();

            for (int i = 0; i < missions.Count; i++)
            {
                int missionIndex           = i;
                QuickLaunchMission mission = missions[missionIndex];

                dialogGUIToggleButton = new DialogGUIToggleButton(false, string.Empty, delegate
                {
                    SelectItem(missionIndex);
                }, -1f, 1f);

                dialogGUIVerticalLayout = new DialogGUIVerticalLayout(true, false, 0f, new RectOffset(4, 4, 4, 4), TextAnchor.UpperLeft);
                dialogGUIVerticalLayout.AddChild(new DialogGUILabel(mission.missionName, skin.customStyles[0], true, false));
                DialogGUIVerticalLayout dialogGUIVerticalLayout2 = dialogGUIVerticalLayout;
                Orbit         orbit     = mission.protoVessel.orbitSnapShot.Load();
                CelestialBody body      = orbit.referenceBody;
                string        orbitBody = string.Format("<color=#ffffff>Orbiting {0}</color>", body.name);
                dialogGUIVerticalLayout2.AddChild(new DialogGUILabel(orbitBody, skin.customStyles[0], true, false));
                string orbitInfo = string.Format("<color=#ffffff>Ap: {0}, Pe: {1}, Inc: {2}</color>", Utils.FormatAltitude(orbit.ApA), Utils.FormatAltitude(orbit.PeA), Math.Round(orbit.inclination, 3));
                dialogGUIVerticalLayout.AddChild(new DialogGUILabel(orbitInfo, skin.customStyles[0], true, false));

                dialogGUIToggleButton.AddChild(dialogGUIVerticalLayout);
                dialogGUIToggleButton.OptionInteractableCondition = (() => true);
                list.Add(dialogGUIToggleButton);
            }
            return(list.ToArray());
        }
        private DialogGUIHorizontalLayout createConstellationRow(Constellation thisConstellation)
        {
            Color color = Constellation.getColor(thisConstellation.frequency);

            DialogGUIImage        colorImage     = new DialogGUIImage(new Vector2(32, 32), Vector2.zero, thisConstellation.color, colorTexture);
            DialogGUILabel        constNameLabel = new DialogGUILabel(thisConstellation.name, 170, 12);
            DialogGUILabel        freqLabel      = new DialogGUILabel(Localizer.Format("#CNC_Generic_FrequencyLabel") + string.Format(": <color={0}>{1}</color>", UIUtils.colorToHex(color), thisConstellation.frequency), 100, 12); //Frequency
            DialogGUILabel        numSatsLabel   = new DialogGUILabel(Localizer.Format("#CNC_ConstellationControl_numSatsLabel", Constellation.countVessels(thisConstellation)), 75, 12);                                            //string.Format("{0} vessels", )
            DialogGUIButton       updateButton   = new DialogGUIButton(Localizer.Format("#CNC_Generic_Editbutton"), delegate { editConstellationClick(thisConstellation); }, 50, 32, false);                                         //"Edit"
            DialogGUIToggleButton toggleButton   = new DialogGUIToggleButton(thisConstellation.visibility, Localizer.Format("#CNC_Generic_Mapbutton"), delegate { toggleConstellationVisibility(thisConstellation); }, 45, 32);      //"Map"

            DialogGUIBase[] rowGUIBase = new DialogGUIBase[] { colorImage, constNameLabel, freqLabel, numSatsLabel, toggleButton, updateButton, null };
            if (thisConstellation.frequency == CNCSettings.Instance.PublicRadioFrequency)
            {
                rowGUIBase[rowGUIBase.Length - 1] = new DialogGUIButton(Localizer.Format("#CNC_Generic_Resetbutton"), resetPublicConstClick, 60, 32, false);//"Reset"
            }
            else
            {
                rowGUIBase[rowGUIBase.Length - 1] = new DialogGUIButton(Localizer.Format("#CNC_Generic_DeleteButton"), delegate { deleteConstellationClick(thisConstellation); }, 60, 32, false);//"Delete"
            }
            DialogGUIHorizontalLayout constellationGroup = new DialogGUIHorizontalLayout(true, false, 4, new RectOffset(), TextAnchor.MiddleCenter, rowGUIBase);

            constellationGroup.SetOptionText(thisConstellation.frequency.ToString()); //for quick identification
            return(constellationGroup);
        }
        public static DialogGUIToggleButton GUIToggleButton(Boolean set, String lbel, Callback <Boolean> selected, Single w = -1f, Single h = 1f, Modifier <DialogGUIToggleButton> modifier = null)
        {
            DialogGUIToggleButton element = new DialogGUIToggleButton(set, lbel, selected, w, h);

            if (modifier != null)
            {
                element = modifier(element);
            }
            _elements.Add(element);
            return(element);
        }
        protected DialogGUIBase DrawTabbedDialog()
        {
            DialogGUIBase[] buttons = new DialogGUIBase[this.allTabTitles.Length];
            for (int i = 0; i < buttons.Length; ++i)
            {
                var thisTab = this.allTabTitles[i];
                buttons[i] = new DialogGUIToggleButton(this.selectedTabTitle == thisTab, thisTab, (isSet) => { this.selectedTabTitle = thisTab; this.Redraw(); }, w: buttonWidth, h: buttonHeight);
            }

            return(new DialogGUIVerticalLayout(new DialogGUIHorizontalLayout(buttons), this.DrawTab(this.selectedTabTitle)));
        }
        public static DialogGUIToggleButton GUIToggleButton(Func <Boolean> set, String lbel, Callback <Boolean> selected, Single w, Single h, Action optionBuilder, Modifier <DialogGUIToggleButton> modifier = null)
        {
            DialogGUIToggleButton element = new DialogGUIToggleButton(set, lbel, selected, w, h);

            element.AddChildren(Declare(optionBuilder));
            if (modifier != null)
            {
                element = modifier(element);
            }
            _elements.Add(element);
            return(element);
        }
        /////////////////////
        // GROUND STATIONS
        /////////////////////

        /////////////////////
        // GUI
        private List <DialogGUIBase> getGroundstationContentLayout()
        {
            List <DialogGUIBase> stationComponments = new List <DialogGUIBase>();

            //toggle button for ground station markers
            DialogGUIToggleButton     toggleStationButton = new DialogGUIToggleButton(CNCCommNetScenario.Instance.hideGroundStations, Localizer.Format("#CNC_ConstellationControl_toggleStationButton"), delegate(bool b) { CNCCommNetScenario.Instance.hideGroundStations = !CNCCommNetScenario.Instance.hideGroundStations; }, 60, 25);//"Hide all station markers"
            DialogGUIHorizontalLayout toggleStationGroup  = new DialogGUIHorizontalLayout(true, false, 4, new RectOffset(), TextAnchor.MiddleCenter, new DialogGUIBase[] { new DialogGUIFlexibleSpace(), toggleStationButton, new DialogGUIFlexibleSpace() });

            stationComponments.Add(toggleStationGroup);

            List <DialogGUIHorizontalLayout> rows = populateGroundStationRows();

            for (int i = 0; i < rows.Count; i++)
            {
                stationComponments.Add(rows[i]);
            }

            return(stationComponments);
        }
        /////////////////////
        // CONSTELLATIONS
        /////////////////////

        /////////////////////
        // GUI
        private List <DialogGUIBase> getConstellationContentLayout()
        {
            List <DialogGUIBase> constellationComponments = new List <DialogGUIBase>();

            DialogGUIButton           createButton      = new DialogGUIButton(Localizer.Format("#CNC_ConstellationControl_createButton"), newConstellationClick, false);                                                                                                                                               //"New constellation"
            DialogGUIToggleButton     toggleOrbitButton = new DialogGUIToggleButton(CNCSettings.Instance.LegacyOrbitLineColor, Localizer.Format("#CNC_ConstellationControl_toggleOrbitButton"), delegate(bool b) { CNCSettings.Instance.LegacyOrbitLineColor = !CNCSettings.Instance.LegacyOrbitLineColor; }, 35, 25); //"Toggle colorized orbits"
            DialogGUIHorizontalLayout creationGroup     = new DialogGUIHorizontalLayout(true, false, 4, new RectOffset(), TextAnchor.MiddleLeft, new DialogGUIBase[] { new DialogGUIFlexibleSpace(), createButton, new DialogGUIFlexibleSpace() });
            DialogGUIHorizontalLayout toggleGroup       = new DialogGUIHorizontalLayout(true, false, 4, new RectOffset(), TextAnchor.MiddleLeft, new DialogGUIBase[] { new DialogGUIFlexibleSpace(), toggleOrbitButton, new DialogGUIFlexibleSpace() });

            constellationComponments.Add(creationGroup);
            constellationComponments.Add(toggleGroup);

            for (int i = 0; i < CNCCommNetScenario.Instance.constellations.Count; i++)
            {
                constellationComponments.Add(createConstellationRow(CNCCommNetScenario.Instance.constellations[i]));
            }

            return(constellationComponments);
        }
        public void Show(Part part)
        {
            if (IsVisible())
            {
                Hide();
                newPart = part;
                return;
            }

            LoadCfgFile();

            this.part = part;

            DialogGUISpace        spaceAxisLeft        = new DialogGUISpace(30f);
            DialogGUISpace        spaceAxisCenter      = new DialogGUISpace(115f);
            DialogGUISpace        spaceAxisRight       = new DialogGUISpace(120f);
            DialogGUISpace        spaceTransform       = new DialogGUISpace(15f);
            DialogGUIButton       buttonReferenceSpace = new DialogGUIButton(GetReferenceSpaceLabel, ToggleReferenceSpace, 100f, LINE_HEIGHT, false);
            DialogGUILabel        labelX                 = new DialogGUILabel(FormatLabel("X"), LINE_HEIGHT);
            DialogGUILabel        labelY                 = new DialogGUILabel(FormatLabel("Y"), LINE_HEIGHT);
            DialogGUILabel        labelZ                 = new DialogGUILabel(FormatLabel("Z"), LINE_HEIGHT);
            DialogGUILabel        labelMinusPlus         = new DialogGUILabel(FormatLabel("- / +"), LINE_HEIGHT);
            DialogGUILabel        labelPosition          = new DialogGUILabel(FormatLabel("Position"), LABEL_WIDTH);
            DialogGUILabel        labelRotation          = new DialogGUILabel(FormatLabel("Rotation"), LABEL_WIDTH);
            DialogGUITextInput    inputPositionX         = new DialogGUITextInput("", false, MAXLENGTH, delegate(string value) { return(SetPosition(0, value)); }, delegate { return(GetPosition(0)); }, TMP_InputField.ContentType.DecimalNumber, LINE_HEIGHT);
            DialogGUITextInput    inputPositionY         = new DialogGUITextInput("", false, MAXLENGTH, delegate(string value) { return(SetPosition(1, value)); }, delegate { return(GetPosition(1)); }, TMP_InputField.ContentType.DecimalNumber, LINE_HEIGHT);
            DialogGUITextInput    inputPositionZ         = new DialogGUITextInput("", false, MAXLENGTH, delegate(string value) { return(SetPosition(2, value)); }, delegate { return(GetPosition(2)); }, TMP_InputField.ContentType.DecimalNumber, LINE_HEIGHT);
            DialogGUITextInput    inputDeltaPosition     = new DialogGUITextInput("", false, MAXLENGTH, delegate(string value) { return(SetDeltaPosition(value)); }, delegate { return(deltaPosition.ToString(FORMAT)); }, TMP_InputField.ContentType.DecimalNumber, LINE_HEIGHT);
            DialogGUITextInput    inputRotationX         = new DialogGUITextInput("", false, MAXLENGTH, delegate(string value) { return(SetRotation(0, value)); }, delegate { return(GetRotation(0)); }, TMP_InputField.ContentType.DecimalNumber, LINE_HEIGHT);
            DialogGUITextInput    inputRotationY         = new DialogGUITextInput("", false, MAXLENGTH, delegate(string value) { return(SetRotation(1, value)); }, delegate { return(GetRotation(1)); }, TMP_InputField.ContentType.DecimalNumber, LINE_HEIGHT);
            DialogGUITextInput    inputRotationZ         = new DialogGUITextInput("", false, MAXLENGTH, delegate(string value) { return(SetRotation(2, value)); }, delegate { return(GetRotation(2)); }, TMP_InputField.ContentType.DecimalNumber, LINE_HEIGHT);
            DialogGUITextInput    inputDeltaRotation     = new DialogGUITextInput("", false, MAXLENGTH, delegate(string value) { return(SetDeltaRotation(value)); }, delegate { return(deltaRotation.ToString(FORMAT)); }, TMP_InputField.ContentType.DecimalNumber, LINE_HEIGHT);
            DialogGUIButton       buttonPosXMinus        = new DialogGUIButton("-", delegate { Translate(0, true); }, LINE_HEIGHT, LINE_HEIGHT, false);
            DialogGUIButton       buttonPosXPlus         = new DialogGUIButton("+", delegate { Translate(0, false); }, LINE_HEIGHT, LINE_HEIGHT, false);
            DialogGUIButton       buttonPosYMinus        = new DialogGUIButton("-", delegate { Translate(1, true); }, LINE_HEIGHT, LINE_HEIGHT, false);
            DialogGUIButton       buttonPosYPlus         = new DialogGUIButton("+", delegate { Translate(1, false); }, LINE_HEIGHT, LINE_HEIGHT, false);
            DialogGUIButton       buttonPosZMinus        = new DialogGUIButton("-", delegate { Translate(2, true); }, LINE_HEIGHT, LINE_HEIGHT, false);
            DialogGUIButton       buttonPosZPlus         = new DialogGUIButton("+", delegate { Translate(2, false); }, LINE_HEIGHT, LINE_HEIGHT, false);
            DialogGUIButton       buttonDeltaPosDiv      = new DialogGUIButton("/10", delegate { SetDeltaPosition((deltaPosition / 10).ToString()); }, 35f, LINE_HEIGHT, false);
            DialogGUIButton       buttonDeltaPosMult     = new DialogGUIButton("×10", delegate { SetDeltaPosition((deltaPosition * 10).ToString()); }, 35f, LINE_HEIGHT, false);
            DialogGUIButton       buttonRotXMinus        = new DialogGUIButton("-", delegate { Rotate(0, true); }, LINE_HEIGHT, LINE_HEIGHT, false);
            DialogGUIButton       buttonRotXPlus         = new DialogGUIButton("+", delegate { Rotate(0, false); }, LINE_HEIGHT, LINE_HEIGHT, false);
            DialogGUIButton       buttonRotYMinus        = new DialogGUIButton("-", delegate { Rotate(1, true); }, LINE_HEIGHT, LINE_HEIGHT, false);
            DialogGUIButton       buttonRotYPlus         = new DialogGUIButton("+", delegate { Rotate(1, false); }, LINE_HEIGHT, LINE_HEIGHT, false);
            DialogGUIButton       buttonRotZMinus        = new DialogGUIButton("-", delegate { Rotate(2, true); }, LINE_HEIGHT, LINE_HEIGHT, false);
            DialogGUIButton       buttonRotZPlus         = new DialogGUIButton("+", delegate { Rotate(2, false); }, LINE_HEIGHT, LINE_HEIGHT, false);
            DialogGUIButton       buttonDeltaRotDiv      = new DialogGUIButton("/10", delegate { SetDeltaRotation((deltaRotation / 10).ToString()); }, 35f, LINE_HEIGHT, false);
            DialogGUIButton       buttonDeltaRotMult     = new DialogGUIButton("×10", delegate { SetDeltaRotation((deltaRotation * 10).ToString()); }, 35f, LINE_HEIGHT, false);
            DialogGUIToggleButton toggleButtonAttachment = new DialogGUIToggleButton(showAttachment, "Attachment Rules", delegate { ToggleAttachment(); }, -1, LINE_HEIGHT);
            DialogGUIToggleButton toggleButtonColliders  = new DialogGUIToggleButton(showColliders, "Colliders", delegate { ToggleColliders(); }, -1, LINE_HEIGHT);
            DialogGUISpace        spaceToCenter          = new DialogGUISpace(-1);
            DialogGUIButton       buttonClose            = new DialogGUIButton("Close", delegate { CloseWindow(); }, 140f, LINE_HEIGHT, true);

            List <DialogGUIBase> dialogGUIBaseList = new List <DialogGUIBase>
            {
                new DialogGUIHorizontalLayout(TextAnchor.MiddleCenter, buttonReferenceSpace, spaceAxisLeft, labelX, spaceAxisCenter, labelY, spaceAxisCenter, labelZ, spaceAxisRight, labelMinusPlus),
                new DialogGUIHorizontalLayout(TextAnchor.MiddleCenter, labelPosition, buttonPosXMinus, inputPositionX, buttonPosXPlus, spaceTransform, buttonPosYMinus, inputPositionY, buttonPosYPlus, spaceTransform, buttonPosZMinus, inputPositionZ, buttonPosZPlus, spaceTransform, buttonDeltaPosDiv, inputDeltaPosition, buttonDeltaPosMult),
                new DialogGUIHorizontalLayout(TextAnchor.MiddleCenter, labelRotation, buttonRotXMinus, inputRotationX, buttonRotXPlus, spaceTransform, buttonRotYMinus, inputRotationY, buttonRotYPlus, spaceTransform, buttonRotZMinus, inputRotationZ, buttonRotZPlus, spaceTransform, buttonDeltaRotDiv, inputDeltaRotation, buttonDeltaRotMult)
            };

            if (part.isCompund)
            {
                DialogGUILabel  labelCompound  = new DialogGUILabel(FormatLabel("Anchor"), LABEL_WIDTH);
                DialogGUIButton buttonCompound = new DialogGUIButton(GetCompoundLabel, ToggleCompound, 100f, LINE_HEIGHT, false);
                dialogGUIBaseList.Add(new DialogGUIHorizontalLayout(TextAnchor.MiddleCenter, labelCompound, buttonCompound));
            }
            dialogGUIBaseList.Add(new DialogGUIHorizontalLayout(toggleButtonAttachment, toggleButtonColliders));
            dialogGUIBaseList.Add(new DialogGUIHorizontalLayout(spaceToCenter, buttonClose, spaceToCenter));

            string windowTitle = FormatLabel("Precise Editor - ") + part.partInfo.title;

            dialog      = new MultiOptionDialog("partEditionDialog", "", windowTitle, HighLogic.UISkin, dialogRect, new DialogGUIVerticalLayout(dialogGUIBaseList.ToArray()));
            popupDialog = PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), dialog, false, HighLogic.UISkin, false);
            popupDialog.onDestroy.AddListener(SaveWindowPosition);
            popupDialog.onDestroy.AddListener(RemoveControlLock);
            popupDialog.onDestroy.AddListener(OnPopupDialogDestroy);

            SetTextInputColor(inputPositionX, axisLines.red);
            SetTextInputColor(inputPositionY, axisLines.green);
            SetTextInputColor(inputPositionZ, axisLines.cyan);
            SetTextInputColor(inputRotationX, axisLines.red);
            SetTextInputColor(inputRotationY, axisLines.green);
            SetTextInputColor(inputRotationZ, axisLines.cyan);

            SetTextInputListeners(inputPositionX);
            SetTextInputListeners(inputPositionY);
            SetTextInputListeners(inputPositionZ);
            SetTextInputListeners(inputRotationX);
            SetTextInputListeners(inputRotationY);
            SetTextInputListeners(inputRotationZ);
            SetTextInputListeners(inputDeltaPosition);
            SetTextInputListeners(inputDeltaRotation);

            if (showAttachment)
            {
                attachmentWindow.Show(part);
            }

            if (showColliders)
            {
                colliderWindow.Show(part);
            }

            axisLines.Show(part, referenceSpace, compoundTargetSelected);
        }
Beispiel #9
0
        private void ButtonOnTrue()
        {
            // Store labels in separate data structure for easy access when updating
            labelMap.Clear();
            List <LifeSupportReportable> modules =
                FlightGlobals.ActiveVessel.FindPartModulesImplementing <LifeSupportReportable>();
            // Calculate once on window generation, instead of each frame
            bool buttonEnable = !FlightGlobals.ActiveVessel.isEVA &&
                                FlightGlobals.ActiveVessel.HasModule <Cons2LSModule>();
            // Cell padding
            RectOffset offset            = new RectOffset(20, 0, 10, 0);
            DialogGUIVerticalLayout vert = new DialogGUIVerticalLayout(
                false, false, 1f,
                new RectOffset(), TextAnchor.UpperLeft);

            DialogGUIBase[] vertHeader;

            if (compress)
            {
                vertHeader = new DialogGUIBase[2]
                {
                    new DialogGUILabel("<b>Kerbal</b>", true, true),
                    new DialogGUILabel("<b>Life Support</b>", true, true)
                };
            }
            else
            {
                vertHeader = new DialogGUIBase[4]
                {
                    new DialogGUILabel("<b>Kerbal</b>", true, true),
                    new DialogGUILabel("<b>Ship Life Support</b>", true, true),
                    new DialogGUILabel("<b>Suit Life Support</b>", true, true),
                    new DialogGUILabel("", true, true)
                };
            }

            vert.AddChild(
                new DialogGUIGridLayout(new RectOffset(),
                                        new Vector2(cellWidth, 20),
                                        Vector2.zero,
                                        UnityEngine.UI.GridLayoutGroup.Corner.UpperLeft,
                                        UnityEngine.UI.GridLayoutGroup.Axis.Horizontal,
                                        TextAnchor.MiddleLeft,
                                        UnityEngine.UI.GridLayoutGroup.Constraint.FixedColumnCount,
                                        compress ? 2 : 4,
                                        vertHeader
                                        ));

            emptyPartLabels.Clear();

            DialogGUILabel emptyLabel = new DialogGUILabel("", true, true);

            foreach (LifeSupportReportable module in modules)
            {
                if (module.part.protoModuleCrew.Count == 0)
                {
                    emptyPartLabels.Add(module.part, new DialogGUILabel("EE", true, true));
                    continue;
                }

                List <ProtoCrewMember> crew        = new List <ProtoCrewMember>(module.part.protoModuleCrew);
                List <DialogGUIBase>   kerbalCells = new List <DialogGUIBase>();
                crew.Sort(CompareCrewNames);
                vert.AddChild(new DialogGUILabel($"{ORANGE}<b>{module.part.partInfo.title}</b></color>"));

                foreach (ProtoCrewMember kerbal in crew)
                {
                    GUIElements elems = new GUIElements(kerbal, buttonEnable);
                    labelMap.Add(kerbal.name, elems);
                    kerbalCells.Add(elems.nameLabel);
                    kerbalCells.Add(elems.shipLS);
                    if (!compress)
                    {
                        elems.nameLabel.SetOptionText(kerbal.name);
                        kerbalCells.Add(elems.evaLS);
                        kerbalCells.Add(elems.fillEVAButton);
                    }

                    // Add raw EVA tracking values
                    if (Config.DEBUG_SHOW_EVA)
                    {
                        kerbalCells.Add(emptyLabel);
                        kerbalCells.Add(elems.evaLS_Value);
                        kerbalCells.Add(elems.evaProp);
                        kerbalCells.Add(emptyLabel);
                    }
                }

                vert.AddChild(
                    new DialogGUIGridLayout(new RectOffset(),
                                            new Vector2(cellWidth, 20),
                                            Vector2.zero,
                                            UnityEngine.UI.GridLayoutGroup.Corner.UpperLeft,
                                            UnityEngine.UI.GridLayoutGroup.Axis.Horizontal,
                                            TextAnchor.MiddleLeft,
                                            UnityEngine.UI.GridLayoutGroup.Constraint.FixedColumnCount,
                                            compress ? 2 : 4,
                                            kerbalCells.ToArray()));
            }

            if (emptyPartLabels.Count > 0 && !compress)
            {
                vert.AddChild(new DialogGUISpace(20));

                foreach (Part part in emptyPartLabels.Keys)
                {
                    vert.AddChild(
                        new DialogGUIGridLayout(new RectOffset(),
                                                new Vector2(cellWidth * 2, 20),
                                                Vector2.zero,
                                                UnityEngine.UI.GridLayoutGroup.Corner.UpperLeft,
                                                UnityEngine.UI.GridLayoutGroup.Axis.Horizontal,
                                                TextAnchor.MiddleLeft,
                                                UnityEngine.UI.GridLayoutGroup.Constraint.FixedColumnCount, 2,
                                                new DialogGUILabel($"{ORANGE}{part.partInfo.title}</color>"),
                                                emptyPartLabels[part]
                                                ));
                }
            }

            // How can the SizeUp() -> RefreshGUI() -> OnButtonTrue() dependency
            // be altered to make these fields static, so that they don't have
            // to be re-initialized each time?
            sizeUpButton   = new DialogGUIButton("+", SizeUp, CanSizeUp, buttonHeight, buttonHeight, false);
            sizeDownButton = new DialogGUIButton("-", SizeDown, CanSizeDown, buttonHeight, buttonHeight, false);

            DialogGUIToggleButton compressButton = new DialogGUIToggleButton(
                compress, "Minimize", ToggleCompressGUI, w: 70, h: buttonHeight);
            DialogGUIHorizontalLayout compressLayout = new DialogGUIHorizontalLayout(
                false, true, 0f, noOffset, TextAnchor.MiddleLeft,
                compressButton, sizeDownButton, sizeUpButton);

            riskToggle = new DialogGUIToggle(
                EVALifeSupportTracker.AllowUnsafeActivity,
                "Allow unsafe crew transfer",
                RiskButtonSelected);
            riskLayout = new DialogGUIHorizontalLayout(
                0f, 0f, 0f, noOffset, TextAnchor.MiddleLeft,
                riskToggle);

            // Define the header which contains additional info
            // (status, Consumables)
            DialogGUIGridLayout statusGrid =
                new DialogGUIGridLayout(noOffset,
                                        new Vector2(cellWidth * (compress ? 1 : 2), 25),
                                        Vector2.zero,
                                        UnityEngine.UI.GridLayoutGroup.Corner.UpperLeft,
                                        UnityEngine.UI.GridLayoutGroup.Axis.Horizontal,
                                        TextAnchor.MiddleLeft,
                                        UnityEngine.UI.GridLayoutGroup.Constraint.FixedColumnCount, 2,
                                        statusLabel, compressLayout);

            // Contains the statusGrid and the "unsafe" toggle
            DialogGUIGridLayout masterGrid =
                new DialogGUIGridLayout(statusOffset,
                                        new Vector2(cellWidth * (compress ? 2 : 4), 25),
                                        new Vector2(0f, 5f),
                                        UnityEngine.UI.GridLayoutGroup.Corner.UpperLeft,
                                        UnityEngine.UI.GridLayoutGroup.Axis.Horizontal,
                                        TextAnchor.MiddleLeft,
                                        UnityEngine.UI.GridLayoutGroup.Constraint.FixedColumnCount, 1,
                                        statusGrid, riskLayout);

            // Set up the pop window
            size.x = compress ? 270 : 470;
            MultiOptionDialog multi = new MultiOptionDialog(
                "lifesupport_readout",
                "",
                "LifeSupport Readout",
                UISkinManager.defaultSkin,
                new Rect(position, size),
                masterGrid,
                new DialogGUIScrollList(Vector2.zero, false, true,
                                        new DialogGUIVerticalLayout(false, false, 1f,
                                                                    offset, TextAnchor.UpperLeft,
                                                                    new DialogGUIContentSizer(
                                                                        UnityEngine.UI.ContentSizeFitter.FitMode.Unconstrained,
                                                                        UnityEngine.UI.ContentSizeFitter.FitMode.PreferredSize,
                                                                        true),
                                                                    vert)));

            gui = PopupDialog.SpawnPopupDialog(
                multi,
                false,
                UISkinManager.defaultSkin,
                false,
                "");

            showgui = true;
            drewgui = false;
        }
        /// <summary>
        /// Generates and spawns the Upgrade Editor UI.
        /// </summary>
        public PopupDialog GenerateUpgradeEditorUI()
        {
            upgrade_editor.Clear();
            upgrade_line.Clear();
            upgrade_editor.Add(new DialogGUIHorizontalLayout(new DialogGUISpace(50), new DialogGUILabel("Upgrade"), new DialogGUISpace(150), new DialogGUILabel("Changes"), new DialogGUISpace(250), new DialogGUILabel("Description")));
            upgrade_editor.Add(new DialogGUISpace(4));


            // create one line with toggle upgrade button, all modules affected and description for every upgrade in the selected part
            for (int cns = 0; cns < allupgrades.Count; cns++)
            {
                var affected_modules = new List <string>();
                foreach (PartModule yapm in part.Modules)
                {
                    if (yapm.HasUpgrades())
                    {
                        foreach (ConfigNode ymup in yapm.upgrades)
                        {
                            if (ymup.GetValue("name__") == allupgrades[cns].GetValue("name__"))
                            {
                                affected_modules.Add(yapm.GetModuleDisplayName() + " => " + ymup.GetValue("description__"));
                            }
                        }
                    }
                }

                // Using PartUpgradeManager.Handler to access the Upgrade as located in the Tech Tree referred
                // in the PartModules and find out its in-game name and description.
                var nameforcurrentupgrade = allupgrades[cns].GetValue("name__");
                var currentupgrade        = PartUpgradeManager.Handler.GetUpgrade(nameforcurrentupgrade);

                if (affected_modules[0] == " => ")
                {
                    affected_modules[0] = "See general description for details";
                }

                var single_upgrade_button = new DialogGUIToggleButton(() => !ListOfTemporarilyDisabledUpgrades.Contains(currentupgrade.name), currentupgrade.title, OnButtonClick_Upgrade(currentupgrade), button_width, button_height); //PartUpgradeManager.Handler.IsEnabled(currentupgrade.name)
                var single_modules_button = new DialogGUIBox(string.Join("\n", affected_modules.ToArray()), 250, button_height);
                var single_desc_button    = new DialogGUIBox(currentupgrade.description, 340, button_height);

                var h = new DialogGUIHorizontalLayout(true, false, 4, new RectOffset(), TextAnchor.MiddleCenter, new DialogGUIBase[] { single_upgrade_button, single_modules_button, single_desc_button });
                upgrade_line.Add(h);
            }

            scrollList = null;
            scrollList = new DialogGUIBase[upgrade_line.Count + 1];

            scrollList[0] = new DialogGUIContentSizer(ContentSizeFitter.FitMode.Unconstrained, ContentSizeFitter.FitMode.PreferredSize, true);

            for (int i = 0; i < upgrade_line.Count; i++)
            {
                scrollList[i + 1] = upgrade_line[i];
            }
            upgrade_editor.Add(new DialogGUIScrollList(new Vector2(270, 200), false, true,
                                                       new DialogGUIVerticalLayout(10, 100, 4, new RectOffset(6, 24, 10, 10), TextAnchor.UpperLeft, scrollList)
                                                       ));
            upgrade_editor.Add(new DialogGUISpace(4));

            upgrade_editor.Add(new DialogGUIHorizontalLayout(new DialogGUIBase[]
            {
                new DialogGUIFlexibleSpace(),
                new DialogGUIButton("Reset & Close", ResetUnlockedUpgrades),
                new DialogGUIFlexibleSpace(),
                new DialogGUIToggleButton(() => EnableAllUpgrades, "Toggle All", OnButtonClick_EnableAllUpgrades, -1, 30),
                new DialogGUIFlexibleSpace(),
                new DialogGUIToggleButton(() => PartUpgradeHandler.AllEnabled, "Always Enable", OnButtonClick_ToggleAllUpgrades, -1, 30),
                new DialogGUIFlexibleSpace(),
                new DialogGUIButton("Close", Dismiss)
            }));
            return(PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new MultiOptionDialog(
                                                    "Upgrade Editor",
                                                    "", "Upgrade Editor",
                                                    HighLogic.UISkin,
                                                    // window origin is center of rect, position is offset from lower left corner of screen and normalized i.e (0.5, 0.5 is screen center)
                                                    new Rect(0.5f, 0.5f, width, height), upgrade_editor.ToArray()), false, HighLogic.UISkin));
        }
        /// <summary>
        ///   Called when [application launcher true].
        /// </summary>
        private void OnAppLauncherTrue()
        {
            const float q = 0.5f;
            const float w = 500f;
            const float h = 28f;
            const float v = 14f;

            DebugLog(m: "OnAppLauncherTrue()");

            OnAppLauncherFalse(); // make sure it's closed

            var components = new List <DialogGUIBase> {
                new DialogGUISpace(v: v)
            };
            var btm = new DialogGUIHorizontalLayout(new DialogGUIFlexibleSpace());


            if (!GameSettings.ADVANCED_TWEAKABLES)
            {
                components.Add(
                    item: new DialogGUIHorizontalLayout(new DialogGUILabel(message: "'Advanced Tweakables' needs to be enabled.\nClick the button below to enable it."))
                    );

                components.Add(
                    item: new DialogGUIHorizontalLayout(
                        new DialogGUIButton(
                            optionText: "Enable 'Advanced Tweakables'",
                            onSelected: () =>
                {
                    GameSettings.ADVANCED_TWEAKABLES = true;
                    GameSettings.SaveSettings();
                    OnAppLauncherFalse();
                    OnAppLauncherTrue();
                },
                            w: -1f,
                            h: h,
                            dismissOnSelect: false
                            ),
                        new DialogGUISpace(v: -1f)
                        )
                    );
                goto SPAWN; // dirty kludge, I know...
            }

            var top = new DialogGUIHorizontalLayout(
                new DialogGUISpace(v: v),
                new DialogGUIToggleButton(
                    set: Settings.Instance.ModEnabled,
                    lbel: "Enable Full AutoStrut",
                    selected: b =>
            {
                Settings.Instance.ModEnabled = b;
                OnAppLauncherFalse();
                OnAppLauncherTrue();
            },
                    w: -1f,
                    h: h
                    )
                );

            components.Add(item: top);

            if (!Settings.Instance.ModEnabled)
            {
                components.Add(
                    item: new DialogGUIHorizontalLayout(
                        new DialogGUIFlexibleSpace(),
                        new DialogGUILabel(message: "Full AutoStrut is currently disabled."),
                        new DialogGUIFlexibleSpace()
                        )
                    );
                components.Add(item: new DialogGUISpace(v: v));
                top.AddChild(child: new DialogGUISpace(v: v));
                goto SPAWN; // dirty kludge, I know...
            }

            top.AddChild(
                child: new DialogGUIToggleButton(
                    set: Settings.Instance.RigidAttachment,
                    lbel: "Use Rigid Attachment",
                    selected: b => Settings.Instance.RigidAttachment = b,
                    w: -1f,
                    h: h
                    )
                );

            _applyChildren = new DialogGUIToggleButton(
                set: Settings.Instance.ApplyChildren,
                lbel: "Re-Apply to child parts",
                selected: b => Settings.Instance.ApplyChildren = b,
                w: -1f,
                h: h
                );

            top.AddChild(child: _applyChildren);
            top.AddChild(child: new DialogGUISpace(v: v));

            components.Add(item: new DialogGUISpace(v: v));
            components.Add(
                item: new DialogGUIHorizontalLayout(new DialogGUIFlexibleSpace(), new DialogGUIBox(message: "AutoStrut", w: w, h: h), new DialogGUIFlexibleSpace())
                );

            components.Add(
                item: new DialogGUIHorizontalLayout(
                    new DialogGUISpace(v: v),
                    new DialogGUIToggleGroup(
                        new DialogGUIToggleButton(
                            set: Settings.Instance.AutoSelect == false && Settings.Instance.AutoStrutMode == Part.AutoStrutMode.Off,
                            lbel: "Off",
                            selected: b =>
            {
                if (!b)
                {
                    return;
                }
                Settings.Instance.AutoSelect    = false;
                Settings.Instance.AutoStrutMode = Part.AutoStrutMode.Off;
            },
                            w: -1f,
                            h: h
                            ),
                        new DialogGUIToggleButton(
                            set: Settings.Instance.AutoSelect == false && Settings.Instance.AutoStrutMode == Part.AutoStrutMode.Root,
                            lbel: "Root",
                            selected: b =>
            {
                if (!b)
                {
                    return;
                }
                Settings.Instance.AutoSelect    = false;
                Settings.Instance.AutoStrutMode = Part.AutoStrutMode.Root;
            },
                            w: -1f,
                            h: h
                            ),
                        new DialogGUIToggleButton(
                            set: Settings.Instance.AutoSelect == false && Settings.Instance.AutoStrutMode == Part.AutoStrutMode.Heaviest,
                            lbel: "Heaviest",
                            selected: b =>
            {
                if (!b)
                {
                    return;
                }
                Settings.Instance.AutoSelect    = false;
                Settings.Instance.AutoStrutMode = Part.AutoStrutMode.Heaviest;
            },
                            w: -1f,
                            h: h
                            ),
                        new DialogGUIToggleButton(
                            set: Settings.Instance.AutoSelect == false && Settings.Instance.AutoStrutMode == Part.AutoStrutMode.Grandparent,
                            lbel: "Grandparent",
                            selected: b =>
            {
                if (!b)
                {
                    return;
                }
                Settings.Instance.AutoSelect    = false;
                Settings.Instance.AutoStrutMode = Part.AutoStrutMode.Grandparent;
            },
                            w: -1f,
                            h: h
                            ),
                        new DialogGUIToggleButton(set: Settings.Instance.AutoSelect, lbel: "Automatic", selected: b => Settings.Instance.AutoSelect = b, w: -1f, h: h)
                        ),
                    new DialogGUISpace(v: v)
                    )
                );

            components.Add(item: new DialogGUISpace(v: v));

            components.Add(item: new DialogGUIHorizontalLayout(new DialogGUIBox(message: "Same Vessel Interaction", w: w, h: h)));
            components.Add(
                item: new DialogGUIHorizontalLayout(
                    new DialogGUISpace(v: v),
                    new DialogGUIToggleGroup(
                        new DialogGUIToggleButton(
                            set: Settings.Instance.AutomaticSameVesselInteraction == false && Settings.Instance.SameVesselInteraction == false,
                            lbel: "Off",
                            selected: b =>
            {
                if (!b)
                {
                    return;
                }
                Settings.Instance.AutomaticSameVesselInteraction = false;
                Settings.Instance.SameVesselInteraction          = false;
            },
                            w: -1F,
                            h: h
                            ),
                        new DialogGUIToggleButton(
                            set: Settings.Instance.AutomaticSameVesselInteraction == false && Settings.Instance.SameVesselInteraction,
                            lbel: "On",
                            selected: b =>
            {
                if (!b)
                {
                    return;
                }
                Settings.Instance.AutomaticSameVesselInteraction = false;
                Settings.Instance.SameVesselInteraction          = true;
            },
                            w: -1F,
                            h: h
                            ),
                        new DialogGUIToggleButton(
                            set: Settings.Instance.AutomaticSameVesselInteraction,
                            lbel: "Automatic",
                            selected: b =>
            {
                Settings.Instance.AutomaticSameVesselInteraction = b;
                Settings.Instance.SameVesselInteraction          = false;
            },
                            w: -1F,
                            h: h
                            )
                        ),
                    new DialogGUISpace(v: v)
                    )
                );


            components.Add(item: new DialogGUISpace(v: v));


            btm.AddChild(
                child: new DialogGUIButton(
                    optionText: "Apply to all",
                    onSelected: () => SetPartOptions(
                        p: EditorLogic.RootPart,
                        autoStrutMode: Settings.Instance.AutoStrutMode,
                        isRoboticHierarchy: EditorLogic.RootPart.IsRoboticCompatible(),
                        applyChildren: true
                        ),
                    EnabledCondition: null,
                    w: -1f,
                    h: h,
                    dismissOnSelect: false
                    )
                );

            btm.AddChild(child: new DialogGUISpace(v: v));
            btm.AddChild(
                child: new DialogGUIButton(
                    optionText: "Reset Settings",
                    onSelected: () =>
            {
                Settings.Instance.Reset();
                OnAppLauncherFalse();
                OnAppLauncherTrue();
            },
                    EnabledCondition: null,
                    w: -1f,
                    h: h,
                    dismissOnSelect: false
                    )
                );
            btm.AddChild(child: new DialogGUISpace(v: v));

SPAWN:      // dirty kludge, I know...
            btm.AddChild(
                child: new DialogGUIButton(optionText: "Close", onSelected: OnAppLauncherFalse, EnabledCondition: null, w: -1f, h: h, dismissOnSelect: false)
                );
            btm.AddChild(child: new DialogGUIFlexibleSpace());

            components.Add(item: btm);
            components.Add(item: new DialogGUISpace(v: v));

            _dialog = PopupDialog.SpawnPopupDialog(
                anchorMin: new Vector2(x: q, y: q),
                anchorMax: new Vector2(x: q, y: q),
                dialog: new MultiOptionDialog(
                    name: "FULL~AUTO~STRUT",
                    msg: string.Empty,
                    windowTitle: "Full AutoStrut v" + AssemblyVersion,
                    skin: HighLogic.UISkin,
                    rct: new Rect(x: Settings.Instance.PosX * GameSettings.UI_SCALE, y: Settings.Instance.PosY * GameSettings.UI_SCALE, width: w, height: -1f),
                    options: new DialogGUIVerticalLayout(list: components.ToArray())
                    ),
                persistAcrossScenes: false,
                skin: HighLogic.UISkin,
                isModal: false
                );
        }