mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-30 07:07:25 +00:00
183 lines
5.8 KiB
C++
183 lines
5.8 KiB
C++
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#pragma once
|
|
|
|
#include <optional>
|
|
#include <slint-platform.h>
|
|
#include "appview.h"
|
|
#include <cassert>
|
|
#include <windows.h>
|
|
|
|
struct Geometry
|
|
{
|
|
int x = 0;
|
|
int y = 0;
|
|
uint32_t width = 0;
|
|
uint32_t height = 0;
|
|
};
|
|
|
|
struct MyWindowAdapter : public slint::platform::WindowAdapter
|
|
{
|
|
HWND hwnd;
|
|
Geometry geometry = { 0, 0, 600, 300 };
|
|
std::optional<slint::platform::SkiaRenderer> m_renderer;
|
|
|
|
MyWindowAdapter(HWND winId)
|
|
{
|
|
HINSTANCE hInstance = GetModuleHandleW(nullptr);
|
|
|
|
// Register the window class.
|
|
const wchar_t CLASS_NAME[] = L"Sample Window Class";
|
|
|
|
WNDCLASS wc = {};
|
|
|
|
wc.lpfnWndProc = MyWindowAdapter::windowProc;
|
|
wc.hInstance = hInstance;
|
|
wc.lpszClassName = CLASS_NAME;
|
|
|
|
RegisterClass(&wc);
|
|
|
|
// Create the window.
|
|
|
|
hwnd = CreateWindowEx(0, // Optional window styles.
|
|
CLASS_NAME, // Window class
|
|
L"Learn to Program Windows", // Window text
|
|
WS_CHILDWINDOW, // Window style
|
|
|
|
// Size and position
|
|
0, 0, 600, 300,
|
|
|
|
winId,
|
|
NULL, // Menu
|
|
hInstance, // Instance handle
|
|
NULL // Additional application data
|
|
);
|
|
|
|
m_renderer.emplace(slint::platform::NativeWindowHandle::from_win32(hwnd, hInstance),
|
|
slint::PhysicalSize({ 600, 300 }));
|
|
|
|
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)this);
|
|
}
|
|
|
|
slint::platform::AbstractRenderer &renderer() override { return m_renderer.value(); }
|
|
|
|
slint::PhysicalSize size() override
|
|
{
|
|
RECT r;
|
|
GetWindowRect(hwnd, &r);
|
|
return slint::PhysicalSize({ uint32_t(r.right - r.left), uint32_t(r.bottom - r.top) });
|
|
}
|
|
|
|
void set_visible(bool visible) override { ShowWindow(hwnd, visible ? SW_SHOWNORMAL : SW_HIDE); }
|
|
|
|
void request_redraw() override { InvalidateRect(hwnd, nullptr, false); }
|
|
|
|
void render()
|
|
{
|
|
m_renderer->render();
|
|
if (window().has_active_animations())
|
|
request_redraw();
|
|
}
|
|
|
|
void resize(uint32_t width, uint32_t height)
|
|
{
|
|
window().dispatch_resize_event(slint::LogicalSize({ (float)width, (float)height }));
|
|
}
|
|
|
|
void setGeometry(int x, int y, int width, int height)
|
|
{
|
|
SetWindowPos(hwnd, nullptr, x, y, width, height, 0);
|
|
}
|
|
|
|
void mouse_event(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
using slint::LogicalPosition;
|
|
using slint::PointerEventButton;
|
|
float x = float(LOWORD(lParam));
|
|
float y = float(HIWORD(lParam));
|
|
switch (uMsg) {
|
|
case WM_LBUTTONUP:
|
|
window().dispatch_pointer_release_event(LogicalPosition({ x, y }),
|
|
PointerEventButton::Left);
|
|
break;
|
|
case WM_MBUTTONUP:
|
|
window().dispatch_pointer_release_event(LogicalPosition({ x, y }),
|
|
PointerEventButton::Middle);
|
|
break;
|
|
case WM_RBUTTONUP:
|
|
window().dispatch_pointer_release_event(LogicalPosition({ x, y }),
|
|
PointerEventButton::Right);
|
|
break;
|
|
case WM_LBUTTONDOWN:
|
|
window().dispatch_pointer_press_event(LogicalPosition({ x, y }),
|
|
PointerEventButton::Left);
|
|
break;
|
|
case WM_MBUTTONDOWN:
|
|
window().dispatch_pointer_press_event(LogicalPosition({ x, y }),
|
|
PointerEventButton::Middle);
|
|
break;
|
|
case WM_RBUTTONDOWN:
|
|
window().dispatch_pointer_press_event(LogicalPosition({ x, y }),
|
|
PointerEventButton::Right);
|
|
break;
|
|
case WM_XBUTTONDOWN:
|
|
switch (GET_XBUTTON_WPARAM(wParam)) {
|
|
case XBUTTON1:
|
|
window().dispatch_pointer_press_event(LogicalPosition({ x, y }),
|
|
PointerEventButton::Back);
|
|
break;
|
|
case XBUTTON2:
|
|
window().dispatch_pointer_press_event(LogicalPosition({ x, y }),
|
|
PointerEventButton::Forward);
|
|
break;
|
|
}
|
|
case WM_MOUSEMOVE:
|
|
window().dispatch_pointer_move_event(LogicalPosition({ x, y }));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static LRESULT CALLBACK windowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
MyWindowAdapter *self =
|
|
reinterpret_cast<MyWindowAdapter *>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
|
|
if (self == nullptr) {
|
|
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
|
}
|
|
switch (uMsg) {
|
|
case WM_DESTROY:
|
|
PostQuitMessage(0);
|
|
return 0;
|
|
|
|
case WM_PAINT: {
|
|
PAINTSTRUCT ps;
|
|
BeginPaint(hwnd, &ps);
|
|
slint::platform::update_timers_and_animations();
|
|
self->render();
|
|
EndPaint(hwnd, &ps);
|
|
return 0;
|
|
}
|
|
|
|
case WM_SIZE:
|
|
self->resize(LOWORD(lParam), HIWORD(lParam));
|
|
return 0;
|
|
|
|
case WM_LBUTTONUP:
|
|
case WM_LBUTTONDOWN:
|
|
case WM_MBUTTONUP:
|
|
case WM_MBUTTONDOWN:
|
|
case WM_RBUTTONUP:
|
|
case WM_RBUTTONDOWN:
|
|
case WM_MOUSEMOVE:
|
|
slint::platform::update_timers_and_animations();
|
|
self->mouse_event(uMsg, wParam, lParam);
|
|
return 0;
|
|
}
|
|
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
|
}
|
|
|
|
private:
|
|
};
|