1. stqn
  2. rwkc

Source

rwkc / src / inputconfigurationdialog.d


module inputconfigurationdialog;

import derelict.sdl.sdl;
import gameconstants;
import gui;
import inputmanager;
import inputconfiguration;
import inputactions;

debug import std.stdio;


class InputConfigurationDialog: GUI.ButtonListener, GUI.MenuListener {

	GUI.Panel mPanel;
	GUI.Button mApplyButton;
	GUI.Button mCancelButton;

	GUI.Menu mActionsMenu;
	GUI.Panel mDefinitionsPanel;

	InputConfiguration mInputConfig;

	InputDetectDialog mDetect;
	int mConfiguredAction;

	bool mDone;

	this() {
		mInputConfig = new InputConfiguration();
		mInputConfig.load( gInputManager.mConfigFilename );

		recreatePanel();
	}

	~this() {
		GUI.instance.removePanel( mPanel );
		delete( mInputConfig );
	}

	void recreatePanel() {

		// reset
		if( mPanel ) GUI.instance.removePanel( mPanel );

		// build the panels data
		string items[];
		string labels[];
		foreach( ia; mInputConfig.mInputActions ) {
			items ~= ia.name;

			switch( ia.method ) {
				case IAM_KEY:
					labels ~= "[ " ~ gInputManager.getKeyName( ia.keycode ) ~ " ]";
				break;
				case IAM_BUTTON:
					labels ~= "joy#" ~ std.string.toString(ia.joynum) ~ " button#" ~ std.string.toString(ia.button);
				break;
				case IAM_AXIS:
					string dir = std.string.toString( ia.dir );
					labels ~= "joy#" ~ std.string.toString(ia.joynum) ~ " axis#" ~ std.string.toString(ia.axis) ~ " dir:" ~ dir;
				break;
				default:
				break;
			}
		}

		// build the panel
		mPanel = GUI.instance.addPanel(0,0);
		mPanel.setAlign( GUI.Panel.ALIGN.CENTERED, GUI.Panel.ALIGN.CENTERED );
		mActionsMenu = mPanel.addMenu( items, 150 );
		mActionsMenu.setListener(this);
		mActionsMenu.drawBorder = false;
		mPanel.addList(labels).drawBorder = false;
		mPanel.nl();

		mApplyButton = mPanel.addTextButton( "Apply", "", this );
		mCancelButton = mPanel.addTextButton( "Cancel", "", this );
		mPanel.show();
	}


	bool done() {

		if( mDetect && mDetect.done() ) {
			if( mDetect.ok ) {
				mInputConfig.mInputActions[mConfiguredAction] = mDetect.getInputAction();
				mInputConfig.apply();
				mInputConfig.save();
			}
			delete(mDetect);
			recreatePanel();
		}

		if( gInputManager.isReleased( IMA_BACK )) {
			mDone = true;
		}

		return mDone;
	};

	void onButtonPressed( GUI.Button b ) {
		if( b == mApplyButton ) {
			mDone = true;
			return;
		}
		if( b == mCancelButton ) {
			mDone = true;
			return;
		}

	}

	void onSelectedItem( int item ) {
		if( item >= 0 ) {
			mConfiguredAction = item;
			mDetect = new InputDetectDialog( mInputConfig.mInputActions[item] );
			mPanel.hide();
		}
	}

}


class InputDetectDialog {

	GUI.Panel mPanel;
	SInputAction mInputAction;
	bool mDone;
	bool mOk;

	this( inout SInputAction inputaction ) {
		mPanel = GUI.instance.addPanel(0,0);
		mPanel.setAlign( GUI.Panel.ALIGN.CENTERED, GUI.Panel.ALIGN.CENTERED );
		mPanel.addLabel( "Press a key "); //, a joystick button or move a joystick axis" );
		mPanel.nl();
		mPanel.addLabel( "to configure <" ~ inputaction.name ~ ">" );
		mPanel.nl();
		mPanel.addLabel( "(or [Esc] to cancel.)" );

		mInputAction = inputaction;
	}

	~this() {
		GUI.instance.removePanel( mPanel );
	}

	bool done() {
		probe();
		return( mDone );
	}

	bool ok() { return mOk; }

	void probe() {
		int key = gInputManager.getKeyDownCode();

		if( key != 0 ) {
			mDone = true;
			if( key == 27 ) return;

			with( mInputAction ) { method = IAM_KEY; keycode = key; }
			mOk = true;
			return;
		}
		//TODO: probe joysticks
	}

	SInputAction getInputAction() {
		return( mInputAction );
	}
}