Removed the NSScrollView-based uIArea on OS X. We'll stick with our custom one.
This commit is contained in:
parent
848eff27e7
commit
d570440a9b
|
@ -1,12 +0,0 @@
|
||||||
// 8 september 2015
|
|
||||||
#import <Cocoa/Cocoa.h>
|
|
||||||
#import <stdint.h>
|
|
||||||
#import "ui.h"
|
|
||||||
|
|
||||||
extern uiArea *newArea(uiAreaHandler *ah);
|
|
||||||
|
|
||||||
extern uiDrawContext *newContext(CGContextRef);
|
|
||||||
|
|
||||||
extern NSView *areaView(uiArea *);
|
|
||||||
|
|
||||||
extern void areaUpdateScroll(uiArea *);
|
|
127
macarea/area.m
127
macarea/area.m
|
@ -1,127 +0,0 @@
|
||||||
// 9 september 2015
|
|
||||||
#include "area.h"
|
|
||||||
|
|
||||||
// model:
|
|
||||||
// - drawing and events happen to the NSClipView
|
|
||||||
// - the document view is only used for scroll extents
|
|
||||||
|
|
||||||
@interface areaClipView : NSClipView {
|
|
||||||
uiArea *libui_a;
|
|
||||||
uiAreaHandler *libui_ah;
|
|
||||||
}
|
|
||||||
- (id)initWithFrame:(NSRect)r area:(uiArea *)a areaHandler:(uiAreaHandler *)ah;
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface areaDocumentView : NSView
|
|
||||||
@end
|
|
||||||
|
|
||||||
struct uiArea {
|
|
||||||
// uiDarwinControl c;
|
|
||||||
NSScrollView *view;
|
|
||||||
areaClipView *clipView;
|
|
||||||
areaDocumentView *documentView;
|
|
||||||
uiAreaHandler *ah;
|
|
||||||
};
|
|
||||||
|
|
||||||
@implementation areaClipView
|
|
||||||
|
|
||||||
- (id)initWithFrame:(NSRect)r area:(uiArea *)a areaHandler:(uiAreaHandler *)ah
|
|
||||||
{
|
|
||||||
self = [super initWithFrame:r];
|
|
||||||
if (self) {
|
|
||||||
self->libui_a = a;
|
|
||||||
self->libui_ah = ah;
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)drawRect:(NSRect)r
|
|
||||||
{
|
|
||||||
CGContextRef c;
|
|
||||||
uiAreaDrawParams dp;
|
|
||||||
|
|
||||||
[super drawRect:r];
|
|
||||||
|
|
||||||
c = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
|
|
||||||
dp.Context = newContext(c);
|
|
||||||
|
|
||||||
dp.ClientWidth = [self frame].size.width;
|
|
||||||
dp.ClientHeight = [self frame].size.height;
|
|
||||||
|
|
||||||
dp.ClipX = r.origin.x;
|
|
||||||
dp.ClipY = r.origin.y;
|
|
||||||
dp.ClipWidth = r.size.width;
|
|
||||||
dp.ClipHeight = r.size.height;
|
|
||||||
|
|
||||||
// TODO DPI
|
|
||||||
|
|
||||||
// TODO scroll position
|
|
||||||
|
|
||||||
(*(self->libui_ah->Draw))(self->libui_ah, self->libui_a, &dp);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)isFlipped
|
|
||||||
{
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
// see http://stackoverflow.com/questions/11318987/black-background-when-overriding-drawrect-in-uiscrollview (for iOS but same idea)
|
|
||||||
// TODO there has to be a better way to set this; how does OS X do it for its default clip view?
|
|
||||||
/*- (BOOL)isOpaque
|
|
||||||
{
|
|
||||||
return NO;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation areaDocumentView
|
|
||||||
|
|
||||||
- (BOOL)isFlipped
|
|
||||||
{
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
uiArea *newArea(uiAreaHandler *ah)
|
|
||||||
{
|
|
||||||
uiArea *a;
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
a = (uiArea *) malloc(sizeof (uiArea));
|
|
||||||
|
|
||||||
a->ah = ah;
|
|
||||||
|
|
||||||
a->view = [[NSScrollView alloc] initWithFrame:NSZeroRect];
|
|
||||||
a->clipView = [[areaClipView alloc] initWithFrame:NSZeroRect area:a areaHandler:ah];
|
|
||||||
a->documentView = [[areaDocumentView alloc] initWithFrame:NSZeroRect];
|
|
||||||
|
|
||||||
[a->view setContentView:a->clipView];
|
|
||||||
[a->view setDocumentView:a->documentView];
|
|
||||||
|
|
||||||
// TODO set up scroll view
|
|
||||||
// for some reason, without this line, NSLayoutConstraints complains about internal limits being exceeded
|
|
||||||
[a->view setDrawsBackground:YES];
|
|
||||||
//TODO [a->view setBackgroundColor:[NSColor controlColor]];
|
|
||||||
|
|
||||||
// set initial state
|
|
||||||
// TODO do this on other platforms?
|
|
||||||
areaUpdateScroll(a);
|
|
||||||
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSView *areaView(uiArea *a)
|
|
||||||
{
|
|
||||||
return a->view;
|
|
||||||
}
|
|
||||||
|
|
||||||
void areaUpdateScroll(uiArea *a)
|
|
||||||
{
|
|
||||||
NSRect frame;
|
|
||||||
|
|
||||||
frame.origin = NSMakePoint(0, 0);
|
|
||||||
frame.size.width = (*(a->ah->HScrollMax))(a->ah, a);
|
|
||||||
frame.size.height = (*(a->ah->VScrollMax))(a->ah, a);
|
|
||||||
[a->documentView setFrame:frame];
|
|
||||||
}
|
|
148
macarea/draw.m
148
macarea/draw.m
|
@ -1,148 +0,0 @@
|
||||||
// 6 september 2015
|
|
||||||
#include "area.h"
|
|
||||||
|
|
||||||
// TODO some pixel thick lines aren't actually pixel thick
|
|
||||||
|
|
||||||
struct uiDrawContext {
|
|
||||||
CGContextRef c;
|
|
||||||
|
|
||||||
BOOL useRGBA;
|
|
||||||
CGFloat r;
|
|
||||||
CGFloat g;
|
|
||||||
CGFloat b;
|
|
||||||
CGFloat a;
|
|
||||||
};
|
|
||||||
|
|
||||||
uiDrawContext *newContext(CGContextRef ctxt)
|
|
||||||
{
|
|
||||||
uiDrawContext *c;
|
|
||||||
|
|
||||||
// TODO use uiNew
|
|
||||||
c = (uiDrawContext *) malloc(sizeof (uiDrawContext));
|
|
||||||
c->c = ctxt;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawBeginPathRGB(uiDrawContext *c, uint8_t r, uint8_t g, uint8_t b)
|
|
||||||
{
|
|
||||||
c->useRGBA = YES;
|
|
||||||
c->r = ((CGFloat) r) / 255;
|
|
||||||
c->g = ((CGFloat) g) / 255;
|
|
||||||
c->b = ((CGFloat) b) / 255;
|
|
||||||
c->a = 1.0;
|
|
||||||
CGContextBeginPath(c->c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawBeginPathRGBA(uiDrawContext *c, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
|
||||||
{
|
|
||||||
c->useRGBA = YES;
|
|
||||||
c->r = ((CGFloat) r) / 255;
|
|
||||||
c->g = ((CGFloat) g) / 255;
|
|
||||||
c->b = ((CGFloat) b) / 255;
|
|
||||||
c->a = ((CGFloat) a) / 255;
|
|
||||||
CGContextBeginPath(c->c);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO 0.25 for retina? some say yes, some say no
|
|
||||||
// TODO same adjustment for cairo
|
|
||||||
#define topoint(x) (((CGFloat) x) + 0.5)
|
|
||||||
|
|
||||||
void uiDrawMoveTo(uiDrawContext *c, intmax_t x, intmax_t y)
|
|
||||||
{
|
|
||||||
CGContextMoveToPoint(c->c, topoint(x), topoint(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawLineTo(uiDrawContext *c, intmax_t x, intmax_t y)
|
|
||||||
{
|
|
||||||
CGContextAddLineToPoint(c->c, topoint(x), topoint(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO width-1/height-1? (also for cairo)
|
|
||||||
void uiDrawRectangle(uiDrawContext *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height)
|
|
||||||
{
|
|
||||||
CGContextAddRect(c->c, CGRectMake(topoint(x), topoint(y), width, height));
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawArcTo(uiDrawContext *c, intmax_t xCenter, intmax_t yCenter, intmax_t radius, double startAngle, double endAngle, int lineFromCurrentPointToStart)
|
|
||||||
{
|
|
||||||
if (!lineFromCurrentPointToStart) {
|
|
||||||
// see http://stackoverflow.com/questions/31489157/extra-line-when-drawing-an-arc-in-swift
|
|
||||||
// TODO verify correctness
|
|
||||||
CGFloat x, y;
|
|
||||||
|
|
||||||
x = topoint(xCenter);
|
|
||||||
y = topoint(yCenter);
|
|
||||||
x += radius * cos(startAngle);
|
|
||||||
y -= radius * sin(startAngle);
|
|
||||||
CGContextMoveToPoint(c->c, x, y);
|
|
||||||
}
|
|
||||||
CGContextAddArc(c->c,
|
|
||||||
topoint(xCenter), topoint(yCenter),
|
|
||||||
radius,
|
|
||||||
startAngle, endAngle,
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawBezierTo(uiDrawContext *c, intmax_t c1x, intmax_t c1y, intmax_t c2x, intmax_t c2y, intmax_t endX, intmax_t endY)
|
|
||||||
{
|
|
||||||
CGContextAddCurveToPoint(c->c,
|
|
||||||
topoint(c1x), topoint(c1y),
|
|
||||||
topoint(c2x), topoint(c2y),
|
|
||||||
topoint(endX), topoint(endY));
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawCloseFigure(uiDrawContext *c)
|
|
||||||
{
|
|
||||||
CGContextClosePath(c->c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawStroke(uiDrawContext *c, uiDrawStrokeParams *p)
|
|
||||||
{
|
|
||||||
switch (p->Cap) {
|
|
||||||
case uiDrawLineCapFlat:
|
|
||||||
CGContextSetLineCap(c->c, kCGLineCapButt);
|
|
||||||
break;
|
|
||||||
case uiDrawLineCapRound:
|
|
||||||
CGContextSetLineCap(c->c, kCGLineCapRound);
|
|
||||||
break;
|
|
||||||
case uiDrawLineCapSquare:
|
|
||||||
CGContextSetLineCap(c->c, kCGLineCapSquare);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
switch (p->Join) {
|
|
||||||
case uiDrawLineJoinMiter:
|
|
||||||
CGContextSetLineJoin(c->c, kCGLineJoinMiter);
|
|
||||||
CGContextSetMiterLimit(c->c, p->MiterLimit);
|
|
||||||
break;
|
|
||||||
case uiDrawLineJoinRound:
|
|
||||||
CGContextSetLineJoin(c->c, kCGLineJoinRound);
|
|
||||||
break;
|
|
||||||
case uiDrawLineJoinBevel:
|
|
||||||
CGContextSetLineJoin(c->c, kCGLineJoinBevel);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
CGContextSetLineWidth(c->c, p->Thickness);
|
|
||||||
if (c->useRGBA)
|
|
||||||
CGContextSetRGBStrokeColor(c->c, c->r, c->g, c->b, c->a);
|
|
||||||
else {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
CGContextStrokePath(c->c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiDrawFill(uiDrawContext *c, uiDrawFillMode mode)
|
|
||||||
{
|
|
||||||
if (c->useRGBA)
|
|
||||||
CGContextSetRGBFillColor(c->c, c->r, c->g, c->b, c->a);
|
|
||||||
else {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
switch (mode) {
|
|
||||||
case uiDrawFillModeWinding:
|
|
||||||
CGContextFillPath(c->c);
|
|
||||||
break;
|
|
||||||
case uiDrawFillModeAlternate:
|
|
||||||
CGContextEOFillPath(c->c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
177
macarea/main.m
177
macarea/main.m
|
@ -1,177 +0,0 @@
|
||||||
// 4 september 2015
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include "area.h"
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
// #qo LDFLAGS: -framework Foundation -framework AppKit -framework CoreGraphics
|
|
||||||
|
|
||||||
struct handler {
|
|
||||||
uiAreaHandler ah;
|
|
||||||
};
|
|
||||||
|
|
||||||
static uiArea *area;
|
|
||||||
static struct handler h;
|
|
||||||
//static NSTextField *nhspinb;
|
|
||||||
//static NSTextField *nvspinb;
|
|
||||||
|
|
||||||
static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *p)
|
|
||||||
{
|
|
||||||
uiDrawStrokeParams sp;
|
|
||||||
|
|
||||||
uiDrawBeginPathRGB(p->Context, 0xFF, 0x00, 0x00);
|
|
||||||
uiDrawMoveTo(p->Context, p->ClipX + 5, p->ClipY + 5);
|
|
||||||
uiDrawLineTo(p->Context, (p->ClipX + p->ClipWidth) - 5, (p->ClipY + p->ClipHeight) - 5);
|
|
||||||
sp.Cap = uiDrawLineCapFlat;
|
|
||||||
sp.Join = uiDrawLineJoinMiter;
|
|
||||||
sp.Thickness = 1;
|
|
||||||
sp.MiterLimit = uiDrawDefaultMiterLimit;
|
|
||||||
uiDrawStroke(p->Context, &sp);
|
|
||||||
|
|
||||||
uiDrawBeginPathRGB(p->Context, 0x00, 0x00, 0xC0);
|
|
||||||
uiDrawMoveTo(p->Context, p->ClipX, p->ClipY);
|
|
||||||
uiDrawLineTo(p->Context, p->ClipX + p->ClipWidth, p->ClipY);
|
|
||||||
uiDrawLineTo(p->Context, 50, 150);
|
|
||||||
uiDrawLineTo(p->Context, 50, 50);
|
|
||||||
uiDrawCloseFigure(p->Context);
|
|
||||||
sp.Cap = uiDrawLineCapFlat;
|
|
||||||
sp.Join = uiDrawLineJoinRound;
|
|
||||||
sp.Thickness = 5;
|
|
||||||
uiDrawStroke(p->Context, &sp);
|
|
||||||
|
|
||||||
uiDrawBeginPathRGBA(p->Context, 0x00, 0xC0, 0x00, 0x80);
|
|
||||||
uiDrawRectangle(p->Context, 120, 80, 50, 50);
|
|
||||||
uiDrawFill(p->Context, uiDrawFillModeWinding);
|
|
||||||
|
|
||||||
uiDrawBeginPathRGB(p->Context, 0x00, 0x80, 0x00);
|
|
||||||
uiDrawMoveTo(p->Context, 5, 10);
|
|
||||||
uiDrawLineTo(p->Context, 5, 50);
|
|
||||||
sp.Cap = uiDrawLineCapFlat;
|
|
||||||
sp.Join = uiDrawLineJoinMiter;
|
|
||||||
sp.Thickness = 1;
|
|
||||||
sp.MiterLimit = uiDrawDefaultMiterLimit;
|
|
||||||
uiDrawStroke(p->Context, &sp);
|
|
||||||
|
|
||||||
uiDrawBeginPathRGB(p->Context, 0x80, 0xC0, 0x00);
|
|
||||||
uiDrawMoveTo(p->Context, 400, 100);
|
|
||||||
uiDrawArcTo(p->Context,
|
|
||||||
400, 100,
|
|
||||||
50,
|
|
||||||
30. * (M_PI / 180.),
|
|
||||||
// note the end angle here
|
|
||||||
// in GDI, the second angle to AngleArc() is relative to the start, not to 0
|
|
||||||
330. * (M_PI / 180.),
|
|
||||||
1);
|
|
||||||
// TODO add a checkbox for this
|
|
||||||
uiDrawLineTo(p->Context, 400, 100);
|
|
||||||
uiDrawArcTo(p->Context,
|
|
||||||
510, 100,
|
|
||||||
50,
|
|
||||||
30. * (M_PI / 180.),
|
|
||||||
330. * (M_PI / 180.),
|
|
||||||
0);
|
|
||||||
uiDrawCloseFigure(p->Context);
|
|
||||||
sp.Cap = uiDrawLineCapFlat;
|
|
||||||
sp.Join = uiDrawLineJoinMiter;
|
|
||||||
sp.Thickness = 1;
|
|
||||||
sp.MiterLimit = uiDrawDefaultMiterLimit;
|
|
||||||
uiDrawStroke(p->Context, &sp);
|
|
||||||
|
|
||||||
uiDrawBeginPathRGB(p->Context, 0x00, 0x80, 0xC0);
|
|
||||||
uiDrawMoveTo(p->Context, 300, 300);
|
|
||||||
uiDrawBezierTo(p->Context,
|
|
||||||
350, 320,
|
|
||||||
310, 390,
|
|
||||||
435, 372);
|
|
||||||
sp.Cap = uiDrawLineCapFlat;
|
|
||||||
sp.Join = uiDrawLineJoinMiter;
|
|
||||||
sp.Thickness = 1;
|
|
||||||
sp.MiterLimit = uiDrawDefaultMiterLimit;
|
|
||||||
uiDrawStroke(p->Context, &sp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uintmax_t handlerHScrollMax(uiAreaHandler *a, uiArea *area)
|
|
||||||
{/* TODO
|
|
||||||
WCHAR c[50];
|
|
||||||
|
|
||||||
GetWindowTextW(nhspinb, c, 50);
|
|
||||||
return _wtoi(c);
|
|
||||||
*/}
|
|
||||||
|
|
||||||
static uintmax_t handlerVScrollMax(uiAreaHandler *a, uiArea *area)
|
|
||||||
{/* TODO
|
|
||||||
WCHAR c[50];
|
|
||||||
|
|
||||||
GetWindowTextW(nvspinb, c, 50);
|
|
||||||
return _wtoi(c);
|
|
||||||
*/}
|
|
||||||
|
|
||||||
static int handlerRedrawOnResize(uiAreaHandler *a, uiArea *area)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// areaUpdateScroll(area);
|
|
||||||
|
|
||||||
@interface appDelegate : NSObject<NSApplicationDelegate, NSTextFieldDelegate>
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation appDelegate
|
|
||||||
|
|
||||||
- (void)controlTextDidChange:(NSNotification *)note
|
|
||||||
{
|
|
||||||
areaUpdateScroll(area);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)applicationDidFinishLaunching:(NSApplication *)app
|
|
||||||
{
|
|
||||||
NSWindow *mainwin;
|
|
||||||
NSView *contentView;
|
|
||||||
NSView *areav;
|
|
||||||
NSArray *constraints;
|
|
||||||
NSDictionary *views;
|
|
||||||
|
|
||||||
mainwin = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 500, 500)
|
|
||||||
styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)
|
|
||||||
backing:NSBackingStoreBuffered
|
|
||||||
defer:YES];
|
|
||||||
contentView = [mainwin contentView];
|
|
||||||
|
|
||||||
area = newArea((uiAreaHandler *) (&h));
|
|
||||||
areav = areaView(area);
|
|
||||||
[areav setTranslatesAutoresizingMaskIntoConstraints:NO];
|
|
||||||
[contentView addSubview:areav];
|
|
||||||
|
|
||||||
views = @{
|
|
||||||
@"areav": areav,
|
|
||||||
};
|
|
||||||
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[areav]-|"
|
|
||||||
options:0
|
|
||||||
metrics:nil
|
|
||||||
views:views];
|
|
||||||
[contentView addConstraints:constraints];
|
|
||||||
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[areav]-|"
|
|
||||||
options:0
|
|
||||||
metrics:nil
|
|
||||||
views:views];
|
|
||||||
[contentView addConstraints:constraints];
|
|
||||||
|
|
||||||
[mainwin makeKeyAndOrderFront:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
NSApplication *app;
|
|
||||||
|
|
||||||
h.ah.Draw = handlerDraw;
|
|
||||||
h.ah.HScrollMax = handlerHScrollMax;
|
|
||||||
h.ah.VScrollMax = handlerVScrollMax;
|
|
||||||
h.ah.RedrawOnResize = handlerRedrawOnResize;
|
|
||||||
|
|
||||||
app = [NSApplication sharedApplication];
|
|
||||||
[app setActivationPolicy:NSApplicationActivationPolicyRegular];
|
|
||||||
[app setDelegate:[appDelegate new]];
|
|
||||||
[app run];
|
|
||||||
return 0;
|
|
||||||
}
|
|
139
macarea/ui.h
139
macarea/ui.h
|
@ -1,139 +0,0 @@
|
||||||
// 4 september 2015
|
|
||||||
|
|
||||||
typedef struct uiArea uiArea;
|
|
||||||
typedef struct uiAreaHandler uiAreaHandler;
|
|
||||||
typedef struct uiAreaDrawParams uiAreaDrawParams;
|
|
||||||
|
|
||||||
typedef struct uiDrawContext uiDrawContext;
|
|
||||||
|
|
||||||
struct uiAreaHandler {
|
|
||||||
void (*Draw)(uiAreaHandler *, uiArea *, uiAreaDrawParams *);
|
|
||||||
uintmax_t (*HScrollMax)(uiAreaHandler *, uiArea *);
|
|
||||||
uintmax_t (*VScrollMax)(uiAreaHandler *, uiArea *);
|
|
||||||
int (*RedrawOnResize)(uiAreaHandler *, uiArea *);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct uiAreaDrawParams {
|
|
||||||
uiDrawContext *Context;
|
|
||||||
|
|
||||||
intmax_t ClientWidth;
|
|
||||||
intmax_t ClientHeight;
|
|
||||||
|
|
||||||
intmax_t ClipX;
|
|
||||||
intmax_t ClipY;
|
|
||||||
intmax_t ClipWidth;
|
|
||||||
intmax_t ClipHeight;
|
|
||||||
|
|
||||||
int DPIX;
|
|
||||||
int DPIY;
|
|
||||||
|
|
||||||
intmax_t HScrollPos;
|
|
||||||
intmax_t VScrollPos;
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO proper sources
|
|
||||||
// TODO dotting/dashing
|
|
||||||
|
|
||||||
typedef struct uiDrawStrokeParams uiDrawStrokeParams;
|
|
||||||
typedef enum uiDrawLineCap uiDrawLineCap;
|
|
||||||
typedef enum uiDrawLineJoin uiDrawLineJoin;
|
|
||||||
typedef enum uiDrawFillMode uiDrawFillMode;
|
|
||||||
|
|
||||||
enum uiDrawLineCap {
|
|
||||||
uiDrawLineCapFlat,
|
|
||||||
uiDrawLineCapRound,
|
|
||||||
uiDrawLineCapSquare,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum uiDrawLineJoin {
|
|
||||||
uiDrawLineJoinMiter,
|
|
||||||
uiDrawLineJoinRound,
|
|
||||||
uiDrawLineJoinBevel,
|
|
||||||
};
|
|
||||||
|
|
||||||
// this is the default for botoh cairo and GDI
|
|
||||||
// Core Graphics doesn't explicitly specify a default, but NSBezierPath allows you to choose one, and this is the initial value
|
|
||||||
// so we're good to use it too!
|
|
||||||
#define uiDrawDefaultMiterLimit 10.0
|
|
||||||
|
|
||||||
enum uiDrawFillMode {
|
|
||||||
uiDrawFillModeWinding,
|
|
||||||
// TODO rename to EvenOdd?
|
|
||||||
uiDrawFillModeAlternate,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct uiDrawStrokeParams {
|
|
||||||
uiDrawLineCap Cap;
|
|
||||||
uiDrawLineJoin Join;
|
|
||||||
intmax_t Thickness;
|
|
||||||
double MiterLimit;
|
|
||||||
};
|
|
||||||
|
|
||||||
void uiDrawBeginPathRGB(uiDrawContext *, uint8_t, uint8_t, uint8_t);
|
|
||||||
// TODO verify these aren't alpha premultiplied anywhere
|
|
||||||
void uiDrawBeginPathRGBA(uiDrawContext *, uint8_t, uint8_t, uint8_t, uint8_t);
|
|
||||||
|
|
||||||
void uiDrawMoveTo(uiDrawContext *, intmax_t, intmax_t);
|
|
||||||
void uiDrawLineTo(uiDrawContext *, intmax_t, intmax_t);
|
|
||||||
void uiDrawRectangle(uiDrawContext *, intmax_t, intmax_t, intmax_t, intmax_t);
|
|
||||||
// notes: angles are both relative to 0 and go counterclockwise
|
|
||||||
void uiDrawArcTo(uiDrawContext *, intmax_t, intmax_t, intmax_t, double, double, int);
|
|
||||||
// TODO behavior when there is no initial point on Windows and OS X
|
|
||||||
void uiDrawBezierTo(uiDrawContext *, intmax_t, intmax_t, intmax_t, intmax_t, intmax_t, intmax_t);
|
|
||||||
void uiDrawCloseFigure(uiDrawContext *);
|
|
||||||
|
|
||||||
void uiDrawStroke(uiDrawContext *, uiDrawStrokeParams *);
|
|
||||||
void uiDrawFill(uiDrawContext *, uiDrawFillMode);
|
|
||||||
|
|
||||||
// path functions
|
|
||||||
// cairo gdi core graphics
|
|
||||||
// move_to MoveToEx MoveToPoint
|
|
||||||
// line_to LineTo AddLineToPoint
|
|
||||||
// arc Arc/ArcTo/AngleArc/Pie AddArc/AddArcToPoint/AddEllipseInRect
|
|
||||||
// arc_negative Arc/ArcTo/AngleArc/Pie AddArc/AddArcToPoint
|
|
||||||
// curve_to PolyBezier/PolyBezierTo AddCurveToPoint
|
|
||||||
// rectangle Rectangle AddRect
|
|
||||||
// [arc functions?] Chord [arc functions?]
|
|
||||||
// [combination] RoundRect [same way as cairo?]
|
|
||||||
// [TODO pango] TextOut/ExtTextOut [TODO core text]
|
|
||||||
// [TODO] [TODO] AddQuadCurveToPoint
|
|
||||||
|
|
||||||
// on sources:
|
|
||||||
// cairo:
|
|
||||||
// - RGB
|
|
||||||
// - RGBA
|
|
||||||
// - images
|
|
||||||
// - linear gradients, RGB or RGBA
|
|
||||||
// - rounded gradients, RGB or RGBA
|
|
||||||
// gdi:
|
|
||||||
// - RGB
|
|
||||||
// - hatches
|
|
||||||
// - images
|
|
||||||
// we can create a linear gradient image, but RGB only, and of finite size
|
|
||||||
// core graphics:
|
|
||||||
// - arbitrary patterns
|
|
||||||
// - solid colors, arbitrary spaces
|
|
||||||
// - shadows
|
|
||||||
|
|
||||||
// arcs
|
|
||||||
// cairo_arc/arc_negative
|
|
||||||
// - parameters: center, radius, angle1 radians, angle2 radins
|
|
||||||
// - if angle2 < angle1, TODO
|
|
||||||
// - if angle2 > angle1, TODO
|
|
||||||
// - line segment from current point to beginning of arc
|
|
||||||
// - arc: clockwise, arc_negative: counterclockwise
|
|
||||||
// - circular
|
|
||||||
// GDI Arc/Pie
|
|
||||||
// - parameters: bounding box, start point, end point
|
|
||||||
// - current position not used/changed
|
|
||||||
// - either clockwise or counterclockwise
|
|
||||||
// - elliptical
|
|
||||||
// GDI ArcTo
|
|
||||||
// - same as Arc except line segment from current point to beginning of arc
|
|
||||||
// - there does not appear to be a PieTo
|
|
||||||
// GDI AngleArc
|
|
||||||
// - parameters: center, radius, angle1 degrees, angle2 degrees
|
|
||||||
// - line segment from current position to beginning of arc
|
|
||||||
// - counterclockwise
|
|
||||||
// - circular
|
|
||||||
// - can be used to draw pies too; MSDN example demonstrates
|
|
Loading…
Reference in New Issue