diff --git a/areaplan.md b/areaplan.md new file mode 100644 index 0000000..c04d064 --- /dev/null +++ b/areaplan.md @@ -0,0 +1,82 @@ +```go +```go +type Area struct { // implements Control + // Paint receives requests to redraw from the window system. + Paint chan PaintRequest + + // Keyboard receives keyboard events. + Key chan KeyEvent // not covered here + + // Mouse receives mouse events. + Mouse chan MouseEvent // not covered here +} + +// PaintRequest represents a request to redraw an Area. +// It is sent across Area.Paint. +type PaintRequest struct { + // Rect is the clipping rectangle that needs redraw. + Rect image.Rect + + // Out is a channel on which you send the image to redraw. + Out chan<- *image.NRGBA +} +``` + +and an example of intended use: + +```go +func myAreaGoroutine(area *ui.Area, start <-chan bool) { + var img *image.NRGBA + + // initialize img here + <-start // sent after calling Window.Open() + area.SetSize(img.Rect.Dx(), img.Rect.Dy()) // sets the internal size; scrollbars and scrolling is handled automatically + for { + select { + case req := <-area.Paint: + req.Out <- img.SubImage(req.Rect).(*image.NRGBA) + case e := <-area.Mouse: + // draw on a mouse click, for instance + } + } +} +``` + +## Windows +TODO + +## GTK+ +We can use `GtkDrawingArea`. We hook into the `draw` signal; it does something equivalent to + +```go +func draw_callback(widget *C.GtkWidget, cr *C.cairo_t, data C.gpointer) C.gboolean { + s := (*sysData)(unsafe.Pointer(data)) + // TODO get clip rectangle that needs drawing + imgret := make(chan *image.NRGBA) + defer close(imgret) + s.paint <- PaintRequest{ + Rect: /* clip rect */, + Out: imgret, + } + i := <-imgret + pixbuf := C.gdk_pixbuf_new_from_data( + (*C.guchar)(unsafe.Pointer(&i.Pix[0])), + C.GDK_COLORSPACE_RGB, + C.TRUE, // has alpha channel + 8, // bits per sample + C.int(i.Rect.Dx()), + C.int(i.Rect.Dy()), + C.int(i.Stride), + nil, nil) // do not free data + C.gdk_cairo_set_source_pixbuf(cr, + pixbuf, + /* x of clip rect */, + /* y of clip rect */) + return C.FALSE // TODO what does this return value mean? docs don't say +} +``` + +TODO figure out how scrolling plays into this + +## Cocoa +TODO