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(); }