From d570440a9b48b249e8cf6a57f37eca33d125e7ac Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Fri, 11 Sep 2015 21:25:38 -0400 Subject: [PATCH] Removed the NSScrollView-based uIArea on OS X. We'll stick with our custom one. --- macarea/area.h | 12 ---- macarea/area.m | 127 ----------------------------------- macarea/draw.m | 148 ----------------------------------------- macarea/main.m | 177 ------------------------------------------------- macarea/ui.h | 139 -------------------------------------- 5 files changed, 603 deletions(-) delete mode 100644 macarea/area.h delete mode 100644 macarea/area.m delete mode 100644 macarea/draw.m delete mode 100644 macarea/main.m delete mode 100644 macarea/ui.h diff --git a/macarea/area.h b/macarea/area.h deleted file mode 100644 index fdd532c3..00000000 --- a/macarea/area.h +++ /dev/null @@ -1,12 +0,0 @@ -// 8 september 2015 -#import -#import -#import "ui.h" - -extern uiArea *newArea(uiAreaHandler *ah); - -extern uiDrawContext *newContext(CGContextRef); - -extern NSView *areaView(uiArea *); - -extern void areaUpdateScroll(uiArea *); diff --git a/macarea/area.m b/macarea/area.m deleted file mode 100644 index 6987ccbc..00000000 --- a/macarea/area.m +++ /dev/null @@ -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]; -} diff --git a/macarea/draw.m b/macarea/draw.m deleted file mode 100644 index 753ecfc1..00000000 --- a/macarea/draw.m +++ /dev/null @@ -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; - } -} diff --git a/macarea/main.m b/macarea/main.m deleted file mode 100644 index 71737b93..00000000 --- a/macarea/main.m +++ /dev/null @@ -1,177 +0,0 @@ -// 4 september 2015 -#define _GNU_SOURCE -#include "area.h" -#include - -// #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 -@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; -} diff --git a/macarea/ui.h b/macarea/ui.h deleted file mode 100644 index 90dc0fbd..00000000 --- a/macarea/ui.h +++ /dev/null @@ -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