Browse Source

Implemented cursor visibility setting for MS-Windows.

David Piuva 2 years ago
parent
commit
d12f74e442
2 changed files with 40 additions and 2 deletions
  1. 6 2
      Source/templates/basic3D/main.cpp
  2. 34 0
      Source/windowManagers/Win32Window.cpp

+ 6 - 2
Source/templates/basic3D/main.cpp

@@ -63,7 +63,9 @@ Model createCubeModel(const FVector3D &min, const FVector3D &max) {
 DSR_MAIN_CALLER(dsrMain)
 void dsrMain(List<String> args) {
 	// Create a window
-	window = window_create(U"Basic 3D template", 1600, 900);
+	window = window_create_fullscreen(U"Basic 3D template");
+	// Hide the cursor
+	window_setCursorVisibility(window, false);
 
 	// Tell the application to terminate when the window is closed
 	window_setCloseEvent(window, []() {
@@ -77,7 +79,9 @@ void dsrMain(List<String> args) {
 			if (key >= DsrKey_1 && key <= DsrKey_9) {
 				window_setPixelScale(window, key - DsrKey_0);
 			} else if (key == DsrKey_F11) {
-				window_setFullScreen(window, !window_isFullScreen(window));
+				bool makeWindowed = window_isFullScreen(window);
+				window_setFullScreen(window, !makeWindowed);
+				window_setCursorVisibility(window, makeWindowed);
 			} else if (key == DsrKey_Escape) {
 				running = false;
 			}

+ 34 - 0
Source/windowManagers/Win32Window.cpp

@@ -18,6 +18,11 @@ class Win32Window : public dsr::BackendWindow {
 public:
 	// The native windows handle
 	HWND hwnd;
+	// The cursors
+	HCURSOR noCursor, defaultCursor;
+	// Keep track of when the cursor is inside of the window,
+	// so that we can show it again when leaving the window
+	bool cursorIsInside = false;
 	// Double buffering to allow drawing to a canvas while displaying the previous one
 	// The image which can be drawn to
 	dsr::AlignedImageRgbaU8 canvas;
@@ -28,6 +33,9 @@ private:
 	// Called before the application fetches events from the input queue
 	//   Closing the window, moving the mouse, pressing a key, et cetera
 	void prefetchEvents() override;
+
+	// Called to change the cursor visibility and returning true on success
+	bool setCursorVisibility(bool visible) override;
 private:
 	// Helper methods specific to calling XLib
 	void updateTitle();
@@ -70,6 +78,13 @@ void Win32Window::updateTitle() {
 	}
 }
 
+bool Win32Window::setCursorVisibility(bool visible) {
+	// Remember the cursor's visibility for anyone asking
+	this->visibleCursor = visible;
+	// Indicate that the feature is implemented
+	return true;
+}
+
 void Win32Window::setFullScreen(bool enabled) {
 	if (this->windowState == 1 && enabled) {
 		// Clean up any previous window
@@ -204,6 +219,14 @@ Win32Window::Win32Window(const dsr::String& title, int width, int height) {
 	// Remember the title
 	this->title = title;
 
+	// Get the default cursor
+	this->defaultCursor = LoadCursor(0, IDC_ARROW);
+
+	// Create an invisible cursor using masks padded to 32 bits for safety
+	uint32_t cursorAndMask = 0b11111111;
+	uint32_t cursorXorMask = 0b00000000;
+	this->noCursor = CreateCursor(NULL, 0, 0, 1, 1, (const void*)&cursorAndMask, (const void*)&cursorXorMask);
+
 	// Create a window
 	if (fullScreen) {
 		this->createFullscreen();
@@ -410,6 +433,15 @@ static LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam,
 	case WM_MOUSEMOVE:
 		parent->queueInputEvent(new dsr::MouseEvent(dsr::MouseEventType::MouseMove, dsr::MouseKeyEnum::NoKey, dsr::IVector2D(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))));
 		break;
+	case WM_SETCURSOR:
+		if (LOWORD(lParam) == HTCLIENT) {
+			if (parent->visibleCursor) {
+				SetCursor(parent->defaultCursor);
+			} else {
+				SetCursor(parent->noCursor);
+			}
+		}
+		break;
 	case WM_MOUSEWHEEL:
 		{
 			int delta = GET_WHEEL_DELTA_WPARAM(wParam);
@@ -488,6 +520,8 @@ void Win32Window::resizeCanvas(int width, int height) {
 	this->canvas = dsr::image_create_RgbaU8_native(width, height, dsr::PackOrderIndex::BGRA);
 }
 Win32Window::~Win32Window() {
+	// Destroy the invisible cursor
+	DestroyCursor(this->noCursor);
 	// Destroy the native window
 	DestroyWindow(this->hwnd);
 }