diff options
Diffstat (limited to 'src/libui_sdl/libui/test')
32 files changed, 5353 insertions, 0 deletions
diff --git a/src/libui_sdl/libui/test/CMakeLists.txt b/src/libui_sdl/libui/test/CMakeLists.txt new file mode 100644 index 0000000..e4924bb --- /dev/null +++ b/src/libui_sdl/libui/test/CMakeLists.txt @@ -0,0 +1,38 @@ +# 3 june 2016 + +if(WIN32) + set(_TEST_RESOURCES_RC resources.rc) +endif() + +_add_exec(tester + drawtests.c + main.c + menus.c + page1.c + page2.c + page3.c + page4.c + page5.c + page6.c + page7.c + page7a.c + page7b.c + page7c.c + page8.c + page9.c + page10.c + page11.c + page12.c + page13.c + page14.c + page15.c + spaced.c + ${_TEST_RESOURCES_RC} +) +target_include_directories(tester + PRIVATE test +) +set_target_properties(tester PROPERTIES + OUTPUT_NAME test + WIN32_EXECUTABLE FALSE +) diff --git a/src/libui_sdl/libui/test/drawtests.c b/src/libui_sdl/libui/test/drawtests.c new file mode 100644 index 0000000..b6de753 --- /dev/null +++ b/src/libui_sdl/libui/test/drawtests.c @@ -0,0 +1,1978 @@ +// 9 october 2015 +#include "test.h" + +// TODO +// - test multiple clips +// - test saving and restoring clips + +struct drawtest { + const char *name; + void (*draw)(uiAreaDrawParams *p); + // TODO mouse event +}; + +static void drawOriginal(uiAreaDrawParams *p) +{ + uiDrawPath *path; + uiDrawBrush brush; + uiDrawStrokeParams sp; + + sp.Dashes = NULL; + sp.NumDashes = 0; + sp.DashPhase = 0; + + brush.Type = uiDrawBrushTypeSolid; + brush.A = 1; + + brush.R = 1; + brush.G = 0; + brush.B = 0; + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(path, p->ClipX + 5, p->ClipY + 5); + uiDrawPathLineTo(path, (p->ClipX + p->ClipWidth) - 5, (p->ClipY + p->ClipHeight) - 5); + uiDrawPathEnd(path); + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.Thickness = 1; + sp.MiterLimit = uiDrawDefaultMiterLimit; + uiDrawStroke(p->Context, path, &brush, &sp); + uiDrawFreePath(path); + + brush.R = 0; + brush.G = 0; + brush.B = 0.75; + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(path, p->ClipX, p->ClipY); + uiDrawPathLineTo(path, p->ClipX + p->ClipWidth, p->ClipY); + uiDrawPathLineTo(path, 50, 150); + uiDrawPathLineTo(path, 50, 50); + uiDrawPathCloseFigure(path); + uiDrawPathEnd(path); + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinRound; + sp.Thickness = 5; + uiDrawStroke(p->Context, path, &brush, &sp); + uiDrawFreePath(path); + + brush.R = 0; + brush.G = 0.75; + brush.B = 0; + brush.A = 0.5; + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(path, 120, 80, 50, 50); + uiDrawPathEnd(path); + uiDrawFill(p->Context, path, &brush); + uiDrawFreePath(path); + brush.A = 1; + + brush.R = 0; + brush.G = 0.5; + brush.B = 0; + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(path, 5.5, 10.5); + uiDrawPathLineTo(path, 5.5, 50.5); + uiDrawPathEnd(path); + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.Thickness = 1; + sp.MiterLimit = uiDrawDefaultMiterLimit; + uiDrawStroke(p->Context, path, &brush, &sp); + uiDrawFreePath(path); + + brush.R = 0.5; + brush.G = 0.75; + brush.B = 0; + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(path, 400, 100); + uiDrawPathArcTo(path, + 400, 100, + 50, + 30. * (uiPi / 180.), + 300. * (uiPi / 180.), + 0); + // the sweep test below doubles as a clockwise test so a checkbox isn't needed anymore + uiDrawPathLineTo(path, 400, 100); + uiDrawPathNewFigureWithArc(path, + 510, 100, + 50, + 30. * (uiPi / 180.), + 300. * (uiPi / 180.), + 0); + uiDrawPathCloseFigure(path); + // and now with 330 to make sure sweeps work properly + uiDrawPathNewFigure(path, 400, 210); + uiDrawPathArcTo(path, + 400, 210, + 50, + 30. * (uiPi / 180.), + 330. * (uiPi / 180.), + 0); + uiDrawPathLineTo(path, 400, 210); + uiDrawPathNewFigureWithArc(path, + 510, 210, + 50, + 30. * (uiPi / 180.), + 330. * (uiPi / 180.), + 0); + uiDrawPathCloseFigure(path); + uiDrawPathEnd(path); + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.Thickness = 1; + sp.MiterLimit = uiDrawDefaultMiterLimit; + uiDrawStroke(p->Context, path, &brush, &sp); + uiDrawFreePath(path); + + brush.R = 0; + brush.G = 0.5; + brush.B = 0.75; + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(path, 300, 300); + uiDrawPathBezierTo(path, + 350, 320, + 310, 390, + 435, 372); + uiDrawPathEnd(path); + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.Thickness = 1; + sp.MiterLimit = uiDrawDefaultMiterLimit; + uiDrawStroke(p->Context, path, &brush, &sp); + uiDrawFreePath(path); +} + +static void drawArcs(uiAreaDrawParams *p) +{ + uiDrawPath *path; + int start = 20; + int step = 20; + int rad = 25; + int x, y; + double angle; + double add; + int i; + uiDrawBrush brush; + uiDrawStrokeParams sp; + + sp.Dashes = NULL; + sp.NumDashes = 0; + sp.DashPhase = 0; + + path = uiDrawNewPath(uiDrawFillModeWinding); + + add = (2.0 * uiPi) / 12; + + x = start + rad; + y = start + rad; + angle = 0; + for (i = 0; i < 13; i++) { + uiDrawPathNewFigureWithArc(path, + x, y, + rad, + 0, angle, + 0); + angle += add; + x += 2 * rad + step; + } + + y += 2 * rad + step; + x = start + rad; + angle = 0; + for (i = 0; i < 13; i++) { + uiDrawPathNewFigure(path, x, y); + uiDrawPathArcTo(path, + x, y, + rad, + 0, angle, + 0); + angle += add; + x += 2 * rad + step; + } + + y += 2 * rad + step; + x = start + rad; + angle = 0; + for (i = 0; i < 13; i++) { + uiDrawPathNewFigureWithArc(path, + x, y, + rad, + (uiPi / 4), angle, + 0); + angle += add; + x += 2 * rad + step; + } + + y += 2 * rad + step; + x = start + rad; + angle = 0; + for (i = 0; i < 13; i++) { + uiDrawPathNewFigure(path, x, y); + uiDrawPathArcTo(path, + x, y, + rad, + (uiPi / 4), angle, + 0); + angle += add; + x += 2 * rad + step; + } + + y += 2 * rad + step; + x = start + rad; + angle = 0; + for (i = 0; i < 13; i++) { + uiDrawPathNewFigureWithArc(path, + x, y, + rad, + uiPi + (uiPi / 5), angle, + 0); + angle += add; + x += 2 * rad + step; + } + + y += 2 * rad + step; + x = start + rad; + angle = 0; + for (i = 0; i < 13; i++) { + uiDrawPathNewFigure(path, x, y); + uiDrawPathArcTo(path, + x, y, + rad, + uiPi + (uiPi / 5), angle, + 0); + angle += add; + x += 2 * rad + step; + } + + uiDrawPathEnd(path); + + brush.Type = uiDrawBrushTypeSolid; + brush.R = 0; + brush.G = 0; + brush.B = 0; + brush.A = 1; + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.Thickness = 1; + sp.MiterLimit = uiDrawDefaultMiterLimit; + uiDrawStroke(p->Context, path, &brush, &sp); + + uiDrawFreePath(path); +} + +// Direct2D Documentation Code + +static void d2dColorToRGB(uint32_t color, double *r, double *g, double *b) +{ + uint8_t rr, gg, bb; + + rr = (color & 0xFF0000) >> 16; + gg = (color & 0x00FF00) >> 8; + bb = color & 0x0000FF; + *r = ((double) rr) / 255.0; + *g = ((double) gg) / 255.0; + *b = ((double) bb) / 255.0; +} +#define d2dBlack 0x000000 +#define d2dLightSlateGray 0x778899 +#define d2dCornflowerBlue 0x6495ED +#define d2dWhite 0xFFFFFF +#define d2dYellowGreen 0x9ACD32 +#define d2dYellow 0xFFFF00 +#define d2dForestGreen 0x228B22 +#define d2dOliveDrab 0x6B8E23 +#define d2dLightSkyBlue 0x87CEFA + +static void d2dSolidBrush(uiDrawBrush *brush, uint32_t color, double alpha) +{ + brush->Type = uiDrawBrushTypeSolid; + d2dColorToRGB(color, &(brush->R), &(brush->G), &(brush->B)); + brush->A = alpha; +} + +static void d2dClear(uiAreaDrawParams *p, uint32_t color, double alpha) +{ + uiDrawPath *path; + uiDrawBrush brush; + + d2dSolidBrush(&brush, color, alpha); + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(path, 0, 0, p->AreaWidth, p->AreaHeight); + uiDrawPathEnd(path); + uiDrawFill(p->Context, path, &brush); + uiDrawFreePath(path); +} + +// from https://msdn.microsoft.com/en-us/library/windows/desktop/hh780340%28v=vs.85%29.aspx +// also at https://msdn.microsoft.com/en-us/library/windows/desktop/dd535473%28v=vs.85%29.aspx +static void drawD2DW8QS(uiAreaDrawParams *p) +{ + uiDrawPath *path; + uiDrawBrush brush; + + d2dSolidBrush(&brush, d2dBlack, 1.0); + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(path, + 100, + 100, + (p->AreaWidth - 100) - 100, + (p->AreaHeight - 100) - 100); + uiDrawPathEnd(path); + uiDrawFill(p->Context, path, &brush); + uiDrawFreePath(path); +} + +// from https://msdn.microsoft.com/en-us/library/windows/desktop/dd370994%28v=vs.85%29.aspx +static void drawD2DSimpleApp(uiAreaDrawParams *p) +{ + uiDrawPath *path; + uiDrawBrush lightSlateGray; + uiDrawBrush cornflowerBlue; + uiDrawStrokeParams sp; + int x, y; + + sp.Dashes = NULL; + sp.NumDashes = 0; + sp.DashPhase = 0; + + d2dSolidBrush(&lightSlateGray, d2dLightSlateGray, 1.0); + d2dSolidBrush(&cornflowerBlue, d2dCornflowerBlue, 1.0); + + d2dClear(p, d2dWhite, 1.0); + + sp.Thickness = 0.5; + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.MiterLimit = uiDrawDefaultMiterLimit; + + for (x = 0; x < p->AreaWidth; x += 10) { + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(path, x, 0); + uiDrawPathLineTo(path, x, p->AreaHeight); + uiDrawPathEnd(path); + uiDrawStroke(p->Context, path, &lightSlateGray, &sp); + uiDrawFreePath(path); + } + + for (y = 0; y < p->AreaHeight; y += 10) { + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(path, 0, y); + uiDrawPathLineTo(path, p->AreaWidth, y); + uiDrawPathEnd(path); + uiDrawStroke(p->Context, path, &lightSlateGray, &sp); + uiDrawFreePath(path); + } + + double left, top, right, bottom; + + left = p->AreaWidth / 2.0 - 50.0; + right = p->AreaWidth / 2.0 + 50.0; + top = p->AreaHeight / 2.0 - 50.0; + bottom = p->AreaHeight / 2.0 + 50.0; + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(path, left, top, right - left, bottom - top); + uiDrawPathEnd(path); + uiDrawFill(p->Context, path, &lightSlateGray); + uiDrawFreePath(path); + + left = p->AreaWidth / 2.0 - 100.0; + right = p->AreaWidth / 2.0 + 100.0; + top = p->AreaHeight / 2.0 - 100.0; + bottom = p->AreaHeight / 2.0 + 100.0; + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(path, left, top, right - left, bottom - top); + uiDrawPathEnd(path); + sp.Thickness = 1.0; + uiDrawStroke(p->Context, path, &cornflowerBlue, &sp); + uiDrawFreePath(path); +} + +// TODO? https://msdn.microsoft.com/en-us/library/windows/desktop/dd372260(v=vs.85).aspx + +// TODO https://msdn.microsoft.com/en-us/library/windows/desktop/dd756654%28v=vs.85%29.aspx + +// TODO? all subsections too? https://msdn.microsoft.com/en-us/library/windows/desktop/hh973240%28v=vs.85%29.aspx + +// TODO differing examples of? https://msdn.microsoft.com/en-us/library/windows/desktop/dd756651%28v=vs.85%29.aspx + +// from https://msdn.microsoft.com/en-us/library/windows/desktop/dd756680%28v=vs.85%29.aspx +static void drawD2DSolidBrush(uiAreaDrawParams *p) +{ + uiDrawPath *path; + uiDrawBrush black; + uiDrawBrush yellowGreen; + uiDrawStrokeParams sp; + + sp.Dashes = NULL; + sp.NumDashes = 0; + sp.DashPhase = 0; + + d2dSolidBrush(&black, d2dBlack, 1.0); + d2dSolidBrush(&yellowGreen, d2dYellowGreen, 1.0); + + path = uiDrawNewPath(uiDrawFillModeWinding); + // the example doesn't define a rectangle + // 150x150 seems to be right given the other examples though + uiDrawPathAddRectangle(path, 25, 25, 150, 150); + uiDrawPathEnd(path); + + uiDrawFill(p->Context, path, &yellowGreen); + sp.Thickness = 1.0; + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.MiterLimit = uiDrawDefaultMiterLimit; + uiDrawStroke(p->Context, path, &black, &sp); + + uiDrawFreePath(path); +} + +// from https://msdn.microsoft.com/en-us/library/windows/desktop/dd756678%28v=vs.85%29.aspx +static void drawD2DLinearBrush(uiAreaDrawParams *p) +{ + uiDrawPath *path; + uiDrawBrush black; + uiDrawBrush gradient; + uiDrawBrushGradientStop stops[2]; + uiDrawStrokeParams sp; + + uiDrawMatrix m; + + sp.Dashes = NULL; + sp.NumDashes = 0; + sp.DashPhase = 0; + + // leave some room + uiDrawMatrixSetIdentity(&m); + uiDrawMatrixTranslate(&m, 25, 25); + uiDrawTransform(p->Context, &m); + + gradient.Type = uiDrawBrushTypeLinearGradient; + gradient.X0 = 0; + gradient.Y0 = 0; + gradient.X1 = 150; + gradient.Y1 = 150; + stops[0].Pos = 0.0; + d2dColorToRGB(d2dYellow, &(stops[0].R), &(stops[0].G), &(stops[0].B)); + stops[0].A = 1.0; + stops[1].Pos = 1.0; + d2dColorToRGB(d2dForestGreen, &(stops[1].R), &(stops[1].G), &(stops[1].B)); + stops[1].A = 1.0; + gradient.Stops = stops; + gradient.NumStops = 2; + + d2dSolidBrush(&black, d2dBlack, 1.0); + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(path, 0, 0, 150, 150); + uiDrawPathEnd(path); + + uiDrawFill(p->Context, path, &gradient); + sp.Thickness = 1.0; + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.MiterLimit = uiDrawDefaultMiterLimit; + uiDrawStroke(p->Context, path, &black, &sp); + + uiDrawFreePath(path); +} + +// from https://msdn.microsoft.com/en-us/library/windows/desktop/dd756679%28v=vs.85%29.aspx +// TODO expand this to change the origin point with a mouse click (not in the original but useful to have) +static void drawD2DRadialBrush(uiAreaDrawParams *p) +{ + uiDrawPath *path; + uiDrawBrush black; + uiDrawBrush gradient; + uiDrawBrushGradientStop stops[2]; + uiDrawStrokeParams sp; + + uiDrawMatrix m; + + sp.Dashes = NULL; + sp.NumDashes = 0; + sp.DashPhase = 0; + + // leave some room + uiDrawMatrixSetIdentity(&m); + uiDrawMatrixTranslate(&m, 25, 25); + uiDrawTransform(p->Context, &m); + + gradient.Type = uiDrawBrushTypeRadialGradient; + gradient.X0 = 75; + gradient.Y0 = 75; + gradient.X1 = 75; + gradient.Y1 = 75; + gradient.OuterRadius = 75; + stops[0].Pos = 0.0; + d2dColorToRGB(d2dYellow, &(stops[0].R), &(stops[0].G), &(stops[0].B)); + stops[0].A = 1.0; + stops[1].Pos = 1.0; + d2dColorToRGB(d2dForestGreen, &(stops[1].R), &(stops[1].G), &(stops[1].B)); + stops[1].A = 1.0; + gradient.Stops = stops; + gradient.NumStops = 2; + + d2dSolidBrush(&black, d2dBlack, 1.0); + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(path, 150, 75); + uiDrawPathArcTo(path, + 75, 75, + 75, + 0, + 2 * uiPi, + 0); + uiDrawPathEnd(path); + + uiDrawFill(p->Context, path, &gradient); + sp.Thickness = 1.0; + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.MiterLimit = uiDrawDefaultMiterLimit; + uiDrawStroke(p->Context, path, &black, &sp); + + uiDrawFreePath(path); +} + +// TODO https://msdn.microsoft.com/en-us/library/windows/desktop/dd756677%28v=vs.85%29.aspx + +// TODO? other pages have some of these https://msdn.microsoft.com/en-us/library/windows/desktop/dd756653%28v=vs.85%29.aspx + +// from https://msdn.microsoft.com/en-us/library/windows/desktop/ee264309%28v=vs.85%29.aspx +static void drawD2DPathGeometries(uiAreaDrawParams *p) +{ + uiDrawPath *leftMountain; + uiDrawPath *rightMountain; + uiDrawPath *sun; + uiDrawPath *sunRays; + uiDrawPath *river; + uiDrawBrush radial; + uiDrawBrush scene; + uiDrawStrokeParams sp; + uiDrawBrushGradientStop stops[2]; + + sp.Dashes = NULL; + sp.NumDashes = 0; + sp.DashPhase = 0; + + // TODO this is definitely wrong but the example doesn't have the right brush in it + radial.Type = uiDrawBrushTypeRadialGradient; + radial.X0 = 75; + radial.Y0 = 75; + radial.X1 = 75; + radial.Y1 = 75; + radial.OuterRadius = 75; + stops[0].Pos = 0.0; + d2dColorToRGB(d2dYellow, &(stops[0].R), &(stops[0].G), &(stops[0].B)); + stops[0].A = 1.0; + stops[1].Pos = 1.0; + d2dColorToRGB(d2dForestGreen, &(stops[1].R), &(stops[1].G), &(stops[1].B)); + stops[1].A = 1.0; + radial.Stops = stops; + radial.NumStops = 2; + + leftMountain = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(leftMountain, 346, 255); + uiDrawPathLineTo(leftMountain, 267, 177); + uiDrawPathLineTo(leftMountain, 236, 192); + uiDrawPathLineTo(leftMountain, 212, 160); + uiDrawPathLineTo(leftMountain, 156, 255); + uiDrawPathLineTo(leftMountain, 346, 255); + uiDrawPathCloseFigure(leftMountain); + uiDrawPathEnd(leftMountain); + + rightMountain = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(rightMountain, 575, 263); + uiDrawPathLineTo(rightMountain, 481, 146); + uiDrawPathLineTo(rightMountain, 449, 181); + uiDrawPathLineTo(rightMountain, 433, 159); + uiDrawPathLineTo(rightMountain, 401, 214); + uiDrawPathLineTo(rightMountain, 381, 199); + uiDrawPathLineTo(rightMountain, 323, 263); + uiDrawPathLineTo(rightMountain, 575, 263); + uiDrawPathCloseFigure(rightMountain); + uiDrawPathEnd(rightMountain); + + sun = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigureWithArc(sun, + (440.0 - 270.0) / 2 + 270.0, 255, + 85, + uiPi, uiPi, + 0); + uiDrawPathCloseFigure(sun); + uiDrawPathEnd(sun); + + // the original examples had these as hollow figures + // we don't support them, so we'll have to stroke it separately + sunRays = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(sunRays, 299, 182); + uiDrawPathBezierTo(sunRays, + 299, 182, + 294, 176, + 285, 178); + uiDrawPathBezierTo(sunRays, + 276, 179, + 272, 173, + 272, 173); + uiDrawPathNewFigure(sunRays, 354, 156); + uiDrawPathBezierTo(sunRays, + 354, 156, + 358, 149, + 354, 142); + uiDrawPathBezierTo(sunRays, + 349, 134, + 354, 127, + 354, 127); + uiDrawPathNewFigure(sunRays, 322, 164); + uiDrawPathBezierTo(sunRays, + 322, 164, + 322, 156, + 314, 152); + uiDrawPathBezierTo(sunRays, + 306, 149, + 305, 141, + 305, 141); + uiDrawPathNewFigure(sunRays, 385, 164); + uiDrawPathBezierTo(sunRays, + 385, 164, + 392, 161, + 394, 152); + uiDrawPathBezierTo(sunRays, + 395, 144, + 402, 141, + 402, 142); + uiDrawPathNewFigure(sunRays, 408, 182); + uiDrawPathBezierTo(sunRays, + 408, 182, + 416, 184, + 422, 178); + uiDrawPathBezierTo(sunRays, + 428, 171, + 435, 173, + 435, 173); + uiDrawPathEnd(sunRays); + + river = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(river, 183, 392); + uiDrawPathBezierTo(river, + 238, 284, + 472, 345, + 356, 303); + uiDrawPathBezierTo(river, + 237, 261, + 333, 256, + 333, 256); + uiDrawPathBezierTo(river, + 335, 257, + 241, 261, + 411, 306); + uiDrawPathBezierTo(river, + 574, 350, + 288, 324, + 296, 392); + uiDrawPathEnd(river); + + d2dClear(p, d2dWhite, 1.0); + + // TODO draw the grid + + uiDrawFill(p->Context, sun, &radial); + + d2dSolidBrush(&scene, d2dBlack, 1.0); + sp.Thickness = 1.0; + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.MiterLimit = uiDrawDefaultMiterLimit; + uiDrawStroke(p->Context, sun, &scene, &sp); + uiDrawStroke(p->Context, sunRays, &scene, &sp); + + d2dSolidBrush(&scene, d2dOliveDrab, 1.0); + uiDrawFill(p->Context, leftMountain, &scene); + + d2dSolidBrush(&scene, d2dBlack, 1.0); + uiDrawStroke(p->Context, leftMountain, &scene, &sp); + + d2dSolidBrush(&scene, d2dLightSkyBlue, 1.0); + uiDrawFill(p->Context, river, &scene); + + d2dSolidBrush(&scene, d2dBlack, 1.0); + uiDrawStroke(p->Context, river, &scene, &sp); + + d2dSolidBrush(&scene, d2dYellowGreen, 1.0); + uiDrawFill(p->Context, rightMountain, &scene); + + d2dSolidBrush(&scene, d2dBlack, 1.0); + uiDrawStroke(p->Context, rightMountain, &scene, &sp); + + uiDrawFreePath(leftMountain); + uiDrawFreePath(rightMountain); + uiDrawFreePath(sun); + uiDrawFreePath(sunRays); + uiDrawFreePath(river); +} + +// TODO https://msdn.microsoft.com/en-us/library/windows/desktop/dd756690%28v=vs.85%29.aspx + +// from https://msdn.microsoft.com/en-us/library/windows/desktop/dd756681%28v=vs.85%29.aspx +static void drawD2DGeometryGroup(uiAreaDrawParams *p) +{ + uiDrawPath *alternate; + uiDrawPath *winding; + uiDrawBrush fill; + uiDrawBrush stroke; + uiDrawStrokeParams sp; + uiDrawMatrix m; + + sp.Dashes = NULL; + sp.NumDashes = 0; + sp.DashPhase = 0; + + alternate = uiDrawNewPath(uiDrawFillModeAlternate); + uiDrawPathNewFigureWithArc(alternate, + 105, 105, + 25, + 0, 2 * uiPi, + 0); + uiDrawPathNewFigureWithArc(alternate, + 105, 105, + 50, + 0, 2 * uiPi, + 0); + uiDrawPathNewFigureWithArc(alternate, + 105, 105, + 75, + 0, 2 * uiPi, + 0); + uiDrawPathNewFigureWithArc(alternate, + 105, 105, + 100, + 0, 2 * uiPi, + 0); + uiDrawPathEnd(alternate); + + winding = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigureWithArc(winding, + 105, 105, + 25, + 0, 2 * uiPi, + 0); + uiDrawPathNewFigureWithArc(winding, + 105, 105, + 50, + 0, 2 * uiPi, + 0); + uiDrawPathNewFigureWithArc(winding, + 105, 105, + 75, + 0, 2 * uiPi, + 0); + uiDrawPathNewFigureWithArc(winding, + 105, 105, + 100, + 0, 2 * uiPi, + 0); + uiDrawPathEnd(winding); + + d2dClear(p, d2dWhite, 1.0); + + // TODO grid + + // TODO the example doesn't provide these + d2dSolidBrush(&fill, d2dForestGreen, 1.0); + d2dSolidBrush(&stroke, d2dCornflowerBlue, 1.0); + + sp.Thickness = 1.0; + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.MiterLimit = uiDrawDefaultMiterLimit; + + uiDrawFill(p->Context, alternate, &fill); + uiDrawStroke(p->Context, alternate, &stroke, &sp); + // TODO text + + uiDrawMatrixSetIdentity(&m); + uiDrawMatrixTranslate(&m, 300, 0); + uiDrawTransform(p->Context, &m); + uiDrawFill(p->Context, winding, &fill); + uiDrawStroke(p->Context, winding, &stroke, &sp); +// // TODO text + + uiDrawFreePath(winding); + uiDrawFreePath(alternate); +} + +// TODO https://msdn.microsoft.com/en-us/library/windows/desktop/dd756676%28v=vs.85%29.aspx + +// TODO? https://msdn.microsoft.com/en-us/library/windows/desktop/dd370971%28v=vs.85%29.aspx + +// TODO are there even examples here? https://msdn.microsoft.com/en-us/library/windows/desktop/dd370966%28v=vs.85%29.aspx + +// from https://msdn.microsoft.com/en-us/library/windows/desktop/dd756687%28v=vs.85%29.aspx +static void drawD2DRotate(uiAreaDrawParams *p) +{ + uiDrawPath *path; + uiDrawBrush original; + uiDrawBrush fill; + uiDrawBrush transform; + uiDrawStrokeParams originalsp; + uiDrawStrokeParams transformsp; + uiDrawMatrix m; + + originalsp.Dashes = NULL; + originalsp.NumDashes = 0; + originalsp.DashPhase = 0; + transformsp.Dashes = NULL; + transformsp.NumDashes = 0; + transformsp.DashPhase = 0; + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(path, 438.0, 301.5, 498.0 - 438.0, 361.5 - 301.5); + uiDrawPathEnd(path); + + // TODO the example doesn't specify what these should be + d2dSolidBrush(&original, d2dBlack, 1.0); + d2dSolidBrush(&fill, d2dWhite, 0.5); + d2dSolidBrush(&transform, d2dForestGreen, 1.0); + // TODO this needs to be dashed + originalsp.Thickness = 1.0; + originalsp.Cap = uiDrawLineCapFlat; + originalsp.Join = uiDrawLineJoinMiter; + originalsp.MiterLimit = uiDrawDefaultMiterLimit; + transformsp.Thickness = 1.0; + transformsp.Cap = uiDrawLineCapFlat; + transformsp.Join = uiDrawLineJoinMiter; + transformsp.MiterLimit = uiDrawDefaultMiterLimit; + + // save for when we do the translated one + uiDrawSave(p->Context); + + uiDrawStroke(p->Context, path, &original, &originalsp); + + uiDrawMatrixSetIdentity(&m); + uiDrawMatrixRotate(&m, + 468.0, 331.5, + 45.0 * (uiPi / 180)); + uiDrawTransform(p->Context, &m); + + uiDrawFill(p->Context, path, &fill); + uiDrawStroke(p->Context, path, &transform, &transformsp); + + uiDrawRestore(p->Context); + + // translate to test the corner axis + uiDrawMatrixSetIdentity(&m); + uiDrawMatrixTranslate(&m, -200, -200); + uiDrawTransform(p->Context, &m); + + uiDrawStroke(p->Context, path, &original, &originalsp); + + uiDrawMatrixSetIdentity(&m); + uiDrawMatrixRotate(&m, + 438.0, 301.5, + 45.0 * (uiPi / 180)); + uiDrawTransform(p->Context, &m); + + uiDrawFill(p->Context, path, &fill); + uiDrawStroke(p->Context, path, &transform, &transformsp); + + uiDrawFreePath(path); +} + +// from https://msdn.microsoft.com/en-us/library/windows/desktop/dd756688%28v=vs.85%29.aspx +static void drawD2DScale(uiAreaDrawParams *p) +{ + uiDrawPath *path; + uiDrawBrush original; + uiDrawBrush fill; + uiDrawBrush transform; + uiDrawStrokeParams originalsp; + uiDrawStrokeParams transformsp; + uiDrawMatrix m; + + originalsp.Dashes = NULL; + originalsp.NumDashes = 0; + originalsp.DashPhase = 0; + transformsp.Dashes = NULL; + transformsp.NumDashes = 0; + transformsp.DashPhase = 0; + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(path, 438.0, 80.5, 498.0 - 438.0, 140.5 - 80.5); + uiDrawPathEnd(path); + + // TODO the example doesn't specify what these should be + d2dSolidBrush(&original, d2dBlack, 1.0); + d2dSolidBrush(&fill, d2dWhite, 0.5); + d2dSolidBrush(&transform, d2dForestGreen, 1.0); + // TODO this needs to be dashed + originalsp.Thickness = 1.0; + originalsp.Cap = uiDrawLineCapFlat; + originalsp.Join = uiDrawLineJoinMiter; + originalsp.MiterLimit = uiDrawDefaultMiterLimit; + transformsp.Thickness = 1.0; + transformsp.Cap = uiDrawLineCapFlat; + transformsp.Join = uiDrawLineJoinMiter; + transformsp.MiterLimit = uiDrawDefaultMiterLimit; + + // save for when we do the translated one + uiDrawSave(p->Context); + + uiDrawStroke(p->Context, path, &original, &originalsp); + + uiDrawMatrixSetIdentity(&m); + uiDrawMatrixScale(&m, + 438.0, 80.5, + 1.3, 1.3); + uiDrawTransform(p->Context, &m); + + uiDrawFill(p->Context, path, &fill); + uiDrawStroke(p->Context, path, &transform, &transformsp); + + uiDrawRestore(p->Context); + + // for testing purposes, show what happens if we scale about (0, 0) + uiDrawMatrixSetIdentity(&m); + uiDrawMatrixTranslate(&m, -300, 50); + uiDrawTransform(p->Context, &m); + + uiDrawStroke(p->Context, path, &original, &originalsp); + + uiDrawMatrixSetIdentity(&m); + uiDrawMatrixScale(&m, + 0, 0, + 1.3, 1.3); + uiDrawTransform(p->Context, &m); + + uiDrawFill(p->Context, path, &fill); + uiDrawStroke(p->Context, path, &transform, &transformsp); + + uiDrawFreePath(path); +} + +// from https://msdn.microsoft.com/en-us/library/windows/desktop/dd756689%28v=vs.85%29.aspx +// TODO counterclockwise?! +void drawD2DSkew(uiAreaDrawParams *p) +{ + uiDrawPath *path; + uiDrawBrush original; + uiDrawBrush fill; + uiDrawBrush transform; + uiDrawStrokeParams originalsp; + uiDrawStrokeParams transformsp; + uiDrawMatrix m; + + originalsp.Dashes = NULL; + originalsp.NumDashes = 0; + originalsp.DashPhase = 0; + transformsp.Dashes = NULL; + transformsp.NumDashes = 0; + transformsp.DashPhase = 0; + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(path, 126.0, 301.5, 186.0 - 126.0, 361.5 - 301.5); + uiDrawPathEnd(path); + + // TODO the example doesn't specify what these should be + d2dSolidBrush(&original, d2dBlack, 1.0); + d2dSolidBrush(&fill, d2dWhite, 0.5); + d2dSolidBrush(&transform, d2dForestGreen, 1.0); + // TODO this needs to be dashed + originalsp.Thickness = 1.0; + originalsp.Cap = uiDrawLineCapFlat; + originalsp.Join = uiDrawLineJoinMiter; + originalsp.MiterLimit = uiDrawDefaultMiterLimit; + transformsp.Thickness = 1.0; + transformsp.Cap = uiDrawLineCapFlat; + transformsp.Join = uiDrawLineJoinMiter; + transformsp.MiterLimit = uiDrawDefaultMiterLimit; + + // save for when we do the translated one + uiDrawSave(p->Context); + + uiDrawStroke(p->Context, path, &original, &originalsp); + + uiDrawMatrixSetIdentity(&m); + uiDrawMatrixSkew(&m, + 126.0, 301.5, + 45.0 * (uiPi / 180), 0); + uiDrawTransform(p->Context, &m); + + uiDrawFill(p->Context, path, &fill); + uiDrawStroke(p->Context, path, &transform, &transformsp); + + uiDrawRestore(p->Context); + + // for testing purposes, show what happens if we skew about (0, 0) + uiDrawMatrixSetIdentity(&m); + uiDrawMatrixTranslate(&m, 0, -200); + uiDrawTransform(p->Context, &m); + + uiDrawStroke(p->Context, path, &original, &originalsp); + + uiDrawMatrixSetIdentity(&m); + uiDrawMatrixSkew(&m, + 0, 0, + 45.0 * (uiPi / 180), 0); + uiDrawTransform(p->Context, &m); + + uiDrawFill(p->Context, path, &fill); + uiDrawStroke(p->Context, path, &transform, &transformsp); + + uiDrawFreePath(path); +} + +// from https://msdn.microsoft.com/en-us/library/windows/desktop/dd756691%28v=vs.85%29.aspx +static void drawD2DTranslate(uiAreaDrawParams *p) +{ + uiDrawPath *path; + uiDrawBrush original; + uiDrawBrush fill; + uiDrawBrush transform; + uiDrawStrokeParams originalsp; + uiDrawStrokeParams transformsp; + uiDrawMatrix m; + + originalsp.Dashes = NULL; + originalsp.NumDashes = 0; + originalsp.DashPhase = 0; + transformsp.Dashes = NULL; + transformsp.NumDashes = 0; + transformsp.DashPhase = 0; + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(path, 126.0, 80.5, 186.0 - 126.0, 140.5 - 80.5); + uiDrawPathEnd(path); + + // TODO the example doesn't specify what these should be + d2dSolidBrush(&original, d2dBlack, 1.0); + d2dSolidBrush(&fill, d2dWhite, 0.5); + d2dSolidBrush(&transform, d2dForestGreen, 1.0); + // TODO this needs to be dashed + originalsp.Thickness = 1.0; + originalsp.Cap = uiDrawLineCapFlat; + originalsp.Join = uiDrawLineJoinMiter; + originalsp.MiterLimit = uiDrawDefaultMiterLimit; + transformsp.Thickness = 1.0; + transformsp.Cap = uiDrawLineCapFlat; + transformsp.Join = uiDrawLineJoinMiter; + transformsp.MiterLimit = uiDrawDefaultMiterLimit; + + uiDrawStroke(p->Context, path, &original, &originalsp); + + uiDrawMatrixSetIdentity(&m); + uiDrawMatrixTranslate(&m, 20, 10); + uiDrawTransform(p->Context, &m); + + uiDrawFill(p->Context, path, &fill); + uiDrawStroke(p->Context, path, &transform, &transformsp); + + uiDrawFreePath(path); +} + +// from https://msdn.microsoft.com/en-us/library/windows/desktop/dd756672%28v=vs.85%29.aspx +// TODO the points seem off +static void drawD2DMultiTransforms(uiAreaDrawParams *p) +{ + uiDrawPath *path; + uiDrawBrush original; + uiDrawBrush fill; + uiDrawBrush transform; + uiDrawStrokeParams originalsp; + uiDrawStrokeParams transformsp; + uiDrawMatrix mtranslate; + uiDrawMatrix mrotate; + + originalsp.Dashes = NULL; + originalsp.NumDashes = 0; + originalsp.DashPhase = 0; + transformsp.Dashes = NULL; + transformsp.NumDashes = 0; + transformsp.DashPhase = 0; + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(path, 300.0, 40.0, 360.0 - 300.0, 100.0 - 40.0); + uiDrawPathEnd(path); + + // TODO the example doesn't specify what these should be + d2dSolidBrush(&original, d2dBlack, 1.0); + d2dSolidBrush(&fill, d2dWhite, 0.5); + d2dSolidBrush(&transform, d2dForestGreen, 1.0); + // TODO this needs to be dashed + originalsp.Thickness = 1.0; + originalsp.Cap = uiDrawLineCapFlat; + originalsp.Join = uiDrawLineJoinMiter; + originalsp.MiterLimit = uiDrawDefaultMiterLimit; + transformsp.Thickness = 1.0; + transformsp.Cap = uiDrawLineCapFlat; + transformsp.Join = uiDrawLineJoinMiter; + transformsp.MiterLimit = uiDrawDefaultMiterLimit; + + uiDrawMatrixSetIdentity(&mtranslate); + uiDrawMatrixTranslate(&mtranslate, 20.0, 10.0); + uiDrawMatrixSetIdentity(&mrotate); + uiDrawMatrixRotate(&mrotate, + 330.0, 70.0, + 45.0 * (uiPi / 180)); + + // save for when we do the opposite one + uiDrawSave(p->Context); + + uiDrawStroke(p->Context, path, &original, &originalsp); + + uiDrawTransform(p->Context, &mrotate); + uiDrawTransform(p->Context, &mtranslate); + + uiDrawFill(p->Context, path, &fill); + uiDrawStroke(p->Context, path, &transform, &transformsp); + + uiDrawRestore(p->Context); + uiDrawFreePath(path); + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(path, 40.0, 40.0, 100.0 - 40.0, 100.0 - 40.0); + uiDrawPathEnd(path); + + uiDrawMatrixSetIdentity(&mtranslate); + uiDrawMatrixTranslate(&mtranslate, 20.0, 10.0); + uiDrawMatrixSetIdentity(&mrotate); + uiDrawMatrixRotate(&mrotate, + 70.0, 70.0, + 45.0 * (uiPi / 180)); + + uiDrawStroke(p->Context, path, &original, &originalsp); + + uiDrawTransform(p->Context, &mtranslate); + uiDrawTransform(p->Context, &mrotate); + + uiDrawFill(p->Context, path, &fill); + uiDrawStroke(p->Context, path, &transform, &transformsp); + + uiDrawFreePath(path); +} + +// TODO https://msdn.microsoft.com/en-us/library/windows/desktop/dd756675%28v=vs.85%29.aspx + +// TODO https://msdn.microsoft.com/en-us/library/windows/desktop/dd756673%28v=vs.85%29.aspx + +// TODO https://msdn.microsoft.com/en-us/library/windows/desktop/dd756684%28v=vs.85%29.aspx + +// TODO dashing https://msdn.microsoft.com/en-us/library/windows/desktop/dd756683%28v=vs.85%29.aspx + +// from https://msdn.microsoft.com/en-us/library/windows/desktop/dd756682%28v=vs.85%29.aspx +static void drawD2DComplexShape(uiAreaDrawParams *p) +{ + uiDrawPath *path; + uiDrawBrush black; + uiDrawBrush gradient; + uiDrawBrushGradientStop stops[2]; + uiDrawStrokeParams sp; + uiDrawMatrix m; + + sp.Dashes = NULL; + sp.NumDashes = 0; + sp.DashPhase = 0; + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(path, 0, 0); + uiDrawPathLineTo(path, 200, 0); + uiDrawPathBezierTo(path, + 150, 50, + 150, 150, + 200, 200); + uiDrawPathLineTo(path, 0, 200); + uiDrawPathBezierTo(path, + 50, 150, + 50, 50, + 0, 0); + uiDrawPathCloseFigure(path); + uiDrawPathEnd(path); + + d2dSolidBrush(&black, d2dBlack, 1.0); + + stops[0].Pos =0.0; + stops[0].R = 0.0; + stops[0].G = 1.0; + stops[0].B = 1.0; + stops[0].A = 0.25; + stops[1].Pos = 1.0; + stops[1].R = 0.0; + stops[1].G = 0.0; + stops[1].B = 1.0; + stops[1].A = 1.0; + gradient.Type = uiDrawBrushTypeLinearGradient; + gradient.X0 = 100; + gradient.Y0 = 0; + gradient.X1 = 100; + gradient.Y1 = 200; + gradient.Stops = stops; + gradient.NumStops = 2; + + uiDrawMatrixSetIdentity(&m); + uiDrawMatrixTranslate(&m, 20, 20); + uiDrawTransform(p->Context, &m); + + sp.Thickness = 10.0; + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.MiterLimit = uiDrawDefaultMiterLimit; + + uiDrawStroke(p->Context, path, &black, &sp); + uiDrawFill(p->Context, path, &gradient); + + uiDrawFreePath(path); +} + +// TODO https://msdn.microsoft.com/en-us/library/windows/desktop/dd756692%28v=vs.85%29.aspx + +// TODO https://msdn.microsoft.com/en-us/library/windows/desktop/dd756686%28v=vs.85%29.aspx + +// TODO https://msdn.microsoft.com/en-us/library/windows/desktop/dd756685%28v=vs.85%29.aspx + +// TODO https://msdn.microsoft.com/en-us/library/windows/desktop/dd756674%28v=vs.85%29.aspx + +// TODO? https://msdn.microsoft.com/en-us/library/windows/desktop/ee329947%28v=vs.85%29.aspx + +// TODO https://msdn.microsoft.com/en-us/library/windows/desktop/ff485857%28v=vs.85%29.aspx + +// TODO? https://msdn.microsoft.com/en-us/library/windows/desktop/dd756755%28v=vs.85%29.aspx + +// TODO go through the API reference and spot examples that aren't listed + +// TODO all of these https://msdn.microsoft.com/en-us/library/windows/desktop/dd368187%28v=vs.85%29.aspx + +// cairo Samples Page (http://cairographics.org/samples/) + +static void crsourcergba(uiDrawBrush *brush, double r, double g, double b, double a) +{ + brush->Type = uiDrawBrushTypeSolid; + brush->R = r; + brush->G = g; + brush->B = b; + brush->A = a; +} + +// arc +static void drawCSArc(uiAreaDrawParams *p) +{ + double xc = 128.0; + double yc = 128.0; + double radius = 100.0; + double angle1 = 45.0 * (uiPi / 180.0); + double angle2 = 180.0 * (uiPi / 180.0); + uiDrawBrush source; + uiDrawStrokeParams sp; + uiDrawPath *path; + + crsourcergba(&source, 0, 0, 0, 1); + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.MiterLimit = uiDrawDefaultMiterLimit; + sp.Dashes = NULL; + sp.NumDashes = 0; + sp.DashPhase = 0; + + sp.Thickness = 10.0; + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigureWithArc(path, + xc, yc, + radius, + angle1, + angle2 - angle1, + 0); + uiDrawPathEnd(path); + uiDrawStroke(p->Context, path, &source, &sp); + uiDrawFreePath(path); + + crsourcergba(&source, 1, 0.2, 0.2, 0.6); + sp.Thickness = 6.0; + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigureWithArc(path, + xc, yc, + 10.0, + 0, 2 * uiPi, + 0); + uiDrawPathEnd(path); + uiDrawFill(p->Context, path, &source); + uiDrawFreePath(path); + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigureWithArc(path, + xc, yc, + radius, + angle1, 0, + 0); + uiDrawPathLineTo(path, xc, yc); + uiDrawPathNewFigureWithArc(path, + xc, yc, + radius, + angle2, 0, + 0); + uiDrawPathLineTo(path, xc, yc); + uiDrawPathEnd(path); + uiDrawStroke(p->Context, path, &source, &sp); + uiDrawFreePath(path); +} + +// arc negative +static void drawCSArcNegative(uiAreaDrawParams *p) +{ + double xc = 128.0; + double yc = 128.0; + double radius = 100.0; + double angle1 = 45.0 * (uiPi / 180.0); + double angle2 = 180.0 * (uiPi / 180.0); + uiDrawBrush source; + uiDrawStrokeParams sp; + uiDrawPath *path; + + crsourcergba(&source, 0, 0, 0, 1); + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.MiterLimit = uiDrawDefaultMiterLimit; + sp.Dashes = NULL; + sp.NumDashes = 0; + sp.DashPhase = 0; + + sp.Thickness = 10.0; + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigureWithArc(path, + xc, yc, + radius, + angle1, + angle2 - angle1, + 1); + uiDrawPathEnd(path); + uiDrawStroke(p->Context, path, &source, &sp); + uiDrawFreePath(path); + + crsourcergba(&source, 1, 0.2, 0.2, 0.6); + sp.Thickness = 6.0; + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigureWithArc(path, + xc, yc, + 10.0, + 0, 2 * uiPi, + 0); + uiDrawPathEnd(path); + uiDrawFill(p->Context, path, &source); + uiDrawFreePath(path); + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigureWithArc(path, + xc, yc, + radius, + angle1, 0, + 0); + uiDrawPathLineTo(path, xc, yc); + uiDrawPathNewFigureWithArc(path, + xc, yc, + radius, + angle2, 0, + 0); + uiDrawPathLineTo(path, xc, yc); + uiDrawPathEnd(path); + uiDrawStroke(p->Context, path, &source, &sp); + uiDrawFreePath(path); +} + +// clip +static void drawCSClip(uiAreaDrawParams *p) +{ + uiDrawBrush source; + uiDrawStrokeParams sp; + uiDrawPath *path; + + crsourcergba(&source, 0, 0, 0, 1); + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.MiterLimit = uiDrawDefaultMiterLimit; + sp.Dashes = NULL; + sp.NumDashes = 0; + sp.DashPhase = 0; + + path = uiDrawNewPath(uiDrawFillModeWinding); + + uiDrawPathNewFigureWithArc(path, + 128.0, 128.0, + 76.8, + 0, 2 * uiPi, + 0); + uiDrawPathEnd(path); + uiDrawClip(p->Context, path); + uiDrawFreePath(path); + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(path, 0, 0, 256, 256); + uiDrawPathEnd(path); + uiDrawFill(p->Context, path, &source); + uiDrawFreePath(path); + + crsourcergba(&source, 0, 1, 0, 1); + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(path, 0, 0); + uiDrawPathLineTo(path, 256, 256); + uiDrawPathNewFigure(path, 256, 0); + uiDrawPathLineTo(path, 0, 256); + uiDrawPathEnd(path); + sp.Thickness = 10.0; + uiDrawStroke(p->Context, path, &source, &sp); + uiDrawFreePath(path); +} + +// TODO clip image + +// curve rectangle +static void drawCSCurveRectangle(uiAreaDrawParams *p) +{ + double x0 = 25.6, /* parameters like cairo_rectangle */ + y0 = 25.6, + rect_width = 204.8, + rect_height = 204.8, + radius = 102.4; /* and an approximate curvature radius */ + + double x1,y1; + + uiDrawBrush source; + uiDrawStrokeParams sp; + uiDrawPath *path; + + crsourcergba(&source, 0, 0, 0, 1); + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.MiterLimit = uiDrawDefaultMiterLimit; + sp.Dashes = NULL; + sp.NumDashes = 0; + sp.DashPhase = 0; + + path = uiDrawNewPath(uiDrawFillModeWinding); + + x1=x0+rect_width; + y1=y0+rect_height; + if (!rect_width || !rect_height) + return; + if (rect_width/2 < radius) { + if (rect_height/2<radius) { + uiDrawPathNewFigure(path, x0, (y0 + y1)/2); + uiDrawPathBezierTo(path, x0 ,y0, x0, y0, (x0 + x1)/2, y0); + uiDrawPathBezierTo(path, x1, y0, x1, y0, x1, (y0 + y1)/2); + uiDrawPathBezierTo(path, x1, y1, x1, y1, (x1 + x0)/2, y1); + uiDrawPathBezierTo(path, x0, y1, x0, y1, x0, (y0 + y1)/2); + } else { + uiDrawPathNewFigure(path, x0, y0 + radius); + uiDrawPathBezierTo(path, x0 ,y0, x0, y0, (x0 + x1)/2, y0); + uiDrawPathBezierTo(path, x1, y0, x1, y0, x1, y0 + radius); + uiDrawPathLineTo(path, x1 , y1 - radius); + uiDrawPathBezierTo(path, x1, y1, x1, y1, (x1 + x0)/2, y1); + uiDrawPathBezierTo(path, x0, y1, x0, y1, x0, y1- radius); + } + } else { + if (rect_height / 2 < radius) { + uiDrawPathNewFigure(path, x0, (y0 + y1)/2); + uiDrawPathBezierTo(path, x0 , y0, x0 , y0, x0 + radius, y0); + uiDrawPathLineTo(path, x1 - radius, y0); + uiDrawPathBezierTo(path, x1, y0, x1, y0, x1, (y0 + y1)/2); + uiDrawPathBezierTo(path, x1, y1, x1, y1, x1 - radius, y1); + uiDrawPathLineTo(path, x0 + radius, y1); + uiDrawPathBezierTo(path, x0, y1, x0, y1, x0, (y0 + y1)/2); + } else { + uiDrawPathNewFigure(path, x0, y0 + radius); + uiDrawPathBezierTo(path, x0 , y0, x0 , y0, x0 + radius, y0); + uiDrawPathLineTo(path, x1 - radius, y0); + uiDrawPathBezierTo(path, x1, y0, x1, y0, x1, y0 + radius); + uiDrawPathLineTo(path, x1 , y1 - radius); + uiDrawPathBezierTo(path, x1, y1, x1, y1, x1 - radius, y1); + uiDrawPathLineTo(path, x0 + radius, y1); + uiDrawPathBezierTo(path, x0, y1, x0, y1, x0, y1- radius); + } + } + uiDrawPathCloseFigure(path); + uiDrawPathEnd(path); + + crsourcergba(&source, 0.5, 0.5, 1, 1.0); + uiDrawFill(p->Context, path, &source); + crsourcergba(&source, 0.5, 0, 0, 0.5); + sp.Thickness = 10.0; + uiDrawStroke(p->Context, path, &source, &sp); + + uiDrawFreePath(path); +} + +// curve to +static void drawCSCurveTo(uiAreaDrawParams *p) +{ + double x=25.6, y=128.0; + double x1=102.4, y1=230.4, + x2=153.6, y2=25.6, + x3=230.4, y3=128.0; + uiDrawBrush source; + uiDrawStrokeParams sp; + uiDrawPath *path; + + crsourcergba(&source, 0, 0, 0, 1); + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.MiterLimit = uiDrawDefaultMiterLimit; + sp.Dashes = NULL; + sp.NumDashes = 0; + sp.DashPhase = 0; + + path = uiDrawNewPath(uiDrawFillModeWinding); + + uiDrawPathNewFigure(path, x, y); + uiDrawPathBezierTo(path, x1, y1, x2, y2, x3, y3); + uiDrawPathEnd(path); + sp.Thickness = 10.0; + uiDrawStroke(p->Context, path, &source, &sp); + uiDrawFreePath(path); + + crsourcergba(&source, 1, 0.2, 0.2, 0.6); + sp.Thickness = 6.0; + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(path, x, y); + uiDrawPathLineTo(path, x1, y1); + uiDrawPathNewFigure(path, x2, y2); + uiDrawPathLineTo(path, x3, y3); + uiDrawPathEnd(path); + uiDrawStroke(p->Context, path, &source, &sp); + uiDrawFreePath(path); +} + +// dash +static void drawCSDash(uiAreaDrawParams *p) +{ + double dashes[] = { + 50.0, /* ink */ + 10.0, /* skip */ + 10.0, /* ink */ + 10.0 /* skip*/ + }; + int ndash = sizeof (dashes)/sizeof(dashes[0]); + double offset = -50.0; + + uiDrawBrush source; + uiDrawStrokeParams sp; + uiDrawPath *path; + + crsourcergba(&source, 0, 0, 0, 1); + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.MiterLimit = uiDrawDefaultMiterLimit; + sp.Dashes = dashes; + sp.NumDashes = ndash; + sp.DashPhase = offset; + sp.Thickness = 10.0; + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(path, 128.0, 25.6); + uiDrawPathLineTo(path, 230.4, 230.4); + uiDrawPathLineTo(path, 230.4 -102.4, 230.4 + 0.0); + uiDrawPathBezierTo(path, + 51.2, 230.4, + 51.2, 128.0, + 128.0, 128.0); + uiDrawPathEnd(path); + + uiDrawStroke(p->Context, path, &source, &sp); + uiDrawFreePath(path); +} + +// fill and stroke2 +static void drawCSFillAndStroke2(uiAreaDrawParams *p) +{ + uiDrawBrush source; + uiDrawStrokeParams sp; + uiDrawPath *path; + + crsourcergba(&source, 0, 0, 0, 1); + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.MiterLimit = uiDrawDefaultMiterLimit; + sp.Dashes = NULL; + sp.NumDashes = 0; + sp.DashPhase = 0; + + path = uiDrawNewPath(uiDrawFillModeWinding); + + uiDrawPathNewFigure(path, 128.0, 25.6); + uiDrawPathLineTo(path, 230.4, 230.4); + uiDrawPathLineTo(path, 230.4 - 102.4, 230.4 + 0.0); + uiDrawPathBezierTo(path, 51.2, 230.4, 51.2, 128.0, 128.0, 128.0); + uiDrawPathCloseFigure(path); + + uiDrawPathNewFigure(path, 64.0, 25.6); + uiDrawPathLineTo(path, 64.0 + 51.2, 25.6 + 51.2); + uiDrawPathLineTo(path, 64.0 + 51.2 -51.2, 25.6 + 51.2 + 51.2); + uiDrawPathLineTo(path, 64.0 + 51.2 -51.2 -51.2, 25.6 + 51.2 + 51.2 -51.2); + uiDrawPathCloseFigure(path); + + uiDrawPathEnd(path); + + sp.Thickness = 10.0; + crsourcergba(&source, 0, 0, 1, 1); + uiDrawFill(p->Context, path, &source); + crsourcergba(&source, 0, 0, 0, 1); + uiDrawStroke(p->Context, path, &source, &sp); + uiDrawFreePath(path); +} + +// fill style +static void drawCSFillStyle(uiAreaDrawParams *p) +{ + uiDrawBrush source; + uiDrawStrokeParams sp; + uiDrawPath *path; + uiDrawMatrix m; + + crsourcergba(&source, 0, 0, 0, 1); + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.MiterLimit = uiDrawDefaultMiterLimit; + sp.Dashes = NULL; + sp.NumDashes = 0; + sp.DashPhase = 0; + + sp.Thickness = 6; + + path = uiDrawNewPath(uiDrawFillModeAlternate); + uiDrawPathAddRectangle(path, 12, 12, 232, 70); + uiDrawPathNewFigureWithArc(path, + 64, 64, + 40, + 0, 2*uiPi, + 0); + uiDrawPathNewFigureWithArc(path, + 192, 64, + 40, + 0, -2*uiPi, + 1); + uiDrawPathEnd(path); + + crsourcergba(&source, 0, 0.7, 0, 1); + uiDrawFill(p->Context, path, &source); + crsourcergba(&source, 0, 0, 0, 1); + uiDrawStroke(p->Context, path, &source, &sp); + uiDrawFreePath(path); + + uiDrawMatrixSetIdentity(&m); + uiDrawMatrixTranslate(&m, 0, 128); + uiDrawTransform(p->Context, &m); + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(path, 12, 12, 232, 70); + uiDrawPathNewFigureWithArc(path, + 64, 64, + 40, + 0, 2*uiPi, + 0); + uiDrawPathNewFigureWithArc(path, + 192, 64, + 40, + 0, -2*uiPi, + 1); + uiDrawPathEnd(path); + + crsourcergba(&source, 0, 0, 0.9, 1); + uiDrawFill(p->Context, path, &source); + crsourcergba(&source, 0, 0, 0, 1); + uiDrawStroke(p->Context, path, &source, &sp); + uiDrawFreePath(path); +} + +// TOOD gradient (radial gradient with two circles) + +// TODO image + +// TODO imagepattern + +// multi segment caps +static void drawCSMultiCaps(uiAreaDrawParams *p) +{ + uiDrawBrush source; + uiDrawStrokeParams sp; + uiDrawPath *path; + + crsourcergba(&source, 0, 0, 0, 1); + sp.Join = uiDrawLineJoinMiter; + sp.MiterLimit = uiDrawDefaultMiterLimit; + sp.Dashes = NULL; + sp.NumDashes = 0; + sp.DashPhase = 0; + + path = uiDrawNewPath(uiDrawFillModeWinding); + + uiDrawPathNewFigure(path, 50.0, 75.0); + uiDrawPathLineTo(path, 200.0, 75.0); + + uiDrawPathNewFigure(path, 50.0, 125.0); + uiDrawPathLineTo(path, 200.0, 125.0); + + uiDrawPathNewFigure(path, 50.0, 175.0); + uiDrawPathLineTo(path, 200.0, 175.0); + uiDrawPathEnd(path); + + sp.Thickness = 30.0; + sp.Cap = uiDrawLineCapRound; + uiDrawStroke(p->Context, path, &source, &sp); + uiDrawFreePath(path); +} + +// rounded rectangle +static void drawCSRoundRect(uiAreaDrawParams *p) +{ + double x = 25.6, /* parameters like cairo_rectangle */ + y = 25.6, + width = 204.8, + height = 204.8, + aspect = 1.0, /* aspect ratio */ + corner_radius = height / 10.0; /* and corner curvature radius */ + + double radius = corner_radius / aspect; + double degrees = uiPi / 180.0; + + uiDrawBrush source; + uiDrawStrokeParams sp; + uiDrawPath *path; + + crsourcergba(&source, 0, 0, 0, 1); + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.MiterLimit = uiDrawDefaultMiterLimit; + sp.Dashes = NULL; + sp.NumDashes = 0; + sp.DashPhase = 0; + + path = uiDrawNewPath(uiDrawFillModeWinding); + + // top right corner + uiDrawPathNewFigureWithArc(path, + x + width - radius, y + radius, + radius, + -90 * degrees, uiPi / 2, + 0); + // bottom right corner + uiDrawPathArcTo(path, + x + width - radius, y + height - radius, + radius, + 0 * degrees, uiPi / 2, + 0); + // bottom left corner + uiDrawPathArcTo(path, + x + radius, y + height - radius, + radius, + 90 * degrees, uiPi / 2, + 0); + // top left corner + uiDrawPathArcTo(path, + x + radius, y + radius, + radius, + 180 * degrees, uiPi / 2, + 0); + uiDrawPathCloseFigure(path); + uiDrawPathEnd(path); + + crsourcergba(&source, 0.5, 0.5, 1, 1); + uiDrawFill(p->Context, path, &source); + crsourcergba(&source, 0.5, 0, 0, 0.5); + sp.Thickness = 10.0; + uiDrawStroke(p->Context, path, &source, &sp); + uiDrawFreePath(path); +} + +// set line cap +static void drawCSSetLineCap(uiAreaDrawParams *p) +{ + uiDrawBrush source; + uiDrawStrokeParams sp; + uiDrawPath *path; + + crsourcergba(&source, 0, 0, 0, 1); + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.MiterLimit = uiDrawDefaultMiterLimit; + sp.Dashes = NULL; + sp.NumDashes = 0; + sp.DashPhase = 0; + + sp.Thickness = 30.0; + + sp.Cap = uiDrawLineCapFlat; + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(path, 64.0, 50.0); + uiDrawPathLineTo(path, 64.0, 200.0); + uiDrawPathEnd(path); + uiDrawStroke(p->Context, path, &source, &sp); + uiDrawFreePath(path); + + sp.Cap = uiDrawLineCapRound; + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(path, 128.0, 50.0); + uiDrawPathLineTo(path, 128.0, 200.0); + uiDrawPathEnd(path); + uiDrawStroke(p->Context, path, &source, &sp); + uiDrawFreePath(path); + + sp.Cap = uiDrawLineCapSquare; + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(path, 192.0, 50.0); + uiDrawPathLineTo(path, 192.0, 200.0); + uiDrawPathEnd(path); + uiDrawStroke(p->Context, path, &source, &sp); + uiDrawFreePath(path); + + // draw helping lines + // keep the square cap to match the reference picture on the cairo website + crsourcergba(&source, 1, 0.2, 0.2, 1); + sp.Thickness = 2.56; + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(path, 64.0, 50.0); + uiDrawPathLineTo(path, 64.0, 200.0); + uiDrawPathNewFigure(path, 128.0, 50.0); + uiDrawPathLineTo(path, 128.0, 200.0); + uiDrawPathNewFigure(path, 192.0, 50.0); + uiDrawPathLineTo(path, 192.0, 200.0); + uiDrawPathEnd(path); + uiDrawStroke(p->Context, path, &source, &sp); + uiDrawFreePath(path); +} + +// set line join +static void drawCSSetLineJoin(uiAreaDrawParams *p) +{ + uiDrawBrush source; + uiDrawStrokeParams sp; + uiDrawPath *path; + + crsourcergba(&source, 0, 0, 0, 1); + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.MiterLimit = uiDrawDefaultMiterLimit; + sp.Dashes = NULL; + sp.NumDashes = 0; + sp.DashPhase = 0; + + sp.Thickness = 40.96; + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(path, 76.8, 84.48); + uiDrawPathLineTo(path, 76.8 + 51.2, 84.48 -51.2); + uiDrawPathLineTo(path, 76.8 + 51.2 + 51.2, 84.48 - 51.2 + 51.2); + uiDrawPathEnd(path); + sp.Join = uiDrawLineJoinMiter; + uiDrawStroke(p->Context, path, &source, &sp); + uiDrawFreePath(path); + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(path, 76.8, 161.28); + uiDrawPathLineTo(path, 76.8 + 51.2, 161.28 -51.2); + uiDrawPathLineTo(path, 76.8 + 51.2 + 51.2, 161.28 - 51.2 + 51.2); + uiDrawPathEnd(path); + sp.Join = uiDrawLineJoinBevel; + uiDrawStroke(p->Context, path, &source, &sp); + uiDrawFreePath(path); + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(path, 76.8, 238.08); + uiDrawPathLineTo(path, 76.8 + 51.2, 238.08 -51.2); + uiDrawPathLineTo(path, 76.8 + 51.2 + 51.2, 238.08 - 51.2 + 51.2); + uiDrawPathEnd(path); + sp.Join = uiDrawLineJoinRound; + uiDrawStroke(p->Context, path, &source, &sp); + uiDrawFreePath(path); +} + +// TODO text + +// TODO text align center + +// TODO text extents + +// Quartz 2D Programming Guide + +static void cgaddrect(uiDrawPath *path, uiAreaDrawParams *p, double x, double y, double width, double height) +{ + uiDrawPathAddRectangle(path, + x, p->AreaHeight - y - height, + width, height); +} + +// Graphics Contexts > Creating a Window Graphics Context in Mac OS X +static void drawQ2DCreateWindowGC(uiAreaDrawParams *p) +{ + uiDrawPath *path; + uiDrawBrush brush; + + crsourcergba(&brush, 1, 0, 0, 1); + path = uiDrawNewPath(uiDrawFillModeWinding); + cgaddrect(path, p, 0, 0, 200, 100); + uiDrawPathEnd(path); + uiDrawFill(p->Context, path, &brush); + uiDrawFreePath(path); + + crsourcergba(&brush, 0, 0, 1, .5); + path = uiDrawNewPath(uiDrawFillModeWinding); + cgaddrect(path, p, 0, 0, 100, 200); + uiDrawPathEnd(path); + uiDrawFill(p->Context, path, &brush); + uiDrawFreePath(path); +} + +// TODO Patterns page? + +// TODO Shadows page? + +// TODO Gradients page (includes some circle-circle radial gradients) + +// TODO Transparency Layers page? + +// TODO Core Graphics Layer Drawing page? + +// Cocoa Drawing Guide + +// TODO Advanced Drawing Techniques page? + +// TODO Text page, if any? + +static const struct drawtest tests[] = { + { "Original uiArea test", drawOriginal }, + { "Arc test", drawArcs }, + { "Direct2D: Direct2D Quickstart for Windows 8", drawD2DW8QS }, + { "Direct2D: Creating a Simple Direct2D Application", drawD2DSimpleApp }, + { "Direct2D: How to Create a Solid Color Brush", drawD2DSolidBrush }, + { "Direct2D: How to Create a Linear Gradient Brush", drawD2DLinearBrush }, + { "Direct2D: How to Create a Radial Gradient Brush", drawD2DRadialBrush }, + { "Direct2D: Path Geometries Overview", drawD2DPathGeometries }, + { "Direct2D: How to Create Geometry Groups", drawD2DGeometryGroup }, + { "Direct2D: How to Rotate an Object", drawD2DRotate }, + { "Direct2D: How to Scale an Object", drawD2DScale }, + { "Direct2D: How to Skew an Object", drawD2DSkew }, + { "Direct2D: How to Translate an Object", drawD2DTranslate }, + { "Direct2D: How to Apply Multiple Transforms to an Object", drawD2DMultiTransforms }, + { "Direct2D: How to Draw and Fill a Complex Shape", drawD2DComplexShape }, + { "cairo samples: arc", drawCSArc }, + { "cairo samples: arc negative", drawCSArcNegative }, + { "cairo samples: clip", drawCSClip }, + { "cairo samples: curve rectangle", drawCSCurveRectangle }, + { "cairo samples: curve to", drawCSCurveTo }, + { "cairo samples: dash", drawCSDash }, + { "cairo samples: fill and stroke2", drawCSFillAndStroke2 }, + { "cairo samples: fill style", drawCSFillStyle }, + { "cairo samples: multi segment caps", drawCSMultiCaps }, + { "cairo samples: rounded rectangle", drawCSRoundRect }, + { "cairo samples: set line cap", drawCSSetLineCap }, + { "cairo samples: set line join", drawCSSetLineJoin }, + { "Quartz 2D PG: Creating a Window Graphics Context in Mac OS X", drawQ2DCreateWindowGC }, + { NULL, NULL }, +}; + +void runDrawTest(int n, uiAreaDrawParams *p) +{ + (*(tests[n].draw))(p); +} + +void populateComboboxWithTests(uiCombobox *c) +{ + size_t i; + + for (i = 0; tests[i].name != NULL; i++) + uiComboboxAppend(c, tests[i].name); +} diff --git a/src/libui_sdl/libui/test/images/andlabs_16x16test_24june2016.png b/src/libui_sdl/libui/test/images/andlabs_16x16test_24june2016.png Binary files differnew file mode 100644 index 0000000..a4c27d9 --- /dev/null +++ b/src/libui_sdl/libui/test/images/andlabs_16x16test_24june2016.png diff --git a/src/libui_sdl/libui/test/images/andlabs_32x32test_24june2016.png b/src/libui_sdl/libui/test/images/andlabs_32x32test_24june2016.png Binary files differnew file mode 100644 index 0000000..e1c33fc --- /dev/null +++ b/src/libui_sdl/libui/test/images/andlabs_32x32test_24june2016.png diff --git a/src/libui_sdl/libui/test/images/gen.go b/src/libui_sdl/libui/test/images/gen.go new file mode 100644 index 0000000..910abc7 --- /dev/null +++ b/src/libui_sdl/libui/test/images/gen.go @@ -0,0 +1,98 @@ +// 25 june 2016 +package main + +import ( + "fmt" + "os" + "image" + "image/draw" + _ "image/png" +) + +type img struct { + filename string + data []byte + width int + height int + stride int +} + +func main() { + if len(os.Args[1:]) == 0 { + panic("no files specified") + } + + images := make([]*img, 0, len(os.Args[1:])) + for _, fn := range os.Args[1:] { + f, err := os.Open(fn) + if err != nil { + panic(err) + } + ii, _, err := image.Decode(f) + if err != nil { + panic(err) + } + f.Close() + + i := image.NewRGBA(ii.Bounds()) + draw.Draw(i, i.Rect, ii, ii.Bounds().Min, draw.Src) + + im := &img{ + filename: fn, + data: i.Pix, + width: i.Rect.Dx(), + height: i.Rect.Dy(), + stride: i.Stride, + } + images = append(images, im) + } + + fmt.Println("// auto-generated by images/gen.go") + fmt.Println("#include \"test.h\"") + fmt.Println() + for i, im := range images { + fmt.Printf("static const uint32_t dat%d[] = {", i) + for j := 0; j < len(im.data); j += 4 { + if (j % (16 * 4)) == 0 { + fmt.Printf("\n\t") + } else { + fmt.Printf(" ") + } + d := uint32(im.data[j + 0]) << 16 + d |= uint32(im.data[j + 1]) << 8 + d |= uint32(im.data[j + 2]) + d |= uint32(im.data[j + 3]) << 24 + fmt.Printf("0x%08X,", d) + + } + fmt.Println("\n};") + fmt.Println() + } + fmt.Println("static const struct {") + fmt.Println(" const char *name;") + fmt.Println(" void *data;") + fmt.Println(" int width;") + fmt.Println(" int height;") + fmt.Println(" int stride;") + fmt.Println("} files[] = {") + for i, im := range images { + fmt.Printf(" { %q, dat%d, %d, %d, %d },\n", + im.filename, i, im.width, im.height, im.stride) + } + fmt.Println("};") + fmt.Println() + fmt.Println("void appendImageNamed(uiImage *img, const char *name)") + fmt.Println("{") + fmt.Println(" int i;") + fmt.Println("") + fmt.Println(" i = 0;") + fmt.Println(" for (;;) {") + fmt.Println(" if (strcmp(name, files[i].name) == 0) {") + fmt.Println(" uiImageAppend(img, files[i].data, files[i].width, files[i].height, files[i].stride);") + fmt.Println(" return;") + fmt.Println(" }") + fmt.Println(" i++;") + fmt.Println(" }") + fmt.Println("}") + fmt.Println() +} diff --git a/src/libui_sdl/libui/test/images/tango-icon-theme-0.8.90_16x16_x-office-spreadsheet.png b/src/libui_sdl/libui/test/images/tango-icon-theme-0.8.90_16x16_x-office-spreadsheet.png Binary files differnew file mode 100644 index 0000000..a6b1268 --- /dev/null +++ b/src/libui_sdl/libui/test/images/tango-icon-theme-0.8.90_16x16_x-office-spreadsheet.png diff --git a/src/libui_sdl/libui/test/images/tango-icon-theme-0.8.90_32x32_x-office-spreadsheet.png b/src/libui_sdl/libui/test/images/tango-icon-theme-0.8.90_32x32_x-office-spreadsheet.png Binary files differnew file mode 100644 index 0000000..c0ccb7a --- /dev/null +++ b/src/libui_sdl/libui/test/images/tango-icon-theme-0.8.90_32x32_x-office-spreadsheet.png diff --git a/src/libui_sdl/libui/test/main.c b/src/libui_sdl/libui/test/main.c new file mode 100644 index 0000000..18774dc --- /dev/null +++ b/src/libui_sdl/libui/test/main.c @@ -0,0 +1,180 @@ +// 22 april 2015 +#include "test.h" + +// TODOs +// - blank page affects menus negatively on Windows + +void die(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + fprintf(stderr, "[test program] "); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); + abort(); +} + +int onClosing(uiWindow *w, void *data) +{ + printf("in onClosing()\n"); + uiQuit(); + return 1; +} + +int onShouldQuit(void *data) +{ + printf("in onShouldQuit()\n"); + if (uiMenuItemChecked(shouldQuitItem)) { + uiControlDestroy(uiControl(data)); + return 1; + } + return 0; +} + +uiBox *mainBox; +uiTab *mainTab; + +uiBox *(*newhbox)(void); +uiBox *(*newvbox)(void); + +int main(int argc, char *argv[]) +{ + uiInitOptions o; + int i; + const char *err; + uiWindow *w; + uiBox *page2, *page3, *page4, *page5; + uiBox *page6, *page7, *page8, *page9, *page10; + uiBox *page11, *page12, *page13; + uiTab *page14; + uiBox *page15; + uiBox *page16; + uiTab *outerTab; + uiTab *innerTab; + int nomenus = 0; + int startspaced = 0; + int steps = 0; + + newhbox = uiNewHorizontalBox; + newvbox = uiNewVerticalBox; + + memset(&o, 0, sizeof (uiInitOptions)); + for (i = 1; i < argc; i++) + if (strcmp(argv[i], "nomenus") == 0) + nomenus = 1; + else if (strcmp(argv[i], "startspaced") == 0) + startspaced = 1; + else if (strcmp(argv[i], "swaphv") == 0) { + newhbox = uiNewVerticalBox; + newvbox = uiNewHorizontalBox; + } else if (strcmp(argv[i], "steps") == 0) + steps = 1; + else { + fprintf(stderr, "%s: unrecognized option %s\n", argv[0], argv[i]); + return 1; + } + + err = uiInit(&o); + if (err != NULL) { + fprintf(stderr, "error initializing ui: %s\n", err); + uiFreeInitError(err); + return 1; + } + + if (!nomenus) + initMenus(); + + w = newWindow("Main Window", 320, 240, 1); + uiWindowOnClosing(w, onClosing, NULL); + printf("main window %p\n", (void *) w); + + uiOnShouldQuit(onShouldQuit, w); + + mainBox = newHorizontalBox(); + uiWindowSetChild(w, uiControl(mainBox)); + + outerTab = newTab(); + uiBoxAppend(mainBox, uiControl(outerTab), 1); + + mainTab = newTab(); + uiTabAppend(outerTab, "Pages 1-5", uiControl(mainTab)); + + // page 1 uses page 2's uiGroup + page2 = makePage2(); + + makePage1(w); + uiTabAppend(mainTab, "Page 1", uiControl(page1)); + + uiTabAppend(mainTab, "Page 2", uiControl(page2)); + + uiTabAppend(mainTab, "Empty Page", uiControl(uiNewHorizontalBox())); + + page3 = makePage3(); + uiTabAppend(mainTab, "Page 3", uiControl(page3)); + + page4 = makePage4(); + uiTabAppend(mainTab, "Page 4", uiControl(page4)); + + page5 = makePage5(w); + uiTabAppend(mainTab, "Page 5", uiControl(page5)); + + innerTab = newTab(); + uiTabAppend(outerTab, "Pages 6-10", uiControl(innerTab)); + + page6 = makePage6(); + uiTabAppend(innerTab, "Page 6", uiControl(page6)); + + page7 = makePage7(); + uiTabAppend(innerTab, "Page 7", uiControl(page7)); + + page8 = makePage8(); + uiTabAppend(innerTab, "Page 8", uiControl(page8)); + + page9 = makePage9(); + uiTabAppend(innerTab, "Page 9", uiControl(page9)); + + page10 = makePage10(); + uiTabAppend(innerTab, "Page 10", uiControl(page10)); + + innerTab = newTab(); + uiTabAppend(outerTab, "Pages 11-15", uiControl(innerTab)); + +// page11 = makePage11(); +// uiTabAppend(innerTab, "Page 11", uiControl(page11)); + + page12 = makePage12(); + uiTabAppend(innerTab, "Page 12", uiControl(page12)); + + page13 = makePage13(); + uiTabAppend(innerTab, "Page 13", uiControl(page13)); + + page14 = makePage14(); + uiTabAppend(innerTab, "Page 14", uiControl(page14)); + + page15 = makePage15(w); + uiTabAppend(innerTab, "Page 15", uiControl(page15)); + + innerTab = newTab(); + uiTabAppend(outerTab, "Pages 16-?", uiControl(innerTab)); + +// page16 = makePage16(); +// uiTabAppend(innerTab, "Page 16", uiControl(page16)); + + if (startspaced) + setSpaced(1); + + uiControlShow(uiControl(w)); + if (!steps) + uiMain(); + else { + uiMainSteps(); + while (uiMainStep(1)) + ; + } + printf("after uiMain()\n"); + uiUninit(); + printf("after uiUninit()\n"); + return 0; +} diff --git a/src/libui_sdl/libui/test/menus.c b/src/libui_sdl/libui/test/menus.c new file mode 100644 index 0000000..87ff80a --- /dev/null +++ b/src/libui_sdl/libui/test/menus.c @@ -0,0 +1,112 @@ +// 23 april 2015 +#include "test.h" + +uiMenu *fileMenu; +uiMenuItem *newItem; +uiMenuItem *openItem; +uiMenuItem *shouldQuitItem; +uiMenuItem *quitItem; +uiMenu *editMenu; +uiMenuItem *undoItem; +uiMenuItem *checkItem; +uiMenuItem *accelItem; +uiMenuItem *prefsItem; +uiMenu *testMenu; +uiMenuItem *enabledItem; +uiMenuItem *enableThisItem; +uiMenuItem *forceCheckedItem; +uiMenuItem *forceUncheckedItem; +uiMenuItem *whatWindowItem; +uiMenu *moreTestsMenu; +uiMenuItem *quitEnabledItem; +uiMenuItem *prefsEnabledItem; +uiMenuItem *aboutEnabledItem; +uiMenuItem *checkEnabledItem; +uiMenu *multiMenu; +uiMenu *helpMenu; +uiMenuItem *helpItem; +uiMenuItem *aboutItem; + +static void enableItemTest(uiMenuItem *item, uiWindow *w, void *data) +{ + if (uiMenuItemChecked(item)) + uiMenuItemEnable(uiMenuItem(data)); + else + uiMenuItemDisable(uiMenuItem(data)); +} + +static void forceOn(uiMenuItem *item, uiWindow *w, void *data) +{ + uiMenuItemSetChecked(enabledItem, 1); +} + +static void forceOff(uiMenuItem *item, uiWindow *w, void *data) +{ + uiMenuItemSetChecked(enabledItem, 0); +} + +static void whatWindow(uiMenuItem *item, uiWindow *w, void *data) +{ + printf("menu item clicked on window %p\n", (void *) w); +} + +void initMenus(void) +{ + fileMenu = uiNewMenu("File"); + newItem = uiMenuAppendItem(fileMenu, "New"); + openItem = uiMenuAppendItem(fileMenu, "Open"); + uiMenuAppendSeparator(fileMenu); + shouldQuitItem = uiMenuAppendCheckItem(fileMenu, "Should Quit"); + quitItem = uiMenuAppendQuitItem(fileMenu); + + editMenu = uiNewMenu("Edit"); + undoItem = uiMenuAppendItem(editMenu, "Undo"); + uiMenuItemDisable(undoItem); + uiMenuAppendSeparator(editMenu); + checkItem = uiMenuAppendCheckItem(editMenu, "Check Me\tTest"); + accelItem = uiMenuAppendItem(editMenu, "A&ccele&&rator T_es__t"); + prefsItem = uiMenuAppendPreferencesItem(editMenu); + + testMenu = uiNewMenu("Test"); + enabledItem = uiMenuAppendCheckItem(testMenu, "Enable Below Item"); + uiMenuItemSetChecked(enabledItem, 1); + enableThisItem = uiMenuAppendItem(testMenu, "This Will Be Enabled"); + uiMenuItemOnClicked(enabledItem, enableItemTest, enableThisItem); + forceCheckedItem = uiMenuAppendItem(testMenu, "Force Above Checked"); + uiMenuItemOnClicked(forceCheckedItem, forceOn, NULL); + forceUncheckedItem = uiMenuAppendItem(testMenu, "Force Above Unchecked"); + uiMenuItemOnClicked(forceUncheckedItem, forceOff, NULL); + uiMenuAppendSeparator(testMenu); + whatWindowItem = uiMenuAppendItem(testMenu, "What Window?"); + uiMenuItemOnClicked(whatWindowItem, whatWindow, NULL); + + moreTestsMenu = uiNewMenu("More Tests"); + quitEnabledItem = uiMenuAppendCheckItem(moreTestsMenu, "Quit Item Enabled"); + uiMenuItemSetChecked(quitEnabledItem, 1); + prefsEnabledItem = uiMenuAppendCheckItem(moreTestsMenu, "Preferences Item Enabled"); + uiMenuItemSetChecked(prefsEnabledItem, 1); + aboutEnabledItem = uiMenuAppendCheckItem(moreTestsMenu, "About Item Enabled"); + uiMenuItemSetChecked(aboutEnabledItem, 1); + uiMenuAppendSeparator(moreTestsMenu); + checkEnabledItem = uiMenuAppendCheckItem(moreTestsMenu, "Check Me Item Enabled"); + uiMenuItemSetChecked(checkEnabledItem, 1); + + multiMenu = uiNewMenu("Multi"); + uiMenuAppendSeparator(multiMenu); + uiMenuAppendSeparator(multiMenu); + uiMenuAppendItem(multiMenu, "Item && Item && Item"); + uiMenuAppendSeparator(multiMenu); + uiMenuAppendSeparator(multiMenu); + uiMenuAppendItem(multiMenu, "Item __ Item __ Item"); + uiMenuAppendSeparator(multiMenu); + uiMenuAppendSeparator(multiMenu); + + helpMenu = uiNewMenu("Help"); + helpItem = uiMenuAppendItem(helpMenu, "Help"); + aboutItem = uiMenuAppendAboutItem(helpMenu); + + uiMenuItemOnClicked(quitEnabledItem, enableItemTest, quitItem); + uiMenuItemOnClicked(prefsEnabledItem, enableItemTest, prefsItem); + uiMenuItemOnClicked(aboutEnabledItem, enableItemTest, aboutItem); + uiMenuItemOnClicked(checkEnabledItem, enableItemTest, checkItem); +} diff --git a/src/libui_sdl/libui/test/page1.c b/src/libui_sdl/libui/test/page1.c new file mode 100644 index 0000000..2115ba2 --- /dev/null +++ b/src/libui_sdl/libui/test/page1.c @@ -0,0 +1,171 @@ +// 29 april 2015 +#include "test.h" + +static uiEntry *entry; +static uiCheckbox *spaced; + +#define TEXT(name, type, getter, setter) \ + static void get ## name ## Text(uiButton *b, void *data) \ + { \ + char *text; \ + text = getter(type(data)); \ + uiEntrySetText(entry, text); \ + uiFreeText(text); \ + } \ + static void set ## name ## Text(uiButton *b, void *data) \ + { \ + char *text; \ + text = uiEntryText(entry); \ + setter(type(data), text); \ + uiFreeText(text); \ + } +TEXT(Window, uiWindow, uiWindowTitle, uiWindowSetTitle) +TEXT(Button, uiButton, uiButtonText, uiButtonSetText) +TEXT(Checkbox, uiCheckbox, uiCheckboxText, uiCheckboxSetText) +TEXT(Label, uiLabel, uiLabelText, uiLabelSetText) +TEXT(Group, uiGroup, uiGroupTitle, uiGroupSetTitle) + +static void onChanged(uiEntry *e, void *data) +{ + printf("onChanged()\n"); +} + +static void toggleSpaced(uiCheckbox *c, void *data) +{ + setSpaced(uiCheckboxChecked(spaced)); +} + +static void forceSpaced(uiButton *b, void *data) +{ + uiCheckboxSetChecked(spaced, data != NULL); +} + +static void showSpaced(uiButton *b, void *data) +{ + char s[12]; + + querySpaced(s); + uiEntrySetText(entry, s); +} + +#define SHED(method, Method) \ + static void method ## Control(uiButton *b, void *data) \ + { \ + uiControl ## Method(uiControl(data)); \ + } +SHED(show, Show) +SHED(hide, Hide) +SHED(enable, Enable) +SHED(disable, Disable) + +uiBox *page1; + +void makePage1(uiWindow *w) +{ + uiButton *getButton, *setButton; + uiBox *hbox; + uiBox *testBox; + uiLabel *label; + + page1 = newVerticalBox(); + + entry = uiNewEntry(); + uiEntryOnChanged(entry, onChanged, NULL); + uiBoxAppend(page1, uiControl(entry), 0); + + spaced = uiNewCheckbox("Spaced"); + uiCheckboxOnToggled(spaced, toggleSpaced, NULL); + label = uiNewLabel("Label"); + + hbox = newHorizontalBox(); + getButton = uiNewButton("Get Window Text"); + uiButtonOnClicked(getButton, getWindowText, w); + setButton = uiNewButton("Set Window Text"); + uiButtonOnClicked(setButton, setWindowText, w); + uiBoxAppend(hbox, uiControl(getButton), 1); + uiBoxAppend(hbox, uiControl(setButton), 1); + uiBoxAppend(page1, uiControl(hbox), 0); + + hbox = newHorizontalBox(); + getButton = uiNewButton("Get Button Text"); + uiButtonOnClicked(getButton, getButtonText, getButton); + setButton = uiNewButton("Set Button Text"); + uiButtonOnClicked(setButton, setButtonText, getButton); + uiBoxAppend(hbox, uiControl(getButton), 1); + uiBoxAppend(hbox, uiControl(setButton), 1); + uiBoxAppend(page1, uiControl(hbox), 0); + + hbox = newHorizontalBox(); + getButton = uiNewButton("Get Checkbox Text"); + uiButtonOnClicked(getButton, getCheckboxText, spaced); + setButton = uiNewButton("Set Checkbox Text"); + uiButtonOnClicked(setButton, setCheckboxText, spaced); + uiBoxAppend(hbox, uiControl(getButton), 1); + uiBoxAppend(hbox, uiControl(setButton), 1); + uiBoxAppend(page1, uiControl(hbox), 0); + + hbox = newHorizontalBox(); + getButton = uiNewButton("Get Label Text"); + uiButtonOnClicked(getButton, getLabelText, label); + setButton = uiNewButton("Set Label Text"); + uiButtonOnClicked(setButton, setLabelText, label); + uiBoxAppend(hbox, uiControl(getButton), 1); + uiBoxAppend(hbox, uiControl(setButton), 1); + uiBoxAppend(page1, uiControl(hbox), 0); + + hbox = newHorizontalBox(); + getButton = uiNewButton("Get Group Text"); + uiButtonOnClicked(getButton, getGroupText, page2group); + setButton = uiNewButton("Set Group Text"); + uiButtonOnClicked(setButton, setGroupText, page2group); + uiBoxAppend(hbox, uiControl(getButton), 1); + uiBoxAppend(hbox, uiControl(setButton), 1); + uiBoxAppend(page1, uiControl(hbox), 0); + + hbox = newHorizontalBox(); + uiBoxAppend(hbox, uiControl(spaced), 1); + getButton = uiNewButton("On"); + uiButtonOnClicked(getButton, forceSpaced, getButton); + uiBoxAppend(hbox, uiControl(getButton), 0); + getButton = uiNewButton("Off"); + uiButtonOnClicked(getButton, forceSpaced, NULL); + uiBoxAppend(hbox, uiControl(getButton), 0); + getButton = uiNewButton("Show"); + uiButtonOnClicked(getButton, showSpaced, NULL); + uiBoxAppend(hbox, uiControl(getButton), 0); + uiBoxAppend(page1, uiControl(hbox), 0); + + testBox = newHorizontalBox(); + setButton = uiNewButton("Button"); + uiBoxAppend(testBox, uiControl(setButton), 1); + getButton = uiNewButton("Show"); + uiButtonOnClicked(getButton, showControl, setButton); + uiBoxAppend(testBox, uiControl(getButton), 0); + getButton = uiNewButton("Hide"); + uiButtonOnClicked(getButton, hideControl, setButton); + uiBoxAppend(testBox, uiControl(getButton), 0); + getButton = uiNewButton("Enable"); + uiButtonOnClicked(getButton, enableControl, setButton); + uiBoxAppend(testBox, uiControl(getButton), 0); + getButton = uiNewButton("Disable"); + uiButtonOnClicked(getButton, disableControl, setButton); + uiBoxAppend(testBox, uiControl(getButton), 0); + uiBoxAppend(page1, uiControl(testBox), 0); + + hbox = newHorizontalBox(); + getButton = uiNewButton("Show Box"); + uiButtonOnClicked(getButton, showControl, testBox); + uiBoxAppend(hbox, uiControl(getButton), 1); + getButton = uiNewButton("Hide Box"); + uiButtonOnClicked(getButton, hideControl, testBox); + uiBoxAppend(hbox, uiControl(getButton), 1); + getButton = uiNewButton("Enable Box"); + uiButtonOnClicked(getButton, enableControl, testBox); + uiBoxAppend(hbox, uiControl(getButton), 1); + getButton = uiNewButton("Disable Box"); + uiButtonOnClicked(getButton, disableControl, testBox); + uiBoxAppend(hbox, uiControl(getButton), 1); + uiBoxAppend(page1, uiControl(hbox), 0); + + uiBoxAppend(page1, uiControl(label), 0); +} diff --git a/src/libui_sdl/libui/test/page10.c b/src/libui_sdl/libui/test/page10.c new file mode 100644 index 0000000..d7f26a7 --- /dev/null +++ b/src/libui_sdl/libui/test/page10.c @@ -0,0 +1,185 @@ +// 22 december 2015 +#include "test.h" + +static uiEntry *textString; +static uiFontButton *textFontButton; +static uiColorButton *textColorButton; +static uiEntry *textWidth; +static uiButton *textApply; +static uiCheckbox *noZ; +static uiArea *textArea; +static uiAreaHandler textAreaHandler; + +static double entryDouble(uiEntry *e) +{ + char *s; + double d; + + s = uiEntryText(e); + d = atof(s); + uiFreeText(s); + return d; +} + +static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *dp) +{ + uiDrawTextFont *font; + uiDrawTextLayout *layout; + double r, g, b, al; + char surrogates[1 + 4 + 1 + 1]; + char composed[2 + 2 + 2 + 3 + 2 + 1]; + double width, height; + + font = uiFontButtonFont(textFontButton); + + layout = uiDrawNewTextLayout("One two three four", font, -1); + uiDrawTextLayoutSetColor(layout, + 4, 7, + 1, 0, 0, 1); + uiDrawTextLayoutSetColor(layout, + 8, 14, + 1, 0, 0.5, 0.5); + uiColorButtonColor(textColorButton, &r, &g, &b, &al); + uiDrawTextLayoutSetColor(layout, + 14, 18, + r, g, b, al); + uiDrawText(dp->Context, 10, 10, layout); + uiDrawTextLayoutExtents(layout, &width, &height); + uiDrawFreeTextLayout(layout); + + surrogates[0] = 'x'; + surrogates[1] = 0xF0; // surrogates D800 DF08 + surrogates[2] = 0x90; + surrogates[3] = 0x8C; + surrogates[4] = 0x88; + surrogates[5] = 'y'; + surrogates[6] = '\0'; + + layout = uiDrawNewTextLayout(surrogates, font, -1); + uiDrawTextLayoutSetColor(layout, + 1, 2, + 1, 0, 0.5, 0.5); + uiDrawText(dp->Context, 10, 10 + height, layout); + uiDrawFreeTextLayout(layout); + + composed[0] = 'z'; + composed[1] = 'z'; + composed[2] = 0xC3; // 2 + composed[3] = 0xA9; + composed[4] = 'z'; + composed[5] = 'z'; + composed[6] = 0x65; // 5 + composed[7] = 0xCC; + composed[8] = 0x81; + composed[9] = 'z'; + composed[10] = 'z'; + composed[11] = '\0'; + + layout = uiDrawNewTextLayout(composed, font, -1); + uiDrawTextLayoutSetColor(layout, + 2, 3, + 1, 0, 0.5, 0.5); + uiDrawTextLayoutSetColor(layout, + 5, 6, + 1, 0, 0.5, 0.5); + if (!uiCheckboxChecked(noZ)) + uiDrawTextLayoutSetColor(layout, + 6, 7, + 0.5, 0, 1, 0.5); + uiDrawText(dp->Context, 10, 10 + height + height, layout); + uiDrawFreeTextLayout(layout); + + uiDrawFreeTextFont(font); +} + +static void handlerMouseEvent(uiAreaHandler *a, uiArea *area, uiAreaMouseEvent *e) +{ + // do nothing +} + +static void handlerMouseCrossed(uiAreaHandler *ah, uiArea *a, int left) +{ + // do nothing +} + +static void handlerDragBroken(uiAreaHandler *ah, uiArea *a) +{ + // do nothing +} + +static int handlerKeyEvent(uiAreaHandler *ah, uiArea *a, uiAreaKeyEvent *e) +{ + // do nothing + return 0; +} + +static void onFontChanged(uiFontButton *b, void *data) +{ + uiAreaQueueRedrawAll(textArea); +} + +static void onColorChanged(uiColorButton *b, void *data) +{ + uiAreaQueueRedrawAll(textArea); +} + +static void onNoZ(uiCheckbox *b, void *data) +{ + uiAreaQueueRedrawAll(textArea); +} + +uiBox *makePage10(void) +{ + uiBox *page10; + uiBox *vbox; + uiBox *hbox; + + page10 = newVerticalBox(); + vbox = page10; + + hbox = newHorizontalBox(); + uiBoxAppend(vbox, uiControl(hbox), 0); + + textString = uiNewEntry(); + // TODO make it placeholder + uiEntrySetText(textString, "Enter text here"); + uiBoxAppend(hbox, uiControl(textString), 1); + + textFontButton = uiNewFontButton(); + uiFontButtonOnChanged(textFontButton, onFontChanged, NULL); + uiBoxAppend(hbox, uiControl(textFontButton), 1); + + textColorButton = uiNewColorButton(); + uiColorButtonOnChanged(textColorButton, onColorChanged, NULL); + uiBoxAppend(hbox, uiControl(textColorButton), 1); + + hbox = newHorizontalBox(); + uiBoxAppend(vbox, uiControl(hbox), 0); + + textApply = uiNewButton("Apply"); + uiBoxAppend(hbox, uiControl(textApply), 1); + + textWidth = uiNewEntry(); + uiEntrySetText(textWidth, "-1"); + uiBoxAppend(hbox, uiControl(textWidth), 1); + + noZ = uiNewCheckbox("No Z Color"); + uiCheckboxOnToggled(noZ, onNoZ, NULL); + uiBoxAppend(hbox, uiControl(noZ), 0); + + textAreaHandler.Draw = handlerDraw; + textAreaHandler.MouseEvent = handlerMouseEvent; + textAreaHandler.MouseCrossed = handlerMouseCrossed; + textAreaHandler.DragBroken = handlerDragBroken; + textAreaHandler.KeyEvent = handlerKeyEvent; + textArea = uiNewArea(&textAreaHandler); + uiBoxAppend(vbox, uiControl(textArea), 1); + + // dummy objects to test single-activation + hbox = newHorizontalBox(); + uiBoxAppend(vbox, uiControl(hbox), 0); + uiBoxAppend(hbox, uiControl(uiNewFontButton()), 1); + uiBoxAppend(hbox, uiControl(uiNewColorButton()), 1); + + return page10; +} diff --git a/src/libui_sdl/libui/test/page11.c b/src/libui_sdl/libui/test/page11.c new file mode 100644 index 0000000..02ad213 --- /dev/null +++ b/src/libui_sdl/libui/test/page11.c @@ -0,0 +1,54 @@ +// 14 may 2016 +#include "test.h" + +// TODO add a test for childless windows +// TODO add tests for contianers with all controls hidden + +static uiGroup *newg(const char *n, int s) +{ + uiGroup *g; + + g = uiNewGroup(n); + if (s) + uiGroupSetChild(g, NULL); + return g; +} + +static uiTab *newt(int tt) +{ + uiTab *t; + + t = uiNewTab(); + if (tt) + uiTabAppend(t, "Test", NULL); + return t; +} + +uiBox *makePage11(void) +{ + uiBox *page11; + uiBox *ns; + uiBox *s; + + page11 = newHorizontalBox(); + + ns = newVerticalBox(); + uiBoxAppend(ns, uiControl(newg("", 0)), 0); + uiBoxAppend(ns, uiControl(newg("", 1)), 0); + uiBoxAppend(ns, uiControl(newg("Group", 0)), 0); + uiBoxAppend(ns, uiControl(newg("Group", 1)), 0); + uiBoxAppend(ns, uiControl(newt(0)), 0); + uiBoxAppend(ns, uiControl(newt(1)), 0); + uiBoxAppend(page11, uiControl(ns), 1); + + s = newVerticalBox(); + uiBoxAppend(s, uiControl(newg("", 0)), 1); + uiBoxAppend(s, uiControl(newg("", 1)), 1); + uiBoxAppend(s, uiControl(newg("Group", 0)), 1); + uiBoxAppend(s, uiControl(newg("Group", 1)), 1); + uiBoxAppend(s, uiControl(newt(0)), 1); + uiBoxAppend(s, uiControl(newt(1)), 1); + uiBoxAppend(page11, uiControl(s), 1); + + return page11; +} diff --git a/src/libui_sdl/libui/test/page12.c b/src/libui_sdl/libui/test/page12.c new file mode 100644 index 0000000..5a8e963 --- /dev/null +++ b/src/libui_sdl/libui/test/page12.c @@ -0,0 +1,60 @@ +// 22 may 2016 +#include "test.h" + +// TODO OS X: if the hboxes are empty, the text views don't show up + +static void meChanged(uiMultilineEntry *e, void *data) +{ + printf("%s changed\n", (char *) data); +} + +static void setClicked(uiButton *b, void *data) +{ + uiMultilineEntrySetText(uiMultilineEntry(data), "set"); +} + +static void appendClicked(uiButton *b, void *data) +{ + uiMultilineEntryAppend(uiMultilineEntry(data), "append\n"); +} + +static uiBox *half(uiMultilineEntry *(*mk)(void), const char *which) +{ + uiBox *vbox, *hbox; + uiMultilineEntry *me; + uiButton *button; + + vbox = newVerticalBox(); + + me = (*mk)(); + uiMultilineEntryOnChanged(me, meChanged, (void *) which); + uiBoxAppend(vbox, uiControl(me), 1); + + hbox = newHorizontalBox(); + uiBoxAppend(vbox, uiControl(hbox), 0); + + button = uiNewButton("Set"); + uiButtonOnClicked(button, setClicked, me); + uiBoxAppend(hbox, uiControl(button), 0); + + button = uiNewButton("Append"); + uiButtonOnClicked(button, appendClicked, me); + uiBoxAppend(hbox, uiControl(button), 0); + + return vbox; +} + +uiBox *makePage12(void) +{ + uiBox *page12; + uiBox *b; + + page12 = newHorizontalBox(); + + b = half(uiNewMultilineEntry, "wrap"); + uiBoxAppend(page12, uiControl(b), 1); + b = half(uiNewNonWrappingMultilineEntry, "no wrap"); + uiBoxAppend(page12, uiControl(b), 1); + + return page12; +} diff --git a/src/libui_sdl/libui/test/page13.c b/src/libui_sdl/libui/test/page13.c new file mode 100644 index 0000000..5e6fd52 --- /dev/null +++ b/src/libui_sdl/libui/test/page13.c @@ -0,0 +1,157 @@ +// 28 may 2016 +#include "test.h" + +static int winClose(uiWindow *w, void *data) +{ + return 1; +} + +static void openTestWindow(uiBox *(*mkf)(void)) +{ + uiWindow *w; + uiBox *b; + uiCombobox *c; + uiEditableCombobox *e; + uiRadioButtons *r; + + w = uiNewWindow("Test", 100, 100, 0); + uiWindowOnClosing(w, winClose, NULL); + uiWindowSetMargined(w, 1); + b = (*mkf)(); + uiWindowSetChild(w, uiControl(b)); + +#define BA(x) uiBoxAppend(b, uiControl(x), 0) + BA(uiNewButton("")); + BA(uiNewCheckbox("")); + BA(uiNewEntry()); + BA(uiNewLabel("")); + BA(uiNewSpinbox(0, 100)); + BA(uiNewProgressBar()); + BA(uiNewSlider(0, 100)); + BA(uiNewHorizontalSeparator()); + c = uiNewCombobox(); + uiComboboxAppend(c, ""); + BA(c); + e = uiNewEditableCombobox(); + uiEditableComboboxAppend(e, ""); + BA(e); + r = uiNewRadioButtons(); + uiRadioButtonsAppend(r, ""); + BA(r); + BA(uiNewDateTimePicker()); + BA(uiNewDatePicker()); + BA(uiNewTimePicker()); + BA(uiNewMultilineEntry()); + // TODO nonscrolling and scrolling areas? + BA(uiNewFontButton()); + BA(uiNewColorButton()); + BA(uiNewPasswordEntry()); + BA(uiNewSearchEntry()); + BA(uiNewVerticalSeparator()); + + uiControlShow(uiControl(w)); +} + +static void buttonClicked(uiButton *b, void *data) +{ + openTestWindow((uiBox *(*)(void)) data); +} + +static void entryChanged(uiEntry *e, void *data) +{ + char *text; + + text = uiEntryText(e); + printf("%s entry changed: %s\n", (const char *) data, text); + uiFreeText(text); +} + +static void showHide(uiButton *b, void *data) +{ + uiControl *c = uiControl(data); + + if (uiControlVisible(c)) + uiControlHide(c); + else + uiControlShow(c); +} + +static void setIndeterminate(uiButton *b, void *data) +{ + uiProgressBar *p = uiProgressBar(data); + int value; + + value = uiProgressBarValue(p); + if (value == -1) + value = 50; + else + value = -1; + uiProgressBarSetValue(p, value); +} + +static void deleteFirst(uiButton *b, void *data) +{ + uiForm *f = uiForm(data); + + uiFormDelete(f, 0); +} + +uiBox *makePage13(void) +{ + uiBox *page13; + uiRadioButtons *rb; + uiButton *b; + uiForm *f; + uiEntry *e; + uiProgressBar *p; + + page13 = newVerticalBox(); + + rb = uiNewRadioButtons(); + uiRadioButtonsAppend(rb, "Item 1"); + uiRadioButtonsAppend(rb, "Item 2"); + uiRadioButtonsAppend(rb, "Item 3"); + uiBoxAppend(page13, uiControl(rb), 0); + + rb = uiNewRadioButtons(); + uiRadioButtonsAppend(rb, "Item A"); + uiRadioButtonsAppend(rb, "Item B"); + uiBoxAppend(page13, uiControl(rb), 0); + + b = uiNewButton("Horizontal"); + uiButtonOnClicked(b, buttonClicked, uiNewHorizontalBox); + uiBoxAppend(page13, uiControl(b), 0); + + b = uiNewButton("Vertical"); + uiButtonOnClicked(b, buttonClicked, uiNewVerticalBox); + uiBoxAppend(page13, uiControl(b), 0); + + f = newForm(); + + e = uiNewPasswordEntry(); + uiEntryOnChanged(e, entryChanged, "password"); + uiFormAppend(f, "Password Entry", uiControl(e), 0); + + e = uiNewSearchEntry(); + uiEntryOnChanged(e, entryChanged, "search"); + uiFormAppend(f, "Search Box", uiControl(e), 0); + + uiFormAppend(f, "MLE", uiControl(uiNewMultilineEntry()), 1); + + p = uiNewProgressBar(); + uiProgressBarSetValue(p, 50); + uiBoxAppend(page13, uiControl(p), 0); + b = uiNewButton("Toggle Indeterminate"); + uiButtonOnClicked(b, setIndeterminate, p); + uiBoxAppend(page13, uiControl(b), 0); + + b = uiNewButton("Show/Hide"); + uiButtonOnClicked(b, showHide, e); + uiBoxAppend(page13, uiControl(b), 0); + b = uiNewButton("Delete First"); + uiButtonOnClicked(b, deleteFirst, f); + uiBoxAppend(page13, uiControl(b), 0); + uiBoxAppend(page13, uiControl(f), 1); + + return page13; +} diff --git a/src/libui_sdl/libui/test/page14.c b/src/libui_sdl/libui/test/page14.c new file mode 100644 index 0000000..880534c --- /dev/null +++ b/src/libui_sdl/libui/test/page14.c @@ -0,0 +1,350 @@ +// 9 june 2016 +#include "test.h" + +// TODOs: +// - GTK+ - make all expanding controls the same size, to match the other OSs? will they match the other OSs? + +enum { + red, + green, + blue, + yellow, + white, + magenta, + orange, + purple, + cyan, +}; + +static const struct { + double r; + double g; + double b; +} colors[] = { + { 1, 0, 0 }, + { 0, 0.5, 0 }, + { 0, 0, 1 }, + { 1, 1, 0 }, + { 1, 1, 1 }, + { 1, 0, 1 }, + { 1, 0.65, 0 }, + { 0.5, 0, 0.5 }, + { 0, 1, 1 }, +}; + +static uiControl *testControl(const char *label, int color) +{ + uiColorButton *b; + + b = uiNewColorButton(); + uiColorButtonSetColor(b, colors[color].r, colors[color].g, colors[color].b, 1.0); + return uiControl(b); +} + +static uiControl *simpleGrid(void) +{ + uiGrid *g; + uiControl *t4; + + g = newGrid(); + uiGridAppend(g, testControl("1", red), + 0, 0, 1, 1, + 0, uiAlignFill, 0, uiAlignFill); + uiGridAppend(g, testControl("2", green), + 1, 0, 1, 1, + 0, uiAlignFill, 0, uiAlignFill); + uiGridAppend(g, testControl("3", blue), + 2, 0, 1, 1, + 0, uiAlignFill, 0, uiAlignFill); + t4 = testControl("4", green); + uiGridAppend(g, t4, + 0, 1, 1, 1, + 0, uiAlignFill, 1, uiAlignFill); + uiGridInsertAt(g, testControl("5", blue), + t4, uiAtTrailing, 2, 1, + 0, uiAlignFill, 0, uiAlignFill); + uiGridAppend(g, testControl("6", yellow), + -1, 0, 1, 2, + 1, uiAlignFill, 0, uiAlignFill); + return uiControl(g); +} + +static uiControl *boxComparison(void) +{ + uiBox *vbox; + uiGrid *g; + uiBox *hbox; + + vbox = newVerticalBox(); + uiBoxAppend(vbox, uiControl(uiNewLabel("Above")), 0); + uiBoxAppend(vbox, uiControl(uiNewHorizontalSeparator()), 0); + + hbox = newHorizontalBox(); + uiBoxAppend(vbox, uiControl(hbox), 0); + uiBoxAppend(hbox, testControl("1", white), 0); + uiBoxAppend(hbox, uiControl(uiNewLabel("A label")), 1); + uiBoxAppend(hbox, testControl("2", green), 0); + uiBoxAppend(hbox, uiControl(uiNewLabel("Another label")), 1); + uiBoxAppend(hbox, testControl("3", red), 0); + + uiBoxAppend(vbox, uiControl(uiNewHorizontalSeparator()), 0); + + g = newGrid(); + uiBoxAppend(vbox, uiControl(g), 0); + uiGridAppend(g, testControl("1", white), + 0, 0, 1, 1, + 0, uiAlignFill, 0, uiAlignFill); + uiGridAppend(g, uiControl(uiNewLabel("A label")), + 1, 0, 1, 1, + 1, uiAlignFill, 0, uiAlignFill); + uiGridAppend(g, testControl("2", green), + 2, 0, 1, 1, + 0, uiAlignFill, 0, uiAlignFill); + uiGridAppend(g, uiControl(uiNewLabel("Another label")), + 3, 0, 1, 1, + 1, uiAlignFill, 0, uiAlignFill); + uiGridAppend(g, testControl("3", red), + 4, 0, 1, 1, + 0, uiAlignFill, 0, uiAlignFill); + + uiBoxAppend(vbox, uiControl(uiNewHorizontalSeparator()), 0); + uiBoxAppend(vbox, uiControl(uiNewLabel("Below")), 0); + return uiControl(vbox); +} + +static uiControl *emptyLine(void) +{ + uiGrid *g; + + g = newGrid(); + uiGridAppend(g, testControl("(0, 0)", red), + 0, 0, 1, 1, + 1, uiAlignFill, 1, uiAlignFill); + uiGridAppend(g, testControl("(0, 1)", blue), + 0, 1, 1, 1, + 0, uiAlignFill, 0, uiAlignFill); + uiGridAppend(g, testControl("(10, 0)", green), + 10, 0, 1, 1, + 0, uiAlignFill, 0, uiAlignFill); + uiGridAppend(g, testControl("(10, 1)", magenta), + 10, 1, 1, 1, + 0, uiAlignFill, 0, uiAlignFill); + return uiControl(g); +} + +static uiControl *emptyGrid(void) +{ + uiGrid *g; + uiControl *t; + + g = newGrid(); + t = testControl("(0, 0)", red); + uiGridAppend(g, t, + 0, 0, 1, 1, + 1, uiAlignFill, 1, uiAlignFill); + uiControlHide(t); + return uiControl(g); +} + +// TODO insert (need specialized insert/delete) + +static uiControl *spanningGrid(void) +{ + uiGrid *g; + + g = newGrid(); + uiGridAppend(g, testControl("0", blue), + 0, 4, 4, 1, + 1, uiAlignFill, 0, uiAlignFill); + uiGridAppend(g, testControl("1", green), + 4, 0, 1, 4, + 0, uiAlignFill, 1, uiAlignFill); + uiGridAppend(g, testControl("2", red), + 3, 3, 1, 1, + 1, uiAlignFill, 1, uiAlignFill); + uiGridAppend(g, testControl("3", yellow), + 0, 3, 2, 1, + 0, uiAlignFill, 0, uiAlignFill); + uiGridAppend(g, testControl("4", orange), + 3, 0, 1, 2, + 0, uiAlignFill, 0, uiAlignFill); + uiGridAppend(g, testControl("5", purple), + 1, 1, 1, 1, + 0, uiAlignFill, 0, uiAlignFill); + uiGridAppend(g, testControl("6", white), + 0, 1, 1, 1, + 0, uiAlignFill, 0, uiAlignFill); + uiGridAppend(g, testControl("7", cyan), + 1, 0, 1, 1, + 0, uiAlignFill, 0, uiAlignFill); + return uiControl(g); +} + +// TODO make non-global +static uiButton *hideOne, *one, *showOne; + +static void onHideOne(uiButton *b, void *data) +{ + uiControlHide(uiControl(one)); +} + +static void onShowOne(uiButton *b, void *data) +{ + uiControlShow(uiControl(one)); +} + +static void onHideAll(uiButton *b, void *data) +{ + uiControlHide(uiControl(hideOne)); + uiControlHide(uiControl(one)); + uiControlHide(uiControl(showOne)); +} + +static void onShowAll(uiButton *b, void *data) +{ + uiControlShow(uiControl(hideOne)); + uiControlShow(uiControl(one)); + uiControlShow(uiControl(showOne)); +} + +#define AT(x) static void onInsert ## x(uiButton *b, void *data) \ + { \ + uiGrid *g = uiGrid(data); \ + uiGridInsertAt(g, uiControl(uiNewButton("Button")), \ + uiControl(b), uiAt ## x, 1, 1, \ + 0, uiAlignFill, 0, uiAlignFill); \ + } +AT(Leading) +AT(Top) +AT(Trailing) +AT(Bottom) + +static uiControl *assorted(void) +{ + uiGrid *outergrid; + uiGrid *innergrid; + uiButton *b; + + outergrid = newGrid(); + + innergrid = newGrid(); + one = uiNewButton("Test"); + uiGridAppend(innergrid, uiControl(one), + 1, 1, 1, 1, + 0, uiAlignFill, 0, uiAlignFill); + hideOne = uiNewButton("Hide One"); + uiButtonOnClicked(hideOne, onHideOne, NULL); + uiGridAppend(innergrid, uiControl(hideOne), + 0, 1, 1, 1, + 0, uiAlignFill, 0, uiAlignFill); + showOne = uiNewButton("Show One"); + uiButtonOnClicked(showOne, onShowOne, NULL); + uiGridAppend(innergrid, uiControl(showOne), + 2, 1, 1, 1, + 0, uiAlignFill, 0, uiAlignFill); + b = uiNewButton("Hide All"); + uiButtonOnClicked(b, onHideAll, NULL); + uiGridAppend(innergrid, uiControl(b), + 1, 0, 1, 1, + 0, uiAlignFill, 0, uiAlignFill); + b = uiNewButton("Show All"); + uiButtonOnClicked(b, onShowAll, NULL); + uiGridAppend(innergrid, uiControl(b), + 1, 2, 1, 1, + 0, uiAlignFill, 0, uiAlignFill); + uiGridAppend(outergrid, uiControl(innergrid), + 0, 0, 1, 1, + 1, uiAlignFill, 1, uiAlignFill); + + innergrid = newGrid(); + b = uiNewButton("Insert Trailing"); + uiButtonOnClicked(b, onInsertTrailing, innergrid); + uiGridAppend(innergrid, uiControl(b), + 0, 0, 1, 1, + 1, uiAlignFill, 0, uiAlignFill); + b = uiNewButton("Insert Bottom"); + uiButtonOnClicked(b, onInsertBottom, innergrid); + uiGridAppend(innergrid, uiControl(b), + 1, 0, 1, 1, + 1, uiAlignFill, 0, uiAlignFill); + b = uiNewButton("Insert Leading"); + uiButtonOnClicked(b, onInsertLeading, innergrid); + uiGridAppend(innergrid, uiControl(b), + 1, 1, 1, 1, + 1, uiAlignFill, 0, uiAlignFill); + b = uiNewButton("Insert Top"); + uiButtonOnClicked(b, onInsertTop, innergrid); + uiGridAppend(innergrid, uiControl(b), + 0, 1, 1, 1, + 1, uiAlignFill, 0, uiAlignFill); + uiGridAppend(outergrid, uiControl(innergrid), + 1, 0, 1, 1, + 1, uiAlignFill, 1, uiAlignFill); + + innergrid = newGrid(); + uiGridAppend(innergrid, uiControl(uiNewColorButton()), + 0, 0, 1, 1, + 1, uiAlignFill, 0, uiAlignFill); + uiGridAppend(innergrid, uiControl(uiNewColorButton()), + 0, 1, 1, 1, + 1, uiAlignStart, 0, uiAlignFill); + uiGridAppend(innergrid, uiControl(uiNewColorButton()), + 0, 2, 1, 1, + 1, uiAlignCenter, 0, uiAlignFill); + uiGridAppend(innergrid, uiControl(uiNewColorButton()), + 0, 3, 1, 1, + 1, uiAlignEnd, 0, uiAlignFill); + uiGridAppend(outergrid, uiControl(innergrid), + 0, 1, 1, 1, + 1, uiAlignFill, 1, uiAlignFill); + + // TODO with only this, wrong size on OS X — expand sizing thing? + innergrid = newGrid(); + uiGridAppend(innergrid, uiControl(uiNewColorButton()), + 0, 0, 1, 1, + 0, uiAlignFill, 1, uiAlignFill); + uiGridAppend(innergrid, uiControl(uiNewColorButton()), + 1, 0, 1, 1, + 0, uiAlignFill, 1, uiAlignStart); + uiGridAppend(innergrid, uiControl(uiNewColorButton()), + 2, 0, 1, 1, + 0, uiAlignFill, 1, uiAlignCenter); + uiGridAppend(innergrid, uiControl(uiNewColorButton()), + 3, 0, 1, 1, + 0, uiAlignFill, 1, uiAlignEnd); + uiGridAppend(outergrid, uiControl(innergrid), + 1, 1, 1, 1, + 1, uiAlignFill, 1, uiAlignFill); + + return uiControl(outergrid); +} + +static const struct { + const char *name; + uiControl *(*f)(void); +} pages[] = { + // based on GTK+ test/testgrid.c + { "Simple Grid", simpleGrid }, + { "Box Comparison", boxComparison }, + { "Empty Line", emptyLine }, + { "Empty Grid", emptyGrid }, + { "Spanning Grid", spanningGrid }, + // my own + { "Assorted", assorted }, + { NULL, NULL }, +}; + +uiTab *makePage14(void) +{ + uiTab *page14; + int i; + + page14 = newTab(); + + for (i = 0; pages[i].name != NULL; i++) + uiTabAppend(page14, + pages[i].name, + (*(pages[i].f))()); + + return page14; +} diff --git a/src/libui_sdl/libui/test/page15.c b/src/libui_sdl/libui/test/page15.c new file mode 100644 index 0000000..e703bee --- /dev/null +++ b/src/libui_sdl/libui/test/page15.c @@ -0,0 +1,260 @@ +// 15 june 2016 +#include "test.h" + +static uiAreaHandler borderAH; +static int borderAHInit = 0; +static double lastx = -1, lasty = -1; + +struct trect { + double left; + double top; + double right; + double bottom; + int in; +}; + +#define tsetrect(re, l, t, r, b) re.left = l; re.top = t; re.right = r; re.bottom = b; re.in = lastx >= re.left && lastx < re.right && lasty >= re.top && lasty < re.bottom + +struct tareas { + struct trect move; + struct trect alsomove; + struct trect leftresize; + struct trect topresize; + struct trect rightresize; + struct trect bottomresize; + struct trect topleftresize; + struct trect toprightresize; + struct trect bottomleftresize; + struct trect bottomrightresize; + struct trect close; +}; + +static void filltareas(double awid, double aht, struct tareas *ta) +{ + tsetrect(ta->move, 20, 20, awid - 20, 20 + 30); + tsetrect(ta->alsomove, 30, 200, 100, 270); + tsetrect(ta->leftresize, 5, 20, 15, aht - 20); + tsetrect(ta->topresize, 20, 5, awid - 20, 15); + tsetrect(ta->rightresize, awid - 15, 20, awid - 5, aht - 20); + tsetrect(ta->bottomresize, 20, aht - 15, awid - 20, aht - 5); + tsetrect(ta->topleftresize, 5, 5, 15, 15); + tsetrect(ta->toprightresize, awid - 15, 5, awid - 5, 15); + tsetrect(ta->bottomleftresize, 5, aht - 15, 15, aht - 5); + tsetrect(ta->bottomrightresize, awid - 15, aht - 15, awid - 5, aht - 5); + tsetrect(ta->close, 130, 200, 200, 270); +} + +static void drawtrect(uiDrawContext *c, struct trect tr, double r, double g, double bl) +{ + uiDrawPath *p; + uiDrawBrush b; + + memset(&b, 0, sizeof (uiDrawBrush)); + b.Type = uiDrawBrushTypeSolid; + b.R = r; + b.G = g; + b.B = bl; + b.A = 1.0; + if (tr.in) { + b.R += b.R * 0.75; + b.G += b.G * 0.75; + b.B += b.B * 0.75; + } + p = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(p, + tr.left, + tr.top, + tr.right - tr.left, + tr.bottom - tr.top); + uiDrawPathEnd(p); + uiDrawFill(c, p, &b); + uiDrawFreePath(p); +} + +static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *p) +{ + struct tareas ta; + + filltareas(p->AreaWidth, p->AreaHeight, &ta); + drawtrect(p->Context, ta.move, 0, 0.5, 0); + drawtrect(p->Context, ta.alsomove, 0, 0.5, 0); + drawtrect(p->Context, ta.leftresize, 0, 0, 0.5); + drawtrect(p->Context, ta.topresize, 0, 0, 0.5); + drawtrect(p->Context, ta.rightresize, 0, 0, 0.5); + drawtrect(p->Context, ta.bottomresize, 0, 0, 0.5); + drawtrect(p->Context, ta.topleftresize, 0, 0.5, 0.5); + drawtrect(p->Context, ta.toprightresize, 0, 0.5, 0.5); + drawtrect(p->Context, ta.bottomleftresize, 0, 0.5, 0.5); + drawtrect(p->Context, ta.bottomrightresize, 0, 0.5, 0.5); + drawtrect(p->Context, ta.close, 0.5, 0, 0); + + // TODO add current position prints here +} + +static void handlerMouseEvent(uiAreaHandler *a, uiArea *area, uiAreaMouseEvent *e) +{ + struct tareas ta; + + lastx = e->X; + lasty = e->Y; + filltareas(e->AreaWidth, e->AreaHeight, &ta); + // redraw our highlighted rect + uiAreaQueueRedrawAll(area); + if (e->Down != 1) + return; + if (ta.move.in || ta.alsomove.in) { + uiAreaBeginUserWindowMove(area); + return; + } +#define resize(cond, edge) if (cond) { uiAreaBeginUserWindowResize(area, edge); return; } + resize(ta.leftresize.in, uiWindowResizeEdgeLeft) + resize(ta.topresize.in, uiWindowResizeEdgeTop) + resize(ta.rightresize.in, uiWindowResizeEdgeRight) + resize(ta.bottomresize.in, uiWindowResizeEdgeBottom) + resize(ta.topleftresize.in, uiWindowResizeEdgeTopLeft) + resize(ta.toprightresize.in, uiWindowResizeEdgeTopRight) + resize(ta.bottomleftresize.in, uiWindowResizeEdgeBottomLeft) + resize(ta.bottomrightresize.in, uiWindowResizeEdgeBottomRight) + if (ta.close.in) { + // TODO + return; + } +} + +static void handlerMouseCrossed(uiAreaHandler *ah, uiArea *a, int left) +{ +} + +static void handlerDragBroken(uiAreaHandler *ah, uiArea *a) +{ +} + +static int handlerKeyEvent(uiAreaHandler *ah, uiArea *a, uiAreaKeyEvent *e) +{ + return 0; +} + +static void borderWindowOpen(uiButton *b, void *data) +{ + uiWindow *w; + uiArea *a; + + if (!borderAHInit) { + borderAH.Draw = handlerDraw; + borderAH.MouseEvent = handlerMouseEvent; + borderAH.MouseCrossed = handlerMouseCrossed; + borderAH.DragBroken = handlerDragBroken; + borderAH.KeyEvent = handlerKeyEvent; + borderAHInit = 1; + } + + w = uiNewWindow("Border Resize Test", 300, 500, 0); + uiWindowSetBorderless(w, 1); + + a = uiNewArea(&borderAH); +// uiWindowSetChild(w, uiControl(a)); +{uiBox *b; +b=uiNewHorizontalBox(); +uiBoxAppend(b,uiControl(a),1); +uiWindowSetChild(w,uiControl(b));} +//TODO why is this hack needed? GTK+ issue + + uiControlShow(uiControl(w)); +} + +static uiSpinbox *width, *height; +static uiCheckbox *fullscreen; + +static void sizeWidth(uiSpinbox *s, void *data) +{ + uiWindow *w = uiWindow(data); + int xp, yp; + + uiWindowContentSize(w, &xp, &yp); + xp = uiSpinboxValue(width); + uiWindowSetContentSize(w, xp, yp); +} + +static void sizeHeight(uiSpinbox *s, void *data) +{ + uiWindow *w = uiWindow(data); + int xp, yp; + + uiWindowContentSize(w, &xp, &yp); + yp = uiSpinboxValue(height); + uiWindowSetContentSize(w, xp, yp); +} + +static void updatesize(uiWindow *w) +{ + int xp, yp; + + uiWindowContentSize(w, &xp, &yp); + uiSpinboxSetValue(width, xp); + uiSpinboxSetValue(height, yp); + // TODO on OS X this is updated AFTER sending the size change, not before + uiCheckboxSetChecked(fullscreen, uiWindowFullscreen(w)); +} + +void onSize(uiWindow *w, void *data) +{ + printf("size\n"); + updatesize(w); +} + +void setFullscreen(uiCheckbox *cb, void *data) +{ + uiWindow *w = uiWindow(data); + + uiWindowSetFullscreen(w, uiCheckboxChecked(fullscreen)); + updatesize(w); +} + +static void borderless(uiCheckbox *c, void *data) +{ + uiWindow *w = uiWindow(data); + + uiWindowSetBorderless(w, uiCheckboxChecked(c)); +} + +uiBox *makePage15(uiWindow *w) +{ + uiBox *page15; + uiBox *hbox; + uiButton *button; + uiCheckbox *checkbox; + + page15 = newVerticalBox(); + + hbox = newHorizontalBox(); + uiBoxAppend(page15, uiControl(hbox), 0); + + uiBoxAppend(hbox, uiControl(uiNewLabel("Size")), 0); + width = uiNewSpinbox(INT_MIN, INT_MAX); + uiBoxAppend(hbox, uiControl(width), 1); + height = uiNewSpinbox(INT_MIN, INT_MAX); + uiBoxAppend(hbox, uiControl(height), 1); + fullscreen = uiNewCheckbox("Fullscreen"); + uiBoxAppend(hbox, uiControl(fullscreen), 0); + + uiSpinboxOnChanged(width, sizeWidth, w); + uiSpinboxOnChanged(height, sizeHeight, w); + uiCheckboxOnToggled(fullscreen, setFullscreen, w); + uiWindowOnContentSizeChanged(w, onSize, NULL); + updatesize(w); + + checkbox = uiNewCheckbox("Borderless"); + uiCheckboxOnToggled(checkbox, borderless, w); + uiBoxAppend(page15, uiControl(checkbox), 0); + + button = uiNewButton("Borderless Resizes"); + uiButtonOnClicked(button, borderWindowOpen, NULL); + uiBoxAppend(page15, uiControl(button), 0); + + hbox = newHorizontalBox(); + uiBoxAppend(page15, uiControl(hbox), 1); + + uiBoxAppend(hbox, uiControl(uiNewVerticalSeparator()), 0); + + return page15; +} diff --git a/src/libui_sdl/libui/test/page2.c b/src/libui_sdl/libui/test/page2.c new file mode 100644 index 0000000..abb0648 --- /dev/null +++ b/src/libui_sdl/libui/test/page2.c @@ -0,0 +1,215 @@ +// 29 april 2015 +#include "test.h" + +uiGroup *page2group; + +static uiLabel *movingLabel; +static uiBox *movingBoxes[2]; +static int movingCurrent; + +static void moveLabel(uiButton *b, void *data) +{ + int from, to; + + from = movingCurrent; + to = 0; + if (from == 0) + to = 1; + uiBoxDelete(movingBoxes[from], 0); + uiBoxAppend(movingBoxes[to], uiControl(movingLabel), 0); + movingCurrent = to; +} + +static int moveBack; +#define moveOutText "Move Page 1 Out" +#define moveBackText "Move Page 1 Back" + +static void movePage1(uiButton *b, void *data) +{ + if (moveBack) { + uiBoxDelete(mainBox, 1); + uiTabInsertAt(mainTab, "Page 1", 0, uiControl(page1)); + uiButtonSetText(b, moveOutText); + moveBack = 0; + return; + } + uiTabDelete(mainTab, 0); + uiBoxAppend(mainBox, uiControl(page1), 1); + uiButtonSetText(b, moveBackText); + moveBack = 1; +} + +static void openAnotherWindow(uiButton *bb, void *data) +{ + uiWindow *w; + uiBox *b; + + w = uiNewWindow("Another Window", 100, 100, data != NULL); + if (data != NULL) { + b = uiNewVerticalBox(); + uiBoxAppend(b, uiControl(uiNewEntry()), 0); + uiBoxAppend(b, uiControl(uiNewButton("Button")), 0); + uiBoxSetPadded(b, 1); + uiWindowSetChild(w, uiControl(b)); + } else + uiWindowSetChild(w, uiControl(makePage6())); + uiWindowSetMargined(w, 1); + uiControlShow(uiControl(w)); +} + +static void openAnotherDisabledWindow(uiButton *b, void *data) +{ + uiWindow *w; + + w = uiNewWindow("Another Window", 100, 100, data != NULL); + uiControlDisable(uiControl(w)); + uiControlShow(uiControl(w)); +} + +#define SHED(method, Method) \ + static void method ## Control(uiButton *b, void *data) \ + { \ + uiControl ## Method(uiControl(data)); \ + } +SHED(show, Show) +SHED(enable, Enable) +SHED(disable, Disable) + +static void echoReadOnlyText(uiEntry *e, void *data) +{ + char *text; + + text = uiEntryText(e); + uiEntrySetText(uiEntry(data), text); + uiFreeText(text); +} + +uiBox *makePage2(void) +{ + uiBox *page2; + uiBox *hbox; + uiGroup *group; + uiBox *vbox; + uiButton *button; + uiBox *nestedBox; + uiBox *innerhbox; + uiBox *innerhbox2; + uiBox *innerhbox3; + uiTab *disabledTab; + uiEntry *entry; + uiEntry *readonly; + uiButton *button2; + + page2 = newVerticalBox(); + + group = newGroup("Moving Label"); + page2group = group; + uiBoxAppend(page2, uiControl(group), 0); + vbox = newVerticalBox(); + uiGroupSetChild(group, uiControl(vbox)); + + hbox = newHorizontalBox(); + button = uiNewButton("Move the Label!"); + uiButtonOnClicked(button, moveLabel, NULL); + uiBoxAppend(hbox, uiControl(button), 1); + // have a blank label for space + uiBoxAppend(hbox, uiControl(uiNewLabel("")), 1); + uiBoxAppend(vbox, uiControl(hbox), 0); + + hbox = newHorizontalBox(); + movingBoxes[0] = newVerticalBox(); + uiBoxAppend(hbox, uiControl(movingBoxes[0]), 1); + movingBoxes[1] = newVerticalBox(); + uiBoxAppend(hbox, uiControl(movingBoxes[1]), 1); + uiBoxAppend(vbox, uiControl(hbox), 0); + + movingCurrent = 0; + movingLabel = uiNewLabel("This label moves!"); + uiBoxAppend(movingBoxes[movingCurrent], uiControl(movingLabel), 0); + + hbox = newHorizontalBox(); + button = uiNewButton(moveOutText); + uiButtonOnClicked(button, movePage1, NULL); + uiBoxAppend(hbox, uiControl(button), 0); + uiBoxAppend(page2, uiControl(hbox), 0); + moveBack = 0; + + hbox = newHorizontalBox(); + uiBoxAppend(hbox, uiControl(uiNewLabel("Label Alignment Test")), 0); + button = uiNewButton("Open Menued Window"); + uiButtonOnClicked(button, openAnotherWindow, button); + uiBoxAppend(hbox, uiControl(button), 0); + button = uiNewButton("Open Menuless Window"); + uiButtonOnClicked(button, openAnotherWindow, NULL); + uiBoxAppend(hbox, uiControl(button), 0); + button = uiNewButton("Disabled Menued"); + uiButtonOnClicked(button, openAnotherDisabledWindow, button); + uiBoxAppend(hbox, uiControl(button), 0); + button = uiNewButton("Disabled Menuless"); + uiButtonOnClicked(button, openAnotherDisabledWindow, NULL); + uiBoxAppend(hbox, uiControl(button), 0); + uiBoxAppend(page2, uiControl(hbox), 0); + + nestedBox = newHorizontalBox(); + innerhbox = newHorizontalBox(); + uiBoxAppend(innerhbox, uiControl(uiNewButton("These")), 0); + button = uiNewButton("buttons"); + uiControlDisable(uiControl(button)); + uiBoxAppend(innerhbox, uiControl(button), 0); + uiBoxAppend(nestedBox, uiControl(innerhbox), 0); + innerhbox = newHorizontalBox(); + uiBoxAppend(innerhbox, uiControl(uiNewButton("are")), 0); + innerhbox2 = newHorizontalBox(); + button = uiNewButton("in"); + uiControlDisable(uiControl(button)); + uiBoxAppend(innerhbox2, uiControl(button), 0); + uiBoxAppend(innerhbox, uiControl(innerhbox2), 0); + uiBoxAppend(nestedBox, uiControl(innerhbox), 0); + innerhbox = newHorizontalBox(); + innerhbox2 = newHorizontalBox(); + uiBoxAppend(innerhbox2, uiControl(uiNewButton("nested")), 0); + innerhbox3 = newHorizontalBox(); + button = uiNewButton("boxes"); + uiControlDisable(uiControl(button)); + uiBoxAppend(innerhbox3, uiControl(button), 0); + uiBoxAppend(innerhbox2, uiControl(innerhbox3), 0); + uiBoxAppend(innerhbox, uiControl(innerhbox2), 0); + uiBoxAppend(nestedBox, uiControl(innerhbox), 0); + uiBoxAppend(page2, uiControl(nestedBox), 0); + + hbox = newHorizontalBox(); + button = uiNewButton("Enable Nested Box"); + uiButtonOnClicked(button, enableControl, nestedBox); + uiBoxAppend(hbox, uiControl(button), 0); + button = uiNewButton("Disable Nested Box"); + uiButtonOnClicked(button, disableControl, nestedBox); + uiBoxAppend(hbox, uiControl(button), 0); + uiBoxAppend(page2, uiControl(hbox), 0); + + disabledTab = newTab(); + uiTabAppend(disabledTab, "Disabled", uiControl(uiNewButton("Button"))); + uiTabAppend(disabledTab, "Tab", uiControl(uiNewLabel("Label"))); + uiControlDisable(uiControl(disabledTab)); + uiBoxAppend(page2, uiControl(disabledTab), 1); + + entry = uiNewEntry(); + readonly = uiNewEntry(); + uiEntryOnChanged(entry, echoReadOnlyText, readonly); + uiEntrySetText(readonly, "If you can see this, uiEntryReadOnly() isn't working properly."); + uiEntrySetReadOnly(readonly, 1); + if (uiEntryReadOnly(readonly)) + uiEntrySetText(readonly, ""); + uiBoxAppend(page2, uiControl(entry), 0); + uiBoxAppend(page2, uiControl(readonly), 0); + + hbox = newHorizontalBox(); + button = uiNewButton("Show Button 2"); + button2 = uiNewButton("Button 2"); + uiButtonOnClicked(button, showControl, button2); + uiControlHide(uiControl(button2)); + uiBoxAppend(hbox, uiControl(button), 1); + uiBoxAppend(hbox, uiControl(button2), 0); + uiBoxAppend(page2, uiControl(hbox), 0); + + return page2; +} diff --git a/src/libui_sdl/libui/test/page3.c b/src/libui_sdl/libui/test/page3.c new file mode 100644 index 0000000..1f229e9 --- /dev/null +++ b/src/libui_sdl/libui/test/page3.c @@ -0,0 +1,69 @@ +// 7 may 2015 +#include "test.h" + +static uiBox *makeSet(int omit, int hidden, int stretch) +{ + uiBox *hbox; + uiButton *buttons[4]; + + // don't use newHorizontalBox() + // the point of this test is to test hidden controls and padded + hbox = (*newhbox)(); + uiBoxSetPadded(hbox, 1); + if (omit != 0) { + buttons[0] = uiNewButton("First"); + uiBoxAppend(hbox, uiControl(buttons[0]), stretch); + } + if (omit != 1) { + buttons[1] = uiNewButton("Second"); + uiBoxAppend(hbox, uiControl(buttons[1]), stretch); + } + if (omit != 2) { + buttons[2] = uiNewButton("Third"); + uiBoxAppend(hbox, uiControl(buttons[2]), stretch); + } + if (omit != 3) { + buttons[3] = uiNewButton("Fourth"); + uiBoxAppend(hbox, uiControl(buttons[3]), stretch); + } + if (hidden != -1) + uiControlHide(uiControl(buttons[hidden])); + return hbox; +} + +uiBox *makePage3(void) +{ + uiBox *page3; + uiBox *hbox; + uiBox *hbox2; + uiBox *vbox; + int hidden; + + page3 = newVerticalBox(); + + // first the non-stretchy type + for (hidden = 0; hidden < 4; hidden++) { + // these two must stay unpadded as well, otherwise the test isn't meaningful + hbox2 = (*newhbox)(); + vbox = (*newvbox)(); + // reference set + hbox = makeSet(hidden, -1, 0); + uiBoxAppend(vbox, uiControl(hbox), 0); + // real thing + hbox = makeSet(-1, hidden, 0); + uiBoxAppend(vbox, uiControl(hbox), 0); + // pack vbox in + uiBoxAppend(hbox2, uiControl(vbox), 0); + // and have a button in there for showing right margins + uiBoxAppend(hbox2, uiControl(uiNewButton("Right Margin Test")), 1); + uiBoxAppend(page3, uiControl(hbox2), 0); + } + + // then the stretchy type + for (hidden = 0; hidden < 4; hidden++) { + hbox = makeSet(-1, hidden, 1); + uiBoxAppend(page3, uiControl(hbox), 0); + } + + return page3; +} diff --git a/src/libui_sdl/libui/test/page4.c b/src/libui_sdl/libui/test/page4.c new file mode 100644 index 0000000..ce4a6af --- /dev/null +++ b/src/libui_sdl/libui/test/page4.c @@ -0,0 +1,165 @@ +// 19 may 2015 +#include "test.h" + +static uiSpinbox *spinbox; +static uiSlider *slider; +static uiProgressBar *pbar; + +#define CHANGED(what) \ + static void on ## what ## Changed(ui ## what *this, void *data) \ + { \ + int value; \ + printf("on %s changed\n", #what); \ + value = ui ## what ## Value(this); \ + uiSpinboxSetValue(spinbox, value); \ + uiSliderSetValue(slider, value); \ + uiProgressBarSetValue(pbar, value); \ + } +CHANGED(Spinbox) +CHANGED(Slider) + +#define SETTOO(what, name, n) \ + static void set ## what ## Too ## name(uiButton *this, void *data) \ + { \ + ui ## what ## SetValue(ui ## what(data), n); \ + } +SETTOO(Spinbox, Low, -80) +SETTOO(Spinbox, High, 80) +SETTOO(Slider, Low, -80) +SETTOO(Slider, High, 80) + +static uiCombobox *cbox; +static uiEditableCombobox *editable; +static uiRadioButtons *rb; + +static void appendCBRB(uiButton *b, void *data) +{ + uiComboboxAppend(cbox, "New Item"); + uiEditableComboboxAppend(editable, "New Item"); + uiRadioButtonsAppend(rb, "New Item"); +} + +static void onCBChanged(uiCombobox *c, void *data) +{ + printf("%s combobox changed to %d\n", + (char *) data, + (int) uiComboboxSelected(c)); + uiEditableComboboxSetText(editable, "changed"); +} + +static void onECBChanged(uiEditableCombobox *c, void *data) +{ + char *t; + + t = uiEditableComboboxText(c); + printf("%s combobox changed to %s\n", + (char *) data, + t); + uiFreeText(t); +} + +static void onRBSelected(uiRadioButtons *r, void *data) +{ + printf("radio buttons %d\n", uiRadioButtonsSelected(r)); +} + +static void selectSecond(uiButton *b, void *data) +{ + // TODO combobox, editable + uiRadioButtonsSetSelected(rb, 1); +} + +static void selectNone(uiButton *b, void *data) +{ + // TODO combobox, editable + uiRadioButtonsSetSelected(rb, -1); +} + +uiBox *makePage4(void) +{ + uiBox *page4; + uiBox *hbox; + uiSpinbox *xsb; + uiButton *b; + uiSlider *xsl; + + page4 = newVerticalBox(); + + spinbox = uiNewSpinbox(0, 100); + uiSpinboxOnChanged(spinbox, onSpinboxChanged, NULL); + uiBoxAppend(page4, uiControl(spinbox), 0); + + slider = uiNewSlider(0, 100); + uiSliderOnChanged(slider, onSliderChanged, NULL); + uiBoxAppend(page4, uiControl(slider), 0); + + pbar = uiNewProgressBar(); + uiBoxAppend(page4, uiControl(pbar), 0); + + uiBoxAppend(page4, uiControl(uiNewHorizontalSeparator()), 0); + + hbox = newHorizontalBox(); + xsb = uiNewSpinbox(-40, 40); + uiBoxAppend(hbox, uiControl(xsb), 0); + b = uiNewButton("Bad Low"); + uiButtonOnClicked(b, setSpinboxTooLow, xsb); + uiBoxAppend(hbox, uiControl(b), 0); + b = uiNewButton("Bad High"); + uiButtonOnClicked(b, setSpinboxTooHigh, xsb); + uiBoxAppend(hbox, uiControl(b), 0); + uiBoxAppend(page4, uiControl(hbox), 0); + + hbox = newHorizontalBox(); + xsl = uiNewSlider(-40, 40); + uiBoxAppend(hbox, uiControl(xsl), 0); + b = uiNewButton("Bad Low"); + uiButtonOnClicked(b, setSliderTooLow, xsl); + uiBoxAppend(hbox, uiControl(b), 0); + b = uiNewButton("Bad High"); + uiButtonOnClicked(b, setSliderTooHigh, xsl); + uiBoxAppend(hbox, uiControl(b), 0); + uiBoxAppend(page4, uiControl(hbox), 0); + + uiBoxAppend(page4, uiControl(uiNewHorizontalSeparator()), 0); + + cbox = uiNewCombobox(); + uiComboboxAppend(cbox, "Item 1"); + uiComboboxAppend(cbox, "Item 2"); + uiComboboxAppend(cbox, "Item 3"); + uiComboboxOnSelected(cbox, onCBChanged, "noneditable"); + uiBoxAppend(page4, uiControl(cbox), 0); + + editable = uiNewEditableCombobox(); + uiEditableComboboxAppend(editable, "Editable Item 1"); + uiEditableComboboxAppend(editable, "Editable Item 2"); + uiEditableComboboxAppend(editable, "Editable Item 3"); + uiEditableComboboxOnChanged(editable, onECBChanged, "editable"); + uiBoxAppend(page4, uiControl(editable), 0); + + rb = uiNewRadioButtons(); + uiRadioButtonsAppend(rb, "Item 1"); + uiRadioButtonsAppend(rb, "Item 2"); + uiRadioButtonsAppend(rb, "Item 3"); + uiRadioButtonsOnSelected(rb, onRBSelected, NULL); + uiBoxAppend(page4, uiControl(rb), 0); + + hbox = newHorizontalBox(); + b = uiNewButton("Append"); + uiButtonOnClicked(b, appendCBRB, NULL); + uiBoxAppend(hbox, uiControl(b), 0); + b = uiNewButton("Second"); + uiButtonOnClicked(b, selectSecond, NULL); + uiBoxAppend(hbox, uiControl(b), 0); + b = uiNewButton("None"); + uiButtonOnClicked(b, selectNone, NULL); + uiBoxAppend(hbox, uiControl(b), 0); + uiBoxAppend(page4, uiControl(hbox), 0); + + uiBoxAppend(page4, uiControl(uiNewHorizontalSeparator()), 0); + + uiBoxAppend(page4, uiControl(uiNewDateTimePicker()), 0); + uiBoxAppend(page4, uiControl(uiNewDatePicker()), 0); + uiBoxAppend(page4, uiControl(uiNewTimePicker()), 0); + + return page4; +} diff --git a/src/libui_sdl/libui/test/page5.c b/src/libui_sdl/libui/test/page5.c new file mode 100644 index 0000000..9bc1105 --- /dev/null +++ b/src/libui_sdl/libui/test/page5.c @@ -0,0 +1,99 @@ +// 22 may 2015 +#include "test.h" + +static uiWindow *parent; + +static void openFile(uiButton *b, void *data) +{ + char *fn; + + fn = uiOpenFile(parent); + if (fn == NULL) + uiLabelSetText(uiLabel(data), "(cancelled)"); + else { + uiLabelSetText(uiLabel(data), fn); + uiFreeText(fn); + } +} + +static void saveFile(uiButton *b, void *data) +{ + char *fn; + + fn = uiSaveFile(parent); + if (fn == NULL) + uiLabelSetText(uiLabel(data), "(cancelled)"); + else { + uiLabelSetText(uiLabel(data), fn); + uiFreeText(fn); + } +} + +static uiEntry *title, *description; + +static void msgBox(uiButton *b, void *data) +{ + char *t, *d; + + t = uiEntryText(title); + d = uiEntryText(description); + uiMsgBox(parent, t, d); + uiFreeText(d); + uiFreeText(t); +} + +static void msgBoxError(uiButton *b, void *data) +{ + char *t, *d; + + t = uiEntryText(title); + d = uiEntryText(description); + uiMsgBoxError(parent, t, d); + uiFreeText(d); + uiFreeText(t); +} + +uiBox *makePage5(uiWindow *pw) +{ + uiBox *page5; + uiBox *hbox; + uiButton *button; + uiLabel *label; + + parent = pw; + + page5 = newVerticalBox(); + +#define D(n, f) \ + hbox = newHorizontalBox(); \ + button = uiNewButton(n); \ + label = uiNewLabel(""); \ + uiButtonOnClicked(button, f, label); \ + uiBoxAppend(hbox, uiControl(button), 0); \ + uiBoxAppend(hbox, uiControl(label), 0); \ + uiBoxAppend(page5, uiControl(hbox), 0); + + D("Open File", openFile); + D("Save File", saveFile); + + title = uiNewEntry(); + uiEntrySetText(title, "Title"); + description = uiNewEntry(); + uiEntrySetText(description, "Description"); + + hbox = newHorizontalBox(); + button = uiNewButton("Message Box"); + uiButtonOnClicked(button, msgBox, NULL); + uiBoxAppend(hbox, uiControl(button), 0); + uiBoxAppend(hbox, uiControl(title), 0); + uiBoxAppend(page5, uiControl(hbox), 0); + + hbox = newHorizontalBox(); + button = uiNewButton("Error Box"); + uiButtonOnClicked(button, msgBoxError, NULL); + uiBoxAppend(hbox, uiControl(button), 0); + uiBoxAppend(hbox, uiControl(description), 0); + uiBoxAppend(page5, uiControl(hbox), 0); + + return page5; +} diff --git a/src/libui_sdl/libui/test/page6.c b/src/libui_sdl/libui/test/page6.c new file mode 100644 index 0000000..896b3d5 --- /dev/null +++ b/src/libui_sdl/libui/test/page6.c @@ -0,0 +1,126 @@ +// 8 october 2015 +#include <inttypes.h> +#include "test.h" + +static uiArea *area; +static uiCombobox *which; +static uiCheckbox *swallowKeys; + +struct handler { + uiAreaHandler ah; +}; + +static struct handler handler; + +static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *p) +{ + runDrawTest(uiComboboxSelected(which), p); +} + +static void handlerMouseEvent(uiAreaHandler *a, uiArea *area, uiAreaMouseEvent *e) +{ + printf("mouse (%g,%g):(%g,%g) down:%d up:%d count:%d mods:%x held:0x%" PRIX64 "\n", + e->X, + e->Y, + e->AreaWidth, + e->AreaHeight, + (int) e->Down, + (int) e->Up, + (int) e->Count, + (uint32_t) e->Modifiers, + e->Held1To64); +} + +static void handlerMouseCrossed(uiAreaHandler *ah, uiArea *a, int left) +{ + printf("mouse crossed %d\n", left); +} + +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 uiCheckboxChecked(swallowKeys); +} + +static void shouldntHappen(uiCombobox *c, void *data) +{ + fprintf(stderr, "YOU SHOULD NOT SEE THIS. If you do, uiComboboxSetSelected() is triggering uiComboboxOnSelected(), which it should not.\n"); +} + +static void redraw(uiCombobox *c, void *data) +{ + uiAreaQueueRedrawAll(area); +} + +static void enableArea(uiButton *b, void *data) +{ + if (data != NULL) + uiControlEnable(uiControl(area)); + else + uiControlDisable(uiControl(area)); +} + +uiBox *makePage6(void) +{ + uiBox *page6; + uiBox *hbox; + uiButton *button; + + handler.ah.Draw = handlerDraw; + handler.ah.MouseEvent = handlerMouseEvent; + handler.ah.MouseCrossed = handlerMouseCrossed; + handler.ah.DragBroken = handlerDragBroken; + handler.ah.KeyEvent = handlerKeyEvent; + + page6 = newVerticalBox(); + + hbox = newHorizontalBox(); + uiBoxAppend(page6, uiControl(hbox), 0); + + which = uiNewCombobox(); + populateComboboxWithTests(which); + // this is to make sure that uiComboboxOnSelected() doesn't trigger with uiComboboxSetSelected() + uiComboboxOnSelected(which, shouldntHappen, NULL); + uiComboboxSetSelected(which, 0); + uiComboboxOnSelected(which, redraw, NULL); + uiBoxAppend(hbox, uiControl(which), 0); + + area = uiNewArea((uiAreaHandler *) (&handler)); + uiBoxAppend(page6, uiControl(area), 1); + + hbox = newHorizontalBox(); + uiBoxAppend(page6, uiControl(hbox), 0); + + swallowKeys = uiNewCheckbox("Consider key events handled"); + uiBoxAppend(hbox, uiControl(swallowKeys), 1); + + button = uiNewButton("Enable"); + uiButtonOnClicked(button, enableArea, button); + uiBoxAppend(hbox, uiControl(button), 0); + + button = uiNewButton("Disable"); + uiButtonOnClicked(button, enableArea, NULL); + uiBoxAppend(hbox, uiControl(button), 0); + + return page6; +} diff --git a/src/libui_sdl/libui/test/page7.c b/src/libui_sdl/libui/test/page7.c new file mode 100644 index 0000000..5cc9114 --- /dev/null +++ b/src/libui_sdl/libui/test/page7.c @@ -0,0 +1,25 @@ +// 13 october 2015 +#include "test.h" + +uiBox *makePage7(void) +{ + uiBox *page7; + uiGroup *group; + uiBox *box2; + + page7 = newHorizontalBox(); + + group = makePage7a(); + uiBoxAppend(page7, uiControl(group), 1); + + box2 = newVerticalBox(); + uiBoxAppend(page7, uiControl(box2), 1); + + group = makePage7b(); + uiBoxAppend(box2, uiControl(group), 1); + + group = makePage7c(); + uiBoxAppend(box2, uiControl(group), 1); + + return page7; +} diff --git a/src/libui_sdl/libui/test/page7a.c b/src/libui_sdl/libui/test/page7a.c new file mode 100644 index 0000000..72e0321 --- /dev/null +++ b/src/libui_sdl/libui/test/page7a.c @@ -0,0 +1,139 @@ +// 13 october 2015 +#include "test.h" + +static uiArea *area; +static uiEntry *startAngle; +static uiEntry *sweep; +static uiCheckbox *negative; +static uiCheckbox *radians; + +struct handler { + uiAreaHandler ah; +}; + +static struct handler handler; + +// based on the cairo arc sample +static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *p) +{ + double xc = 128.0; + double yc = 128.0; + double radius = 100.0; + uiDrawBrush source; + uiDrawStrokeParams sp; + uiDrawPath *path; + char *startText; + char *sweepText; + double factor; + + source.Type = uiDrawBrushTypeSolid; + source.R = 0; + source.G = 0; + source.B = 0; + source.A = 1; + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.MiterLimit = uiDrawDefaultMiterLimit; + sp.Dashes = NULL; + sp.NumDashes = 0; + sp.DashPhase = 0; + + startText = uiEntryText(startAngle); + sweepText = uiEntryText(sweep); + + factor = uiPi / 180; + if (uiCheckboxChecked(radians)) + factor = 1; + + sp.Thickness = 10.0; + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(path, xc, yc); + uiDrawPathArcTo(path, + xc, yc, + radius, + atof(startText) * factor, + atof(sweepText) * factor, + uiCheckboxChecked(negative)); + uiDrawPathEnd(path); + uiDrawStroke(p->Context, path, &source, &sp); + uiDrawFreePath(path); + + uiFreeText(startText); + uiFreeText(sweepText); +} + +static void handlerMouseEvent(uiAreaHandler *a, uiArea *area, uiAreaMouseEvent *e) +{ + // do nothing +} + +static void handlerMouseCrossed(uiAreaHandler *ah, uiArea *a, int left) +{ + // do nothing +} + +static void handlerDragBroken(uiAreaHandler *ah, uiArea *a) +{ + // do nothing +} + +static int handlerKeyEvent(uiAreaHandler *ah, uiArea *a, uiAreaKeyEvent *e) +{ + return 0; +} + +static void entryChanged(uiEntry *e, void *data) +{ + uiAreaQueueRedrawAll(area); +} + +static void checkboxToggled(uiCheckbox *c, void *data) +{ + uiAreaQueueRedrawAll(area); +} + +uiGroup *makePage7a(void) +{ + uiGroup *group; + uiBox *box, *box2; + + handler.ah.Draw = handlerDraw; + handler.ah.MouseEvent = handlerMouseEvent; + handler.ah.MouseCrossed = handlerMouseCrossed; + handler.ah.DragBroken = handlerDragBroken; + handler.ah.KeyEvent = handlerKeyEvent; + + group = newGroup("Arc Test"); + + box = newVerticalBox(); + uiGroupSetChild(group, uiControl(box)); + + area = uiNewArea((uiAreaHandler *) (&handler)); + uiBoxAppend(box, uiControl(area), 1); + + box2 = newHorizontalBox(); + uiBoxAppend(box, uiControl(box2), 0); + + uiBoxAppend(box2, uiControl(uiNewLabel("Start Angle")), 0); + startAngle = uiNewEntry(); + uiEntryOnChanged(startAngle, entryChanged, NULL); + uiBoxAppend(box2, uiControl(startAngle), 1); + + box2 = newHorizontalBox(); + uiBoxAppend(box, uiControl(box2), 0); + + uiBoxAppend(box2, uiControl(uiNewLabel("Sweep")), 0); + sweep = uiNewEntry(); + uiEntryOnChanged(sweep, entryChanged, NULL); + uiBoxAppend(box2, uiControl(sweep), 1); + + negative = uiNewCheckbox("Negative"); + uiCheckboxOnToggled(negative, checkboxToggled, NULL); + uiBoxAppend(box, uiControl(negative), 0); + + radians = uiNewCheckbox("Radians"); + uiCheckboxOnToggled(radians, checkboxToggled, NULL); + uiBoxAppend(box, uiControl(radians), 0); + + return group; +} diff --git a/src/libui_sdl/libui/test/page7b.c b/src/libui_sdl/libui/test/page7b.c new file mode 100644 index 0000000..d1f98a7 --- /dev/null +++ b/src/libui_sdl/libui/test/page7b.c @@ -0,0 +1,71 @@ +// 13 october 2015 +#include "test.h" + +static uiArea *area; +static uiCheckbox *label; + +struct handler { + uiAreaHandler ah; +}; + +static struct handler handler; + +static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *p) +{ + // do nothing +} + +static void handlerMouseEvent(uiAreaHandler *a, uiArea *area, uiAreaMouseEvent *e) +{ + char pos[128]; + + // wonderful, vanilla snprintf() isn't in visual studio 2013 - http://blogs.msdn.com/b/vcblog/archive/2013/07/19/c99-library-support-in-visual-studio-2013.aspx + // we can't use _snprintf() in the test suite because that's msvc-only, so oops. sprintf() it is. + sprintf(pos, "X %g Y %g", e->X, e->Y); + uiCheckboxSetText(label, pos); +} + +static void handlerMouseCrossed(uiAreaHandler *ah, uiArea *a, int left) +{ +printf("%d %d\n", left, !left); + uiCheckboxSetChecked(label, !left); +} + +static void handlerDragBroken(uiAreaHandler *ah, uiArea *a) +{ + // do nothing +} + +static int handlerKeyEvent(uiAreaHandler *ah, uiArea *a, uiAreaKeyEvent *e) +{ + if (e->Key == 'h' && !e->Up) { + // TODO hide the widget momentarily on the h key + return 1; + } + return 0; +} + +uiGroup *makePage7b(void) +{ + uiGroup *group; + uiBox *box; + + handler.ah.Draw = handlerDraw; + handler.ah.MouseEvent = handlerMouseEvent; + handler.ah.MouseCrossed = handlerMouseCrossed; + handler.ah.DragBroken = handlerDragBroken; + handler.ah.KeyEvent = handlerKeyEvent; + + group = newGroup("Scrolling Mouse Test"); + + box = newVerticalBox(); + uiGroupSetChild(group, uiControl(box)); + + area = uiNewScrollingArea((uiAreaHandler *) (&handler), 5000, 5000); + uiBoxAppend(box, uiControl(area), 1); + + label = uiNewCheckbox(""); + uiBoxAppend(box, uiControl(label), 0); + + return group; +} diff --git a/src/libui_sdl/libui/test/page7c.c b/src/libui_sdl/libui/test/page7c.c new file mode 100644 index 0000000..ac6a316 --- /dev/null +++ b/src/libui_sdl/libui/test/page7c.c @@ -0,0 +1,133 @@ +// 13 october 2015 +#include "test.h" + +static uiArea *area; + +struct handler { + uiAreaHandler ah; +}; + +static struct handler handler; + +#define areaSize 250 +#define borderThickness 1 +#define padding 30 +#define circleRadius ((areaSize - padding) / 2) + +static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *dp) +{ + uiDrawPath *path; + uiDrawBrush brush; + uiDrawStrokeParams sp; + uiDrawBrushGradientStop stops[2]; + + memset(&brush, 0, sizeof (uiDrawBrush)); + memset(&sp, 0, sizeof (uiDrawStrokeParams)); + + // add some buffering to detect scrolls that aren't on the dot and draws that are outside the scroll area on Windows + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(path, + -50, -50, + areaSize + 100, areaSize + 100); + uiDrawPathEnd(path); + brush.Type = uiDrawBrushTypeSolid; + brush.R = 0; + brush.G = 1; + brush.B = 0; + brush.A = 1; + uiDrawFill(dp->Context, path, &brush); + uiDrawFreePath(path); + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(path, + 0, 0, + areaSize, areaSize); + uiDrawPathEnd(path); + brush.Type = uiDrawBrushTypeSolid; + brush.R = 1; + brush.G = 1; + brush.B = 1; + brush.A = 1; + uiDrawFill(dp->Context, path, &brush); + brush.Type = uiDrawBrushTypeSolid; + brush.R = 1; + brush.G = 0; + brush.B = 0; + brush.A = 1; + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.Thickness = 1; + sp.MiterLimit = uiDrawDefaultMiterLimit; + uiDrawStroke(dp->Context, path, &brush, &sp); + uiDrawFreePath(path); + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigureWithArc(path, + areaSize / 2, areaSize / 2, + circleRadius, + 0, 2 * uiPi, + 0); + uiDrawPathEnd(path); + stops[0].Pos =0.0; + stops[0].R = 0.0; + stops[0].G = 1.0; + stops[0].B = 1.0; + stops[0].A = 1.0; + stops[1].Pos = 1.0; + stops[1].R = 0.0; + stops[1].G = 0.0; + stops[1].B = 1.0; + stops[1].A = 1.0; + brush.Type = uiDrawBrushTypeLinearGradient; + brush.X0 = areaSize / 2; + brush.Y0 = padding; + brush.X1 = areaSize / 2; + brush.Y1 = areaSize - padding; + brush.Stops = stops; + brush.NumStops = 2; + uiDrawFill(dp->Context, path, &brush); + uiDrawFreePath(path); +} + +static void handlerMouseEvent(uiAreaHandler *a, uiArea *area, uiAreaMouseEvent *e) +{ + // do nothing +} + +static void handlerMouseCrossed(uiAreaHandler *ah, uiArea *a, int left) +{ + // do nothing +} + +static void handlerDragBroken(uiAreaHandler *ah, uiArea *a) +{ + // do nothing +} + +static int handlerKeyEvent(uiAreaHandler *ah, uiArea *a, uiAreaKeyEvent *e) +{ + if (e->Key == 'h' && !e->Up) { + // TODO hide the widget momentarily on the h key + return 1; + } + return 0; +} + +uiGroup *makePage7c(void) +{ + uiGroup *group; + + handler.ah.Draw = handlerDraw; + handler.ah.MouseEvent = handlerMouseEvent; + handler.ah.MouseCrossed = handlerMouseCrossed; + handler.ah.DragBroken = handlerDragBroken; + handler.ah.KeyEvent = handlerKeyEvent; + + group = newGroup("Scrolling Drawing Test"); + + area = uiNewScrollingArea((uiAreaHandler *) (&handler), + areaSize, areaSize); + uiGroupSetChild(group, uiControl(area)); + + return group; +} diff --git a/src/libui_sdl/libui/test/page8.c b/src/libui_sdl/libui/test/page8.c new file mode 100644 index 0000000..7d85556 --- /dev/null +++ b/src/libui_sdl/libui/test/page8.c @@ -0,0 +1,46 @@ +// 22 december 2015 +#include "test.h" + +static void onListFonts(uiButton *b, void *data) +{ + uiDrawFontFamilies *ff; + char *this; + int i, n; + + uiMultilineEntrySetText(uiMultilineEntry(data), ""); + ff = uiDrawListFontFamilies(); + n = uiDrawFontFamiliesNumFamilies(ff); + for (i = 0; i < n; i++) { + this = uiDrawFontFamiliesFamily(ff, i); + uiMultilineEntryAppend(uiMultilineEntry(data), this); + uiMultilineEntryAppend(uiMultilineEntry(data), "\n"); + uiFreeText(this); + } + uiDrawFreeFontFamilies(ff); +} + +uiBox *makePage8(void) +{ + uiBox *page8; + uiGroup *group; + uiBox *vbox; + uiMultilineEntry *me; + uiButton *button; + + page8 = newHorizontalBox(); + + group = newGroup("Font Families"); + uiBoxAppend(page8, uiControl(group), 1); + + vbox = newVerticalBox(); + uiGroupSetChild(group, uiControl(vbox)); + + me = uiNewMultilineEntry(); + uiBoxAppend(vbox, uiControl(me), 1); + + button = uiNewButton("List Font Families"); + uiButtonOnClicked(button, onListFonts, me); + uiBoxAppend(vbox, uiControl(button), 0); + + return page8; +} diff --git a/src/libui_sdl/libui/test/page9.c b/src/libui_sdl/libui/test/page9.c new file mode 100644 index 0000000..65b2d3a --- /dev/null +++ b/src/libui_sdl/libui/test/page9.c @@ -0,0 +1,289 @@ +// 22 december 2015 +#include "test.h" + +static uiEntry *textString; +static uiEntry *textFont; +static uiEntry *textSize; +static uiCombobox *textWeight; +static uiCombobox *textItalic; +static uiCheckbox *textSmallCaps; +static uiCombobox *textStretch; +static uiEntry *textWidth; +static uiButton *textApply; +static uiCheckbox *addLeading; +static uiArea *textArea; +static uiAreaHandler textAreaHandler; + +static double entryDouble(uiEntry *e) +{ + char *s; + double d; + + s = uiEntryText(e); + d = atof(s); + uiFreeText(s); + return d; +} + +static void drawGuides(uiDrawContext *c, uiDrawTextFontMetrics *m) +{ + uiDrawPath *p; + uiDrawBrush b; + uiDrawStrokeParams sp; + double leading; + double y; + + leading = 0; + if (uiCheckboxChecked(addLeading)) + leading = m->Leading; + + memset(&b, 0, sizeof (uiDrawBrush)); + b.Type = uiDrawBrushTypeSolid; + memset(&sp, 0, sizeof (uiDrawStrokeParams)); + sp.Cap = uiDrawLineCapFlat; + sp.Join = uiDrawLineJoinMiter; + sp.MiterLimit = uiDrawDefaultMiterLimit; + sp.Thickness = 2; + + uiDrawSave(c); + + p = uiDrawNewPath(uiDrawFillModeWinding); + y = 10; + uiDrawPathNewFigure(p, 8, y); + y += m->Ascent; + uiDrawPathLineTo(p, 8, y); + uiDrawPathEnd(p); + b.R = 0.94; + b.G = 0.5; + b.B = 0.5; + b.A = 1.0; + uiDrawStroke(c, p, &b, &sp); + uiDrawFreePath(p); + + p = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(p, 8, y); + y += m->Descent; + uiDrawPathLineTo(p, 8, y); + uiDrawPathEnd(p); + b.R = 0.12; + b.G = 0.56; + b.B = 1.0; + b.A = 1.0; + uiDrawStroke(c, p, &b, &sp); + uiDrawFreePath(p); + + // and again for the second line + p = uiDrawNewPath(uiDrawFillModeWinding); + y += leading; + uiDrawPathNewFigure(p, 8, y); + y += m->Ascent; + uiDrawPathLineTo(p, 8, y); + uiDrawPathEnd(p); + b.R = 0.94; + b.G = 0.5; + b.B = 0.5; + b.A = 0.75; + uiDrawStroke(c, p, &b, &sp); + uiDrawFreePath(p); + + p = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(p, 8, y); + y += m->Descent; + uiDrawPathLineTo(p, 8, y); + uiDrawPathEnd(p); + b.R = 0.12; + b.G = 0.56; + b.B = 1.0; + b.A = 0.75; + uiDrawStroke(c, p, &b, &sp); + uiDrawFreePath(p); + + // and a box to text layout top-left corners + p = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(p, 0, 0, 10, 10); + uiDrawPathEnd(p); + uiDrawClip(c, p); + b.R = 0.85; + b.G = 0.65; + b.B = 0.13; + b.A = 1.0; + uiDrawStroke(c, p, &b, &sp); + uiDrawFreePath(p); + + uiDrawRestore(c); +} + +static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *dp) +{ + uiDrawTextFontDescriptor desc; + uiDrawTextFont *font; + char *s; + char *family; // make compiler happy + uiDrawTextLayout *layout; + uiDrawTextFontMetrics metrics; + double ypos; + double width; + double height; + + memset(&desc, 0, sizeof (uiDrawTextFontDescriptor)); + family = uiEntryText(textFont); + desc.Family = family; + desc.Size = entryDouble(textSize); + desc.Weight = uiComboboxSelected(textWeight); + desc.Italic = uiComboboxSelected(textItalic); + desc.Stretch = uiComboboxSelected(textStretch); + font = uiDrawLoadClosestFont(&desc); + uiFreeText(family); + uiDrawTextFontGetMetrics(font, &metrics); + + width = entryDouble(textWidth); + + drawGuides(dp->Context, &metrics); + + s = uiEntryText(textString); + layout = uiDrawNewTextLayout(s, font, width); + uiFreeText(s); + if (uiCheckboxChecked(textSmallCaps)) + ; // TODO + ypos = 10; + uiDrawText(dp->Context, 10, ypos, layout); + // TODO make these optional? + uiDrawTextLayoutExtents(layout, &width, &height); + uiDrawFreeTextLayout(layout); + + layout = uiDrawNewTextLayout("This is a second line", font, -1); + if (/*TODO reuse width*/entryDouble(textWidth) < 0) { + double ad; + + ad = metrics.Ascent + metrics.Descent; + printf("ad:%g extent:%g\n", ad, height); + } + ypos += height; + if (uiCheckboxChecked(addLeading)) + ypos += metrics.Leading; + uiDrawText(dp->Context, 10, ypos, layout); + uiDrawFreeTextLayout(layout); + + uiDrawFreeTextFont(font); +} + +static void handlerMouseEvent(uiAreaHandler *a, uiArea *area, uiAreaMouseEvent *e) +{ + // do nothing +} + +static void handlerMouseCrossed(uiAreaHandler *ah, uiArea *a, int left) +{ + // do nothing +} + +static void handlerDragBroken(uiAreaHandler *ah, uiArea *a) +{ + // do nothing +} + +static int handlerKeyEvent(uiAreaHandler *ah, uiArea *a, uiAreaKeyEvent *e) +{ + // do nothing + return 0; +} + +static void onTextApply(uiButton *b, void *data) +{ + uiAreaQueueRedrawAll(textArea); +} + +uiBox *makePage9(void) +{ + uiBox *page9; + uiBox *vbox; + uiBox *hbox; + + page9 = newVerticalBox(); + vbox = page9; + + hbox = newHorizontalBox(); + uiBoxAppend(vbox, uiControl(hbox), 0); + + textString = uiNewEntry(); + // TODO make it placeholder + uiEntrySetText(textString, "Enter text here"); + uiBoxAppend(hbox, uiControl(textString), 1); + + textFont = uiNewEntry(); + uiEntrySetText(textFont, "Arial"); + uiBoxAppend(hbox, uiControl(textFont), 1); + + textSize = uiNewEntry(); + uiEntrySetText(textSize, "10"); + uiBoxAppend(hbox, uiControl(textSize), 1); + + hbox = newHorizontalBox(); + uiBoxAppend(vbox, uiControl(hbox), 0); + + textWeight = uiNewCombobox(); + uiComboboxAppend(textWeight, "Thin"); + uiComboboxAppend(textWeight, "Ultra Light"); + uiComboboxAppend(textWeight, "Light"); + uiComboboxAppend(textWeight, "Book"); + uiComboboxAppend(textWeight, "Normal"); + uiComboboxAppend(textWeight, "Medium"); + uiComboboxAppend(textWeight, "Semi Bold"); + uiComboboxAppend(textWeight, "Bold"); + uiComboboxAppend(textWeight, "Ultra Bold"); + uiComboboxAppend(textWeight, "Heavy"); + uiComboboxAppend(textWeight, "Ultra Heavy"); + uiComboboxSetSelected(textWeight, uiDrawTextWeightNormal); + uiBoxAppend(hbox, uiControl(textWeight), 1); + + textItalic = uiNewCombobox(); + uiComboboxAppend(textItalic, "Normal"); + uiComboboxAppend(textItalic, "Oblique"); + uiComboboxAppend(textItalic, "Italic"); + uiComboboxSetSelected(textItalic, uiDrawTextItalicNormal); + uiBoxAppend(hbox, uiControl(textItalic), 1); + + textSmallCaps = uiNewCheckbox("Small Caps"); + uiBoxAppend(hbox, uiControl(textSmallCaps), 1); + + hbox = newHorizontalBox(); + uiBoxAppend(vbox, uiControl(hbox), 0); + + textStretch = uiNewCombobox(); + uiComboboxAppend(textStretch, "Ultra Condensed"); + uiComboboxAppend(textStretch, "Extra Condensed"); + uiComboboxAppend(textStretch, "Condensed"); + uiComboboxAppend(textStretch, "Semi Condensed"); + uiComboboxAppend(textStretch, "Normal"); + uiComboboxAppend(textStretch, "Semi Expanded"); + uiComboboxAppend(textStretch, "Expanded"); + uiComboboxAppend(textStretch, "Extra Expanded"); + uiComboboxAppend(textStretch, "Ultra Expanded"); + uiComboboxSetSelected(textStretch, uiDrawTextStretchNormal); + uiBoxAppend(hbox, uiControl(textStretch), 1); + + textWidth = uiNewEntry(); + uiEntrySetText(textWidth, "-1"); + uiBoxAppend(hbox, uiControl(textWidth), 1); + + hbox = newHorizontalBox(); + uiBoxAppend(vbox, uiControl(hbox), 0); + + textApply = uiNewButton("Apply"); + uiButtonOnClicked(textApply, onTextApply, NULL); + uiBoxAppend(hbox, uiControl(textApply), 1); + + addLeading = uiNewCheckbox("Add Leading"); + uiCheckboxSetChecked(addLeading, 1); + uiBoxAppend(hbox, uiControl(addLeading), 0); + + textAreaHandler.Draw = handlerDraw; + textAreaHandler.MouseEvent = handlerMouseEvent; + textAreaHandler.MouseCrossed = handlerMouseCrossed; + textAreaHandler.DragBroken = handlerDragBroken; + textAreaHandler.KeyEvent = handlerKeyEvent; + textArea = uiNewArea(&textAreaHandler); + uiBoxAppend(vbox, uiControl(textArea), 1); + + return page9; +} diff --git a/src/libui_sdl/libui/test/resources.rc b/src/libui_sdl/libui/test/resources.rc new file mode 100644 index 0000000..ebc5d6e --- /dev/null +++ b/src/libui_sdl/libui/test/resources.rc @@ -0,0 +1,13 @@ +// 30 may 2015 + +// this is a UTF-8 file +#pragma code_page(65001) + +// this is the Common Controls 6 manifest +// TODO set up the string values here +// 1 is the value of CREATEPROCESS_MANIFEST_RESOURCE_ID and 24 is the value of RT_MANIFEST; we use it directly to avoid needing to share winapi.h with the tests and examples +#ifndef _UI_STATIC +1 24 "test.manifest" +#else +1 24 "test.static.manifest" +#endif diff --git a/src/libui_sdl/libui/test/spaced.c b/src/libui_sdl/libui/test/spaced.c new file mode 100644 index 0000000..02db99a --- /dev/null +++ b/src/libui_sdl/libui/test/spaced.c @@ -0,0 +1,177 @@ +// 22 april 2015 +#include "test.h" + +struct thing { + void *ptr; + int type; +}; + +static struct thing *things = NULL; +static size_t len = 0; +static size_t cap = 0; + +#define grow 32 + +static void *append(void *thing, int type) +{ + if (len >= cap) { + cap += grow; + things = (struct thing *) realloc(things, cap * sizeof (struct thing)); + if (things == NULL) + die("reallocating things array in test/spaced.c append()"); + } + things[len].ptr = thing; + things[len].type = type; + len++; + return things[len - 1].ptr; +} + +enum types { + window, + box, + tab, + group, + form, + grid, +}; + +void setSpaced(int spaced) +{ + size_t i; + void *p; + size_t j, n; + + for (i = 0; i < len; i++) { + p = things[i].ptr; + switch (things[i].type) { + case window: + uiWindowSetMargined(uiWindow(p), spaced); + break; + case box: + uiBoxSetPadded(uiBox(p), spaced); + break; + case tab: + n = uiTabNumPages(uiTab(p)); + for (j = 0; j < n; j++) + uiTabSetMargined(uiTab(p), j, spaced); + break; + case group: + uiGroupSetMargined(uiGroup(p), spaced); + break; + case form: + uiFormSetPadded(uiForm(p), spaced); + break; + case grid: + uiGridSetPadded(uiGrid(p), spaced); + break; + } + } +} + +void querySpaced(char out[12]) // more than enough +{ + int m = 0; + int p = 0; + size_t i; + void *pp; + size_t j, n; + + for (i = 0; i < len; i++) { + pp = things[i].ptr; + switch (things[i].type) { + case window: + if (uiWindowMargined(uiWindow(pp))) + m++; + break; + case box: + p = uiBoxPadded(uiBox(pp)); + break; + case tab: + n = uiTabNumPages(uiTab(pp)); + for (j = 0; j < n; j++) + if (uiTabMargined(uiTab(pp), j)) + m++; + break; + case group: + if (uiGroupMargined(uiGroup(pp))) + m++; + break; + // TODO form + // TODO grid + } + } + + out[0] = 'm'; + out[1] = ' '; + out[2] = '0' + m; + out[3] = ' '; + out[4] = 'p'; + out[5] = ' '; + out[6] = '0'; + if (p) + out[6] = '1'; + out[7] = '\0'; +} + +uiWindow *newWindow(const char *title, int width, int height, int hasMenubar) +{ + uiWindow *w; + + w = uiNewWindow(title, width, height, hasMenubar); + append(w, window); + return w; +} + +uiBox *newHorizontalBox(void) +{ + uiBox *b; + + b = (*newhbox)(); + append(b, box); + return b; +} + +uiBox *newVerticalBox(void) +{ + uiBox *b; + + b = (*newvbox)(); + append(b, box); + return b; +} + +uiTab *newTab(void) +{ + uiTab *t; + + t = uiNewTab(); + append(t, tab); + return t; +} + +uiGroup *newGroup(const char *text) +{ + uiGroup *g; + + g = uiNewGroup(text); + append(g, group); + return g; +} + +uiForm *newForm(void) +{ + uiForm *f; + + f = uiNewForm(); + append(f, form); + return f; +} + +uiGrid *newGrid(void) +{ + uiGrid *g; + + g = uiNewGrid(); + append(g, grid); + return g; +} diff --git a/src/libui_sdl/libui/test/test.h b/src/libui_sdl/libui/test/test.h new file mode 100644 index 0000000..66b1baa --- /dev/null +++ b/src/libui_sdl/libui/test/test.h @@ -0,0 +1,91 @@ +// 22 april 2015 +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <stdarg.h> +#include <string.h> +#include <math.h> +#include <limits.h> +#include "../ui.h" + +// main.c +extern void die(const char *, ...); +extern uiBox *mainBox; +extern uiTab *mainTab; +extern uiBox *(*newhbox)(void); +extern uiBox *(*newvbox)(void); + +// spaced.c +extern void setSpaced(int); +extern void querySpaced(char[12]); +extern uiWindow *newWindow(const char *title, int width, int height, int hasMenubar); +extern uiBox *newHorizontalBox(void); +extern uiBox *newVerticalBox(void); +extern uiTab *newTab(void); +extern uiGroup *newGroup(const char *); +extern uiForm *newForm(void); +extern uiGrid *newGrid(void); + +// menus.c +extern uiMenuItem *shouldQuitItem; +extern void initMenus(void); + +// page1.c +extern uiBox *page1; +extern void makePage1(uiWindow *); + +// page2.c +extern uiGroup *page2group; +extern uiBox *makePage2(void); + +// page3.c +extern uiBox *makePage3(void); + +// page4.c +extern uiBox *makePage4(void); + +// page5.c +extern uiBox *makePage5(uiWindow *); + +// page6.c +extern uiBox *makePage6(void); + +// drawtests.c +extern void runDrawTest(int, uiAreaDrawParams *); +extern void populateComboboxWithTests(uiCombobox *); + +// page7.c +extern uiBox *makePage7(void); + +// page7a.c +extern uiGroup *makePage7a(void); + +// page7b.c +extern uiGroup *makePage7b(void); + +// page7c.c +extern uiGroup *makePage7c(void); + +// page8.c +extern uiBox *makePage8(void); + +// page9.c +extern uiBox *makePage9(void); + +// page10.c +extern uiBox *makePage10(void); + +// page11.c +extern uiBox *makePage11(void); + +// page12.c +extern uiBox *makePage12(void); + +// page13.c +extern uiBox *makePage13(void); + +// page14.c +extern uiTab *makePage14(void); + +// page15.c +extern uiBox *makePage15(uiWindow *); diff --git a/src/libui_sdl/libui/test/test.manifest b/src/libui_sdl/libui/test/test.manifest new file mode 100644 index 0000000..41e7c9c --- /dev/null +++ b/src/libui_sdl/libui/test/test.manifest @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> +<assemblyIdentity + version="1.0.0.0" + processorArchitecture="*" + name="CompanyName.ProductName.YourApplication" + type="win32" +/> +<description>Your application description here.</description> +<!-- do NOT include the comctl6 dependency here; this lets us find bugs related to theming --> +<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> + <application> + <!--The ID below indicates application support for Windows Vista --> + <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> + <!--The ID below indicates application support for Windows 7 --> + <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> + </application> +</compatibility> +</assembly> + diff --git a/src/libui_sdl/libui/test/test.static.manifest b/src/libui_sdl/libui/test/test.static.manifest new file mode 100644 index 0000000..d8e83a8 --- /dev/null +++ b/src/libui_sdl/libui/test/test.static.manifest @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> +<assemblyIdentity + version="1.0.0.0" + processorArchitecture="*" + name="CompanyName.ProductName.YourApplication" + type="win32" +/> +<description>Your application description here.</description> +<!-- we DO need comctl6 in the static case --> +<dependency> + <dependentAssembly> + <assemblyIdentity + type="win32" + name="Microsoft.Windows.Common-Controls" + version="6.0.0.0" + processorArchitecture="*" + publicKeyToken="6595b64144ccf1df" + language="*" + /> + </dependentAssembly> +</dependency> +<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> + <application> + <!--The ID below indicates application support for Windows Vista --> + <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> + <!--The ID below indicates application support for Windows 7 --> + <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> + </application> +</compatibility> +</assembly> + |