cdef extern from "Python.h": void *PyMem_Malloc(int size) except NULL void Py_INCREF(object) int PyUnicode_Check(object str) object PyUnicode_AsUTF8String(object str) cdef extern from "x3.h": ctypedef struct x3widget ctypedef struct x3dc: int x int y int width int height cdef enum x3windowflags: x3window_main = 1 x3window_dialog = 2 ctypedef struct x3viewclient: void (*destroy)(x3viewclient *self) void (*mouse)(x3viewclient *self, int buttons, int mods, double x, double y) int (*key)(x3viewclient *self, char *keyname, int mods, int key) void (*draw)(x3viewclient *self, x3dc *dc) # client extension void *py_client ctypedef struct x3extents: double x_bearing double y_bearing double width double height double x_advance double y_advance void x3init(int argc, char **argv) void x3main() x3widget *x3window(x3windowflags flags, char *name, int (callback)(x3widget *w, void *data, char *cmd, char *what, char *arg, void *more), void *data) x3widget *x3menu(x3widget *parent, char *name) x3widget *x3menuitem(x3widget *parent, char *name, char *cmd, char *shortcut) x3widget *x3menusep(x3widget *parent) x3widget *x3align(x3widget *parent, int alignment) x3widget *x3pad(x3widget *parent, int t, int b, int l, int r) x3widget *x3vbox(x3widget *parent, int homogeneous, int spacing) x3widget *x3hpane(x3widget *parent) x3widget *x3vpane(x3widget *parent) x3widget *x3button(x3widget *parent, char *name, char *label) x3widget *x3label(x3widget *parent, char *text) x3widget *x3edittext(x3widget *parent, char *cmd) x3widget *x3view(x3widget *parent, int flags, x3viewclient *vc) void x3viewclient_init(x3viewclient *vc) void x3view_dirty(x3widget *w) void x3view_scrollto(x3widget *w, int x, int y, int width, int height) void x3setactive(x3widget *w, int active) void x3setpacking(x3widget *w, int fill, int expand, int padding) int x3hasfocus(x3widget *w) void x3moveto(x3dc *dc, double x, double y) void x3lineto(x3dc *dc, double x, double y) void x3curveto(x3dc *dc, double x1, double y1, double x2, double y2, double x3, double y3) void x3closepath(x3dc *dc) void x3rectangle(x3dc *dc, double x, double y, double width, double height) void x3getcurrentpoint(x3dc *dc, double *px, double *py) void x3setrgba(x3dc *dc, unsigned int rgba) void x3setlinewidth(x3dc *dc, double w) void x3fill(x3dc *dc) void x3stroke(x3dc *dc) void x3selectfont(x3dc *dc, char *fontname, int slant, int weight) void x3setfontsize(x3dc *dc, double size) void x3showtext(x3dc *dc, char *text) void x3textextents(x3dc *dc, char *text, x3extents *extents) X3_GMW(g, m, w) cdef object strmaybenull(char *str): if str == NULL: return None else: return str cdef object utf8(object ustr): if PyUnicode_Check(ustr): return PyUnicode_AsUTF8String(ustr) else: return ustr ctypedef struct x3viewclient_py: x3viewclient base # client extension void *py_client cdef class widget: cdef x3widget *w def hasfocus(self): return x3hasfocus(self.w) cdef int x3py_callback(x3widget *window, void *data, char *cmd, char *what, char *arg, void *more): callback = data callback(cmd, strmaybenull(what), strmaybenull(arg), None) cdef class window(widget): def __new__(self, int flags, char *name, callback): self.w = x3window(flags, name, x3py_callback, callback) cdef class menu(widget): def __new__(self, widget parent, name): uname = utf8(name) self.w = x3menu(parent.w, uname) cdef class menuitem(widget): def __new__(self, widget parent, name, char *cmd, char *shortcut = NULL): uname = utf8(name) self.w = x3menuitem(parent.w, uname, cmd, shortcut) cdef class menusep(widget): def __new__(self, widget parent): self.w = x3menusep(parent.w) cdef class align(widget): def __new__(self, widget parent, int alignment): self.w = x3align(parent.w, alignment) cdef class pad(widget): def __new__(self, widget parent, int t, int b, int l, int r): self.w = x3pad(parent.w, t, b, l, r) cdef class vbox(widget): def __new__(self, widget parent, homogeneous, int spacing): self.w = x3vbox(parent.w, not not homogeneous, spacing) def setpacking(self, fill, expand, int padding): x3setpacking(self.w, not not fill, not not expand, padding) cdef class hpane(widget): def __new__(self, widget parent): self.w = x3hpane(parent.w) cdef class vpane(widget): def __new__(self, widget parent): self.w = x3vpane(parent.w) cdef class button(widget): def __new__(self, widget parent, char *name, label): ulabel = utf8(label) self.w = x3button(parent.w, name, ulabel) cdef class label(widget): def __new__(self, widget parent, text): ulabel = utf8(text) self.w = x3label(parent.w, ulabel) cdef class edittext(widget): def __new__(self, widget parent, char *cmd): self.w = x3edittext(parent.w, cmd) cdef int x3py_key(x3viewclient *self, char *keyname, int mods, int key): py_client = (self).py_client return py_client.key(keyname, mods, key) cdef void x3py_mouse(x3viewclient *self, int button, int mods, double x, double y): py_client = (self).py_client py_client.mouse(button, mods, x, y) cdef int dbl_to_byte(double x): if x <= 0: return 0 if x >= 1: return 255 return x * 255 + 0.5 cdef class x3dc_wrap: cdef x3dc *dc property rect: def __get__(self): return (self.dc.x, self.dc.y, self.dc.width, self.dc.height) def moveto(self, double x, double y): x3moveto(self.dc, x, y) def lineto(self, double x, double y): x3lineto(self.dc, x, y) def curveto(self, double x1, double y1, double x2, double y2, double x3, double y3): x3curveto(self.dc, x1, y1, x2, y2, x3, y3) def closepath(self): x3closepath(self.dc) def rectangle(self, double x, double y, double width, double height): x3rectangle(self.dc, x, y, width, height) def currentpoint(self): cdef double x cdef double y x3getcurrentpoint(self.dc, &x, &y) return (x, y) def setrgba(self, double r, double g, double b, double a): x3setrgba(self.dc, (dbl_to_byte(r) << 24) | (dbl_to_byte(g) << 16) | (dbl_to_byte(b) << 8) | dbl_to_byte(a)) def setlinewidth(self, double w): x3setlinewidth(self.dc, w) def fill(self): x3fill(self.dc) def stroke(self): x3stroke(self.dc) def selectfont(self, char *name, int slant, int weight): x3selectfont(self.dc, name, slant, weight) def setfontsize(self, double size): x3setfontsize(self.dc, size) def showtext(self, text): utext = utf8(text) x3showtext(self.dc, utext) def textextents(self, text): cdef x3extents ext utext = utf8(text) x3textextents(self.dc, utext, &ext) return (ext.x_bearing, ext.y_bearing, ext.width, ext.height, ext.x_advance, ext.y_advance) cdef void x3py_draw(x3viewclient *self, x3dc *dc): cdef x3dc_wrap dc_wrap py_client = (self).py_client dc_wrap = x3dc_wrap() dc_wrap.dc = dc py_client.draw(dc_wrap) cdef class view(widget): def __new__(self, widget parent, int flags, viewclient): cdef x3viewclient_py *vc vc = PyMem_Malloc(sizeof(x3viewclient_py)) x3viewclient_init(&vc.base) vc.py_client = viewclient Py_INCREF(viewclient) vc.base.key = x3py_key vc.base.mouse = x3py_mouse vc.base.draw = x3py_draw self.w = x3view(parent.w, flags, &vc.base) viewclient.view = self def dirty(self): x3view_dirty(self.w) def scrollto(self, int x, int y, int width, int height): x3view_scrollto(self.w, x, y, width, height) def main(): x3main() def gmw(g, m, w): return X3_GMW(g, m, w) platform = gmw("gtk", "mac", "win32") x3init(0, NULL)