diff --git a/areaplan.md b/areaplan.md index c04d064..b085aa9 100644 --- a/areaplan.md +++ b/areaplan.md @@ -1,5 +1,4 @@ ```go -```go type Area struct { // implements Control // Paint receives requests to redraw from the window system. Paint chan PaintRequest @@ -42,6 +41,8 @@ func myAreaGoroutine(area *ui.Area, start <-chan bool) { } ``` +TODO is there a race on `area.SetSize()`? + ## Windows TODO @@ -79,4 +80,67 @@ func draw_callback(widget *C.GtkWidget, cr *C.cairo_t, data C.gpointer) C.gboole TODO figure out how scrolling plays into this ## Cocoa -TODO +For this one we **must** create a subclass of `NSView` that overrides the drawing and keyboard/mouse event messages. + +The drawing message is `-[NSView drawRect:]`, which just takes the `NSRect` as an argument. So we already need to use `bleh_darwin.m` to grab the actual `NSRect` and convert it into something with a predictable data type before passing it back to Go. If we do this: +```go +//export our_drawRect +func our_drawRect(self C.id, rect C.struct_xrect) { +``` +we can call `our_drawRect()` from this C wrapper: +```objective-c +extern void our_drawRect(id, struct xrect); + +void _our_drawRect(id self, SEL sel, NSRect r) +{ + struct xrect t; + + t.x = (int64_t) s.origin.x; + t.y = (int64_t) s.origin.y; + t.width = (int64_t) s.size.width; + t.height = (int64_t) s.size.height; + our_drawRect(self, t); +} +``` +This just leaves `our_drawRect` itself. For this mockup, I will use "Objective-Go": +```go +//export our_drawRect +func our_drawRect(self C.id, rect C.struct_xrect) { + s := getSysData(self) + cliprect := image.Rect(int(rect.x), int(rect.y), int(rect.width), int(rect.height)) + imgret := make(chan *image.NRGBA) + defer close(imgret) + s.paint <- PaintRequest{ + Rect: cliprect, + Out: imgret, + } + i := <-imgret + // the NSBitmapImageRep constructor requires a list of pointers + _bitmapData := [1]*uint8{&i.Pix[0]} + bitmapData := (**C.uchar)(unsafe.Pointer(&bitmapData)) + bitmap := [[NSBitmapImageRep alloc] + initWithBitmapDataPlanes:bitmapData + pixelsWide:i.Rect.Dx() + pixelsHigh:i.Rect.Dy() + bitsPerSample:8 + samplesPerPixel:4 + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSCalibratedRGBColorSpace // TODO NSDeviceRGBColorSpace? + bytesPerRow:i.Stride + bitsPerPixel:32] + [bitmap drawAtPoint:NSMakePoint(cliprect.x, cliprect.y)] + [bitmap release] +} +``` +Due to the utter complexity of all that `NSImage` stuff, I might just have another C function that performs the `NSBitmapImageRep` constructor using the `image.NRGBA` fields. + +Finally, we need to override `-[NSView isFlipped]` since we want to keep (0,0) at the top-left: +```go +//export our_isFlipped +func our_isFlipped(self C.id, sel C.SEL) C.BOOL { + return C.BOOL(C.YES) +} +``` + +TODO figure out scrolling