More OS X uiArea implementation work.
This commit is contained in:
parent
24c8c085a0
commit
7e0dae000f
|
@ -0,0 +1,12 @@
|
|||
// 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 *);
|
|
@ -0,0 +1,117 @@
|
|||
// 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;
|
||||
}
|
||||
|
||||
@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 scoll view
|
||||
|
||||
// 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];
|
||||
}
|
|
@ -23,7 +23,7 @@ uiDrawContext *newContext(CGContextRef ctxt)
|
|||
|
||||
void uiDrawBeginPathRGB(uiDrawContext *c, uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
c->useRGB = YES;
|
||||
c->useRGBA = YES;
|
||||
c->r = ((CGFloat) r) / 255;
|
||||
c->g = ((CGFloat) g) / 255;
|
||||
c->b = ((CGFloat) b) / 255;
|
||||
|
@ -33,7 +33,7 @@ void uiDrawBeginPathRGB(uiDrawContext *c, uint8_t r, uint8_t g, uint8_t b)
|
|||
|
||||
void uiDrawBeginPathRGBA(uiDrawContext *c, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
||||
{
|
||||
c->useRGB = YES;
|
||||
c->useRGBA = YES;
|
||||
c->r = ((CGFloat) r) / 255;
|
||||
c->g = ((CGFloat) g) / 255;
|
||||
c->b = ((CGFloat) b) / 255;
|
||||
|
@ -53,7 +53,7 @@ void uiDrawLineTo(uiDrawContext *c, intmax_t x, intmax_t y)
|
|||
|
||||
void uiDrawRectangle(uiDrawContext *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height)
|
||||
{
|
||||
CGContextAddRect(c->c, TODO(x, y, width, height));
|
||||
CGContextAddRect(c->c, CGRectMake(x, y, width, height));
|
||||
}
|
||||
|
||||
void uiDrawArcTo(uiDrawContext *c, intmax_t xCenter, intmax_t yCenter, intmax_t radius, double startAngle, double endAngle, int lineFromCurrentPointToStart)
|
||||
|
@ -104,28 +104,28 @@ void uiDrawStroke(uiDrawContext *c, uiDrawStrokeParams *p)
|
|||
}
|
||||
switch (p->Join) {
|
||||
case uiDrawLineJoinMiter:
|
||||
CGContextSetLineJoin(c->cr, kCGLineJoinMiter);
|
||||
CGContextSetLineJoin(c->c, kCGLineJoinMiter);
|
||||
CGContextSetMiterLimit(c->c, p->MiterLimit);
|
||||
break;
|
||||
case uiDrawLineJoinRound:
|
||||
CGContextSetLineJoin(c->cr, kCGLineJoinRound);
|
||||
CGContextSetLineJoin(c->c, kCGLineJoinRound);
|
||||
break;
|
||||
case uiDrawLineJoinBevel:
|
||||
CGContextSetLineJoin(c->cr, kCGLineJoinBevel);
|
||||
CGContextSetLineJoin(c->c, kCGLineJoinBevel);
|
||||
break;
|
||||
}
|
||||
CGContextSetLineWidth(c->c, p->Thickness);
|
||||
if (c->useRGB)
|
||||
if (c->useRGBA)
|
||||
CGContextSetRGBStrokeColor(c->c, c->r, c->g, c->b, c->a);
|
||||
else {
|
||||
// TODO
|
||||
}
|
||||
CGContextStrokePath(c->cr);
|
||||
CGContextStrokePath(c->c);
|
||||
}
|
||||
|
||||
void uiDrawFill(uiDrawContext *c, uiDrawFillMode mode)
|
||||
{
|
||||
if (c->useRGB)
|
||||
if (c->useRGBA)
|
||||
CGContextSetRGBFillColor(c->c, c->r, c->g, c->b, c->a);
|
||||
else {
|
||||
// TODO
|
|
@ -0,0 +1,171 @@
|
|||
// 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);
|
||||
*/}
|
||||
|
||||
// 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;
|
||||
|
||||
app = [NSApplication sharedApplication];
|
||||
[app setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
[app setDelegate:[appDelegate new]];
|
||||
[app run];
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue