/// <summary>Main GUI method.</summary> void GuiMain(int windowID) { guiActionList.ExecutePendingGuiActions(); GUILayout.Label("Inventory: " + DebugEx.ObjectToString(tgtInventory), GUI.skin.box); GUILayout.Label("NOTE: The item's volume and mass are NOT checked!"); using (new GUILayout.HorizontalScope(GUI.skin.box)) { GUILayout.Label("Search:"); GUI.changed = false; searchText = GUILayout.TextField(searchText, GUILayout.Width(300)); if (GUI.changed) { guiActionList.Add(() => GuiUpdateSearch(searchText)); } GUILayout.Label("Quantity:"); var oldQuantity = createQuantity; createQuantity = GUILayout.TextField(createQuantity, GUILayout.Width(50)); int newQuantity; if (!int.TryParse(createQuantity, out newQuantity)) { createQuantity = oldQuantity; } } if (searchText.Length < 3) { GUILayout.Label("...give at least 3 characters...", GUI.skin.box); } else if (foundMatches.Length == 0) { GUILayout.Label("...nothing is found for the pattern...", GUI.skin.box); } else { for (var i = 0; i < MaxFoundItems && i < foundMatches.Length; i++) { var p = foundMatches[i]; using (new GUILayout.HorizontalScope(GUI.skin.box)) { GUILayout.Label(p.title + " (" + p.name + ")"); GUILayout.FlexibleSpace(); if (GUILayout.Button("Add", GUILayout.ExpandHeight(true))) { guiActionList.Add(() => GuiSpawnItems(p)); } } } if (foundMatches.Length > MaxFoundItems) { GUILayout.Label("...there are more, but they are not shown..."); } } if (GUILayout.Button("Close")) { Destroy(gameObject); } GUI.DragWindow(new Rect(0, 0, 10000, 30)); }
/// <summary>Shows a window that displays the recorded logs.</summary> /// <param name="windowId">Window ID.</param> void ConsoleWindowFunc(int windowId) { // Only show the logs snapshot when it's safe to change the GUI layout. if (guiActions.ExecutePendingGuiActions()) { UpdateLogsView(); // Check if the toolbar goes out of the screen. isToolbarAtTheBottom = windowRect.yMax < Screen.height; } if (!isToolbarAtTheBottom) { GUICreateToolbar(); } // Main scrolling view. using (var logsScrollView = new GUILayout.ScrollViewScope(scrollPosition)) { scrollPosition = logsScrollView.scrollPosition; // Report conditions. if (!LogInterceptor.isStarted) { using (new GuiColorScope(contentColor: errorLogColor)) { GUILayout.Label("KSPDev is not handling system logs. Open standard in-game debug console" + " to see the current logs"); } } if (quickFilterInputEnabled) { using (new GuiColorScope(contentColor: Color.gray)) { GUILayout.Label("<i>Logs update is PAUSED due to the quick filter editing is active." + " Hit ENTER to accept the filter, or ESC to discard.</i>"); } } GUIShowLogRecords(); } if (isToolbarAtTheBottom) { GUICreateToolbar(); } // Allow the window to be dragged by its title bar. GuiWindow.DragWindow(ref windowRect, titleBarRect); }
/// <summary>Shows a window that displays the resource transfer controls.</summary> /// <param name="windowId">Window ID.</param> void TransferResourcesWindowFunc(int windowId) { // Allow the window to be dragged by its title bar. GuiWindow.DragWindow(ref windowRect, titleBarRect); MakeGuiStyles(); // In the docked mode the players must use the stock transfer mechanism. if (vessel == linkTarget.part.vessel) { GUILayout.Label(NotAvailableInDockedMode, new GUIStyle(GUI.skin.label) { wordWrap = false }); if (GUILayout.Button(CloseDialogBtn, MinSizeLayout)) { isGUIOpen = false; } SetPendingTransferOption(null); // Cancel all transfers. return; } if (guiActions.ExecutePendingGuiActions()) { MaybeUpdateResourceOptionList(); guiResourcesTable.UpdateFrame(); if (pendingOption != null) { if (!DoTransfer()) { SetPendingTransferOption(null); // Cancel all transfers. } } UpdateResourcesTransferGui(); } GUILayout.Label(OwnerVesselTxt.Format(vessel.vesselName), GUI.skin.box); GUILayout.Label(ConnectedVesselTxt.Format(linkTarget.part.vessel.vesselName), GUI.skin.box); for (var i = resourceRows.Length - 1; i >= 0; i--) { var row = resourceRows[i]; guiResourcesTable.StartNewRow(); using (new GUILayout.HorizontalScope()) { guiResourcesTable.AddTextColumn( row.caption, guiResourceStyle, minWidth: resourceName.guiTags.minWidth); guiResourcesTable.AddTextColumn( row.leftInfo, guiNoWrapCenteredStyle, minWidth: resourceAmounts.guiTags.minWidth); using (new GuiEnabledStateScope(row.canMoveRightToLeft)) { row.rightToLeftTransferToggle = GUILayoutButtons.Toggle( row.rightToLeftTransferToggle, leftToRigthToggleCnt, guiTransferBtnStyle, null, GuiActionUpdateTransferItem, GuiActionUpdateTransferItem, guiActions); row.rightToLeftTransferPress = GUILayoutButtons.Push( row.rightToLeftTransferPress, leftToRigthButtonCnt, guiTransferBtnStyle, null, GuiActionUpdateTransferItem, GuiActionUpdateTransferItem, guiActions); } using (new GuiEnabledStateScope(row.canMoveLeftToRight)) { row.leftToRightTransferPress = GUILayoutButtons.Push( row.leftToRightTransferPress, rightToLeftButtonCnt, guiTransferBtnStyle, null, GuiActionUpdateTransferItem, GuiActionUpdateTransferItem, guiActions); row.leftToRightTransferToggle = GUILayoutButtons.Toggle( row.leftToRightTransferToggle, rightToLeftToggleCnt, guiTransferBtnStyle, null, GuiActionUpdateTransferItem, GuiActionUpdateTransferItem, guiActions); } guiResourcesTable.AddTextColumn( row.rightInfo, guiNoWrapCenteredStyle, minWidth: resourceAmounts.guiTags.minWidth); guiResourcesTable.AddTextColumn( row.caption, guiResourceStyle, minWidth: resourceName.guiTags.minWidth); } } // Resource transfer speed. autoScaleSpeed = GUILayoutButtons.Toggle( autoScaleSpeed, autoScaleToggleCnt, GUI.skin.toggle, null, MaybeAutoScaleSpeed, null, guiActions); using (new GuiEnabledStateScope(!autoScaleSpeed)) { transferSpeed = GUILayout.HorizontalSlider(transferSpeed, 0f, maxTransferSpeed); if (transferSpeed < float.Epsilon && pendingOption != null) { guiActions.Add(() => SetPendingTransferOption(null)); // Cancel all transfers. } } GUILayout.Label(TransferSpeedTxt.Format(transferSpeed)); using (new GUILayout.HorizontalScope()) { if (GUILayout.Button(CloseDialogBtn, MinSizeLayout)) { guiActions.Add(() => isGUIOpen = false); } GUILayout.Label(""); GUI.Label(GUILayoutUtility.GetLastRect(), GUI.tooltip); } }
/// <summary>Shows a UI dialog.</summary> /// <param name="windowID">The window ID. Unused.</param> void MakeConsoleWindow(int windowID) { guiActions.ExecutePendingGuiActions(); // Search prefix controls. using (new GUILayout.HorizontalScope(GUI.skin.box)) { GUILayout.Label(UrlPrefixFieldCaptionTxt, GUILayout.ExpandWidth(false)); lookupPrefix = GUILayout.TextField(lookupPrefix, GUILayout.ExpandWidth(true)).TrimStart(); if (lookupPrefix != lastCachedLookupPrefix) { lastCachedLookupPrefix = lookupPrefix; guiActions.Add(() => GuiActionUpdateTargets(lookupPrefix)); } } // Found items scroll view. using (var scrollScope = new GUILayout.ScrollViewScope( partsScrollPos, GUI.skin.box, GUILayout.Height(scrollHeight))) { partsScrollPos = scrollScope.scrollPosition; foreach (var target in targets) { target.GUIAddItem(); } } GUI.changed = false; allowNoModulesAssemblies = GUILayout.Toggle(allowNoModulesAssemblies, AssembliesWithoutModulesToggleTxt); if (GUI.changed) { guiActions.Add(() => GuiActionUpdateTargets(lookupPrefix)); } // Action buttons. var selectedModulesCount = targets.OfType <AssemblyRecord>() .Where(x => x.selected) .Sum(x => x.types.Count); var selectedPartsCount = targets.OfType <PartsRecord>() .Where(x => x.selected) .Sum(x => x.parts.Count); var selectedLocsCount = targets.OfType <ConfigRecord>() .Count(x => x.selected); var selectedAssemblies = targets.OfType <AssemblyRecord>().Where(x => x.selected); var selectedParts = targets.OfType <PartsRecord>().Where(x => x.selected); var selectedConfigs = targets.OfType <ConfigRecord>().Where(x => x.selected); // Strings export controls. if (selectedPartsCount > 0 || allowNoModulesAssemblies && selectedAssemblies.Any() || !allowNoModulesAssemblies && selectedModulesCount > 0) { var title = ExportBtnTxt.Format(selectedParts.Sum(x => x.parts.Count), selectedAssemblies.Count()); if (GUILayout.Button(title)) { GuiActionExportStrings(selectedParts, selectedAssemblies); } } else { GUI.enabled = false; GUILayout.Button(MakeSelectionsForExportTxt); GUI.enabled = true; } // Parts export controls. if (selectedPartsCount > 0) { var title = PatchPartsBtnTxt.Format(selectedParts.Sum(x => x.parts.Count)); if (GUILayout.Button(title)) { GuiExportPartConfigs(selectedParts); } } else { GUI.enabled = false; GUILayout.Button(MakeSelectionsForPatchTxt); GUI.enabled = true; } // Strings reload controls. if (selectedLocsCount > 0) { var title = RefreshBtnTxt.Format(selectedConfigs.Count(), selectedParts.Sum(x => x.parts.Count)); if (GUILayout.Button(title)) { GuiActionRefreshStrings(selectedConfigs, selectedParts); } } else { GUI.enabled = false; GUILayout.Button(MakeSelectionsForReloadTxt); GUI.enabled = true; } // Parts DB update controls. if (GUILayout.Button(UpdateAllPartsTxt)) { GuiActionUpdateAllParts(); } GUI.DragWindow(); }
/// <summary>Shows a UI dialog.</summary> /// <param name="windowID">The window ID. Unused.</param> void MakeConsoleWindow(int windowID) { guiActions.ExecutePendingGuiActions(); // Search prefix controls. using (new GUILayout.HorizontalScope(GUI.skin.box)) { GUILayout.Label("URL prefix:", GUILayout.ExpandWidth(false)); lookupPrefix = GUILayout.TextField(lookupPrefix, GUILayout.ExpandWidth(true)).TrimStart(); if (lookupPrefix != lastCachedLookupPrefix) { lastCachedLookupPrefix = lookupPrefix; guiActions.Add(() => GuiActionUpdateTargets(lookupPrefix)); } } // Found items scroll view. using (new GUILayout.HorizontalScope(GUI.skin.box)) { using (var scrollScope = new GUILayout.ScrollViewScope(partsScrollPos, GUILayout.Height(scrollHeight))) { partsScrollPos = scrollScope.scrollPosition; foreach (var target in targets) { target.GUIAddItem(); } } } // Action buttons. var selectedModulesCount = targets.OfType <AssemblyRecord>() .Where(x => x.selected) .Sum(x => x.types.Count); var selectedPartsCount = targets.OfType <PartsRecord>() .Where(x => x.selected) .Sum(x => x.parts.Count); var selectedLocsCount = targets.OfType <ConfigRecord>() .Count(x => x.selected); var selectedModules = targets.OfType <AssemblyRecord>().Where(x => x.selected); var selectedParts = targets.OfType <PartsRecord>().Where(x => x.selected); var selectedConfigs = targets.OfType <ConfigRecord>().Where(x => x.selected); if (selectedPartsCount > 0 || selectedModulesCount > 0) { var title = string.Format(ExportBtnFmt, selectedParts.Sum(x => x.parts.Count), selectedModules.Sum(x => x.types.Count)); if (GUILayout.Button(title)) { GuiActionExportStrings(selectedParts, selectedModules); } } else { GUI.enabled = false; GUILayout.Button(ExportBtnFmtNotSelected); GUI.enabled = true; } if (selectedLocsCount > 0) { var title = string.Format(RefreshBtnFmt, selectedConfigs.Count(), selectedParts.Sum(x => x.parts.Count)); if (GUILayout.Button(title)) { GuiActionRefreshStrings(selectedConfigs, selectedParts); } } else { GUI.enabled = false; GUILayout.Button(RefreshBtnFmtNotSelected); GUI.enabled = true; } GUI.DragWindow(titleBarRect); }
/// <summary>Shows a window that displays the winch controls.</summary> /// <param name="windowId">Window ID.</param> void ConsoleWindowFunc(int windowId) { MakeGuiStyles(); if (GuiActions.ExecutePendingGuiActions()) { MaybeUpdateModules(); _guiWinchTable.UpdateFrame(); } if (_sortedSceneModules.Length == 0) { GUILayout.Label(NoContentTxt, _guiNoWrapStyle); } // TODO(ihsoft): Add paging and the setting for the number of items per page. // Render the winch items if any. foreach (var winchState in _sortedSceneModules) { var winch = winchState.winchModule; var winchCable = winchState.winchModule.linkJoint as ILinkCableJoint; var disableWinchGui = !winch.part.vessel.IsControllable || winch.isNodeBlocked || winch.isLocked; var motorSpeed = winchState.motorSpeedSetting * winch.cfgMotorMaxSpeed; _guiWinchTable.StartNewRow(); using (new GUILayout.HorizontalScope(GUI.skin.box)) { // Winch highlighting column. winchState.highlighted = GUILayoutButtons.Toggle( winchState.highlighted, _highlightWinchCnt, GUI.skin.button, null, fnOn: () => { winch.part.SetHighlight(true, false); winch.part.SetHighlightType(Part.HighlightType.AlwaysOn); }, fnOff: () => { winch.part.SetHighlightDefault(); }, actionsList: GuiActions); // Cable retracting controls. System.Diagnostics.Debug.Assert(winchCable != null, nameof(winchCable) + " != null"); using (new GuiEnabledStateScope(!disableWinchGui && winchCable.realCableLength > 0)) { // Start retracting the cable column. winchState.retractBtnPressed &= winch.motorTargetSpeed < 0; winchState.retractBtnPressed = GUILayoutButtons.Toggle( winchState.retractBtnPressed, _startRetractingCnt, GUI.skin.button, new[] { MinSizeLayout }, fnOn: () => winch.SetMotor(-motorSpeed), fnOff: () => winch.SetMotor(0), actionsList: GuiActions); // Retract the cable column. winchState.retracting &= winch.motorTargetSpeed < 0; winchState.retracting = GUILayoutButtons.Push( winchState.retracting, _retractCnt, GUI.skin.button, new[] { MinSizeLayout }, fnPush: () => winch.SetMotor(-motorSpeed), fnRelease: () => winch.SetMotor(0), actionsList: GuiActions); } // Cable length/status column. if (!winch.part.vessel.IsControllable) { _guiWinchTable.AddTextColumn( _winchModeOfflineCnt, _guiNoWrapCenteredStyle, minWidth: _winchCableStatusMinWidth); } else if (winch.isNodeBlocked || winch.isLocked) { _guiWinchTable.AddTextColumn( _winchModeBlockedCnt, _guiNoWrapCenteredStyle, minWidth: _winchCableStatusMinWidth); } else if (winch.isConnectorLocked) { _guiWinchTable.AddTextColumn( _winchModeRetractedCnt, _guiNoWrapCenteredStyle, minWidth: _winchCableStatusMinWidth); } else { _cableStatusCnt.text = winchCable.realCableLength <= winch.currentCableLength ? RelaxedCableLengthTxt.Format(winch.currentCableLength, winchCable.realCableLength) : StrainedCableLengthTxt.Format(winch.currentCableLength, winchCable.realCableLength); _guiWinchTable.AddTextColumn( _cableStatusCnt, _guiNoWrapCenteredStyle, minWidth: _winchCableStatusMinWidth); } // Cable extending controls. using (new GuiEnabledStateScope( !disableWinchGui && winchCable.deployedCableLength < winch.cfgMaxCableLength)) { // Start extending the cable column. winchState.extendBtnPressed &= winch.motorTargetSpeed > 0; winchState.extendBtnPressed = GUILayoutButtons.Toggle( winchState.extendBtnPressed, _startExtendingCnt, GUI.skin.button, new[] { MinSizeLayout }, fnOn: () => winch.SetMotor(motorSpeed), fnOff: () => winch.SetMotor(0), actionsList: GuiActions); // Extend the cable column. winchState.extending &= winch.motorTargetSpeed > 0; winchState.extending = GUILayoutButtons.Push( winchState.extending, _extendCnt, GUI.skin.button, new[] { MinSizeLayout }, fnPush: () => winch.SetMotor(motorSpeed), fnRelease: () => winch.SetMotor(0), actionsList: GuiActions); } using (new GuiEnabledStateScope(!disableWinchGui)) { // Motor speed settings column. using (new GUILayout.VerticalScope(_motorSpeedSettingsCnt, GUI.skin.label)) { GUI.changed = false; GUILayout.FlexibleSpace(); var newMotorSpeedSetting = GUILayout.HorizontalSlider( winchState.motorSpeedSetting, 0.1f, 1.0f, GUILayout.Width(100f)); if (GUI.changed) { var state = winchState; GuiActions.Add(() => { state.motorSpeedSetting = newMotorSpeedSetting; var newSpeed = newMotorSpeedSetting * winch.cfgMotorMaxSpeed; if (state.extending || state.extendBtnPressed) { winch.SetMotor(newSpeed); } if (state.retracting || state.retractBtnPressed) { winch.SetMotor(-newSpeed); } }); } } } // Motor speed info column. _motorSpeedCnt.text = MotorSpeedTxt.Format(Mathf.Abs(winch.motorCurrentSpeed), motorSpeed); _guiWinchTable.AddTextColumn( _motorSpeedCnt, _guiNoWrapCenteredStyle, minWidth: MotorSpeedTxt.guiTags.minWidth); // Release cable column. using (new GuiEnabledStateScope( !disableWinchGui && winch.currentCableLength < winch.cfgMaxCableLength)) { if (GUILayout.Button(_releaseBtnCnt, GUI.skin.button, MinSizeLayout)) { GuiActions.Add(winch.ReleaseCable); } } // Stretch cable column. using (new GuiEnabledStateScope(!disableWinchGui && !winch.isConnectorLocked)) { if (GUILayout.Button(_stretchBtnCnt, GUI.skin.button, MinSizeLayout)) { GuiActions.Add(winch.StretchCable); } } // Disconnect connector column. using (new GuiEnabledStateScope(!disableWinchGui && winch.isLinked)) { if (GUILayout.Button(_detachBtnCnt, GUI.skin.button, MinSizeLayout)) { GuiActions.Add(() => winch.BreakCurrentLink(LinkActorType.Player)); } } } } using (new GUILayout.HorizontalScope()) { if (GUILayout.Button(_closeGuiCnt, MinSizeLayout)) { GuiActions.Add(() => _isGuiOpen = false); } GUILayout.Label(""); GUI.Label(GUILayoutUtility.GetLastRect(), GUI.tooltip); } // Allow the window to be dragged by its title bar. GuiWindow.DragWindow(ref _windowRect, TitleBarRect); }
/// <summary>Shows a window that displays the winch controls.</summary> /// <param name="windowId">Window ID.</param> void ConsoleWindowFunc(int windowId) { if (guiActions.ExecutePendingGuiActions()) { if (parentPartTracking && Input.GetMouseButtonDown(0) && !windowRect.Contains(Mouse.screenPos)) { SetPart(Mouse.HoveredPart); parentPartTracking = false; } } string parentPartName = parentPart != null?DbgFormatter.PartId(parentPart) : "NONE"; if (!lockToPart) { if (GUILayout.Button(!parentPartTracking ? "Set part" : "Cancel set mode...")) { guiActions.Add(() => { parentPartTracking = !parentPartTracking; }); } if (parentPartTracking && Mouse.HoveredPart != null) { parentPartName = "Select: " + DbgFormatter.PartId(Mouse.HoveredPart); } GUILayout.Label(parentPartName, new GUIStyle(GUI.skin.box) { wordWrap = true }); } // Render the adjustable fields. if (parentPart != null && adjustableModules != null) { if (adjustableModules.Length > 0) { mainScrollView.BeginView(GUI.skin.box, Screen.height - 200); for (var i = 0; i < adjustableModules.Length; i++) { var isSelected = selectedModule == i; var module = adjustableModules[i]; var toggleCaption = (isSelected ? "\u25b2 " : "\u25bc ") + "Module: " + module.Key; if (GUILayout.Button(toggleCaption)) { var selectedModuleSnapshot = selectedModule == i ? -1 : i; // Make a copy for lambda! guiActions.Add(() => selectedModule = selectedModuleSnapshot); } if (isSelected) { foreach (var control in module.Value) { control.RenderControl( guiActions, GUI.skin.label, new[] { GUILayout.Width(dialogValueSize) }); } } } mainScrollView.EndView(); } else { GUILayout.Box("No adjustable members found"); } } if (GUILayout.Button("Close", GUILayout.ExpandWidth(false))) { guiActions.Add(() => DebugGui.DestroyPartDebugDialog(this)); } // Allow the window to be dragged by its title bar. GuiWindow.DragWindow(ref windowRect, titleBarRect); }
/// <summary>Shows a window that displays the winch controls.</summary> /// <param name="windowId">Window ID.</param> void ConsoleWindowFunc(int windowId) { MakeGuiStyles(); if (guiActions.ExecutePendingGuiActions()) { if (parentPartTracking) { SetPart(Mouse.HoveredPart); } if (parentPartTracking && Input.GetMouseButtonDown(0)) { parentPartTracking = false; } } using (new GUILayout.VerticalScope(GUI.skin.box)) { using (new GuiEnabledStateScope(!parentPartTracking)) { if (GUILayout.Button("Set part")) { guiActions.Add(() => parentPartTracking = true); } } using (new GuiEnabledStateScope(parentPartTracking)) { if (GUILayout.Button("Cancel set mode...")) { guiActions.Add(() => parentPartTracking = false); } } var parentPartName = "Part: " + (parentPart != null ? DbgFormatter.PartId(parentPart) : "NONE"); GUILayout.Label(parentPartName, guiNoWrapStyle); } if (parentPart != null && itemModule != null && (itemModule.equipable || itemModule.carriable)) { GUILayout.Label("KIS Item detected:"); using (new GUILayout.VerticalScope(GUI.skin.box)) { using (new GUILayout.HorizontalScope(GUI.skin.box)) { GUILayout.Label("Equip pos (metres):", guiCaptionStyle); GUILayout.FlexibleSpace(); itemModule.equipPos = itemPosition.UpdateFrame( itemModule.equipPos, guiValueStyle, new[] { GUILayout.Width(100) }); } using (new GUILayout.HorizontalScope(GUI.skin.box)) { GUILayout.Label("Equip dir (euler degrees):", guiCaptionStyle); GUILayout.FlexibleSpace(); itemModule.equipDir = itemDirection.UpdateFrame( itemModule.equipDir, guiValueStyle, new[] { GUILayout.Width(100) }); } } } if (GUILayout.Button("Close", GUILayout.ExpandWidth(false))) { guiActions.Add(() => isGUIOpen = false); } // Allow the window to be dragged by its title bar. GuiWindow.DragWindow(ref windowRect, titleBarRect); }