add mouse and window focus - resolves #382

Sun, 11 Aug 2024 16:11:30 +0200

author
Mike Becker <universe@uap-core.de>
date
Sun, 11 Aug 2024 16:11:30 +0200
changeset 68
823c03733e42
parent 67
0b96fe6d6b5e
child 69
86d545f490e4

add mouse and window focus - resolves #382

plus some minor code improvements

src/ascension/input.h file | annotate | diff | comparison | revisions
src/ascension/window.h file | annotate | diff | comparison | revisions
src/context.c file | annotate | diff | comparison | revisions
src/window.c file | annotate | diff | comparison | revisions
test/Makefile file | annotate | diff | comparison | revisions
--- a/src/ascension/input.h	Sun Aug 11 15:43:01 2024 +0200
+++ b/src/ascension/input.h	Sun Aug 11 16:11:30 2024 +0200
@@ -35,10 +35,26 @@
 typedef struct AscInput AscInput;
 
 struct AscInput {
+    /**
+     * The last X position of the mouse in \c mouse_window.
+     */
     int mouse_x;
+    /**
+     * The last Y position of the mouse in \c mouse_window.
+     */
     int mouse_y;
+    /**
+     * The mouse movement in X direction since the last frame.
+     */
     int mouse_xrel;
+    /**
+     * The mouse movement in Y direction since the last frame.
+     */
     int mouse_yrel;
+    /**
+     * The index of the window, the mouse was last seen in.
+     */
+    unsigned mouse_window;
     bool keys[SDL_NUM_SCANCODES];
 };
 
@@ -47,6 +63,7 @@
 
 #define asc_mouse_x asc_context.input.mouse_x
 #define asc_mouse_y asc_context.input.mouse_y
+#define asc_mouse_window asc_context.input.mouse_window
 #define asc_mouse_pos (asc_vec2i) {asc_mouse_x, asc_mouse_y}
 
 #define asc_mouse_move_x asc_context.input.mouse_xrel
--- a/src/ascension/window.h	Sun Aug 11 15:43:01 2024 +0200
+++ b/src/ascension/window.h	Sun Aug 11 16:11:30 2024 +0200
@@ -40,17 +40,18 @@
 #endif // ASC_MAX_WINDOWS
 
 typedef struct AscWindowSettings {
+    AscGLContextSettings glsettings;
     asc_vec2i dimensions;
-    int fullscreen;
     char const* title;
-    AscGLContextSettings glsettings;
+    bool fullscreen;
 } AscWindowSettings;
 
 typedef struct AscWindow {
     Uint32 id;
+    bool resized;
+    bool focused;
     SDL_Window* window;
     asc_vec2i dimensions;
-    bool resized;
     AscGLContext glctx;
     AscSceneNode *ui;
 } AscWindow;
@@ -110,5 +111,16 @@
  */
 void asc_window_activate(unsigned int index);
 
+
+/**
+ * Returns the index of the window with the specified SDL window ID.
+ *
+ * Returns #ASC_MAX_WINDOWS if no window with the specified ID exists.
+ *
+ * @param id the SDL window ID
+ * @return the window index
+ */
+unsigned int asc_window_index(Uint32 id);
+
 #endif /* ASCENSION_WINDOW_H */
 
--- a/src/context.c	Sun Aug 11 15:43:01 2024 +0200
+++ b/src/context.c	Sun Aug 11 16:11:30 2024 +0200
@@ -118,13 +118,11 @@
 }
 
 static void asc_event_window_resized(Uint32 id, Sint32 width, Sint32 height) {
-    for (unsigned int i = 0 ; i < ASC_MAX_WINDOWS ; i++) {
-        if (asc_context.windows[i].id == id) {
-            asc_vec2i dimensions = (asc_vec2i) {width, height};
-            asc_context.windows[i].resized = true;
-            asc_context.windows[i].dimensions = dimensions;
-            return;
-        }
+    unsigned int i = asc_window_index(id);
+    if (i < ASC_MAX_WINDOWS) {
+        asc_vec2i dimensions = (asc_vec2i) {width, height};
+        asc_context.windows[i].resized = true;
+        asc_context.windows[i].dimensions = dimensions;
     }
 }
 
@@ -141,12 +139,19 @@
                 asc_set_flag(asc_context.flags, ASC_FLAG_QUIT);
                 break;
             case SDL_WINDOWEVENT: {
-                if (event.window.event == SDL_WINDOWEVENT_RESIZED)
+                if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
                     asc_event_window_resized(
                             event.window.windowID,
                             event.window.data1,
                             event.window.data2
                     );
+                } else if (event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) {
+                    unsigned int idx = asc_window_index(event.window.windowID);
+                    asc_context.windows[idx].focused = true;
+                } else if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) {
+                    unsigned int idx = asc_window_index(event.window.windowID);
+                    asc_context.windows[idx].focused = false;
+                }
                 break;
             }
             case SDL_MOUSEMOTION: {
@@ -156,6 +161,9 @@
                 // update absolute position
                 asc_context.input.mouse_x = event.motion.x;
                 asc_context.input.mouse_y = event.motion.y;
+                // update which window the mouse was seen in
+                asc_context.input.mouse_window =
+                        asc_window_index(event.motion.windowID);
                 break;
             }
             case SDL_KEYDOWN:
--- a/src/window.c	Sun Aug 11 15:43:01 2024 +0200
+++ b/src/window.c	Sun Aug 11 16:11:30 2024 +0200
@@ -35,7 +35,7 @@
 void asc_window_settings_init_defaults(AscWindowSettings* settings) {
     settings->dimensions.width = 800;
     settings->dimensions.height = 600;
-    settings->fullscreen = 0;
+    settings->fullscreen = false;
     settings->glsettings.depth_size = 24;
     settings->glsettings.vsync = 1;
     settings->glsettings.gl_major_version = 4;
@@ -169,3 +169,11 @@
     asc_context.active_window = index;
     asc_gl_context_activate(&asc_active_window->glctx);
 }
+
+unsigned int asc_window_index(Uint32 id) {
+    unsigned int i = 0;
+    for (; i < ASC_MAX_WINDOWS ; i++) {
+        if (asc_context.windows[i].id == id) break;
+    }
+    return i;
+}
--- a/test/Makefile	Sun Aug 11 15:43:01 2024 +0200
+++ b/test/Makefile	Sun Aug 11 16:11:30 2024 +0200
@@ -47,10 +47,11 @@
  ../src/ascension/glcontext.h ../src/ascension/primitives.h \
  ../src/ascension/mesh.h ../src/ascension/shader.h \
  ../src/ascension/scene.h ../src/ascension/transform.h \
- ../src/ascension/camera.h ../src/ascension/ui/font.h \
- ../src/ascension/ui.h ../src/ascension/ui/text.h \
- ../src/ascension/ui/font.h ../src/ascension/ui/../scene.h \
- ../src/ascension/ui/../texture.h ../src/ascension/ui/../utils.h
+ ../src/ascension/camera.h ../src/ascension/input.h \
+ ../src/ascension/ui/font.h ../src/ascension/ui.h \
+ ../src/ascension/ui/text.h ../src/ascension/ui/font.h \
+ ../src/ascension/ui/../scene.h ../src/ascension/ui/../texture.h \
+ ../src/ascension/ui/../utils.h
 	@echo "Compiling $<"
 	$(CC) -o $@ $(CFLAGS) -c $<
 

mercurial