Răsfoiți Sursa

Converted from C++ to C
WARNING: Is currently not working! Needs more debugging.

Ludwig Füchsl 3 ani în urmă
părinte
comite
169470d2e3

+ 1 - 1
demo/gdi_native_nuklear/build.bat

@@ -3,4 +3,4 @@
 rem This will use VS2015 for compiler
 call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86
 
-cl /nologo /W3 /O2 /fp:fast /Gm- /D_CRT_SECURE_NO_DEPRECATE /Fedemo.exe main.cpp user32.lib gdi32.lib Msimg32.lib /link /incremental:no 
+cl /nologo /W3 /O2 /fp:fast /Gm- /D_CRT_SECURE_NO_DEPRECATE /Fedemo.exe main.c user32.lib gdi32.lib Msimg32.lib /link /incremental:no 

+ 13 - 12
demo/gdi_native_nuklear/main.cpp → demo/gdi_native_nuklear/main.c

@@ -1,5 +1,4 @@
 #include <Windows.h>
-#include <iostream>
 
 #pragma comment(linker,"\"/manifestdependency:type='win32' \
 name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
@@ -19,19 +18,21 @@ processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
 
 INT WINAPI wWinMain(HINSTANCE _In_ hInstance, HINSTANCE _In_opt_ hPrevInstance, PWSTR _In_ cmdArgs, INT _In_ cmdShow)
 {
-    NkGdi::Window w1(500, 500, "F1", 10, 10);
-    w1.AllowSizing = false;
-    w1.AllowMaximize = false;
-    w1.AllowMove = false;
-    w1.HasTitlebar = false;
+    struct nkgdi_window w1, w2;
 
-    NkGdi::Window w2(500, 500, "F2", 520, 10);
-    w2.AllowSizing = true;
-    w2.AllowMaximize = true;
-    w2.AllowMove = true;
-    w2.HasTitlebar = true;
+    w1.allow_sizing = 0;
+    w1.allow_maximize = 0;
+    w1.allow_move = 0;
+    w1.has_titlebar = 0;
+    nkgdi_window_create(&w1, 500, 500, "F1", 10, 10);
+
+    w2.allow_sizing = 1;
+    w2.allow_maximize = 1;
+    w2.allow_move = 1;
+    w2.has_titlebar = 1;
+    nkgdi_window_create(&w2, 500, 500, "F2", 520, 10);
     
-    while (w1.Update() && w2.Update()) Sleep(20);
+    while (nkgdi_window_update(&w1) && nkgdi_window_update(&w2)) Sleep(20);
 
     return 0;
 }

+ 171 - 189
demo/gdi_native_nuklear/window.h

@@ -1,117 +1,93 @@
-#pragma once
+#ifndef NK_GDI_WINDOW
+#define NK_GDI_WINDOW
 
-namespace NkGdi
-{
-    // Container for window management
-    class WindowClass
-    {
-        public:
-            // Public exposed name
-            static const wchar_t* const ClassName;
+#define NK_GDI_WINDOW_CLS L"WNDCLS_NkGdi"
 
-            WindowClass(const WindowClass&) = delete;
-        private:
-            // Instance
-            static WindowClass ClassInstance;
+#include <Windows.h>
 
-            // Sigelton
-            WindowClass();
-    };
+/* Functin pointer types for window callbacks */
+typedef void(*nkgdi_window_func_update)(void);
+typedef int(*nkgdi_window_func_close)(void);
+typedef int(*nkgdi_window_func_draw)(struct nk_context*);
 
-    // Window base class
-    class Window
+/* Window container / context */
+struct nkgdi_window
+{
+    /* Properties */
+    int allow_sizing;
+    int allow_maximize;
+    int allow_move;
+    int has_titlebar;
+
+    /* Callbacks */
+    nkgdi_window_func_update cb_on_update;
+    nkgdi_window_func_close cb_on_close;
+    nkgdi_window_func_draw cb_on_draw;
+
+    /* Internal Data */
+    struct
     {
-        friend class WindowClass;
-
-        public:
-            // Default constructs
-            Window() = default;
-            Window(const Window&) = delete;
-            Window(Window&&) = default;
-            // Constructor
-            Window(unsigned int width, unsigned int height, const char* name, int posX = 100, int posY = 100);
-            // Destructor
-            ~Window();
-
-            // Processs window events and render the window (returns true as long as window is open)
-            bool Update();
-
-            // Properties
-            bool AllowSizing = true;
-            bool AllowMaximize = true;
-            bool AllowMove = true;
-            bool HasTitlebar = true;
-
-        public:
-            // Called when the core window gets an event
-            virtual LRESULT OnWindowMessage(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam);
-
-            // Called when the window is created
-            inline virtual void OnCreate() {};
-            // Called when the window is destroyed
-            inline virtual void OnDestroy() {};
-            // Called when the windows is beein updated (before events are served)
-            inline virtual void OnUpdate() {};
-            // Called when the window is beeing closed by the user (return false to abort)
-            inline virtual bool OnClose() { return true; };
-            // Called when nuklear drawcalls can be issued (return false to close the window)
-            inline virtual bool OnDraw(nk_context* ctx) { return true; };
-
-        private:
-            // Static window procs
-            static LRESULT wndProcSetup(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam);
-            static LRESULT wndProcRun(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam);
-
-        private:
-            // Window handle
-            HWND m_window = NULL;
-
-            // Nuklear context
-            nk_gdi_ctx m_nkGdiCtx = nullptr;
-            nk_context* m_nkCtx = nullptr;
-
-            // Nuklear objects
-            GdiFont* m_gdiFont = nullptr;
-            HDC m_windowDc = NULL;
-
-            // Window runtime features
-            bool m_isOpen = true;
-            bool m_isDraggin = false;
-            bool m_wsOverride = false;
-            bool m_isMaximized = false;
-            POINT m_dragOffset = {};
-            int m_width = 0;
-            int m_height = 0;
-    };
-}
+        // Window handle
+        HWND window_handle;
+
+        // Nuklear context
+        nk_gdi_ctx nk_gdi_ctx;
+        struct nk_context* nk_ctx;
+
+        // Nuklear objects
+        GdiFont* gdi_font;
+        HDC window_dc;
+
+        // Window runtime features
+        int is_open;
+        int is_draggin;
+        int ws_override;
+        int is_maximized;
+        POINT drag_offset;
+        int width;
+        int height;
+    }_internal;
+};
+
+/* API */
+void nkgdi_window_init(void);
+void nkgdi_window_shutdown(void);
+void nkgdi_window_create(struct nkgdi_window* wnd, unsigned int width, unsigned int height, const char* name, int posX, int posY);
+int nkgdi_window_update(struct nkgdi_window* wnd);
+void nkgdi_window_destroy(struct nkgdi_window* wnd);
 
 #ifdef NKGDI_IMPLEMENT_WINDOW
 
-const wchar_t* const NkGdi::WindowClass::ClassName = L"WNDCLS_NkGdi";
-NkGdi::WindowClass NkGdi::WindowClass::ClassInstance;
+LRESULT nkgdi_window_proc_setup(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam);
+LRESULT nkgdi_window_proc_run(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam);
 
-NkGdi::WindowClass::WindowClass()
+void nkgdi_window_init(void)
 {
     // Describe class
     WNDCLASSEXW cls;
     cls.cbSize = sizeof(WNDCLASSEXW);
     cls.style = CS_OWNDC | CS_DBLCLKS;
-    cls.lpfnWndProc = &Window::wndProcSetup;
+    cls.lpfnWndProc = &nkgdi_window_proc_setup;
     cls.cbClsExtra = 0;
     cls.cbWndExtra = 0;
     cls.hInstance = GetModuleHandle(NULL);
     cls.hIcon = LoadIcon(NULL, IDI_APPLICATION);
     cls.hCursor = LoadCursor(NULL, IDC_ARROW);
     cls.hbrBackground = NULL;
-    cls.lpszMenuName = nullptr;
-    cls.lpszClassName = ClassName;
+    cls.lpszMenuName = NULL;
+    cls.lpszClassName = NK_GDI_WINDOW_CLS;
     cls.hIconSm = NULL;
 
     // Register class
     RegisterClassExW(&cls);
 }
 
-NkGdi::Window::Window(unsigned int width, unsigned int height, const char* name, int posX, int posY)
+void nkgdi_window_shutdown(void)
+{
+    UnregisterClassW(NK_GDI_WINDOW_CLS, GetModuleHandle(NULL));
+}
+
+void nkgdi_window_create(struct nkgdi_window* wnd, unsigned int width, unsigned int height, const char* name, int posX, int posY)
 {
     DWORD styleEx = WS_EX_WINDOWEDGE;
     DWORD style = WS_POPUP;
@@ -125,121 +101,155 @@ NkGdi::Window::Window(unsigned int width, unsigned int height, const char* name,
     AdjustWindowRectEx(&cr, style, FALSE, styleEx);
 
     // Create the window
-    m_window = CreateWindowExW(
+    wnd->_internal.window_handle = CreateWindowExW(
         styleEx,
-        WindowClass::ClassName,
+        NK_GDI_WINDOW_CLS,
         L"NkGdi",
         style | WS_VISIBLE,
         posX, posY,
         cr.right - cr.left, cr.bottom - cr.top,
         NULL, NULL,
-        GetModuleHandleW(nullptr),
-        this
+        GetModuleHandleW(NULL),
+        wnd
     );
  
     // Rename window to user picked name
-    SetWindowTextA(m_window, name);
+    SetWindowTextA(wnd->_internal.window_handle, name);
 
     // Get DC
-    m_windowDc = GetWindowDC(m_window);
+    wnd->_internal.window_dc = GetWindowDC(wnd->_internal.window_handle);
 
     // Create font
-    m_gdiFont = nk_gdifont_create("Arial", 16);
-    m_nkCtx = nk_gdi_init(&m_nkGdiCtx, m_gdiFont, m_windowDc, width, height);
+    wnd->_internal.gdi_font = nk_gdifont_create("Arial", 16);
+    wnd->_internal.nk_ctx = nk_gdi_init(&wnd->_internal.nk_gdi_ctx, wnd->_internal.gdi_font, wnd->_internal.window_dc, width, height);
+
+    // Setup internal data
+    wnd->_internal.is_open = 1;
+    wnd->_internal.is_draggin = 0;
+    wnd->_internal.ws_override = 0;
+    wnd->_internal.is_maximized = 0;
+    wnd->_internal.drag_offset.x = 0;
+    wnd->_internal.drag_offset.y = 0;
+    wnd->_internal.width = 0;
+    wnd->_internal.height = 0;
 }
 
-NkGdi::Window::~Window()
+void nkgdi_window_destroy(struct nkgdi_window* wnd)
 {
     // Destroy  GDI context
-    if (m_nkGdiCtx)
+    if (wnd->_internal.nk_gdi_ctx)
     {
-        nk_gdi_shutdown(m_nkGdiCtx);
+        nk_gdi_shutdown(wnd->_internal.nk_gdi_ctx);
     }
 
     // Destroy font
-    if (m_gdiFont)
+    if (wnd->_internal.gdi_font)
     {
-        nk_gdifont_del(m_gdiFont);
+        nk_gdifont_del(wnd->_internal.gdi_font);
     }
 
     // Close DC
-    if (m_windowDc)
+    if (wnd->_internal.window_dc)
     {
-        ReleaseDC(m_window, m_windowDc);
+        ReleaseDC(wnd->_internal.window_handle, wnd->_internal.window_dc);
     }
 
     // Destroy window
-    if (m_window)
+    if (wnd->_internal.window_handle)
     {
-        CloseWindow(m_window);
-        DestroyWindow(m_window);
+        CloseWindow(wnd->_internal.window_handle);
+        DestroyWindow(wnd->_internal.window_handle);
     }
 }
 
-bool NkGdi::Window::Update()
+int nkgdi_window_update(struct nkgdi_window* wnd)
 {
     // Only process events while window is open
-    if (m_isOpen)
+    if (wnd->_internal.is_open)
     {
-        // Notify class that event processing has stated
-        OnUpdate();
-
         // Windows event loop
-        MSG msg = {};
-        nk_input_begin(m_nkCtx);
-        while (PeekMessage(&msg, m_window, 0, 0, PM_REMOVE))
+        MSG msg;
+        nk_input_begin(wnd->_internal.nk_ctx);
+        while (PeekMessage(&msg, wnd->_internal.window_handle, 0, 0, PM_REMOVE))
         {
             TranslateMessage(&msg);
             DispatchMessageW(&msg);
         }
-        nk_input_end(m_nkCtx);
+        nk_input_end(wnd->_internal.nk_ctx);
 
         // Get title
         char title[1024];
-        GetWindowTextA(m_window, title, 1024);
+        GetWindowTextA(wnd->_internal.window_handle, title, 1024);
+
+        // Window flags
+        nk_flags window_flags = NK_WINDOW_BORDER;
+        if(wnd->has_titlebar)
+            window_flags |= NK_WINDOW_CLOSABLE | NK_WINDOW_TITLE;
+        if(!wnd->_internal.is_maximized && wnd->allow_sizing)
+            window_flags |= NK_WINDOW_SCALABLE;
 
         // Window body
-        if (m_wsOverride)
-            nk_window_set_bounds(m_nkCtx, title, nk_rect(0, 0, m_width, m_height));
-        if (nk_begin(m_nkCtx, title, nk_rect(0, 0, m_width, m_height), 
-            NK_WINDOW_BORDER | 
-            (HasTitlebar ? NK_WINDOW_CLOSABLE | NK_WINDOW_TITLE : NULL) |
-            (m_isMaximized || !AllowSizing ? NULL : NK_WINDOW_SCALABLE) 
-        ))
+        if (wnd->_internal.ws_override)
+            nk_window_set_bounds(wnd->_internal.nk_ctx, title, nk_rect(0, 0, wnd->_internal.width, wnd->_internal.height));
+        if (nk_begin(wnd->_internal.nk_ctx, title, nk_rect(0, 0, wnd->_internal.width, wnd->_internal.height), window_flags))
         {
-            if(!OnDraw(m_nkCtx))
-                m_isOpen = false;
+            if(!wnd->cb_on_draw(wnd->_internal.nk_ctx))
+                wnd->_internal.is_open = 0;
 
             // Update window size
-            struct nk_rect bounds = nk_window_get_bounds(m_nkCtx);
-            if(bounds.w != m_width || bounds.h != m_height)
-                SetWindowPos(m_window, NULL, 0, 0, bounds.w, bounds.h, SWP_NOMOVE | SWP_NOOWNERZORDER);
+            struct nk_rect bounds = nk_window_get_bounds(wnd->_internal.nk_ctx);
+            if(bounds.w != wnd->_internal.width || bounds.h != wnd->_internal.height)
+                SetWindowPos(wnd->_internal.window_handle, NULL, 0, 0, bounds.w, bounds.h, SWP_NOMOVE | SWP_NOOWNERZORDER);
         }
         else
         {
             // Handle window closing
-            if(OnClose())
-                m_isOpen = false;
+            if(!wnd->cb_on_close || wnd->cb_on_close())
+                wnd->_internal.is_open = 0;
         }
-        nk_end(m_nkCtx);
-        m_wsOverride = false;
+        nk_end(wnd->_internal.nk_ctx);
+        wnd->_internal.ws_override = 0;
 
         // Final render pass
-        nk_gdi_render(m_nkGdiCtx, nk_rgb(30, 30, 30));
+        nk_gdi_render(wnd->_internal.nk_gdi_ctx, nk_rgb(30, 30, 30));
     }
 
-    return m_isOpen;
+    return wnd->_internal.is_open;
 }
 
-LRESULT NkGdi::Window::OnWindowMessage(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
+LRESULT nkgdi_window_proc_setup(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
+    // Wait for setup message
+    if (msg == WM_NCCREATE)
+    {
+        // Get creation parameters & window pointer
+        CREATESTRUCT* ptrCr = (CREATESTRUCT*)lParam;
+        struct nkgdi_window* nkgdi_wnd = (struct nkgdi_window*)ptrCr->lpCreateParams;
+
+        // Store pointer and new proc in window
+        SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)nkgdi_wnd);
+        SetWindowLongPtr(wnd, GWLP_WNDPROC, (LONG_PTR)&nkgdi_window_proc_run);
+
+        // Handled by window
+        return nkgdi_window_proc_run(wnd, msg, wParam, lParam);
+    }
+
+    // Default handler
+    return DefWindowProc(wnd, msg, wParam, lParam);
+}
+
+LRESULT nkgdi_window_proc_run(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    // Get window pointer
+    struct nkgdi_window* nkwnd = (struct nkgdi_window*)GetWindowLongPtrW(wnd, GWLP_USERDATA);
+    
     // Switch on supplied message code
     switch (msg)
     {
         // Close event
         case WM_CLOSE:
-            if (OnClose())
-                m_isOpen = false;
+            if(!nkwnd->cb_on_close || nkwnd->cb_on_close())
+                nkwnd->_internal.is_open = 0;
             return 0; // Will always be handled internaly
         
         // While sizing
@@ -247,8 +257,8 @@ LRESULT NkGdi::Window::OnWindowMessage(HWND wnd, UINT msg, WPARAM wParam, LPARAM
             {
             RECT cr;
             GetClientRect(wnd, &cr);
-            m_width = cr.right - cr.left;
-            m_height = cr.bottom - cr.top;
+            nkwnd->_internal.width = cr.right - cr.left;
+            nkwnd->_internal.height = cr.bottom - cr.top;
             }
             break;
 
@@ -263,56 +273,56 @@ LRESULT NkGdi::Window::OnWindowMessage(HWND wnd, UINT msg, WPARAM wParam, LPARAM
                 monitorInfo.cbSize = sizeof(MONITORINFO);
                 if (GetMonitorInfoW(monitor, &monitorInfo))
                 {
-                    m_height = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
-                    m_width = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
-                    m_wsOverride = true;
-                    m_isMaximized = true;
-                    SetWindowPos(wnd, NULL, 0, 0, m_width, m_height, SWP_NOMOVE | SWP_NOZORDER);
+                    nkwnd->_internal.height = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
+                    nkwnd->_internal.width = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
+                    nkwnd->_internal.ws_override = 1;
+                    nkwnd->_internal.is_maximized = 1;
+                    SetWindowPos(wnd, NULL, 0, 0, nkwnd->_internal.width, nkwnd->_internal.height, SWP_NOMOVE | SWP_NOZORDER);
                 }
             }
             else if (wParam == SIZE_RESTORED)
             {
-                m_isMaximized = false;
+                nkwnd->_internal.is_maximized = 0;
             }
 
             // Compute new bounds
             RECT cr;
             GetClientRect(wnd, &cr);
-            m_width = cr.right - cr.left;
-            m_height = cr.bottom - cr.top;
+            nkwnd->_internal.width = cr.right - cr.left;
+            nkwnd->_internal.height = cr.bottom - cr.top;
             }
             break;
 
         // When mouse start l-press (drag window)
         case WM_LBUTTONDOWN:
             {
-            if (HIWORD(lParam) <= 30 && AllowMove)
+            if (HIWORD(lParam) <= 30 && nkwnd->allow_move)
             {
                 // Start dragging
-                m_isDraggin = true;
-                m_dragOffset.x = LOWORD(lParam);
-                m_dragOffset.y = HIWORD(lParam);
+                nkwnd->_internal.is_draggin = 1;
+                nkwnd->_internal.drag_offset.x = LOWORD(lParam);
+                nkwnd->_internal.drag_offset.y = HIWORD(lParam);
             }
             }
             break;
 
         // When mouse stops l-press (drag window)
         case WM_LBUTTONUP:
-            m_isDraggin = false;
+            nkwnd->_internal.is_draggin = 0;
             break;
 
         // Mouse movement (dragging)
         case WM_MOUSEMOVE:
             {
-            if (m_isDraggin && !m_isMaximized)
+            if (nkwnd->_internal.is_draggin && !nkwnd->_internal.is_maximized)
             {
                 // Get mouse postion and substract offset
                 POINT cursorPos;
                 GetCursorPos(&cursorPos);
-                cursorPos.x -= m_dragOffset.x;
-                cursorPos.y -= m_dragOffset.y;
+                cursorPos.x -= nkwnd->_internal.drag_offset.x;
+                cursorPos.y -= nkwnd->_internal.drag_offset.y;
                 // Use as new position
-                ShowWindow(m_window, SW_RESTORE);
+                ShowWindow(wnd, SW_RESTORE);
                 SetWindowPos(wnd, NULL, cursorPos.x, cursorPos.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
             }
             }
@@ -321,9 +331,9 @@ LRESULT NkGdi::Window::OnWindowMessage(HWND wnd, UINT msg, WPARAM wParam, LPARAM
         // On mouse doubble click (maximize)
         case WM_LBUTTONDBLCLK:
             {
-            if (HIWORD(lParam) <= 30 && AllowMaximize)
+            if (HIWORD(lParam) <= 30 && nkwnd->allow_maximize)
             {
-                if (m_isMaximized)
+                if (nkwnd->_internal.is_maximized)
                 {
                     ShowWindow(wnd, SW_RESTORE);
                 }
@@ -331,47 +341,19 @@ LRESULT NkGdi::Window::OnWindowMessage(HWND wnd, UINT msg, WPARAM wParam, LPARAM
                 {
                     ShowWindow(wnd, SW_MAXIMIZE);
                 }
-                m_wsOverride = true;
+                nkwnd->_internal.ws_override = 1;
             }
             }
             break;
     }
 
     // Send to nuklear
-    if (m_nkGdiCtx && nk_gdi_handle_event(m_nkGdiCtx, wnd, msg, wParam, lParam))
+    if (nkwnd->_internal.nk_gdi_ctx && nk_gdi_handle_event(nkwnd->_internal.nk_gdi_ctx, wnd, msg, wParam, lParam))
         return 0;
 
     // In case this is ever reached: Run default behaviour
     return DefWindowProc(wnd, msg, wParam, lParam);
 }
 
-LRESULT NkGdi::Window::wndProcSetup(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
-    // Wait for setup message
-    if (msg == WM_NCCREATE)
-    {
-        // Get creation parameters & window pointer
-        CREATESTRUCT* ptrCr = (CREATESTRUCT*)lParam;
-        Window* ptrWindow = (Window*)ptrCr->lpCreateParams;
-
-        // Store pointer and new proc in window
-        SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)ptrWindow);
-        SetWindowLongPtr(wnd, GWLP_WNDPROC, (LONG_PTR)&wndProcRun);
-
-        // Handled by window
-        return ptrWindow->OnWindowMessage(wnd, msg, wParam, lParam);
-    }
-
-    // Default handler
-    return DefWindowProc(wnd, msg, wParam, lParam);
-}
-
-LRESULT NkGdi::Window::wndProcRun(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
-    // Get window pointer
-    Window* ptrWindow = (Window*)GetWindowLongPtr(wnd, GWLP_USERDATA);
-    // Call window
-    return ptrWindow->OnWindowMessage(wnd, msg, wParam, lParam);
-}
-
+#endif
 #endif