Commits

Anonymous committed ae3c79e

Début d'ajout de la GUI dans l'éditeur
* ajouté gui
* ajouté editortools(gestion des outils)
* modifés chrono, messages et menu : ajout de delete(TextSurface)s pour éviter le crash à la fermeture
* modifié : input manager : ajout de la gestion de la souris

Comments (0)

Files changed (9)

 		<Unit filename="src/chrono.d" />
 		<Unit filename="src/configfile.d" />
 		<Unit filename="src/editor.d" />
+		<Unit filename="src/editortools.d" />
 		<Unit filename="src/game.d" />
 		<Unit filename="src/gameconstants.d" />
 		<Unit filename="src/gamemanager.d" />
 		<Unit filename="src/gameobjects/updatedgameobject.d" />
 		<Unit filename="src/gameobjects/wall.d" />
 		<Unit filename="src/gamepart.d" />
+		<Unit filename="src/gui.d" />
 		<Unit filename="src/inputactions.d" />
 		<Unit filename="src/inputconfiguration.d" />
 		<Unit filename="src/inputmanager.d" />
 		<Unit filename="src/messages.d" />
 		<Unit filename="src/objectlist.d" />
 		<Unit filename="src/screen.d" />
+		<Unit filename="src/slist.d" />
 		<Unit filename="src/soundmanager.d" />
 		<Unit filename="src/textsurface.d" />
 		<Unit filename="src/texturemanager.d" />
 		mText = new TextSurface( "" );
 	}
 
+	~this() {
+		delete(mText);
+	}
 
 	void update() {
 		if( !mFrozen ) {
 import gameconstants;
 import texturemanager;
 import screen;
+import editortools;
+import gui;
 
 class Editor: public GamePart {
 
 	float mVx = 0;
 	float mVy = 0;
 
+	EditorTools mTools;
+
 	this() {
 
 		SDL_WM_GrabInput(SDL_GRAB_ON);
 	}
 
 	void update() {
+		SDL_BlitSurface( mBg, null, gScreen.mSurface, null );
+
+		gView.update();
+		gView.draw();
 		processInput();
 
-		SDL_BlitSurface( mBg, null, gScreen.mSurface, null );
-		gView.update();
-		gView.draw();
-
-		drawPointer();
-
 	}
 
-	void drawPointer() {
-		SDL_Rect rect;
-		rect.x = cast(short)mPx;
-		rect.y = cast(short)mPy;
-		rect.w = 32;
-		rect.h = 32;
-		SDL_BlitSurface( mPointer, null, gScreen.mSurface, &rect);
-	}
-
-
     void processInput() {
 
         if( gInputManager.isReleased(IMA_TOGGLE_EDITOR)
 			mState = GAMEPART_STATE.CONTINUE;
 
 		int x,y;
-		ubyte button = SDL_GetRelativeMouseState( &x, &y );
+		//ubyte button = SDL_GetRelativeMouseState( &x, &y );
+		gInputManager.getMousePositionRelative( x,y );
 
-		if ( button & SDL_BUTTON_RMASK ) {
-			mVx += x;
-			mVy += y;
-			gView.setPosition( mVx, mVy );
+		if( mTools is null) {
+
+			if( gInputManager.isMouseButtonUp(SDL_BUTTON_MIDDLE) ) {
+				mTools = new EditorTools;
+			}
+			else {
+
+				if ( gInputManager.isMouseButtonPressed(SDL_BUTTON_RIGHT) ) {
+		//			SDL_WM_GrabInput(SDL_GRAB_ON);
+					GUI.instance.hidePointer();
+					mVx += x;
+					mVy += y;
+					gView.setPosition( mVx, mVy );
+				}
+				else {
+					GUI.instance.showPointer();
+					mPx += x;
+					mPy += y;
+					if( mPx < 0 ) mPx = 0;
+					if( mPy < 0 ) mPy = 0;
+					if( mPx > 640 ) mPx = 640;
+					if( mPy > 480 ) mPy = 480;
+		//			SDL_WM_GrabInput(SDL_GRAB_OFF);
+				}
+			}
 		}
 		else {
-			mPx += x;
-			mPy += y;
-			if( mPx < 0 ) mPx = 0;
-			if( mPy < 0 ) mPy = 0;
-			if( mPx > 640 ) mPx = 640;
-			if( mPy > 480 ) mPy = 480;
-		//SDL_WarpMouse(320,240);
+			if( mTools.done() || gInputManager.isMouseButtonUp(SDL_BUTTON_MIDDLE) )
+				delete( mTools );
 		}
+
+		GUI.instance.update( x,y, gInputManager.isMouseButtonUp(SDL_BUTTON_LEFT) );
+
     }
 
 	GAMEPART_STATE getState() {

src/editortools.d

+
+module editortools;
+
+import gui;
+import gameobject;
+import std.stdio;
+
+
+class EditorTools: public GUI.ButtonListener {
+
+	GUI.Panel mTilesPanel;
+	GUI.Panel mActionsPanel;
+
+	struct Action {
+		string caption;
+		GUI.Button button;
+		//void opCall( string c ) { caption = c; };
+	};
+
+	Action[] mActions;
+
+	struct Tile{
+		string bitmap;
+		GUI.Button button;
+		GameObject.Type type;
+	};
+
+	Tile[] mTiles;
+
+	bool mDone = false;
+
+	this() {
+
+		initActions();
+
+		mActionsPanel = GUI.instance.addPanel( 0,0 );
+		foreach( action; mActions ) {
+			action.button = mActionsPanel.addTextButton( action.caption, "", this );
+			mActionsPanel.nl();
+		}
+
+		initTiles();
+
+		mTilesPanel = GUI.instance.addPanel( 320, 0 );
+		foreach( int i, tile; mTiles ) {
+			tile.button = mTilesPanel.addIconButton( tile.bitmap, this );
+			if( i%10 == 0) mTilesPanel.nl();
+		}
+	}
+
+	~this() {
+		GUI.instance.removePanel( mActionsPanel );
+		GUI.instance.removePanel( mTilesPanel );
+	}
+
+	void initActions() {
+		mActions ~= Action( "Insert Column");
+		mActions ~= Action( "Insert Line");
+		mActions ~= Action( "Delete Column");
+		mActions ~= Action( "Delete Line");
+	}
+
+	void initTiles() {
+		mTiles ~= Tile( "brick.png" );
+		mTiles ~= Tile( "wall1.png" );
+		mTiles ~= Tile( "wall2.png" );
+	}
+
+	void onButtonPressed( GUI.Button b ) {
+		mDone = true;
+	}
+
+	bool done() {
+		return( mDone );
+	}
+}
+
+module gui;
+
+import derelict.sdl.sdl;
+import texturemanager;
+import screen;
+import std.stdio;
+import textsurface;
+import slist;
+
+import std.stdio;
+
+class GUI {
+
+	class Widget {
+		int mX, mY, mW, mH;
+		bool mVisible = false;
+		Widget mParent;
+
+		this( Widget parent, int x, int y ) {
+			mParent = parent;
+			if( mParent !is null ) {
+				mX = mParent.mX + x;
+				mY = mParent.mY + y;
+			}
+			else {
+				mX = x;
+				mY = y;
+			}
+		}
+
+		int width() { return mW; }
+		int height() { return mH; }
+
+		/*
+		int derivedX() {
+			if( mParent !is null ) return (mX + mParent.derivedX());
+			else return( 0 );
+		}
+
+		int derivedY() {
+			if( mParent !is null ) return (mY + mParent.derivedY());
+			else return( 0 );
+		}
+		*/
+	}
+
+	interface Renderable {
+		void render();
+	}
+
+	interface Clickable {
+		bool isIn(int x, int y);
+	}
+
+	class Button: public Widget, Renderable, Clickable {
+
+		ButtonListener mListener;
+		bool mHighlighted=false;
+
+		this( Widget parent, int x, int y, ButtonListener listener ) {
+			super( parent, x, y );
+			mListener = listener;
+		}
+
+		bool isIn( int x, int y ) {
+			return( x>mX && x<mX+mW
+				&& y>mY && y<mY+mH );
+		}
+
+		void render() {
+		}
+
+		void notifyListener() {
+			if( mListener !is null ) {
+				mListener.onButtonPressed( this );
+			}
+		}
+
+		bool highlighted() { return mHighlighted; }
+
+		void highlight( bool h ) {
+			mHighlighted = h;
+		}
+
+	}
+
+	interface ButtonListener {
+		void onButtonPressed( Button b);
+	}
+
+	class IconButton: public Button {
+
+		SDL_Surface* mIcon;
+		SDL_Rect mRect;
+		SDL_Surface* mHl;
+
+		this( Widget parent, int x, int y, string imageName, ButtonListener listener ) {
+			super( parent, x, y, listener );
+			mIcon = gTextureManager.get( imageName );
+			mW = mIcon.w;
+			mH = mIcon.h;
+			with( mRect ) {
+				w=cast(ushort)mW;
+				h=cast(ushort)mH;
+				x=cast(short)mX;
+				y=cast(short)mY;
+			}
+
+			mHl = SDL_CreateRGBSurface(
+				SDL_HWSURFACE,
+				mW, mH, 32,
+				0x00, 0x00, 0x00, 0x00 );
+			SDL_FillRect( mHl, null, 0xFFFFFFFF );
+			SDL_SetAlpha( mHl, SDL_SRCALPHA, 128 );
+
+		}
+
+		~this() {
+			SDL_FreeSurface( mHl );
+		}
+
+		void render() {
+			SDL_BlitSurface( mIcon, null, gScreen.mSurface, &mRect );
+			if( mHighlighted ) SDL_BlitSurface( mHl, null, gScreen.mSurface, &mRect );
+		}
+
+	}
+
+	class TextButton: public Button {
+		SDL_Rect mRect;
+		SDL_Surface* mBg;
+		TextSurface mText;
+
+		this( Widget parent, int x, int y, string caption, string fontid, ButtonListener listener ) {
+			super( parent, x, y, listener );
+
+			mText = new TextSurface(caption ); // , fontid, 0x00FFFF );
+
+			mW = mText.getSurface().w;
+			mH = mText.getSurface().h;
+			with( mRect ) {
+				x = cast(short)mX;
+				y = cast(short)mY;
+				w = cast(ushort)mW;
+				h = cast(ushort)mH;
+			}
+
+			mBg = SDL_CreateRGBSurface(
+				SDL_HWSURFACE,
+				mW, mH, 32,
+				0x00, 0x00, 0x00, 0x00 );
+			SDL_FillRect( mBg, null, 0xFFFFFFFF );
+			SDL_SetAlpha( mBg, SDL_SRCALPHA, 64 );
+		}
+
+		~this() {
+			delete( mText );
+			SDL_FreeSurface( mBg );
+		}
+
+		void render() {
+			SDL_BlitSurface( mBg, null, gScreen.mSurface, &mRect );
+			SDL_BlitSurface( mText.getSurface(), null, gScreen.mSurface, &mRect );
+			if( mHighlighted) SDL_BlitSurface( mBg, null, gScreen.mSurface, &mRect );
+		}
+	}
+
+	class Panel: public Widget, Renderable {
+
+		//Panel[] mPanels;
+		Button[] mButtons;
+
+		int mMargin = 3;
+		int mLineHeight;
+		int mLineGap = 3;
+		int mElementGap = 3;
+		int mXInsert;
+		int mYInsert;
+		SDL_Surface* mBg;
+		SDL_Rect mRect;
+
+		this( Widget parent, int x=0, int y=0 ) {
+			super( parent, x, y );
+			mRect.x = cast(short)x;
+			mRect.y = cast(short)y;
+			mXInsert = mMargin;
+			mYInsert = mMargin;
+		}
+
+		~this() {
+			foreach( b; mButtons ) {
+				delete(b);
+			}
+		}
+
+		TextButton addTextButton( string caption, string fontid, ButtonListener listener=null ) {
+			TextButton b = new TextButton(this, mXInsert, mYInsert, caption, fontid, listener );
+			mButtons ~= b;
+
+			resize( b.width, b.height );
+			return( b );
+		}
+
+		IconButton addIconButton( string iconFileName, ButtonListener listener=null  ) {
+			IconButton b = new IconButton(this, mXInsert, mYInsert, iconFileName, listener );
+			mButtons ~= b;
+
+			resize( b.width, b.height );
+			return( b );
+		}
+
+/*
+		Panel addPanel() {
+			Panel p = new Panel( this );
+			mPanels ~= p;
+			return( p );
+		}
+*/
+		void nl() {
+			mXInsert = mMargin;
+			mYInsert += mLineHeight + mLineGap;
+			mLineHeight = 0;
+		}
+
+		private void adjustLineHeight( int h ) {
+			if( h > mLineHeight ) mLineHeight = h;
+		}
+
+		private void resize( int w, int h ) {
+
+			adjustLineHeight( h );
+
+			mXInsert += w + mElementGap;
+			//mYInsert += h;
+			bool updateBg = false;
+			if( mXInsert+w > mW ) { mW = mXInsert; updateBg = true; }
+			if( mYInsert+h > mH ) { mH = mYInsert + h + mMargin; updateBg = true; }
+
+			if( updateBg ) {
+				if( mBg != null ) SDL_FreeSurface( mBg );
+				mBg = SDL_CreateRGBSurface(
+					SDL_HWSURFACE,
+					mW, mH, 32, 0,0,0,0 );
+
+				mRect.w =cast(ushort)mW;
+				mRect.h =cast(ushort)mH;
+			}
+
+		}
+
+		void render() {
+			if( mBg != null )
+				SDL_BlitSurface( mBg, null, gScreen.mSurface, &mRect );
+
+			foreach( b; mButtons ) {
+				b.render();
+			}
+		}
+
+		void checkButtons( int x, int y, bool clicked ) {
+			//foreach( p; mPanels ) {
+			//	p.checkButtons( x, y );
+			//}
+			foreach( b; mButtons ) {
+				if( b.isIn( x, y ) ) {
+					if( !b.highlighted()) b.highlight(true);
+					if( clicked ) b.notifyListener();
+				}
+				else {
+					if( b.highlighted()) b.highlight(false);
+				}
+			}
+		}
+	}
+
+	// =======================================
+
+	SDL_Surface* mPointer;
+	bool mPointerHidden;
+	int mPx, mPy;
+
+	Panel[] mPanels;
+	//auto mPanels = new SList!(Panel); // pas utilisable : bug du D ( cas : template d'une sous-classe avec paramètres )
+
+	static GUI mInstance;
+
+	public static GUI instance() {
+		if( mInstance is null ) mInstance = new GUI();
+		return ( mInstance );
+	}
+
+	private this() {
+		mPointerHidden = false;
+		mPointer = gTextureManager.get("pointer.png");
+	}
+
+	void showPointer() {
+		mPointerHidden = false;
+	}
+
+	void hidePointer() {
+		mPointerHidden = true;
+	}
+
+	void drawPointer() {
+		SDL_Rect rect;
+		rect.x = cast(short)mPx;
+		rect.y = cast(short)mPy;
+		rect.w = 32;
+		rect.h = 32;
+		SDL_BlitSurface( mPointer, null, gScreen.mSurface, &rect);
+	}
+
+
+	void update( int relx, int rely, bool click ) {
+
+		mPx += relx;
+		mPy += rely;
+		if( mPx < 0 ) mPx = 0;
+		if( mPy < 0 ) mPy = 0;
+		if( mPx > 640 ) mPx = 640;
+		if( mPy > 480 ) mPy = 480;
+
+		foreach( p; mPanels ) {
+			p.checkButtons( mPx, mPy, click );
+			p.render();
+		}
+
+		if( !mPointerHidden ) {
+			drawPointer();
+		}
+
+	}
+
+/*
+	bool isUp( bool pressed ) {
+		static bool wasPressed = false;
+
+		if (pressed)
+			wasPressed = true;
+		else {
+			if( wasPressed ) {
+				wasPressed = false;
+				return( true );
+			}
+		}
+		return( false );
+	}
+*/
+
+	Panel addPanel( int x, int y ) {
+		Panel p = new Panel( null, x, y );
+		mPanels ~= p;
+		return( p );
+	}
+
+	void removePanel( Panel p ) {
+		foreach( i, panel; mPanels ) {
+			if( panel is p ) {
+				delete( p );
+				if( mPanels.length==1 ) { mPanels.length = 0; break; }
+				if( i == 0 ) { mPanels = mPanels[1..$]; break; }
+				if( i == mPanels.length-1 ) { mPanels = mPanels[0..$-1]; break; }
+				mPanels = mPanels[0..(i-1)] ~ mPanels[(i+1)..$];
+				break;
+			}
+		}
+	}
+
+}
+
+

src/inputmanager.d

 	// char[][] mPossibleActions;
 	char[] mConfigFilename;
 
+	bool[8] mMouseButtonsUp;
+	bool[8] mMouseButtonsDown;
+
 	this( char[] configFilename ) {
 		gInputManager = this;
 
 			action.update();
 		}
 
+		mMouseButtonsUp[] = false;
+		mMouseButtonsDown[] = false;
+
         while( SDL_PollEvent(&event) ) {
-            if(event.type == SDL_QUIT ) throw new Error( "quitting" );  // *tousse* *tousse*
+
+        	switch( event.type ) {
+				case SDL_QUIT:
+					throw new Error( "quitting" );  // *tousse* *tousse*
+
+				case SDL_MOUSEBUTTONUP:
+					mMouseButtonsUp[event.button.button] = true;
+				break;
+
+				case SDL_MOUSEBUTTONDOWN:
+					mMouseButtonsDown[event.button.button] = true;
+				break;
+
+				default:
+				break;
+        	}
         }
+	}
 
+	void getMousePositionRelative( out int x, out int y ) {
+		SDL_GetRelativeMouseState( &x, &y );
+	}
+
+	void getMousePosition( out int x, out int y ) {
+		SDL_GetMouseState( &x, & y);
+	}
+
+	bool isMouseButtonUp( ubyte button ) {
+	// button is one of SDL_BUTTON_LEFT, _RIGHT, _MIDDLE, _WHEELUP, etc..
+		return( mMouseButtonsUp[button] );
+	}
+
+	bool isMouseButtonDown( ubyte button ) {
+	// button is one of SDL_BUTTON_LEFT, _RIGHT, _MIDDLE, _WHEELUP, etc..
+		return( mMouseButtonsDown[button] );
+	}
+
+	bool isMouseButtonPressed( ubyte button ) {
+		ubyte state = SDL_GetMouseState( null, null );
+		switch( button ) {
+			case SDL_BUTTON_LEFT:
+				return( (state & SDL_BUTTON_LMASK)!=0 );
+
+			case SDL_BUTTON_RIGHT:
+				return( (state & SDL_BUTTON_RMASK)!=0 );
+
+			case SDL_BUTTON_MIDDLE:
+				return( (state & SDL_BUTTON_MMASK)!=0 );
+
+			default:
+				return( false );
+		}
 	}
 
 	bool isPressed( uint action ) {
 	    bind_actions();
 	    gInputManager.loadConfig();
 
-
 		GameManager gm;
 		gm = new GameManager();
 		while( gm.update() ) {};
 	this() {
 		mArrow = new TextSurface( "=>" );
 	}
+
+	~this() {
+		delete( mArrow );
+		foreach( t; mText ) {
+			if( t[0] !is null ) delete(t[0]);
+			if( t[1] !is null ) delete(t[1]);
+		}
+	}
 
     void update() {
         overlay(false);
 import textsurface;
 import texturemanager;
 import time;
-
+
 
 class Messages {
 
-	struct Mess {
-		TextSurface text;
-		float timer;
-		SDL_Rect pos;
-		float origY;
+	struct Mess {
+		TextSurface text;
+		float timer;
+		SDL_Rect pos;
+		float origY;
 	}
 
 	static Mess*[] mMessages;
 
-
 	static void add( char[] text ) {
-		Mess *m = new Mess;
+		Mess* m = new Mess;
 		m.text = new TextSurface( text );
 		SDL_Surface* surf = m.text.getSurface();
 		m.timer = 0.f;
 		m.pos.w = cast(ushort) surf.w;
 		m.pos.h = cast(ushort) surf.h;
 		m.origY = m.pos.y;
-		mMessages ~= m;
+		mMessages ~= m;
 		writefln( "add message text=%s", text );
 	}
 
 			m.pos.y = cast(short) (m.origY - t * t * t * t * t);
 
 			if( m.pos.y < - cast(int) m.pos.h ) {
-				// Out of screen, remove message
+				// Out of screen, remove message
 				Mess*[] m1;
 				Mess*[] m2;
 				if( i > 0 ) {
 				if( i < mMessages.length - 1 ) {
 					m2 = mMessages[i+1..$];
 				}
-				mMessages = m1 ~ m2;
+				mMessages = m1 ~ m2;
+
+				delete(m);
 			}
 		}
 	}