From efdd60375ab3048919bde2d5f410b92626a6a712 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Sat, 29 Mar 2014 19:02:09 -0400 Subject: [PATCH] Documented that the clip area in AreaHandler.Paint() more properly and indicate that it is cleared on each AreaHandler.Paint() call; (try to) implement that on Windows (GTK+ does it for us; noted that as well). --- area.go | 4 +++- area_unix.go | 1 + area_windows.go | 3 +-- todo.md | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/area.go b/area.go index 05d3361..1fbaa28 100644 --- a/area.go +++ b/area.go @@ -37,6 +37,8 @@ type Area struct { // (Having to use this interface does not strike me as being particularly Go-like, but the nature of Paint makes channel-based event handling a non-option; in practice, deadlocks occur.) type AreaHandler interface { // Paint is called when the Area needs to be redrawn. + // The part of the Area that needs to be redrawn is stored in cliprect. + // Before Paint() is called, this region is cleared with a system-defined background color. // You MUST handle this event, and you MUST return a valid image, otherwise deadlocks and panicking will occur. // The image returned must have the same size as rect (but does not have to have the same origin points). // Example: @@ -48,7 +50,7 @@ type AreaHandler interface { // func (h *myAreaHandler) Paint(rect image.Rectangle) *image.NRGBA { // return img.SubImage(rect).(*image.NRGBA) // } - Paint(rect image.Rectangle) *image.NRGBA + Paint(cliprect image.Rectangle) *image.NRGBA // Mouse is called when the Area receives a mouse event. // You are allowed to do nothing in this handler (to ignore mouse events). diff --git a/area_unix.go b/area_unix.go index 08dd48d..0155bdc 100644 --- a/area_unix.go +++ b/area_unix.go @@ -48,6 +48,7 @@ func our_area_draw_callback(widget *C.GtkWidget, cr *C.cairo_t, data C.gpointer) s := (*sysData)(unsafe.Pointer(data)) // thanks to desrt in irc.gimp.net/#gtk+ C.cairo_clip_extents(cr, &x, &y, &w, &h) + // we do not need to clear the cliprect; GtkDrawingArea did it for us beforehand cliprect := image.Rect(int(x), int(y), int(w), int(h)) // the cliprect can actually fall outside the size of the Area; clip it by intersecting the two rectangles C.gtk_widget_get_size_request(widget, &maxwid, &maxht) diff --git a/area_windows.go b/area_windows.go index 70beb8c..52cc781 100644 --- a/area_windows.go +++ b/area_windows.go @@ -78,11 +78,10 @@ func paintArea(s *sysData) { var xrect _RECT var ps _PAINTSTRUCT - // TODO send _TRUE if we want to erase the clip area r1, _, _ := _getUpdateRect.Call( uintptr(s.hwnd), uintptr(unsafe.Pointer(&xrect)), - uintptr(_FALSE)) + uintptr(_TRUE)) // erase the update rect with the background color if r1 == 0 { // no update rect; do nothing return } diff --git a/todo.md b/todo.md index 7afeef2..46c34db 100644 --- a/todo.md +++ b/todo.md @@ -86,6 +86,7 @@ super ultra important things: - for our two custom window classes, we should allocate extra space in the window class's info structure and then use SetWindowLongPtrW() during WM_CREATE to store the sysData and not have to make a new window class each time; this might also fix the s != nil && s.hwnd != 0 special cases in the Area WndProc if done right - references: https://github.com/glfw/glfw/blob/master/src/win32_window.c#L182, http://www.catch22.net/tuts/custom-controls - Area redraw on Windows is still a bit flaky, especially after changing the Area size to something larger than the window size and then resizing the window(???) +- despite us explicitly clearing the clip area on Windows, Area still doesn't seem to draw alpha bits correctly... it appears as if we are drawing over the existing image each time important things: - make specific wording in documentation consistent (make/create, etc.)