mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-10-28 00:54:19 -04:00
252 lines
7.9 KiB
C#
252 lines
7.9 KiB
C#
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
|
using System;
|
|
using System.Drawing;
|
|
using ClassicalSharp.Gui.Widgets;
|
|
using OpenTK.Input;
|
|
|
|
namespace ClassicalSharp.Gui.Screens {
|
|
public abstract class MenuOptionsScreen : MenuScreen {
|
|
|
|
public MenuOptionsScreen(Game game) : base(game) {
|
|
}
|
|
|
|
protected InputWidget input;
|
|
protected MenuInputValidator[] validators;
|
|
protected string[][] descriptions;
|
|
protected TextGroupWidget extendedHelp;
|
|
|
|
public override void Render(double delta) {
|
|
RenderMenuBounds();
|
|
int extClipY = extendedHelp == null ? 0 : widgets[widgets.Length - 3].Y;
|
|
int extEndY = extendedHelp == null ? 0 : extendedHelp.Y + extendedHelp.Height;
|
|
|
|
if (extendedHelp != null && extEndY <= extClipY) {
|
|
int tableWidth = extendedHelp.Width, tableHeight = extendedHelp.Height;
|
|
int x = game.Width / 2 - tableWidth / 2 - 5;
|
|
int y = game.Height / 2 + extHelpY - 5;
|
|
gfx.Draw2DQuad(x, y, tableWidth + 10, tableHeight + 10, tableCol);
|
|
}
|
|
|
|
gfx.Texturing = true;
|
|
RenderMenuWidgets(delta);
|
|
|
|
if (extendedHelp != null && extEndY <= extClipY)
|
|
extendedHelp.Render(delta);
|
|
gfx.Texturing = false;
|
|
}
|
|
|
|
public override void Init() {
|
|
titleFont = new Font(game.FontName, 16, FontStyle.Bold);
|
|
regularFont = new Font(game.FontName, 16, FontStyle.Regular);
|
|
game.Keyboard.KeyRepeat = true;
|
|
}
|
|
|
|
public override bool HandlesKeyPress(char key) {
|
|
if (input == null) return true;
|
|
return input.HandlesKeyPress(key);
|
|
}
|
|
|
|
public override bool HandlesKeyDown(Key key) {
|
|
if (key == Key.Escape) {
|
|
game.Gui.SetNewScreen(null);
|
|
return true;
|
|
} else if ((key == Key.Enter || key == Key.KeypadEnter)
|
|
&& input != null) {
|
|
ChangeSetting();
|
|
return true;
|
|
}
|
|
if (input == null)
|
|
return key < Key.F1 || key > Key.F35;
|
|
return input.HandlesKeyDown(key);
|
|
}
|
|
|
|
public override bool HandlesKeyUp(Key key) {
|
|
if (input == null) return true;
|
|
return input.HandlesKeyUp(key);
|
|
}
|
|
|
|
public override void OnResize(int width, int height) {
|
|
base.OnResize(width, height);
|
|
if (extendedHelp == null) return;
|
|
|
|
extendedHelp.XOffset = game.Width / 2 - extendedHelp.Width / 2;
|
|
extendedHelp.YOffset = game.Height / 2 + extHelpY;
|
|
extendedHelp.CalculatePosition();
|
|
}
|
|
|
|
public override void Dispose() {
|
|
DisposeWidgets();
|
|
game.Keyboard.KeyRepeat = false;
|
|
DisposeExtendedHelp();
|
|
base.Dispose();
|
|
}
|
|
|
|
protected ButtonWidget selectedWidget, targetWidget;
|
|
protected override void WidgetSelected(Widget widget) {
|
|
ButtonWidget button = widget as ButtonWidget;
|
|
if (selectedWidget == button || button == null ||
|
|
button == widgets[widgets.Length - 2]) return;
|
|
|
|
selectedWidget = button;
|
|
if (targetWidget != null) return;
|
|
UpdateDescription(selectedWidget);
|
|
}
|
|
|
|
protected void UpdateDescription(ButtonWidget widget) {
|
|
DisposeExtendedHelp();
|
|
if (widget == null || widget.GetValue == null) return;
|
|
|
|
ShowExtendedHelp();
|
|
}
|
|
|
|
protected virtual void InputOpened() { }
|
|
|
|
protected virtual void InputClosed() { }
|
|
|
|
protected ButtonWidget MakeOpt(int dir, int y, string text, ClickHandler onClick,
|
|
Func<Game, string> getter, Action<Game, string> setter) {
|
|
ButtonWidget widget = ButtonWidget.Create(game, 301, 41, text + ": " + getter(game), titleFont, onClick)
|
|
.SetLocation(Anchor.Centre, Anchor.Centre, 160 * dir, y);
|
|
widget.Metadata = text;
|
|
widget.GetValue = getter;
|
|
widget.SetValue = (g, v) => {
|
|
setter(g, v);
|
|
widget.SetText((string)widget.Metadata + ": " + getter(g));
|
|
};
|
|
return widget;
|
|
}
|
|
|
|
protected ButtonWidget MakeBool(int dir, int y, string text, string optKey,
|
|
ClickHandler onClick, Func<Game, bool> getter, Action<Game, bool> setter) {
|
|
return MakeBool(dir, y, text, optKey, false, onClick, getter, setter);
|
|
}
|
|
|
|
protected ButtonWidget MakeBool(int dir, int y, string text, string optKey, bool invert,
|
|
ClickHandler onClick, Func<Game, bool> getter, Action<Game, bool> setter) {
|
|
string optName = text;
|
|
text = text + ": " + (getter(game) ? "ON" : "OFF");
|
|
ButtonWidget widget = ButtonWidget.Create(game, 301, 41, text, titleFont, onClick)
|
|
.SetLocation(Anchor.Centre, Anchor.Centre, 160 * dir, y);
|
|
widget.Metadata = optName;
|
|
widget.GetValue = g => getter(g) ? "yes" : "no";
|
|
string target = invert ? "no" : "yes";
|
|
|
|
widget.SetValue = (g, v) => {
|
|
setter(g, v == "yes");
|
|
Options.Set(optKey, v == target);
|
|
widget.SetText((string)widget.Metadata + ": " + (v == "yes" ? "ON" : "OFF"));
|
|
};
|
|
return widget;
|
|
}
|
|
|
|
void ShowExtendedHelp() {
|
|
bool canShow = input == null && selectedWidget != null && descriptions != null;
|
|
if (!canShow) return;
|
|
|
|
int index = Array.IndexOf<Widget>(widgets, selectedWidget);
|
|
if (index < 0 || index >= descriptions.Length) return;
|
|
string[] desc = descriptions[index];
|
|
if (desc == null) return;
|
|
MakeExtendedHelp(desc);
|
|
}
|
|
|
|
static FastColour tableCol = new FastColour(20, 20, 20, 200);
|
|
const int extHelpY = 100;
|
|
|
|
void MakeExtendedHelp(string[] desc) {
|
|
extendedHelp = new TextGroupWidget(game, desc.Length, regularFont, null)
|
|
.SetLocation(Anchor.LeftOrTop, Anchor.LeftOrTop, 0, 0);
|
|
extendedHelp.Init();
|
|
for (int i = 0; i < desc.Length; i++)
|
|
extendedHelp.SetText(i, desc[i]);
|
|
|
|
extendedHelp.XOffset = game.Width / 2 - extendedHelp.Width / 2;
|
|
extendedHelp.YOffset = game.Height / 2 + extHelpY;
|
|
extendedHelp.CalculatePosition();
|
|
}
|
|
|
|
void DisposeExtendedHelp() {
|
|
if (extendedHelp == null) return;
|
|
extendedHelp.Dispose();
|
|
extendedHelp = null;
|
|
}
|
|
|
|
protected void OnWidgetClick(Game game, Widget widget, MouseButton btn, int x, int y) {
|
|
ButtonWidget button = widget as ButtonWidget;
|
|
if (btn != MouseButton.Left) return;
|
|
if (widget == widgets[widgets.Length - 1]) {
|
|
ChangeSetting(); return;
|
|
}
|
|
if (button == null) return;
|
|
DisposeExtendedHelp();
|
|
|
|
int index = Array.IndexOf<Widget>(widgets, button);
|
|
MenuInputValidator validator = validators[index];
|
|
if (validator is BooleanValidator) {
|
|
string value = button.GetValue(game);
|
|
button.SetValue(game, value == "yes" ? "no" : "yes");
|
|
UpdateDescription(button);
|
|
return;
|
|
} else if (validator is EnumValidator) {
|
|
Type type = ((EnumValidator)validator).EnumType;
|
|
HandleEnumOption(button, type);
|
|
return;
|
|
}
|
|
|
|
targetWidget = selectedWidget;
|
|
if (input != null) input.Dispose();
|
|
|
|
input = MenuInputWidget.Create(game, 400, 30,
|
|
button.GetValue(game), regularFont, validator)
|
|
.SetLocation(Anchor.Centre, Anchor.Centre, 0, 110);
|
|
input.ShowCaret = true;
|
|
input.OnClick = InputClick;
|
|
|
|
widgets[widgets.Length - 2] = input;
|
|
widgets[widgets.Length - 1] = ButtonWidget.Create(game, 40, 30, "OK", titleFont, OnWidgetClick)
|
|
.SetLocation(Anchor.Centre, Anchor.Centre, 240, 110);
|
|
|
|
InputOpened();
|
|
UpdateDescription(targetWidget);
|
|
}
|
|
|
|
void InputClick(Game game, Widget widget, MouseButton btn, int x, int y) {
|
|
if (btn != MouseButton.Left) return;
|
|
widget.HandlesMouseClick(x, y, btn);
|
|
}
|
|
|
|
void HandleEnumOption(ButtonWidget button, Type type) {
|
|
string value = button.GetValue(game);
|
|
int enumValue = (int)Enum.Parse(type, value, true);
|
|
enumValue++;
|
|
// go back to first value
|
|
if (!Enum.IsDefined(type, enumValue))
|
|
enumValue = 0;
|
|
button.SetValue(game, Enum.GetName(type, enumValue));
|
|
UpdateDescription(button);
|
|
}
|
|
|
|
void ChangeSetting() {
|
|
string text = input.Text.ToString();
|
|
if (((MenuInputWidget)input).Validator.IsValidValue(text))
|
|
targetWidget.SetValue(game, text);
|
|
|
|
DisposeWidgets();
|
|
UpdateDescription(targetWidget);
|
|
targetWidget = null;
|
|
InputClosed();
|
|
}
|
|
|
|
void DisposeWidgets() {
|
|
if (input != null)
|
|
input.Dispose();
|
|
widgets[widgets.Length - 2] = null;
|
|
input = null;
|
|
|
|
int okayIndex = widgets.Length - 1;
|
|
if (widgets[okayIndex] != null)
|
|
widgets[okayIndex].Dispose();
|
|
widgets[okayIndex] = null;
|
|
}
|
|
}
|
|
} |