Skip to content

Commit

Permalink
change: Use a TabControl to draw the Preferences screen.
Browse files Browse the repository at this point in the history
  • Loading branch information
DaleStan committed Oct 28, 2024
1 parent ed8d031 commit 8ac61d4
Showing 1 changed file with 113 additions and 128 deletions.
241 changes: 113 additions & 128 deletions Yafc/Windows/PreferencesScreen.cs
Original file line number Diff line number Diff line change
@@ -1,169 +1,154 @@
using System;
using System.Numerics;
using Yafc.Model;
using Yafc.UI;

namespace Yafc;

public class PreferencesScreen : PseudoScreen {
private static readonly PreferencesScreen Instance = new PreferencesScreen();
private bool onProgressionPage;
private const int GENERAL_PAGE = 0, PROGRESSION_PAGE = 1;
private readonly TabControl tabControl = new(("General", DrawGeneral), ("Progression", DrawProgression), ("Tab 1", null), ("Tab 2", null), ("Tab 3", null), ("Tab 4", null), ("Tab 5's title text causes fewer problems", DrawGeneral), ("Tab 6", null), ("Tab 7", null), ("Tab 8 has an obscenely long title text for the purpose of causing as many problems as physically possible", null), ("Tab 9 wants three lines\nin its text, but\nthat doesn't work", null));

public override void Build(ImGui gui) {
BuildHeader(gui, "Preferences");
gui.AllocateSpacing();
tabControl.FullWidthTabRows = true;
tabControl.MaximumTextCompression=.1f;
tabControl.HorizontalTabSeparation=.8f;
tabControl.HorizontalTextPadding = .5f;
tabControl.Build(gui);
gui.AllocateSpacing();
if (gui.BuildButton("Done")) {
Close();
}

// Draw tabs
Rect generalRect = new(gui.statePosition.TopLeft, new((gui.statePosition.Width + .8f) / 2 - .8f, 2.25f));
Rect progressionRect = generalRect + new Vector2(generalRect.Width + .8f, 0);
gui.DrawText(generalRect, "General", RectAlignment.Middle);
gui.DrawText(progressionRect, "Progression", RectAlignment.Middle);
if (onProgressionPage) {
gui.DrawRectangle(progressionRect, SchemeColor.Secondary);
if (gui.BuildButton(generalRect, SchemeColor.Primary, SchemeColor.PrimaryAlt)) {
onProgressionPage = false;
}
if (Project.current.preferences.justChanged) {
MainScreen.Instance.RebuildProjectView();
}
else {
if (gui.BuildButton(progressionRect, SchemeColor.Primary, SchemeColor.PrimaryAlt)) {
onProgressionPage = true;
}
gui.DrawRectangle(generalRect, SchemeColor.Secondary);

if (Project.current.settings.justChanged) {
Project.current.RecalculateDisplayPages();
}
gui.DrawRectangle(new(gui.statePosition.X, gui.statePosition.Y + 2.25f, gui.statePosition.Width, .25f), SchemeColor.Secondary);
gui.AllocateRect(0, 2.5f, 0); // Allocate (vertical) space for the tabs
}

private static void DrawProgression(ImGui gui) {
var prefs = Project.current.preferences;
var settings = Project.current.settings;

// Allocate both pages, draw current page
using (var controller = gui.StartOverlappingAllocations(onProgressionPage)) {
ChooseObject(gui, "Default belt:", Database.allBelts, prefs.defaultBelt, s => {
prefs.RecordUndo().defaultBelt = s;
gui.Rebuild();
});
ChooseObject(gui, "Default inserter:", Database.allInserters, prefs.defaultInserter, s => {
prefs.RecordUndo().defaultInserter = s;
gui.Rebuild();
});
ChooseObject(gui, "Default belt:", Database.allBelts, prefs.defaultBelt, s => {
prefs.RecordUndo().defaultBelt = s;
gui.Rebuild();
});
ChooseObject(gui, "Default inserter:", Database.allInserters, prefs.defaultInserter, s => {
prefs.RecordUndo().defaultInserter = s;
gui.Rebuild();
});

using (gui.EnterRow()) {
gui.BuildText("Inserter capacity:", topOffset: 0.5f);
if (gui.BuildIntegerInput(prefs.inserterCapacity, out int newCapacity)) {
prefs.RecordUndo().inserterCapacity = newCapacity;
}
using (gui.EnterRow()) {
gui.BuildText("Inserter capacity:", topOffset: 0.5f);
if (gui.BuildIntegerInput(prefs.inserterCapacity, out int newCapacity)) {
prefs.RecordUndo().inserterCapacity = newCapacity;
}
ChooseObjectWithNone(gui, "Target technology for cost analysis: ", Database.technologies.all, prefs.targetTechnology, x => {
prefs.RecordUndo().targetTechnology = x;
gui.Rebuild();
}, width: 25f);
}
ChooseObjectWithNone(gui, "Target technology for cost analysis: ", Database.technologies.all, prefs.targetTechnology, x => {
prefs.RecordUndo().targetTechnology = x;
gui.Rebuild();
}, width: 25f);

gui.AllocateSpacing();
using (gui.EnterRow()) {
gui.BuildText("Mining productivity bonus: ", topOffset: 0.5f);
DisplayAmount amount = new(Project.current.settings.miningProductivity, UnitOfMeasure.Percent);
if (gui.BuildFloatInput(amount, TextBoxDisplayStyle.DefaultTextInput) && amount.Value >= 0) {
Project.current.settings.RecordUndo().miningProductivity = amount.Value;
}
gui.AllocateSpacing();
using (gui.EnterRow()) {
gui.BuildText("Mining productivity bonus: ", topOffset: 0.5f);
DisplayAmount amount = new(Project.current.settings.miningProductivity, UnitOfMeasure.Percent);
if (gui.BuildFloatInput(amount, TextBoxDisplayStyle.DefaultTextInput) && amount.Value >= 0) {
Project.current.settings.RecordUndo().miningProductivity = amount.Value;
}
using (gui.EnterRow()) {
gui.BuildText("Research speed bonus: ", topOffset: 0.5f);
DisplayAmount amount = new(Project.current.settings.researchSpeedBonus, UnitOfMeasure.Percent);
if (gui.BuildFloatInput(amount, TextBoxDisplayStyle.DefaultTextInput) && amount.Value >= 0) {
Project.current.settings.RecordUndo().researchSpeedBonus = amount.Value;
}
}
using (gui.EnterRow()) {
gui.BuildText("Research speed bonus: ", topOffset: 0.5f);
DisplayAmount amount = new(Project.current.settings.researchSpeedBonus, UnitOfMeasure.Percent);
if (gui.BuildFloatInput(amount, TextBoxDisplayStyle.DefaultTextInput) && amount.Value >= 0) {
Project.current.settings.RecordUndo().researchSpeedBonus = amount.Value;
}
using (gui.EnterRow()) {
gui.BuildText("Research productivity bonus: ", topOffset: 0.5f);
DisplayAmount amount = new(Project.current.settings.researchProductivity, UnitOfMeasure.Percent);
if (gui.BuildFloatInput(amount, TextBoxDisplayStyle.DefaultTextInput) && amount.Value >= 0) {
Project.current.settings.RecordUndo().researchProductivity = amount.Value;
}
}
using (gui.EnterRow()) {
gui.BuildText("Research productivity bonus: ", topOffset: 0.5f);
DisplayAmount amount = new(Project.current.settings.researchProductivity, UnitOfMeasure.Percent);
if (gui.BuildFloatInput(amount, TextBoxDisplayStyle.DefaultTextInput) && amount.Value >= 0) {
Project.current.settings.RecordUndo().researchProductivity = amount.Value;
}
}
}

controller.StartNextAllocatePass(!onProgressionPage);

gui.BuildText("Unit of time:", Font.subheader);
using (gui.EnterRow()) {
if (gui.BuildRadioButton("Second", prefs.time == 1)) {
prefs.RecordUndo(true).time = 1;
}

if (gui.BuildRadioButton("Minute", prefs.time == 60)) {
prefs.RecordUndo(true).time = 60;
}

if (gui.BuildRadioButton("Hour", prefs.time == 3600)) {
prefs.RecordUndo(true).time = 3600;
}

if (gui.BuildRadioButton("Custom", prefs.time is not 1 and not 60 and not 3600)) {
prefs.RecordUndo(true).time = 0;
}
private static void DrawGeneral(ImGui gui) {
var prefs = Project.current.preferences;
var settings = Project.current.settings;

if (gui.BuildIntegerInput(prefs.time, out int newTime)) {
prefs.RecordUndo(true).time = newTime;
}
}
gui.AllocateSpacing(1f);
gui.BuildText("Item production/consumption:", Font.subheader);
BuildUnitPerTime(gui, false, prefs);
gui.BuildText("Fluid production/consumption:", Font.subheader);
BuildUnitPerTime(gui, true, prefs);

using (gui.EnterRowWithHelpIcon("0% for off, 100% for old default")) {
gui.BuildText("Pollution cost modifier", topOffset: 0.5f);
DisplayAmount amount = new(settings.PollutionCostModifier, UnitOfMeasure.Percent);
if (gui.BuildFloatInput(amount, TextBoxDisplayStyle.DefaultTextInput) && amount.Value >= 0) {
settings.RecordUndo().PollutionCostModifier = amount.Value;
gui.Rebuild();
}
gui.BuildText("Unit of time:", Font.subheader);
using (gui.EnterRow()) {
if (gui.BuildRadioButton("Second", prefs.time == 1)) {
prefs.RecordUndo(true).time = 1;
}

string iconScaleMessage = "Some mod icons have little or no transparency, hiding the background color. This setting reduces the size of icons that could hide link information.";
if (gui.BuildRadioButton("Minute", prefs.time == 60)) {
prefs.RecordUndo(true).time = 60;
}

using (gui.EnterRowWithHelpIcon(iconScaleMessage)) {
gui.BuildText("Display scale for linkable icons", topOffset: 0.5f);
DisplayAmount amount = new(prefs.iconScale, UnitOfMeasure.Percent);
if (gui.BuildFloatInput(amount, TextBoxDisplayStyle.DefaultTextInput) && amount.Value > 0 && amount.Value <= 1) {
prefs.RecordUndo().iconScale = amount.Value;
gui.Rebuild();
}
if (gui.BuildRadioButton("Hour", prefs.time == 3600)) {
prefs.RecordUndo(true).time = 3600;
}

using (gui.EnterRow()) {
gui.BuildText("Reactor layout:", topOffset: 0.5f);
if (gui.BuildTextInput(settings.reactorSizeX + "x" + settings.reactorSizeY, out string newSize, null, delayed: true)) {
int px = newSize.IndexOf('x');
if (px < 0 && int.TryParse(newSize, out int value)) {
settings.RecordUndo().reactorSizeX = value;
settings.reactorSizeY = value;
}
else if (int.TryParse(newSize[..px], out int sizeX) && int.TryParse(newSize[(px + 1)..], out int sizeY)) {
settings.RecordUndo().reactorSizeX = sizeX;
settings.reactorSizeY = sizeY;
}
}
if (gui.BuildRadioButton("Custom", prefs.time is not 1 and not 60 and not 3600)) {
prefs.RecordUndo(true).time = 0;
}

if (gui.BuildCheckBox("Dark mode", Preferences.Instance.darkMode, out bool newValue)) {
Preferences.Instance.darkMode = newValue;
Preferences.Instance.Save();
RenderingUtils.SetColorScheme(newValue);
if (gui.BuildIntegerInput(prefs.time, out int newTime)) {
prefs.RecordUndo(true).time = newTime;
}
}
gui.AllocateSpacing(1f);
gui.BuildText("Item production/consumption:", Font.subheader);
BuildUnitPerTime(gui, false, prefs);
gui.BuildText("Fluid production/consumption:", Font.subheader);
BuildUnitPerTime(gui, true, prefs);

using (gui.EnterRowWithHelpIcon("0% for off, 100% for old default")) {
gui.BuildText("Pollution cost modifier", topOffset: 0.5f);
DisplayAmount amount = new(settings.PollutionCostModifier, UnitOfMeasure.Percent);
if (gui.BuildFloatInput(amount, TextBoxDisplayStyle.DefaultTextInput) && amount.Value >= 0) {
settings.RecordUndo().PollutionCostModifier = amount.Value;
gui.Rebuild();
}
}

gui.AllocateSpacing();
if (gui.BuildButton("Done")) {
Close();
string iconScaleMessage = "Some mod icons have little or no transparency, hiding the background color. This setting reduces the size of icons that could hide link information.";

using (gui.EnterRowWithHelpIcon(iconScaleMessage)) {
gui.BuildText("Display scale for linkable icons", topOffset: 0.5f);
DisplayAmount amount = new(prefs.iconScale, UnitOfMeasure.Percent);
if (gui.BuildFloatInput(amount, TextBoxDisplayStyle.DefaultTextInput) && amount.Value > 0 && amount.Value <= 1) {
prefs.RecordUndo().iconScale = amount.Value;
gui.Rebuild();
}
}

if (prefs.justChanged) {
MainScreen.Instance.RebuildProjectView();
using (gui.EnterRow()) {
gui.BuildText("Reactor layout:", topOffset: 0.5f);
if (gui.BuildTextInput(settings.reactorSizeX + "x" + settings.reactorSizeY, out string newSize, null, delayed: true)) {
int px = newSize.IndexOf('x');
if (px < 0 && int.TryParse(newSize, out int value)) {
settings.RecordUndo().reactorSizeX = value;
settings.reactorSizeY = value;
}
else if (int.TryParse(newSize[..px], out int sizeX) && int.TryParse(newSize[(px + 1)..], out int sizeY)) {
settings.RecordUndo().reactorSizeX = sizeX;
settings.reactorSizeY = sizeY;
}
}
}

if (settings.justChanged) {
Project.current.RecalculateDisplayPages();
if (gui.BuildCheckBox("Dark mode", Preferences.Instance.darkMode, out bool newValue)) {
Preferences.Instance.darkMode = newValue;
Preferences.Instance.Save();
RenderingUtils.SetColorScheme(newValue);
}
}

Expand Down Expand Up @@ -233,11 +218,11 @@ private static void BuildUnitPerTime(ImGui gui, bool fluid, ProjectPreferences p
}

public static void ShowProgression() {
Instance.onProgressionPage = true;
Instance.tabControl.SetActivePage(PROGRESSION_PAGE);
_ = MainScreen.Instance.ShowPseudoScreen(Instance);
}
public static void ShowGeneral() {
Instance.onProgressionPage = false;
Instance.tabControl.SetActivePage(GENERAL_PAGE);
_ = MainScreen.Instance.ShowPseudoScreen(Instance);
}
public static void ShowPreviousState() => _ = MainScreen.Instance.ShowPseudoScreen(Instance);
Expand Down

0 comments on commit 8ac61d4

Please sign in to comment.