Răsfoiți Sursa

added resizability configuration and screen centering for DirectX and SDL windows

The option to enable user resizing of the window can be enabled or disabled upon initialization (through constructor parameters) for both DirectX and SDL windows. A new method was created for the C bindings in order to maintain compatibility.

SDL was provided with position getters and a position setter method to match DirectX's implementation. Furthermore, both window implementations were provided with a method to center the window to the screen.
robbor_io 6 ani în urmă
părinte
comite
34580e0388
4 a modificat fișierele cu 112 adăugiri și 7 ștergeri
  1. 13 2
      libs/directx/dx/Window.hx
  2. 40 1
      libs/directx/window.c
  3. 22 2
      libs/sdl/sdl.c
  4. 37 2
      libs/sdl/sdl/Window.hx

+ 13 - 2
libs/directx/dx/Window.hx

@@ -29,8 +29,8 @@ class Window {
 	public var visible(default, set) : Bool = true;
 	public var vsync : Bool;
 
-	public function new( title : String, width : Int, height : Int ) {
-		win = winCreate(width, height);
+	public function new( title : String, width : Int, height : Int, resizable : Bool = true ) {
+		win = winCreateEx(width, height, resizable);
 		this.title = title;
 		windows.push(this);
 		vsync = true;
@@ -78,6 +78,10 @@ class Window {
 		winSetPosition(win, x, y);
 	}
 
+	public function center( centerPrimary : Bool = true ) {
+		winCenter(win, centerPrimary);
+	}
+
 	function get_width() {
 		var w = 0;
 		winGetSize(win, w, null);
@@ -128,6 +132,10 @@ class Window {
 		winClipCursor(enable ? win : null);
 	}
 
+	static function winCreateEx( width : Int, height : Int, resizable : Bool ) : WinPtr {
+		return null;
+	}
+
 	static function winCreate( width : Int, height : Int ) : WinPtr {
 		return null;
 	}
@@ -144,6 +152,9 @@ class Window {
 	static function winSetPosition( win : WinPtr, x : Int, y : Int ) {
 	}
 
+	static function winCenter( win : WinPtr, centerPrimary : Bool ) {
+	}
+
 	static function winResize( win : WinPtr, mode : Int ) {
 	}
 

+ 40 - 1
libs/directx/window.c

@@ -215,7 +215,7 @@ static LRESULT CALLBACK WndProc( HWND wnd, UINT umsg, WPARAM wparam, LPARAM lpar
 	return DefWindowProc(wnd, umsg, wparam, lparam);
 }
 
-HL_PRIM dx_window *HL_NAME(win_create)( int width, int height ) {
+HL_PRIM dx_window *HL_NAME(win_create_ex)( int width, int height, bool resizable ) {
 	static bool wnd_class_reg = false;
 	HINSTANCE hinst = GetModuleHandle(NULL);
 	if( !wnd_class_reg ) {
@@ -239,6 +239,9 @@ HL_PRIM dx_window *HL_NAME(win_create)( int width, int height ) {
 
 	RECT r;
 	DWORD style = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
+	if( !resizable )  {
+		style &= ~( WS_MAXIMIZEBOX | WS_THICKFRAME );
+	}
 	r.left = r.top = 0;
 	r.right = width;
 	r.bottom = height;
@@ -254,6 +257,10 @@ HL_PRIM dx_window *HL_NAME(win_create)( int width, int height ) {
 	return win;
 }
 
+HL_PRIM dx_window *HL_NAME(win_create)( int width, int height ) {
+	return HL_NAME(win_create_ex)(width, height, true);
+}
+
 HL_PRIM void HL_NAME(win_set_title)(dx_window *win, vbyte *title) {
 	SetWindowText(win,(LPCWSTR)title);
 }
@@ -286,6 +293,36 @@ HL_PRIM void HL_NAME(win_set_position)(dx_window *win, int x, int y) {
 	SetWindowPos(win,NULL,x,y,0,0,SWP_NOSIZE|SWP_NOZORDER);
 }
 
+// initially written with the intent to center on closest monitor; however, SDL centers to primary, so both options are provided
+HL_PRIM void HL_NAME(win_center)(dx_window *win, bool centerPrimary) {
+	int scnX = 0;
+	int scnY = 0;
+	int scnWidth = -1;
+	int scnHeight = -1;
+	if( centerPrimary ) {
+		scnWidth = GetSystemMetrics(SM_CXSCREEN);
+		scnHeight = GetSystemMetrics(SM_CYSCREEN);
+	} else {
+		HMONITOR m = MonitorFromWindow(win, MONITOR_DEFAULTTONEAREST);
+		if( m != NULL ) {
+			MONITORINFO info;
+			info.cbSize = sizeof(MONITORINFO);
+			GetMonitorInfo(m, &info);
+			RECT screen = info.rcMonitor; // "rcMonitor" to match SM_CXSCREEN/SM_CYSCREEN measurements
+			scnX = screen.left;
+			scnY = screen.top;
+			scnWidth = (screen.right - scnX);
+			scnHeight = (screen.bottom - scnY);
+		}
+	}
+	if( scnWidth >= 0 && scnHeight >= 0 ) {
+		int winWidth = 0;
+		int winHeight = 0;
+		HL_NAME(win_get_size)(win, &winWidth, &winHeight);
+		HL_NAME(win_set_position)(win, scnX + ((scnWidth - winWidth) / 2), scnY + ((scnHeight - winHeight) / 2));
+	}
+}
+
 HL_PRIM void HL_NAME(win_resize)(dx_window *win, int mode) {
 	switch( mode ) {
 	case 0:
@@ -366,12 +403,14 @@ HL_PRIM int HL_NAME(get_screen_height)() {
 }
 
 #define TWIN _ABSTRACT(dx_window)
+DEFINE_PRIM(TWIN, win_create_ex, _I32 _I32 _BOOL);
 DEFINE_PRIM(TWIN, win_create, _I32 _I32);
 DEFINE_PRIM(_VOID, win_set_fullscreen, TWIN _BOOL);
 DEFINE_PRIM(_VOID, win_resize, TWIN _I32);
 DEFINE_PRIM(_VOID, win_set_title, TWIN _BYTES);
 DEFINE_PRIM(_VOID, win_set_size, TWIN _I32 _I32);
 DEFINE_PRIM(_VOID, win_set_position, TWIN _I32 _I32);
+DEFINE_PRIM(_VOID, win_center, TWIN _BOOL);
 DEFINE_PRIM(_VOID, win_get_size, TWIN _REF(_I32) _REF(_I32));
 DEFINE_PRIM(_VOID, win_get_position, TWIN _REF(_I32) _REF(_I32));
 DEFINE_PRIM(_VOID, win_destroy, TWIN);

+ 22 - 2
libs/sdl/sdl.c

@@ -366,7 +366,7 @@ DEFINE_PRIM(_BYTES, detect_keyboard_layout, _NO_ARG);
 
 // Window
 
-HL_PRIM SDL_Window *HL_NAME(win_create)(int width, int height) {
+HL_PRIM SDL_Window *HL_NAME(win_create_ex)(int width, int height, bool resizable) {
 	SDL_Window *w;
 	// force window to match device resolution on mobile
 #ifdef	HL_MOBILE
@@ -374,7 +374,7 @@ HL_PRIM SDL_Window *HL_NAME(win_create)(int width, int height) {
 	SDL_GetDesktopDisplayMode(0, &displayMode);
 	w = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS);
 #else
-	w = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
+	w = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | (resizable ? SDL_WINDOW_RESIZABLE : 0));
 #endif
 #	ifdef HL_WIN
 	// force window to show even if the debugger force process windows to be hidden
@@ -386,6 +386,10 @@ HL_PRIM SDL_Window *HL_NAME(win_create)(int width, int height) {
 	return w;
 }
 
+HL_PRIM SDL_Window *HL_NAME(win_create)(int width, int height) {
+	return HL_NAME(win_create_ex)(width, height, false);
+}
+
 HL_PRIM SDL_GLContext HL_NAME(win_get_glcontext)(SDL_Window *win) {
 	return SDL_GL_CreateContext(win);
 }
@@ -445,6 +449,18 @@ HL_PRIM void HL_NAME(win_set_title)(SDL_Window *win, vbyte *title) {
 	SDL_SetWindowTitle(win, (char*)title);
 }
 
+HL_PRIM void HL_NAME(win_set_position)(SDL_Window *win, int x, int y) {
+	SDL_SetWindowPosition(win, x, y);
+}
+
+HL_PRIM void HL_NAME(win_get_position)(SDL_Window *win, int *x, int *y) {
+	SDL_GetWindowPosition(win, x, y);
+}
+
+HL_PRIM void HL_NAME(win_center)(SDL_Window *win) {
+	SDL_SetWindowPosition(win, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
+}
+
 HL_PRIM void HL_NAME(win_set_size)(SDL_Window *win, int width, int height) {
 	SDL_SetWindowSize(win, width, height);
 }
@@ -499,11 +515,15 @@ HL_PRIM void HL_NAME(win_destroy)(SDL_Window *win, SDL_GLContext gl) {
 
 #define TWIN _ABSTRACT(sdl_window)
 #define TGL _ABSTRACT(sdl_gl)
+DEFINE_PRIM(TWIN, win_create_ex, _I32 _I32 _BOOL);
 DEFINE_PRIM(TWIN, win_create, _I32 _I32);
 DEFINE_PRIM(TGL, win_get_glcontext, TWIN);
 DEFINE_PRIM(_BOOL, win_set_fullscreen, TWIN _I32);
 DEFINE_PRIM(_VOID, win_resize, TWIN _I32);
 DEFINE_PRIM(_VOID, win_set_title, TWIN _BYTES);
+DEFINE_PRIM(_VOID, win_set_position, TWIN _I32 _I32);
+DEFINE_PRIM(_VOID, win_get_position, TWIN _REF(_I32) _REF(_I32));
+DEFINE_PRIM(_VOID, win_center, TWIN);
 DEFINE_PRIM(_VOID, win_set_size, TWIN _I32 _I32);
 DEFINE_PRIM(_VOID, win_get_size, TWIN _REF(_I32) _REF(_I32));
 DEFINE_PRIM(_VOID, win_swap_window, TWIN);

+ 37 - 2
libs/sdl/sdl/Window.hx

@@ -25,12 +25,14 @@ class Window {
 	public var vsync(default, set) : Bool;
 	public var width(get, never) : Int;
 	public var height(get, never) : Int;
+	public var x(get, never) : Int;
+	public var y(get, never) : Int;
 	public var displayMode(default, set) : DisplayMode;
 	public var visible(default, set) : Bool = true;
 
-	public function new( title : String, width : Int, height : Int ) {
+	public function new( title : String, width : Int, height : Int, resizable : Bool = true ) {
 		while( true ) {
-			win = winCreate(width, height);
+			win = winCreateEx(width, height, resizable);
 			if( win == null ) throw "Failed to create window";
 			glctx = winGetGLContext(win);
 			if( glctx == null || !GL.init() || !testGL() ) {
@@ -122,6 +124,14 @@ class Window {
 		winSetSize(win, width, height);
 	}
 
+	public function setPosition( x : Int, y : Int ) {
+		winSetPosition(win, x, y);
+	}
+
+	public function center() {
+		winCenter(win);
+	}
+
 	function get_width() {
 		var w = 0;
 		winGetSize(win, w, null);
@@ -134,6 +144,18 @@ class Window {
 		return h;
 	}
 
+	function get_x() {
+		var x = 0;
+		winGetPosition(win, x, null);
+		return x;
+	}
+
+	function get_y() {
+		var y = 0;
+		winGetPosition(win, null, y);
+		return y;
+	}
+
 	function set_vsync(v) {
 		setVsync(v);
 		return vsync = v;
@@ -176,6 +198,10 @@ class Window {
 		winResize(win, 2);
 	}
 
+	static function winCreateEx( width : Int, height : Int, resizable : Bool ) : WinPtr {
+		return null;
+	}
+
 	static function winCreate( width : Int, height : Int ) : WinPtr {
 		return null;
 	}
@@ -183,6 +209,15 @@ class Window {
 	static function winSetTitle( win : WinPtr, title : hl.Bytes ) {
 	}
 
+	static function winSetPosition( win : WinPtr, width : Int, height : Int ) {
+	}
+
+	static function winGetPosition( win : WinPtr, width : hl.Ref<Int>, height : hl.Ref<Int> ) {
+	}
+
+	static function winCenter( win : WinPtr ) {
+	}
+
 	static function winGetGLContext( win : WinPtr ) : GLContext {
 		return null;
 	}