263 lines
6.0 KiB
C
263 lines
6.0 KiB
C
|
// 4 september 2015
|
||
|
#define _GNU_SOURCE
|
||
|
#include "area.h"
|
||
|
#include <math.h>
|
||
|
|
||
|
// #qo LIBS: user32 kernel32 d2d1 ole32 uuid gdi32 msimg32
|
||
|
|
||
|
struct handler {
|
||
|
uiAreaHandler ah;
|
||
|
};
|
||
|
|
||
|
static HWND area;
|
||
|
static struct handler h;
|
||
|
static HWND nhspinb;
|
||
|
static HWND nvspinb;
|
||
|
|
||
|
static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *p)
|
||
|
{
|
||
|
uiDrawStrokeParams sp;
|
||
|
|
||
|
uiDrawBeginPathRGB(p->Context, 0xFF, 0x00, 0x00);
|
||
|
uiDrawMoveTo(p->Context, p->ClipX + 5, p->ClipY + 5);
|
||
|
uiDrawLineTo(p->Context, (p->ClipX + p->ClipWidth) - 5, (p->ClipY + p->ClipHeight) - 5);
|
||
|
sp.Cap = uiDrawLineCapFlat;
|
||
|
sp.Join = uiDrawLineJoinMiter;
|
||
|
sp.Thickness = 1;
|
||
|
sp.MiterLimit = uiDrawDefaultMiterLimit;
|
||
|
uiDrawStroke(p->Context, &sp);
|
||
|
|
||
|
uiDrawBeginPathRGB(p->Context, 0x00, 0x00, 0xC0);
|
||
|
uiDrawMoveTo(p->Context, p->ClipX, p->ClipY);
|
||
|
uiDrawLineTo(p->Context, p->ClipX + p->ClipWidth, p->ClipY);
|
||
|
uiDrawLineTo(p->Context, 50, 150);
|
||
|
uiDrawLineTo(p->Context, 50, 50);
|
||
|
uiDrawCloseFigure(p->Context);
|
||
|
sp.Cap = uiDrawLineCapFlat;
|
||
|
sp.Join = uiDrawLineJoinRound;
|
||
|
sp.Thickness = 5;
|
||
|
uiDrawStroke(p->Context, &sp);
|
||
|
|
||
|
uiDrawBeginPathRGBA(p->Context, 0x00, 0xC0, 0x00, 0x80);
|
||
|
uiDrawRectangle(p->Context, 120, 80, 50, 50);
|
||
|
uiDrawFill(p->Context, uiDrawFillModeWinding);
|
||
|
|
||
|
uiDrawBeginPathRGB(p->Context, 0x00, 0x80, 0x00);
|
||
|
uiDrawMoveTo(p->Context, 5, 10);
|
||
|
uiDrawLineTo(p->Context, 5, 50);
|
||
|
sp.Cap = uiDrawLineCapFlat;
|
||
|
sp.Join = uiDrawLineJoinMiter;
|
||
|
sp.Thickness = 1;
|
||
|
sp.MiterLimit = uiDrawDefaultMiterLimit;
|
||
|
uiDrawStroke(p->Context, &sp);
|
||
|
|
||
|
uiDrawBeginPathRGB(p->Context, 0x80, 0xC0, 0x00);
|
||
|
uiDrawMoveTo(p->Context, 400, 100);
|
||
|
uiDrawArcTo(p->Context,
|
||
|
400, 100,
|
||
|
50,
|
||
|
30. * (M_PI / 180.),
|
||
|
// note the end angle here
|
||
|
// in GDI, the second angle to AngleArc() is relative to the start, not to 0
|
||
|
330. * (M_PI / 180.),
|
||
|
1);
|
||
|
// TODO add a checkbox for this
|
||
|
uiDrawLineTo(p->Context, 400, 100);
|
||
|
uiDrawArcTo(p->Context,
|
||
|
510, 100,
|
||
|
50,
|
||
|
30. * (M_PI / 180.),
|
||
|
330. * (M_PI / 180.),
|
||
|
0);
|
||
|
uiDrawCloseFigure(p->Context);
|
||
|
sp.Cap = uiDrawLineCapFlat;
|
||
|
sp.Join = uiDrawLineJoinMiter;
|
||
|
sp.Thickness = 1;
|
||
|
sp.MiterLimit = uiDrawDefaultMiterLimit;
|
||
|
uiDrawStroke(p->Context, &sp);
|
||
|
|
||
|
uiDrawBeginPathRGB(p->Context, 0x00, 0x80, 0xC0);
|
||
|
uiDrawMoveTo(p->Context, 300, 300);
|
||
|
uiDrawBezierTo(p->Context,
|
||
|
350, 320,
|
||
|
310, 390,
|
||
|
435, 372);
|
||
|
sp.Cap = uiDrawLineCapFlat;
|
||
|
sp.Join = uiDrawLineJoinMiter;
|
||
|
sp.Thickness = 1;
|
||
|
sp.MiterLimit = uiDrawDefaultMiterLimit;
|
||
|
uiDrawStroke(p->Context, &sp);
|
||
|
}
|
||
|
|
||
|
static uintmax_t handlerHScrollMax(uiAreaHandler *a, uiArea *area)
|
||
|
{
|
||
|
WCHAR c[50];
|
||
|
|
||
|
GetWindowTextW(nhspinb, c, 50);
|
||
|
return _wtoi(c);
|
||
|
}
|
||
|
|
||
|
static uintmax_t handlerVScrollMax(uiAreaHandler *a, uiArea *area)
|
||
|
{
|
||
|
WCHAR c[50];
|
||
|
|
||
|
GetWindowTextW(nvspinb, c, 50);
|
||
|
return _wtoi(c);
|
||
|
}
|
||
|
|
||
|
static int handlerRedrawOnResize(uiAreaHandler *a, uiArea *area)
|
||
|
{
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
static void handlerMouseEvent(uiAreaHandler *a, uiArea *area, uiAreaMouseEvent *e)
|
||
|
{
|
||
|
printf("mouse (%d,%d):(%d,%d) down:%d up:%d count:%d mods:%x held:%I64x\n",
|
||
|
(int) e->X,
|
||
|
(int) e->Y,
|
||
|
(int) e->HScrollPos,
|
||
|
(int) e->VScrollPos,
|
||
|
(int) e->Down,
|
||
|
(int) e->Up,
|
||
|
(int) e->Count,
|
||
|
(uint32_t) e->Modifiers,
|
||
|
e->Held1To64);
|
||
|
}
|
||
|
|
||
|
static void handlerDragBroken(uiAreaHandler *ah, uiArea *a)
|
||
|
{
|
||
|
printf("drag broken\n");
|
||
|
}
|
||
|
|
||
|
static int handlerKeyEvent(uiAreaHandler *ah, uiArea *a, uiAreaKeyEvent *e)
|
||
|
{
|
||
|
char k[4];
|
||
|
|
||
|
k[0] = '\'';
|
||
|
k[1] = e->Key;
|
||
|
k[2] = '\'';
|
||
|
k[3] = '\0';
|
||
|
if (e->Key == 0) {
|
||
|
k[0] = '0';
|
||
|
k[1] = '\0';
|
||
|
}
|
||
|
printf("key key:%s extkey:%d mod:%d mods:%d up:%d\n",
|
||
|
k,
|
||
|
(int) e->ExtKey,
|
||
|
(int) e->Modifier,
|
||
|
(int) e->Modifiers,
|
||
|
e->Up);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static void repos(HWND hwnd)
|
||
|
{
|
||
|
RECT r;
|
||
|
|
||
|
GetClientRect(hwnd, &r);
|
||
|
SetWindowPos(nhspinb, NULL, r.left + 12, r.top + 12,
|
||
|
120, 20,
|
||
|
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
|
||
|
SetWindowPos(nvspinb, NULL, r.left + 12 + 120 + 6, r.top + 12,
|
||
|
120, 20,
|
||
|
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
|
||
|
SetWindowPos(area, NULL, r.left + 12, r.top + 12 + 20 + 6,
|
||
|
r.right - r.left - 24, r.bottom - r.top - 24 - 20 - 6,
|
||
|
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
|
||
|
}
|
||
|
|
||
|
static LRESULT CALLBACK wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
WINDOWPOS *wp = (WINDOWPOS *) lParam;
|
||
|
|
||
|
switch (uMsg) {
|
||
|
case WM_COMMAND:
|
||
|
if (((HWND) lParam) == nhspinb || ((HWND) lParam) == nvspinb)
|
||
|
if (HIWORD(wParam) == EN_CHANGE)
|
||
|
areaUpdateScroll(area);
|
||
|
break;
|
||
|
case WM_WINDOWPOSCHANGED:
|
||
|
if ((wp->flags & SWP_NOSIZE) != 0)
|
||
|
break;
|
||
|
repos(hwnd);
|
||
|
return 0;
|
||
|
case WM_CLOSE:
|
||
|
PostQuitMessage(0);
|
||
|
}
|
||
|
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||
|
}
|
||
|
|
||
|
HINSTANCE hInstance;
|
||
|
|
||
|
int main(void)
|
||
|
{
|
||
|
WNDCLASSW wc;
|
||
|
HWND mainwin;
|
||
|
MSG msg;
|
||
|
|
||
|
CoInitialize(NULL);
|
||
|
initDraw();
|
||
|
|
||
|
hInstance = GetModuleHandle(NULL);
|
||
|
|
||
|
h.ah.Draw = handlerDraw;
|
||
|
h.ah.HScrollMax = handlerHScrollMax;
|
||
|
h.ah.VScrollMax = handlerVScrollMax;
|
||
|
h.ah.RedrawOnResize = handlerRedrawOnResize;
|
||
|
h.ah.MouseEvent = handlerMouseEvent;
|
||
|
h.ah.DragBroken = handlerDragBroken;
|
||
|
h.ah.KeyEvent = handlerKeyEvent;
|
||
|
|
||
|
registerAreaClass();
|
||
|
|
||
|
ZeroMemory(&wc, sizeof (WNDCLASSW));
|
||
|
wc.lpszClassName = L"mainwin";
|
||
|
wc.lpfnWndProc = wndproc;
|
||
|
wc.hInstance = hInstance;
|
||
|
wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
|
||
|
RegisterClassW(&wc);
|
||
|
|
||
|
mainwin = CreateWindowExW(0,
|
||
|
L"mainwin", L"mainwin",
|
||
|
WS_OVERLAPPEDWINDOW,
|
||
|
CW_USEDEFAULT, CW_USEDEFAULT,
|
||
|
CW_USEDEFAULT, CW_USEDEFAULT,
|
||
|
NULL, NULL, hInstance, NULL);
|
||
|
|
||
|
area = makeArea(0,
|
||
|
WS_CHILD | WS_VISIBLE,
|
||
|
0, 0, 0, 0,
|
||
|
mainwin,
|
||
|
(uiAreaHandler *) (&h));
|
||
|
|
||
|
nhspinb = CreateWindowExW(WS_EX_CLIENTEDGE,
|
||
|
L"edit", L"0",
|
||
|
ES_NUMBER | WS_CHILD | WS_VISIBLE,
|
||
|
0, 0, 100, 100,
|
||
|
mainwin, NULL, hInstance, NULL);
|
||
|
|
||
|
nvspinb = CreateWindowExW(WS_EX_CLIENTEDGE,
|
||
|
L"edit", L"0",
|
||
|
ES_NUMBER | WS_CHILD | WS_VISIBLE,
|
||
|
0, 0, 100, 100,
|
||
|
mainwin, NULL, hInstance, NULL);
|
||
|
|
||
|
// initial state
|
||
|
repos(mainwin);
|
||
|
areaUpdateScroll(area);
|
||
|
|
||
|
ShowWindow(mainwin, SW_SHOWDEFAULT);
|
||
|
UpdateWindow(mainwin);
|
||
|
|
||
|
extern BOOL processAreaMessage(MSG *);
|
||
|
while (GetMessage(&msg, NULL, 0, 0)) {
|
||
|
if (processAreaMessage(&msg)) continue;
|
||
|
TranslateMessage(&msg);
|
||
|
DispatchMessage(&msg);
|
||
|
}
|
||
|
|
||
|
uninitDraw();
|
||
|
CoUninitialize();
|
||
|
return 0;
|
||
|
}
|