/// <summary> /// Performs initial setup /// </summary> /// <param name="parentTransform">Parent transform</param> /// <param name="targetPrefabInfo">Currently selected target prefab</param> internal override void Setup(Transform parentTransform, PrefabInfo targetPrefabInfo) { try { // Perform basic panel setup. base.Setup(parentTransform, targetPrefabInfo); Logging.Message("commencing InfoPanel setup"); // Replace all button. replaceAllButton = AddIconButton(this, MidControlX + replaceButton.width, ReplaceY, BigIconSize, ReplaceAllTooltipKey, ReplaceAllAtlas); replaceAllButton.eventClicked += ReplaceAll; // Probability. UIPanel probabilityPanel = Sliderpanel(this, MidControlX, ProbabilityY, SliderHeight); probabilitySlider = AddBOBSlider(probabilityPanel, 0f, "BOB_PNL_PRB", 0, 100, 1); probabilitySlider.TrueValue = 100f; probabilitySlider.LimitToVisible = true; // Angle. UIPanel anglePanel = Sliderpanel(this, MidControlX, AngleY, SliderHeight); angleSlider = AddBOBSlider(anglePanel, 0f, "BOB_PNL_ANG", -180, 180, 1); Logging.Message("Creating offset panel"); // Offset panel. UIPanel offsetPanel = Sliderpanel(this, MidControlX, OffsetPanelY, OffsetPanelHeight); UILabel offsetLabel = UIControls.AddLabel(offsetPanel, 0f, OffsetLabelY, Translations.Translate("BOB_PNL_OFF")); offsetLabel.textAlignment = UIHorizontalAlignment.Center; while (offsetLabel.width > MidControlWidth) { offsetLabel.textScale -= 0.05f; offsetLabel.PerformLayout(); } offsetLabel.relativePosition = new Vector2((offsetPanel.width - offsetLabel.width) / 2f, OffsetLabelY); // Offset sliders. xSlider = AddBOBSlider(offsetPanel, XOffsetY, "BOB_PNL_XOF", -8f, 8f, 0.01f); ySlider = AddBOBSlider(offsetPanel, YOffsetY, "BOB_PNL_YOF", -8f, 8f, 0.01f); zSlider = AddBOBSlider(offsetPanel, ZOffsetY, "BOB_PNL_ZOF", -8f, 8f, 0.01f); // Set initial button states. UpdateButtonStates(); // Normal/random toggle. randomCheck = UIControls.LabelledCheckBox((UIComponent)(object)this, hideVanilla.relativePosition.x, hideVanilla.relativePosition.y + hideVanilla.height + (Margin / 2f), Translations.Translate("BOB_PNL_RSW"), 12f, 0.7f); randomCheck.eventCheckChanged += RandomCheckChanged; // Random settings button. UIButton randomButton = UIControls.EvenSmallerButton(this, RightX - 200f, TitleHeight + Margin + 20f, Translations.Translate("BOB_PNL_RST")); randomButton.eventClicked += (control, clickEvent) => BOBRandomPanel.Create(); Logging.Message("InfoPanel setup completed"); } catch (Exception e) { Logging.LogException(e, "exception setting up InfoPanel"); } }
/// <summary> /// Adds a BOB slider to the specified component. /// </summary> /// <param name="parent">Parent component</param> /// <param name="xPos">Relative X position</param /// <param name="yPos">Relative Y position</param /// <param name="width">Slider width</param> /// <param name="labelKey">Text label translation key</param> /// <param name="minValue">Minimum displayed value</param /// <param name="maxValue">Maximum displayed value</param> /// <param name="stepSize">Minimum slider step size</param> /// <param name="name">Slider name</param> /// <returns>New BOBSlider</returns> protected BOBSlider AddBOBSlider(UIComponent parent, float xPos, float yPos, float width, string labelKey, float minValue, float maxValue, float stepSize, string name) { const float SliderY = 18f; const float ValueY = 3f; const float LabelY = -13f; const float SliderHeight = 18f; const float FloatTextFieldWidth = 45f; const float IntTextFieldWidth = 38f; // Slider control. BOBSlider newSlider = parent.AddUIComponent <BOBSlider>(); newSlider.size = new Vector2(width, SliderHeight); newSlider.relativePosition = new Vector2(xPos, yPos + SliderY); newSlider.name = name; // Value field - added to parent, not to slider, otherwise slider catches all input attempts. Integer textfields (stepsize == 1) have shorter widths. float textFieldWidth = stepSize == 1 ? IntTextFieldWidth : FloatTextFieldWidth; UITextField valueField = UIControls.TinyTextField(parent, xPos + Margin + newSlider.width - textFieldWidth, yPos + ValueY, textFieldWidth); // Title label. UILabel titleLabel = UIControls.AddLabel(newSlider, 0f, LabelY, Translations.Translate(labelKey), textScale: 0.7f); // Autoscale tile label text, with minimum size 0.35. while (titleLabel.width > newSlider.width - textFieldWidth && titleLabel.textScale > 0.35f) { titleLabel.textScale -= 0.05f; } // Slider track. UISlicedSprite sliderSprite = newSlider.AddUIComponent <UISlicedSprite>(); sliderSprite.atlas = TextureUtils.InGameAtlas; sliderSprite.spriteName = "BudgetSlider"; sliderSprite.size = new Vector2(newSlider.width, 9f); sliderSprite.relativePosition = new Vector2(0f, 4f); // Slider thumb. UISlicedSprite sliderThumb = newSlider.AddUIComponent <UISlicedSprite>(); sliderThumb.atlas = TextureUtils.InGameAtlas; sliderThumb.spriteName = "SliderBudget"; newSlider.thumbObject = sliderThumb; // Set references. newSlider.ValueField = valueField; // Event handler for textfield. newSlider.ValueField.eventTextSubmitted += newSlider.OnTextSubmitted; // Set initial values. newSlider.StepSize = stepSize; newSlider.maxValue = maxValue; newSlider.minValue = minValue; newSlider.TrueValue = 0f; return(newSlider); }
/// <summary> /// Constructor. /// </summary> internal BOBPanelBase() { // Basic behaviour. autoLayout = false; canFocus = true; isInteractive = true; // Appearance. backgroundSprite = "MenuPanel2"; opacity = PanelOpacity; // Size. size = new Vector2(PanelWidth, PanelHeight); // Drag bar. UIDragHandle dragHandle = AddUIComponent <UIDragHandle>(); dragHandle.width = this.width - 50f; dragHandle.height = this.height; dragHandle.relativePosition = Vector3.zero; dragHandle.target = this; // Close button. UIButton closeButton = AddUIComponent <UIButton>(); closeButton.relativePosition = new Vector2(width - 35, 2); closeButton.normalBgSprite = "buttonclose"; closeButton.hoveredBgSprite = "buttonclosehover"; closeButton.pressedBgSprite = "buttonclosepressed"; closeButton.eventClick += (component, clickEvent) => CloseEvent(); // Name filter. nameFilter = UIControls.SmallLabelledTextField(this, width - 200f - Margin, TitleHeight + Margin, Translations.Translate("BOB_FIL_NAME")); // Event handlers for name filter textbox. nameFilter.eventTextChanged += (control, text) => LoadedList(); nameFilter.eventTextSubmitted += (control, text) => LoadedList(); // Vanilla filter. hideVanilla = UIControls.LabelledCheckBox((UIComponent)(object)this, nameFilter.relativePosition.x, nameFilter.relativePosition.y + nameFilter.height + (Margin / 2f), Translations.Translate("BOB_PNL_HDV"), 12f, 0.7f); hideVanilla.isChecked = ModSettings.hideVanilla; hideVanilla.eventCheckChanged += VanillaCheckChanged; // Mode label. modeLabel = UIControls.AddLabel(this, Margin, ToggleHeaderY, Translations.Translate("BOB_PNL_MOD"), textScale: 0.8f); // Tree/Prop checkboxes. propCheck = IconToggleCheck(this, Margin, ToggleY, "BOB-PropsSmall", "BOB_PNL_PRP"); treeCheck = IconToggleCheck(this, Margin + ToggleSize, ToggleY, "BOB-TreesSmall", "BOB_PNL_TRE"); propCheck.isChecked = !InitialTreeCheckedState; treeCheck.isChecked = InitialTreeCheckedState; propCheck.eventCheckChanged += PropCheckChanged; treeCheck.eventCheckChanged += TreeCheckChanged; }
/// <summary> /// Adds configurations panel tab to tabstrip. /// </summary> /// <param name="tabStrip">Tab strip to add to</param> /// <param name="tabIndex">Index number of tab</param> internal ConfigurationsPanel(UITabstrip tabStrip, int tabIndex) { // Set reference. instance = this; // Determine if we're in-game or not; use status of replacer managers to determine. inGame = BuildingReplacement.Instance != null && NetworkReplacement.Instance != null; // Add tab and helper. UIPanel panel = PanelUtils.AddTab(tabStrip, Translations.Translate("BOB_OPT_CFG"), tabIndex); UIHelper helper = new UIHelper(panel); panel.autoLayout = false; // Config list panel. UIPanel configListPanel = panel.AddUIComponent <UIPanel>(); configListPanel.width = ListWidth; configListPanel.height = ListHeight; configListPanel.relativePosition = new Vector2(Margin, ListY); // Config selection list. configList = UIFastList.Create <UIConfigRow>(configListPanel); configList.backgroundSprite = "UnlockingPanel"; configList.width = configListPanel.width; configList.height = configListPanel.height; configList.canSelect = true; configList.rowHeight = RowHeight; configList.autoHideScrollbar = true; configList.relativePosition = Vector2.zero; configList.rowsData = new FastList <object>(); // File name textfield. UILabel fileTextLabel = UIControls.AddLabel(panel, ControlPanelX, ListY, "New configuration name:"); fileNameField = UIControls.AddTextField(panel, ControlPanelX, ListY + fileTextLabel.height); fileNameField.eventTextChanged += (control, text) => UpdateButtonStates(); // Buttons. activeCopyButton = UIControls.AddButton(panel, ControlPanelX, ListY + 70f, Translations.Translate("BOB_CFG_SAC"), 300f, scale: 0.8f); activeCopyButton.eventClicked += NewCurrent; selectedCopyButton = UIControls.AddButton(panel, ControlPanelX, ListY + 105f, Translations.Translate("BOB_CFG_SSC"), 300f, scale: 0.8f); selectedCopyButton.eventClicked += CopySelected; newCleanButton = UIControls.AddButton(panel, ControlPanelX, ListY + 140f, Translations.Translate("BOB_CFG_SEC"), 300f, scale: 0.8f); newCleanButton.eventClicked += NewClean; deleteButton = UIControls.AddButton(panel, ControlPanelX, ListY + 210f, Translations.Translate("BOB_CFG_DEL"), 300f, scale: 0.8f); deleteButton.eventClicked += Delete; // Ingame buttons - 'use custom' check and apply and nuke buttons. if (inGame) { // Use custom check box. customCheck = UIControls.LabelledCheckBox(panel, Margin, ToolBarY, Translations.Translate("BOB_CFG_UCS")); customCheck.eventCheckChanged += (control, isChecked) => { // If we've got a valid selection, set the current config name to this. if (isChecked && !string.IsNullOrEmpty(selectedConfig)) { ConfigurationUtils.CurrentSavedConfigName = selectedConfig; } }; // Apply button. UIButton applyButton = UIControls.AddButton(panel, Margin, FooterY, Translations.Translate("BOB_CFG_LAA"), 400f, scale: 0.8f); applyButton.eventClicked += Apply; // Use global configuration button. UIButton globalButton = UIControls.AddButton(panel, Margin, FooterY + 50f, Translations.Translate("BOB_CFG_LGL"), 400f, scale: 0.8f); globalButton.eventClicked += UseGlobal; // Clean up config button. UIButton cleanUpButton = UIControls.AddButton(panel, Margin + 50f, FooterY + 150f, Translations.Translate("BOB_CFG_CLE"), 300f); cleanUpButton.tooltip = Translations.Translate("BOB_CFG_CLE_TIP"); cleanUpButton.eventClicked += (control, clickEvent) => ConfigurationUtils.Cleanup(); // Nuke all settings button. UIButton nukeButton = UIControls.AddButton(panel, Margin + 50f, FooterY + 200f, Translations.Translate("BOB_NUKE"), 300f); nukeButton.eventClicked += (control, clickEvent) => { // Revert all-building and building settings. ReplacementUtils.NukeSettings(); // Save clean configuration. //ConfigurationUtils.SaveConfig(ConfigurationUtils.CurrentSavedConfigName, true); }; } // Populate selection list and set initial button states. RefreshList(); // Select current pack if we've got one. if (customCheck != null && customCheck.isChecked) { // Try to select current config name. selectedConfig = configList.FindItem(ConfigurationUtils.CurrentSavedConfigName); // Did we find it? if (selectedConfig == null) { // Not found; uncheck the use custom check. customCheck.isChecked = false; } } // Set initial button states. UpdateButtonStates(); }
/// <summary> /// Sets the target prefab. /// </summary> /// <param name="targetPrefabInfo">Target prefab to set</param> internal override void SetTarget(PrefabInfo targetPrefabInfo) { // Don't do anything if invalid target, or target hasn't changed. if (!(targetPrefabInfo is BuildingInfo) || selectedPrefab == targetPrefabInfo) { return; } // Base setup. base.SetTarget(targetPrefabInfo); // Set target reference. currentBuilding = SelectedBuilding; // Does this building have sub-buildings? if (currentBuilding.m_subBuildings != null && currentBuilding.m_subBuildings.Length > 0) { // Yes - create lists of sub-buildings (names and infos). int numSubs = currentBuilding.m_subBuildings.Length; int numChoices = numSubs + 1; SubBuildingNames = new string[numChoices]; subBuildings = new BuildingInfo[numChoices]; SubBuildingNames[0] = PrefabLists.GetDisplayName(currentBuilding); subBuildings[0] = currentBuilding; object[] subBuildingIndexes = new object[numChoices]; subBuildingIndexes[0] = 0; for (int i = 0; i < numSubs; ++i) { SubBuildingNames[i + 1] = PrefabLists.GetDisplayName(currentBuilding.m_subBuildings[i].m_buildingInfo); subBuildings[i + 1] = currentBuilding.m_subBuildings[i].m_buildingInfo; subBuildingIndexes[i + 1] = i + 1; } // Add sub-building menu, if it doesn't already exist. if (subBuildingPanel == null) { subBuildingPanel = this.AddUIComponent <UIPanel>(); // Basic behaviour. subBuildingPanel.autoLayout = false; subBuildingPanel.canFocus = true; subBuildingPanel.isInteractive = true; // Appearance. subBuildingPanel.backgroundSprite = "MenuPanel2"; subBuildingPanel.opacity = PanelOpacity; // Size and position. subBuildingPanel.size = new Vector2(200f, PanelHeight - TitleHeight); subBuildingPanel.relativePosition = new Vector2(-205f, TitleHeight); // Heading. UILabel subTitleLabel = UIControls.AddLabel(subBuildingPanel, 5f, 5f, Translations.Translate("BOB_PNL_SUB"), 190f); subTitleLabel.textAlignment = UIHorizontalAlignment.Center; subTitleLabel.relativePosition = new Vector2(5f, (TitleHeight - subTitleLabel.height) / 2f); // List panel. UIPanel subBuildingListPanel = subBuildingPanel.AddUIComponent <UIPanel>(); subBuildingListPanel.relativePosition = new Vector2(Margin, TitleHeight); subBuildingListPanel.width = subBuildingPanel.width - (Margin * 2f); subBuildingListPanel.height = subBuildingPanel.height - TitleHeight - (Margin * 2f); subBuildingList = UIFastList.Create <UISubBuildingRow>(subBuildingListPanel); ListSetup(subBuildingList); // Create return fastlist from our filtered list. subBuildingList.rowsData = new FastList <object> { m_buffer = subBuildingIndexes, m_size = subBuildingIndexes.Length }; } else { // If the sub-building panel has already been created. just make sure it's visible. subBuildingPanel.Show(); } } else { // Otherwise, hide the sub-building panel (if it exists). subBuildingPanel?.Hide(); } // Populate target list and select target item. TargetList(); // Apply Harmony rendering patches. RenderOverlays.CurrentBuilding = selectedPrefab as BuildingInfo; Patcher.PatchBuildingOverlays(true); }