GDI - vurtun/nuklear GitHub Wiki
The Graphics Device Interface (GDI) is a component of the operating system Windows. If you are just starting with nuklear, GDI is the easiest way to get it running with Windows.
Compiling hints: You need to compile against the gdi32 library. For GCC (MinGW) you just need to add -lgdi32
to the compiler parameters.
Mode hints: Have a look to the demo demo/gdi/main.c
.
The following headers are needed. In this example the GDI demo is used for the rendering.
#define COBJMACROS
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define NK_IMPLEMENTATION
#define NK_ASSERT
#include "nuklear/nuklear.h"
#include "nuklear/demo/gdi/nuklear_gdi.h"
In windows your application must create a window to show something on the screen.
First of all the window parameters have to be defined.
ATOM atom;
RECT rect = { 0, 0, 500, 500};
DWORD style = WS_OVERLAPPEDWINDOW;
DWORD exstyle = WS_EX_APPWINDOW;
/* Win32 */
memset(&wc, 0, sizeof(wc));
wc.style = CS_DBLCLKS;
// Reserve space to store the instance pointer
wc.lpfnWndProc = WindowProc;
wc.hInstance = GetModuleHandleW(nullptr);
wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.lpszClassName = L"NuklearWindowClass";
atom = RegisterClassW(&wc);
The window is created by calling CreateWindowExW
with the properties we just setup.
AdjustWindowRectEx(&rect, style, FALSE, exstyle);
wnd = CreateWindowExW(exstyle, wc.lpszClassName, L"Nuklear Demo",
style | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT,
rect.right - rect.left, rect.bottom - rect.top,
nullptr, nullptr, wc.hInstance, nullptr);
The next few lines will get the device context of the window, creates the font (Arial, 14) and creates the Nuklear context.
/* GUI */
dc = GetDC(wnd);
font = nk_gdifont_create("Arial", 14);
ctx = nk_gdi_init(font, dc, 200, 200);
The window messages are handled by this function. By calling nk_gdi_handle_event
the received events are commited to Nuklear.
static LRESULT CALLBACK WindowProc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
if (nk_gdi_handle_event(wnd, msg, wparam, lparam))
return 0;
return DefWindowProcW(wnd, msg, wparam, lparam);
}
The main loop of Nuklear have to tasks to do. Processing the inputs and rendering the GUI.
int running = 1;
int need_refresh = 0;
while (running)
{
// HANDLE INPUTS
// RENDER GUI
}
/* Input */
MSG msg;
nk_input_begin(ctx);
if (needs_refresh == 0) {
if (GetMessageW(&msg, NULL, 0, 0) <= 0)
running = 0;
else {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
needs_refresh = 1;
} else needs_refresh = 0;
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT)
running = 0;
TranslateMessage(&msg);
DispatchMessageW(&msg);
needs_refresh = 1;
}
nk_input_end(ctx);
/* GUI */
if (nk_begin(ctx, "Demo", nk_rect(50, 50, 200, 200),
NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
NK_WINDOW_CLOSABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
{
enum {EASY, HARD};
static int op = EASY;
static int property = 20;
nk_layout_row_static(ctx, 30, 80, 1);
if (nk_button_label(ctx, "button"))
fprintf(stdout, "button pressed\n");
nk_layout_row_dynamic(ctx, 30, 2);
if (nk_option_label(ctx, "easy", op == EASY)) op = EASY;
if (nk_option_label(ctx, "hard", op == HARD)) op = HARD;
nk_layout_row_dynamic(ctx, 22, 1);
nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1);
}
nk_end(ctx);
/* Draw */
nk_gdi_render(nk_rgb(30,30,30));