private void DoCategory(EntityCategory node, int openMask, int indentLevel) { if (!node.DescendantThings.Any()) { return; } base.OpenCloseWidget(node, indentLevel, openMask); base.LabelLeft(node.LabelCap, node.Description, indentLevel); MultiCheckboxState multiCheckboxState = this.AllowanceStateOf(node); if (Widgets.CheckboxMulti(new Vector2(this.LabelWidth, this.curY), multiCheckboxState, this.lineHeight)) { bool allow = multiCheckboxState == MultiCheckboxState.Off; foreach (var thing in node.DescendantThings) { this.filter.SetAllow(thing, allow); } foreach (var spFilter in node.catDef.DescendantSpecialEntityFilterDefs) { this.filter.SetAllow(spFilter, allow); } } base.EndLine(); if (node.IsOpen(openMask)) { this.DoCurrent(node, openMask, indentLevel + 1); } }
public void DoCategory(TreeNode_ThingCategory node, int indentLevel, int openMask, Map map) { OpenCloseWidget(node, indentLevel, openMask); LabelLeft(node.LabelCap, node.catDef.description, indentLevel); MultiCheckboxState multiCheckboxState = AllowanceStateOf(node); MultiCheckboxState multiCheckboxState2 = Widgets.CheckboxMulti(new Rect(LabelWidth, curY, lineHeight, lineHeight), multiCheckboxState, paintable: true); if (multiCheckboxState != multiCheckboxState2) { filter.SetAllow(node.catDef, multiCheckboxState2 == MultiCheckboxState.On, forceHiddenDefs, hiddenSpecialFilters); } EndLine(); if (node.IsOpen(openMask)) { DoCategoryChildren(node, indentLevel + 1, openMask, map); } }
public void DoCategory(TreeNode_ThingCategory node, int indentLevel, int openMask) { base.OpenCloseWidget(node, indentLevel, openMask); base.LabelLeft(node.LabelCap, node.catDef.description, indentLevel); MultiCheckboxState multiCheckboxState = this.AllowanceStateOf(node); if (Widgets.CheckboxMulti(new Vector2(this.LabelWidth, this.curY), multiCheckboxState, this.lineHeight)) { bool allow = multiCheckboxState == MultiCheckboxState.Off; this.filter.SetAllow(node.catDef, allow, this.forceHiddenDefs, this.hiddenSpecialFilters); } base.EndLine(); if (node.IsOpen(openMask)) { this.DoCategoryChildren(node, indentLevel + 1, openMask, false); } }
public void DoCategory(TreeNode_ThingCategory node, int indentLevel, int openMask, Map map) { base.OpenCloseWidget(node, indentLevel, openMask); base.LabelLeft(node.LabelCap, node.catDef.description, indentLevel, 0f); MultiCheckboxState multiCheckboxState = this.AllowanceStateOf(node); MultiCheckboxState multiCheckboxState2 = Widgets.CheckboxMulti(new Rect(this.LabelWidth, this.curY, this.lineHeight, this.lineHeight), multiCheckboxState, true); if (multiCheckboxState != multiCheckboxState2) { this.filter.SetAllow(node.catDef, multiCheckboxState2 == MultiCheckboxState.On, this.forceHiddenDefs, this.hiddenSpecialFilters); } base.EndLine(); if (node.IsOpen(openMask)) { this.DoCategoryChildren(node, indentLevel + 1, openMask, map, false); } }
private void DrawPartButtons(ref float curY, Rect partListViewRect, List <Hediff_AddedMutation> mutations, List <BodyPartRecord> parts, MutationLayer layer, string label) { // Draw the main mutation selection button. It should take up the whole width if there are no mutations, otherwise it will leave a space for the edit button. float partButtonWidth = partListViewRect.width - (mutations.NullOrEmpty() ? 0 : editButtonWidth); Rect partButtonRect = new Rect(partListViewRect.x, curY, partButtonWidth, Text.CalcHeight(label, partButtonWidth - BUTTON_HORIZONTAL_PADDING)); if (Widgets.ButtonText(partButtonRect, label)) { List <FloatMenuOption> options = new List <FloatMenuOption>(); void removeMutations() { foreach (Hediff_AddedMutation mutation in mutations) { addedMutations.RemoveByPartAndLayer(mutation.Part, layer); if (cachedInitialHediffs.Select(m => m.hediff).Contains(mutation)) { addedMutations.AddData(mutation.Def, mutation.Part, mutation.Severity, mutation.ProgressionHalted, true); } pawn.health.RemoveHediff(mutation); } recachePreview = true; RecachePawnMutations(); } options.Add(new FloatMenuOption(NO_MUTATIONS_LOC_STRING.Translate(), removeMutations)); List <MutationDef> mutationDefs = cachedMutationDefsByPartDef[parts.FirstOrDefault().def]; foreach (MutationDef mutationDef in mutationDefs.Where(m => m.RemoveComp.layer == layer && (DebugSettings.godMode || m.IsTagged()))) { void addMutation() { foreach (Hediff_AddedMutation mutation in mutations) { pawn.health.RemoveHediff(mutation); } foreach (BodyPartRecord part in parts) { addedMutations.RemoveByPartAndLayer(part, layer); addedMutations.AddData(mutationDef, part, mutationDef.initialSeverity, false, false); MutationUtilities.AddMutation(pawn, mutationDef, part, ancillaryEffects: MutationUtilities.AncillaryMutationEffects.None); //don't give the green puffs } recachePreview = true; RecachePawnMutations(); } options.Add(new FloatMenuOption(mutationDef.LabelCap, addMutation)); } Find.WindowStack.Add(new FloatMenu(options)); } curY += partButtonRect.height; // If there are actually mutations, draw the edit button. if (!mutations.NullOrEmpty()) { Rect editButtonRect = new Rect(partButtonWidth, partButtonRect.y, editButtonWidth, partButtonRect.height); if (Widgets.ButtonText(editButtonRect, editButtonText)) { detailPart = (detailPart.Item1 == parts.FirstOrDefault() && detailPart.Item2 == layer) ? new Tuple <BodyPartRecord, MutationLayer>(new BodyPartRecord(), 0) : new Tuple <BodyPartRecord, MutationLayer>(parts.FirstOrDefault(), layer); } } // If the currently selected part and layer match up with the part to give details for, draw the edit area below the buttons. if (detailPart.Item1 == parts.FirstOrDefault() && detailPart.Item2 == layer) { foreach (MutationDef mutationDef in mutations.Select(m => m.Def).Distinct()) { List <Hediff_AddedMutation> mutationsOfDef = mutations.Where(m => m.Def == mutationDef).ToList(); // Draw the LabelCap of the current Def if there is more than one type of mutation in the current list. if (mutations.Select(m => m.Def).Distinct().Count() > 1) { Widgets.ListSeparator(ref curY, partListViewRect.width, mutationDef.LabelCap); } // Draw the various labels for the severity bar (need to refine this later). string stageLabelText = $"Stage {mutationsOfDef.FirstOrDefault().CurStageIndex}: {mutationsOfDef.FirstOrDefault().LabelCap}"; Rect severityLabelsRect = new Rect(partListViewRect.x, curY, partListViewRect.width, Text.CalcHeight(stageLabelText, partListViewRect.width)); Text.Anchor = TextAnchor.MiddleLeft; Widgets.Label(severityLabelsRect, stageLabelText); Text.Anchor = TextAnchor.MiddleRight; Widgets.Label(severityLabelsRect, mutationsOfDef.FirstOrDefault().Severity.ToString("n2")); Text.Anchor = TextAnchor.UpperLeft; curY += severityLabelsRect.height; // Draw the severity slider float curSeverity = mutationsOfDef.Select(n => n.Severity).Average(); float newSeverity = Widgets.HorizontalSlider(new Rect(partListViewRect.x, curY, partListViewRect.width, SLIDER_HEIGHT), curSeverity, mutationDef.minSeverity, mutationDef.maxSeverity); if (curSeverity != newSeverity) { curSeverity = newSeverity; foreach (Hediff_AddedMutation mutationOfDef in mutationsOfDef) { MutationData relevantEntry = addedMutations.MutationsByPartAndLayer(mutationOfDef.Part, layer); if (relevantEntry != null) { relevantEntry.severity = newSeverity; } else { addedMutations.AddData(mutationOfDef.Def, mutationOfDef.Part, newSeverity, mutationOfDef.ProgressionHalted, false); } mutationOfDef.Severity = newSeverity; } recachePreview = true; } curY += SLIDER_HEIGHT; // If the mutation has the ability to be paused, show the toggle for it. // This is a CheckboxMulti to handle edge cases, but likely could be replaced with a simple Checkbox. if (mutationDef.CompProps <CompProperties_MutationSeverityAdjust>() != null) { float pauseLabelWidth = partListViewRect.width - IS_PAUSED_CHECKBOX_SIZE.x; Rect pauseLabelRect = new Rect(partListViewRect.x, curY, pauseLabelWidth, Text.CalcHeight(IS_PAUSED_LOC_STRING.Translate(), partListViewRect.width)); Rect checkBoxRect = new Rect(partListViewRect.x + pauseLabelWidth, curY, IS_PAUSED_CHECKBOX_SIZE.x, IS_PAUSED_CHECKBOX_SIZE.y); MultiCheckboxState initialState = !mutationsOfDef.Select(n => n.ProgressionHalted).Contains(true) ? MultiCheckboxState.Off : !mutationsOfDef.Select(n => n.ProgressionHalted).Contains(false) ? MultiCheckboxState.On : MultiCheckboxState.Partial; Widgets.Label(pauseLabelRect, IS_PAUSED_LOC_STRING.Translate()); MultiCheckboxState newState = Widgets.CheckboxMulti(checkBoxRect, initialState); if (initialState != newState) { initialState = newState; mutationsOfDef.FirstOrDefault().SeverityAdjust.Halted = !mutationsOfDef.FirstOrDefault().SeverityAdjust.Halted; foreach (Hediff_AddedMutation mutationOfDef in mutationsOfDef) { MutationData relevantEntry = addedMutations.MutationsByPartAndLayer(mutationOfDef.Part, layer); if (cachedInitialHediffs.Select(m => m.hediff).Contains(mutationOfDef)) { bool initialHediffIsHalted = cachedInitialHediffs.Where(m => m.hediff == mutationOfDef).FirstOrDefault().isHalted; if (newState == MultiCheckboxState.On == initialHediffIsHalted) { addedMutations.RemoveByPartAndLayer(mutationOfDef.Part, layer); } } if (relevantEntry != null) { relevantEntry.isHalted = newState == MultiCheckboxState.On; } else { addedMutations.AddData(mutationOfDef.Def, mutationOfDef.Part, mutationOfDef.Severity, newState == MultiCheckboxState.On, false); } } } curY += Math.Max(pauseLabelRect.height, checkBoxRect.height); } } } // Create a zone for updating the lower description box (The one that shows details based on the currently hovered over mutation). Rect descriptionUpdateRect = new Rect(partListViewRect.x, partButtonRect.y, partListViewRect.width, curY - partButtonRect.y); if (Mouse.IsOver(descriptionUpdateRect)) { foreach (MutationDef mutation in mutations.Select(m => m.def).Distinct()) { Hediff_AddedMutation firstMutationOfDef = mutations.Where(m => m.def == mutation).FirstOrDefault(); partDescBuilder.AppendLine(firstMutationOfDef.LabelCap); partDescBuilder.AppendLine(firstMutationOfDef.Description); partDescBuilder.AppendLine(firstMutationOfDef.TipStringExtra); partDescBuilder.AppendLine(); } } }
public void DrawFilters(Rect canvas) { GUI.BeginGroup(canvas); var listing = new Listing_Standard(); var viewPort = new Rect(canvas.x, canvas.y, canvas.width - 16f, _filters.Sum(f => f.Height)); Widgets.BeginScrollView(canvas, ref _scrollPos, viewPort); listing.Begin(viewPort); foreach (ThingItemFilterCategory category in _filters) { Rect lineRect = listing.GetRect(Text.LineHeight); if (!lineRect.IsVisible(viewPort, _scrollPos) && !category.Expanded) { continue; } Rect arrowIconRect = new Rect(lineRect.x, lineRect.y, lineRect.height, lineRect.height).ContractedBy(4f); Rect checkStateRect = new Rect(arrowIconRect.x + arrowIconRect.width, lineRect.y, lineRect.height, lineRect.height).ContractedBy(4f); var categoryTextRect = new Rect( checkStateRect.x + checkStateRect.width + 5f, lineRect.y, lineRect.width - 5f - arrowIconRect.width - checkStateRect.width, lineRect.height ); GUI.DrawTexture(arrowIconRect.ContractedBy(2f), category.Expanded ? Textures.ExpandedArrow : Textures.CollapsedArrow); MultiCheckboxState state = Widgets.CheckboxMulti(checkStateRect, category.CheckState, true); if (state != category.CheckState) { category.CheckState = state; foreach (ThingItemFilter filter in category.Filters) { switch (category.CheckState) { case MultiCheckboxState.Off: filter.Active = false; break; case MultiCheckboxState.On: filter.Active = true; break; } } } UiHelper.Label(categoryTextRect, $"TKUtils.FilterTypes.{category.FilterType}".TranslateSimple()); if (Widgets.ButtonInvisible(arrowIconRect)) { category.Expanded = !category.Expanded; } if (category.Expanded) { DrawFiltersFor(category, listing, viewPort); } } GUI.EndGroup(); listing.End(); Widgets.EndScrollView(); }