mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-10-08 13:34:54 -04:00
277 lines
10 KiB
C#
277 lines
10 KiB
C#
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
|
|
using System;
|
|
using System.Drawing;
|
|
using OpenTK.Input;
|
|
|
|
namespace ClassicalSharp.Gui {
|
|
|
|
public abstract class MenuOptionsScreen : MenuScreen {
|
|
|
|
public MenuOptionsScreen( Game game ) : base( game ) {
|
|
}
|
|
|
|
protected MenuInputWidget inputWidget;
|
|
protected MenuInputValidator[] validators;
|
|
protected string[][] descriptions;
|
|
protected TextGroupWidget extendedHelp;
|
|
Font extendedHelpFont;
|
|
|
|
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 x = game.Width / 2 - tableWidth / 2 - 5;
|
|
int y = game.Height / 2 + extHelpY - 5;
|
|
api.Draw2DQuad( x, y, tableWidth + 10, tableHeight + 10, tableCol );
|
|
}
|
|
|
|
api.Texturing = true;
|
|
RenderMenuWidgets( delta );
|
|
if( inputWidget != null )
|
|
inputWidget.Render( delta );
|
|
|
|
if( extendedHelp != null && extEndY <= extClipY )
|
|
extendedHelp.Render( delta );
|
|
api.Texturing = false;
|
|
}
|
|
|
|
public override void Init() {
|
|
base.Init();
|
|
regularFont = new Font( game.FontName, 16, FontStyle.Regular );
|
|
extendedHelpFont = new Font( game.FontName, 13, FontStyle.Regular );
|
|
game.Keyboard.KeyRepeat = true;
|
|
}
|
|
|
|
public override bool HandlesKeyPress( char key ) {
|
|
if( inputWidget == null ) return true;
|
|
return inputWidget.HandlesKeyPress( key );
|
|
}
|
|
|
|
public override bool HandlesKeyDown( Key key ) {
|
|
if( key == Key.Escape ) {
|
|
game.SetNewScreen( null );
|
|
return true;
|
|
} else if( (key == Key.Enter || key == Key.KeypadEnter)
|
|
&& inputWidget != null ) {
|
|
ChangeSetting();
|
|
return true;
|
|
}
|
|
if( inputWidget == null )
|
|
return key < Key.F1 || key > Key.F35;
|
|
return inputWidget.HandlesKeyDown( key );
|
|
}
|
|
|
|
public override bool HandlesKeyUp( Key key ) {
|
|
if( inputWidget == null ) return true;
|
|
return inputWidget.HandlesKeyUp( key );
|
|
}
|
|
|
|
public override void OnResize( int oldWidth, int oldHeight, int width, int height ) {
|
|
if( inputWidget != null )
|
|
inputWidget.OnResize( oldWidth, oldHeight, width, height );
|
|
|
|
base.OnResize( oldWidth, oldHeight, width, height );
|
|
if( extendedHelp == null ) return;
|
|
extendedHelp.OnResize( oldWidth, oldHeight, width, height );
|
|
}
|
|
|
|
public override void Dispose() {
|
|
if( inputWidget != null ) {
|
|
inputWidget.Dispose();
|
|
inputWidget = null;
|
|
}
|
|
|
|
game.Keyboard.KeyRepeat = false;
|
|
extendedHelpFont.Dispose();
|
|
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 Make( int dir, int y, string text, ClickHandler onClick,
|
|
Func<Game, string> getter, Action<Game, string> setter ) {
|
|
ButtonWidget widget = ButtonWidget.Create( game, 160 * dir, y, 280, 35, text, Anchor.Centre,
|
|
Anchor.Centre, titleFont, onClick );
|
|
widget.GetValue = getter; widget.SetValue = setter;
|
|
return widget;
|
|
}
|
|
|
|
protected ButtonWidget Make2( int dir, int y, string text, ClickHandler onClick,
|
|
Func<Game, string> getter, Action<Game, string> setter ) {
|
|
return Make2Impl( 160 * dir, y, 280, 35, text, onClick, getter, setter );
|
|
}
|
|
|
|
protected ButtonWidget MakeBool( int dir, int y, string optName, string optKey,
|
|
ClickHandler onClick, Func<Game, bool> getter, Action<Game, bool> setter ) {
|
|
return MakeBoolImpl( 160 * dir, y, 280, 35, optName, optKey, onClick, getter, setter );
|
|
}
|
|
|
|
protected ButtonWidget MakeClassic( int dir, int y, string text, ClickHandler onClick,
|
|
Func<Game, string> getter, Action<Game, string> setter ) {
|
|
ButtonWidget widget = ButtonWidget.Create( game, 165 * dir, y, 301, 41, text, Anchor.Centre,
|
|
Anchor.Centre, titleFont, onClick );
|
|
widget.GetValue = getter; widget.SetValue = setter;
|
|
return widget;
|
|
}
|
|
|
|
protected ButtonWidget MakeClassic2( int dir, int y, string text, ClickHandler onClick,
|
|
Func<Game, string> getter, Action<Game, string> setter ) {
|
|
return Make2Impl( 165 * dir, y, 301, 41, text, onClick, getter, setter );
|
|
}
|
|
|
|
protected ButtonWidget MakeClassicBool( int dir, int y, string text, string optKey,
|
|
ClickHandler onClick, Func<Game, bool> getter, Action<Game, bool> setter ) {
|
|
return MakeBoolImpl( 165 * dir, y, 301, 41, text, optKey, onClick, getter, setter );
|
|
}
|
|
|
|
ButtonWidget Make2Impl( int x, int y, int width, int height, string text,
|
|
ClickHandler onClick, Func<Game, string> getter, Action<Game, string> setter ) {
|
|
ButtonWidget widget = ButtonWidget.Create( game, x, y, width, height, text + ": " + getter( game ),
|
|
Anchor.Centre, Anchor.Centre, titleFont, onClick );
|
|
widget.Metadata = text;
|
|
widget.GetValue = getter;
|
|
widget.SetValue = (g, v) => {
|
|
setter( g, v );
|
|
widget.SetText( (string)widget.Metadata + ": " + getter( g ) );
|
|
};
|
|
return widget;
|
|
}
|
|
|
|
ButtonWidget MakeBoolImpl( int x, int y, int width, int height, string text, string optKey,
|
|
ClickHandler onClick, Func<Game, bool> getter, Action<Game, bool> setter ) {
|
|
string optName = text;
|
|
text = text + ": " + (getter( game ) ? "ON" : "OFF");
|
|
ButtonWidget widget = ButtonWidget.Create( game, x, y, width, height, text, Anchor.Centre,
|
|
Anchor.Centre, titleFont, onClick );
|
|
widget.Metadata = optName;
|
|
widget.GetValue = g => getter( g ) ? "yes" : "no";
|
|
widget.SetValue = (g, v) => {
|
|
setter( g, v == "yes" );
|
|
Options.Set( optKey, v == "yes" );
|
|
widget.SetText( (string)widget.Metadata + ": " + (v == "yes" ? "ON" : "OFF") );
|
|
};
|
|
return widget;
|
|
}
|
|
|
|
void ShowExtendedHelp() {
|
|
bool canShow = inputWidget == null && selectedWidget != null && descriptions != null;
|
|
if( !canShow ) return;
|
|
|
|
int index = Array.IndexOf<Widget>( widgets, selectedWidget );
|
|
string[] desc = descriptions[index];
|
|
if( desc == null ) return;
|
|
MakeExtendedHelp( desc );
|
|
}
|
|
|
|
static FastColour tableCol = new FastColour( 20, 20, 20, 200 );
|
|
int tableWidth, tableHeight;
|
|
const int extHelpY = 100;
|
|
void MakeExtendedHelp( string[] desc ) {
|
|
extendedHelp = new TextGroupWidget( game, desc.Length, extendedHelpFont, null,
|
|
Anchor.Centre, Anchor.Centre );
|
|
extendedHelp.Init();
|
|
|
|
for( int i = 0; i < desc.Length; i++ )
|
|
extendedHelp.SetText( i, desc[i] );
|
|
for( int i = 0; i < desc.Length; i++ )
|
|
extendedHelp.Textures[i].X1 = extendedHelp.X;
|
|
|
|
tableWidth = extendedHelp.Width;
|
|
tableHeight = extendedHelp.Height;
|
|
extendedHelp.MoveTo( extendedHelp.X, extHelpY + tableHeight / 2 );
|
|
}
|
|
|
|
void DisposeExtendedHelp() {
|
|
if( extendedHelp == null ) return;
|
|
extendedHelp.Dispose();
|
|
extendedHelp = null;
|
|
}
|
|
|
|
protected void OnWidgetClick( Game game, Widget widget, MouseButton mouseBtn ) {
|
|
ButtonWidget button = widget as ButtonWidget;
|
|
if( mouseBtn != 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;
|
|
}
|
|
|
|
if( inputWidget != null )
|
|
inputWidget.Dispose();
|
|
|
|
targetWidget = selectedWidget;
|
|
inputWidget = MenuInputWidget.Create( game, 0, 110, 400, 30, button.GetValue( game ), Anchor.Centre,
|
|
Anchor.Centre, regularFont, titleFont, validator );
|
|
widgets[widgets.Length - 2] = inputWidget;
|
|
widgets[widgets.Length - 1] = ButtonWidget.Create( game, 240, 110, 40, 30, "OK",
|
|
Anchor.Centre, Anchor.Centre, titleFont, OnWidgetClick );
|
|
InputOpened();
|
|
UpdateDescription( targetWidget );
|
|
}
|
|
|
|
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 = inputWidget.GetText();
|
|
if( inputWidget.Validator.IsValidValue( text ) )
|
|
targetWidget.SetValue( game, text );
|
|
if( inputWidget != null )
|
|
inputWidget.Dispose();
|
|
widgets[widgets.Length - 2] = null;
|
|
inputWidget = null;
|
|
UpdateDescription( targetWidget );
|
|
targetWidget = null;
|
|
|
|
int okayIndex = widgets.Length - 1;
|
|
if( widgets[okayIndex] != null )
|
|
widgets[okayIndex].Dispose();
|
|
widgets[okayIndex] = null;
|
|
InputClosed();
|
|
}
|
|
}
|
|
} |