mirror of
				https://github.com/nicbarker/clay.git
				synced 2025-11-04 00:26:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			219 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			219 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
 | 
						|
#define WIN32_LEAN_AND_MEAN
 | 
						|
#include <windows.h>
 | 
						|
#include <windowsx.h>
 | 
						|
 | 
						|
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
 | 
						|
#include <math.h>
 | 
						|
 | 
						|
#include "../../renderers/win32_gdi/clay_renderer_gdi.c"
 | 
						|
 | 
						|
#define CLAY_IMPLEMENTATION
 | 
						|
#include "../../clay.h"
 | 
						|
 | 
						|
#include "../shared-layouts/clay-video-demo.c"
 | 
						|
 | 
						|
ClayVideoDemo_Data demo_data;
 | 
						|
 | 
						|
#define APPNAME "Clay GDI Example"
 | 
						|
char szAppName[] = APPNAME; // The name of this application
 | 
						|
char szTitle[] = APPNAME;   // The title bar text
 | 
						|
 | 
						|
void CenterWindow(HWND hWnd);
 | 
						|
 | 
						|
long lastMsgTime = 0;
 | 
						|
bool ui_debug_mode;
 | 
						|
 | 
						|
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 | 
						|
{
 | 
						|
 | 
						|
    switch (message)
 | 
						|
    {
 | 
						|
 | 
						|
    // ----------------------- first and last
 | 
						|
    case WM_CREATE:
 | 
						|
        CenterWindow(hwnd);
 | 
						|
        break;
 | 
						|
 | 
						|
    case WM_DESTROY:
 | 
						|
        PostQuitMessage(0);
 | 
						|
        break;
 | 
						|
 | 
						|
    case WM_MOUSEWHEEL: // scrolling data
 | 
						|
    {
 | 
						|
        short zDelta = GET_WHEEL_DELTA_WPARAM(wParam);
 | 
						|
        // todo: i think GetMessageTime can roll over, so something like if(lastmsgtime > now) ... may be needed
 | 
						|
        long now = GetMessageTime();
 | 
						|
        float dt = (now - lastMsgTime) / 1000.00;
 | 
						|
 | 
						|
        lastMsgTime = now;
 | 
						|
 | 
						|
        // little hacky hack to make scrolling *feel* right
 | 
						|
        if (abs(zDelta) > 100)
 | 
						|
        {
 | 
						|
            zDelta = zDelta * .012;
 | 
						|
        }
 | 
						|
 | 
						|
        Clay_UpdateScrollContainers(true, (Clay_Vector2){.x = 0, .y = zDelta}, dt);
 | 
						|
 | 
						|
        InvalidateRect(hwnd, NULL, false); // force a wm_paint event
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case WM_RBUTTONUP:
 | 
						|
    case WM_LBUTTONUP:
 | 
						|
    case WM_LBUTTONDOWN:
 | 
						|
    case WM_RBUTTONDOWN:
 | 
						|
    case WM_MOUSEMOVE: // mouse events
 | 
						|
    {
 | 
						|
        short mouseX = GET_X_LPARAM(lParam);
 | 
						|
        short mouseY = GET_Y_LPARAM(lParam);
 | 
						|
        short mouseButtons = LOWORD(wParam);
 | 
						|
 | 
						|
        Clay_SetPointerState((Clay_Vector2){mouseX, mouseY}, mouseButtons & 0b01);
 | 
						|
 | 
						|
        InvalidateRect(hwnd, NULL, false); // force a wm_paint event
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    case WM_SIZE: // resize events
 | 
						|
    {
 | 
						|
 | 
						|
        RECT r = {0};
 | 
						|
        if (GetClientRect(hwnd, &r))
 | 
						|
        {
 | 
						|
            Clay_Dimensions dim = (Clay_Dimensions){.height = r.bottom - r.top, .width = r.right - r.left};
 | 
						|
            Clay_SetLayoutDimensions(dim);
 | 
						|
        }
 | 
						|
 | 
						|
        InvalidateRect(hwnd, NULL, false); // force a wm_paint event
 | 
						|
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    case WM_KEYDOWN:
 | 
						|
        if (VK_ESCAPE == wParam)
 | 
						|
        {
 | 
						|
            DestroyWindow(hwnd);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
 | 
						|
        if (wParam == VK_F12)
 | 
						|
        {
 | 
						|
            Clay_SetDebugModeEnabled(ui_debug_mode = !ui_debug_mode);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
 | 
						|
        printf("Key Pressed: %d\r\n", wParam);
 | 
						|
        InvalidateRect(hwnd, NULL, false); // force a wm_paint event
 | 
						|
        break;
 | 
						|
 | 
						|
    // ----------------------- render
 | 
						|
    case WM_PAINT:
 | 
						|
    {
 | 
						|
        Clay_RenderCommandArray renderCommands = ClayVideoDemo_CreateLayout(&demo_data);
 | 
						|
        Clay_Win32_Render(hwnd, renderCommands);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    // ----------------------- let windows do all other stuff
 | 
						|
    default:
 | 
						|
        return DefWindowProc(hwnd, message, wParam, lParam);
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
bool didAllocConsole = false;
 | 
						|
 | 
						|
void HandleClayErrors(Clay_ErrorData errorData)
 | 
						|
{
 | 
						|
    if (!didAllocConsole)
 | 
						|
    {
 | 
						|
        didAllocConsole = AllocConsole();
 | 
						|
    }
 | 
						|
 | 
						|
    printf("Handle Clay Errors: %s\r\n", errorData.errorText.chars);
 | 
						|
}
 | 
						|
 | 
						|
int APIENTRY WinMain(
 | 
						|
    HINSTANCE hInstance,
 | 
						|
    HINSTANCE hPrevInstance,
 | 
						|
    LPSTR lpCmdLine,
 | 
						|
    int nCmdShow)
 | 
						|
{
 | 
						|
    MSG msg;
 | 
						|
    WNDCLASS wc;
 | 
						|
    HWND hwnd;
 | 
						|
 | 
						|
    demo_data = ClayVideoDemo_Initialize();
 | 
						|
 | 
						|
    uint64_t clayRequiredMemory = Clay_MinMemorySize();
 | 
						|
    Clay_Arena clayMemory = Clay_CreateArenaWithCapacityAndMemory(clayRequiredMemory, malloc(clayRequiredMemory));
 | 
						|
    Clay_Initialize(clayMemory, (Clay_Dimensions){.width = 800, .height = 600}, (Clay_ErrorHandler){HandleClayErrors}); // This final argument is new since the video was published
 | 
						|
    Clay_SetMeasureTextFunction(Clay_Win32_MeasureText, NULL); 
 | 
						|
 | 
						|
    ZeroMemory(&wc, sizeof wc);
 | 
						|
    wc.hInstance = hInstance;
 | 
						|
    wc.lpszClassName = szAppName;
 | 
						|
    wc.lpfnWndProc = (WNDPROC)WndProc;
 | 
						|
    wc.style = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW;
 | 
						|
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
 | 
						|
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 | 
						|
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
 | 
						|
 | 
						|
    if (FALSE == RegisterClass(&wc))
 | 
						|
        return 0;
 | 
						|
 | 
						|
 | 
						|
    hwnd = CreateWindow(
 | 
						|
        szAppName,
 | 
						|
        szTitle,
 | 
						|
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
 | 
						|
        CW_USEDEFAULT,
 | 
						|
        CW_USEDEFAULT,
 | 
						|
        800, // CW_USEDEFAULT,
 | 
						|
        600, // CW_USEDEFAULT,
 | 
						|
        0,
 | 
						|
        0,
 | 
						|
        hInstance,
 | 
						|
        0);
 | 
						|
 | 
						|
    if (hwnd == NULL)
 | 
						|
        return 0;
 | 
						|
 | 
						|
    // Main message loop:
 | 
						|
    while (GetMessage(&msg, NULL, 0, 0) > 0)
 | 
						|
    {
 | 
						|
        TranslateMessage(&msg);
 | 
						|
        DispatchMessage(&msg);
 | 
						|
    }
 | 
						|
 | 
						|
    return msg.wParam;
 | 
						|
}
 | 
						|
 | 
						|
void CenterWindow(HWND hwnd_self)
 | 
						|
{
 | 
						|
    HWND hwnd_parent;
 | 
						|
    RECT rw_self, rc_parent, rw_parent;
 | 
						|
    int xpos, ypos;
 | 
						|
 | 
						|
    hwnd_parent = GetParent(hwnd_self);
 | 
						|
    if (NULL == hwnd_parent)
 | 
						|
        hwnd_parent = GetDesktopWindow();
 | 
						|
 | 
						|
    GetWindowRect(hwnd_parent, &rw_parent);
 | 
						|
    GetClientRect(hwnd_parent, &rc_parent);
 | 
						|
    GetWindowRect(hwnd_self, &rw_self);
 | 
						|
 | 
						|
    xpos = rw_parent.left + (rc_parent.right + rw_self.left - rw_self.right) / 2;
 | 
						|
    ypos = rw_parent.top + (rc_parent.bottom + rw_self.top - rw_self.bottom) / 2;
 | 
						|
 | 
						|
    SetWindowPos(
 | 
						|
        hwnd_self, NULL,
 | 
						|
        xpos, ypos, 0, 0,
 | 
						|
        SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
 | 
						|
}
 | 
						|
 | 
						|
//+---------------------------------------------------------------------------
 |