2014-03-14 22:06:51 -05:00
// +build !windows,!darwin,!plan9
2014-03-14 17:44:59 -05:00
// 14 march 2014
package ui
import (
2014-03-14 22:06:51 -05:00
"unsafe"
2014-03-14 17:44:59 -05:00
"image"
)
// #cgo pkg-config: gtk+-3.0
2014-03-14 22:06:51 -05:00
// /* GTK+ 3.8 deprecates gtk_scrolled_window_add_with_viewport(); we need 3.4 miniimum though
// setting MIN_REQUIRED ensures nothing older; setting MAX_ALLOWED disallows newer functions - thanks to desrt in irc.gimp.net/#gtk+
// TODO add this to the other files too */
// #define GDK_VERSION_MIN_REQUIRED GDK_VERSION_3_4
// #define GDK_VERSION_MAX_ALLOWED GDK_VERSION_3_4
2014-03-14 17:44:59 -05:00
// #include <gtk/gtk.h>
// extern gboolean our_draw_callback(GtkWidget *, cairo_t *, gpointer);
2014-03-14 22:06:51 -05:00
// /* HACK - see https://code.google.com/p/go/issues/detail?id=7548 */
// struct _cairo {};
2014-03-14 17:44:59 -05:00
import "C"
func gtkAreaNew ( ) * gtkWidget {
drawingarea := C . gtk_drawing_area_new ( )
2014-03-14 22:06:51 -05:00
C . gtk_widget_set_size_request ( drawingarea , 320 , 240 )
2014-03-14 17:44:59 -05:00
scrollarea := C . gtk_scrolled_window_new ( ( * C . GtkAdjustment ) ( nil ) , ( * C . GtkAdjustment ) ( nil ) )
// need a viewport because GtkDrawingArea isn't natively scrollable
2014-03-14 22:06:51 -05:00
C . gtk_scrolled_window_add_with_viewport ( ( * C . GtkScrolledWindow ) ( unsafe . Pointer ( scrollarea ) ) , drawingarea )
2014-03-14 17:44:59 -05:00
return fromgtkwidget ( scrollarea )
}
//export our_draw_callback
func our_draw_callback ( widget * C . GtkWidget , cr * C . cairo_t , data C . gpointer ) C . gboolean {
var x , y , w , h C . double
s := ( * sysData ) ( unsafe . Pointer ( data ) )
// thanks to desrt in irc.gimp.net/#gtk+
C . cairo_clip_extents ( cr , & x , & y , & w , & h )
cliprect := image . Rect ( int ( x ) , int ( y ) , int ( w ) , int ( h ) )
imgret := make ( chan * image . NRGBA )
defer close ( imgret )
s . paint <- PaintRequest {
Rect : cliprect ,
Out : imgret ,
}
i := <- imgret
// pixel order is [R G B A] (see Example 1 on https://developer.gnome.org/gdk-pixbuf/2.26/gdk-pixbuf-The-GdkPixbuf-Structure.html) so we don't have to convert anything
// gdk-pixbuf is not alpha-premultiplied (thanks to desrt in irc.gimp.net/#gtk+)
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 ,
C . gdouble ( cliprect . Min . X ) ,
C . gdouble ( cliprect . Min . Y ) )
C . g_object_unref ( ( C . gpointer ) ( unsafe . Pointer ( pixbuf ) ) ) // free pixbuf
2014-03-14 22:06:51 -05:00
return C . FALSE // signals handled without stopping the event chain (thanks to desrt again)
2014-03-14 17:44:59 -05:00
}
var draw_callback = C . GCallback ( C . our_draw_callback )