2021-01-21 15:20:59 +03:00
/* Kuroko bindings for Yutani */
# include <assert.h>
# include <toaru/yutani.h>
2021-01-23 09:31:38 +03:00
# include <toaru/decorations.h>
2021-01-25 14:12:39 +03:00
# include <toaru/menu.h>
2021-07-22 14:43:01 +03:00
# include <toaru/text.h>
2021-03-25 09:53:40 +03:00
# include <kuroko/kuroko.h>
# include <kuroko/vm.h>
# include <kuroko/value.h>
# include <kuroko/object.h>
2021-01-21 15:20:59 +03:00
static KrkInstance * module ;
static KrkInstance * yctxInstance = NULL ;
# define S(c) (krk_copyString(c,sizeof(c)-1))
2021-01-24 13:35:39 +03:00
static KrkClass * Message ;
2021-01-23 03:26:04 +03:00
struct MessageClass {
KrkInstance inst ;
yutani_msg_t * msg ;
} ;
2021-01-24 13:35:39 +03:00
static KrkClass * Yutani ;
2021-01-23 03:26:04 +03:00
struct YutaniClass {
KrkInstance inst ;
yutani_t * yctx ;
} ;
2021-01-24 13:35:39 +03:00
static KrkClass * GraphicsContext ;
struct GraphicsContext {
KrkInstance inst ;
gfx_context_t * ctx ;
int doubleBuffered ;
} ;
static KrkClass * YutaniWindow ;
struct WindowClass {
KrkInstance inst ;
gfx_context_t * ctx ;
int doubleBuffered ;
yutani_window_t * window ;
} ;
2021-01-24 15:47:50 +03:00
static KrkClass * YutaniSprite ;
struct YutaniSprite {
KrkInstance inst ;
gfx_context_t * ctx ;
int doubleBuffered ;
sprite_t sprite ;
} ;
2021-01-24 13:35:39 +03:00
static KrkClass * YutaniColor ;
struct YutaniColor {
KrkInstance inst ;
uint32_t color ;
} ;
2021-01-25 05:36:38 +03:00
static KrkClass * YutaniFont ;
struct YutaniFont {
KrkInstance inst ;
2021-07-22 14:43:01 +03:00
struct TT_Font * fontData ;
2021-01-25 05:36:38 +03:00
int fontSize ;
uint32_t fontColor ;
} ;
2021-01-25 14:12:39 +03:00
static KrkClass * MenuBarClass ;
struct MenuBarClass {
KrkInstance inst ;
struct menu_bar menuBar ;
} ;
static KrkClass * MenuListClass ;
struct MenuListClass {
KrkInstance inst ;
struct MenuList * menuList ;
} ;
static KrkClass * MenuEntryClass ;
struct MenuEntryClass {
KrkInstance inst ;
struct MenuEntry * menuEntry ;
} ;
static KrkClass * MenuEntrySubmenuClass ;
static KrkClass * MenuEntrySeparatorClass ;
2021-01-21 15:20:59 +03:00
/**
* Convenience wrapper to make a class and attach it to the module , while
* handling stack push / pop to keep things from being prematurely GC ' d .
*/
KrkClass * krk_createClass ( KrkInstance * inModule , const char * name , KrkClass * base ) {
2021-02-16 12:50:17 +03:00
if ( ! base ) base = vm . baseClasses - > objectClass ;
2021-01-21 15:20:59 +03:00
KrkString * str_Name = krk_copyString ( name , strlen ( name ) ) ;
krk_push ( OBJECT_VAL ( str_Name ) ) ;
2021-01-23 03:26:04 +03:00
KrkClass * obj_Class = krk_newClass ( str_Name , base ) ;
2021-01-21 15:20:59 +03:00
krk_push ( OBJECT_VAL ( obj_Class ) ) ;
krk_attachNamedObject ( & inModule - > fields , name , ( KrkObj * ) obj_Class ) ;
krk_pop ( ) ; /* obj_Class */
krk_pop ( ) ; /* str_Name */
return obj_Class ;
}
# define DO_FIELD(name, body) \
{ krk_push ( OBJECT_VAL ( S ( name ) ) ) ; \
if ( krk_valuesEqual ( argv [ 1 ] , krk_peek ( 0 ) ) ) { \
krk_pop ( ) ; \
body \
} krk_pop ( ) ; }
# define TO_INT_(name) { return INTEGER_VAL((msg-> name)); }
# define TO_INT(name) { return INTEGER_VAL((me-> name)); }
# define WID() DO_FIELD("wid", TO_INT(wid))
# define STRUCT(type) type * me = (void*)msg->data
2021-01-23 03:26:04 +03:00
static void _message_sweep ( KrkInstance * self ) {
free ( ( ( struct MessageClass * ) self ) - > msg ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _message_getattr ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-21 15:20:59 +03:00
assert ( argc = = 2 ) ;
KrkInstance * self = AS_INSTANCE ( argv [ 0 ] ) ;
2021-01-23 03:26:04 +03:00
yutani_msg_t * msg = ( ( struct MessageClass * ) self ) - > msg ;
2021-01-21 15:20:59 +03:00
if ( ! msg ) return NONE_VAL ( ) ;
DO_FIELD ( " magic " , TO_INT_ ( magic ) ) ;
DO_FIELD ( " type " , TO_INT_ ( type ) ) ;
DO_FIELD ( " size " , TO_INT_ ( size ) ) ;
switch ( msg - > type ) {
case YUTANI_MSG_WELCOME : {
STRUCT ( struct yutani_msg_welcome ) ;
DO_FIELD ( " display_width " , TO_INT ( display_width ) ) ;
DO_FIELD ( " display_height " , TO_INT ( display_height ) ) ;
} break ;
case YUTANI_MSG_WINDOW_MOUSE_EVENT : {
STRUCT ( struct yutani_msg_window_mouse_event ) ;
WID ( ) ;
DO_FIELD ( " new_x " , TO_INT ( new_x ) ) ;
DO_FIELD ( " new_y " , TO_INT ( new_y ) ) ;
DO_FIELD ( " old_x " , TO_INT ( old_x ) ) ;
DO_FIELD ( " old_y " , TO_INT ( old_y ) ) ;
DO_FIELD ( " buttons " , TO_INT ( buttons ) ) ;
DO_FIELD ( " command " , TO_INT ( command ) ) ;
DO_FIELD ( " modifiers " , TO_INT ( modifiers ) ) ;
} break ;
case YUTANI_MSG_WINDOW_FOCUS_CHANGE : {
STRUCT ( struct yutani_msg_window_focus_change ) ;
WID ( ) ;
DO_FIELD ( " focused " , TO_INT ( focused ) ) ;
} break ;
case YUTANI_MSG_RESIZE_OFFER : {
STRUCT ( struct yutani_msg_window_resize ) ;
WID ( ) ;
DO_FIELD ( " width " , TO_INT ( width ) ) ;
DO_FIELD ( " height " , TO_INT ( height ) ) ;
DO_FIELD ( " bufid " , TO_INT ( bufid ) ) ;
} break ;
case YUTANI_MSG_WINDOW_ADVERTISE : {
STRUCT ( struct yutani_msg_window_advertise ) ;
WID ( ) ;
DO_FIELD ( " flags " , TO_INT ( flags ) ) ;
DO_FIELD ( " size " , TO_INT ( size ) ) ;
DO_FIELD ( " name " , { char * s = me - > strings + me - > offsets [ 0 ] ; size_t l = strlen ( s ) ; return OBJECT_VAL ( krk_copyString ( s , l ) ) ; } ) ;
DO_FIELD ( " icon " , { char * s = me - > strings + me - > offsets [ 1 ] ; size_t l = strlen ( s ) ; return OBJECT_VAL ( krk_copyString ( s , l ) ) ; } ) ;
} break ;
case YUTANI_MSG_WINDOW_MOVE : {
STRUCT ( struct yutani_msg_window_move ) ;
WID ( ) ;
DO_FIELD ( " x " , TO_INT ( x ) ) ;
DO_FIELD ( " y " , TO_INT ( y ) ) ;
} break ;
case YUTANI_MSG_KEY_EVENT : {
STRUCT ( struct yutani_msg_key_event ) ;
WID ( ) ;
DO_FIELD ( " keycode " , TO_INT ( event . keycode ) ) ;
DO_FIELD ( " modifiers " , TO_INT ( event . modifiers ) ) ;
DO_FIELD ( " action " , TO_INT ( event . action ) ) ;
DO_FIELD ( " key " , TO_INT ( event . key ) ) ;
DO_FIELD ( " kbd_state " , TO_INT ( state . kbd_state ) ) ;
DO_FIELD ( " kbd_s_state " , TO_INT ( state . kbd_s_state ) ) ;
DO_FIELD ( " k_ctrl " , TO_INT ( state . k_ctrl ) ) ;
DO_FIELD ( " k_shift " , TO_INT ( state . k_shift ) ) ;
DO_FIELD ( " k_alt " , TO_INT ( state . k_alt ) ) ;
DO_FIELD ( " k_super " , TO_INT ( state . k_super ) ) ;
DO_FIELD ( " kl_ctrl " , TO_INT ( state . kl_ctrl ) ) ;
DO_FIELD ( " kl_shift " , TO_INT ( state . kl_shift ) ) ;
DO_FIELD ( " kl_alt " , TO_INT ( state . kl_alt ) ) ;
DO_FIELD ( " kl_super " , TO_INT ( state . kl_super ) ) ;
DO_FIELD ( " kr_ctrl " , TO_INT ( state . kr_ctrl ) ) ;
DO_FIELD ( " kr_shift " , TO_INT ( state . kr_shift ) ) ;
DO_FIELD ( " kr_alt " , TO_INT ( state . kr_alt ) ) ;
DO_FIELD ( " kr_super " , TO_INT ( state . kr_super ) ) ;
DO_FIELD ( " kbd_esc_buf " , TO_INT ( state . kbd_esc_buf ) ) ;
} break ;
}
2021-02-16 12:50:17 +03:00
krk_runtimeError ( vm . exceptions - > attributeError , " no attribute '%s' " , AS_CSTRING ( argv [ 1 ] ) ) ;
2021-01-21 15:20:59 +03:00
return NONE_VAL ( ) ;
}
# undef DO_FIELD
# undef TO_INT_
# undef GET
# undef TO_INT
# undef WID
2021-02-16 12:50:17 +03:00
static KrkValue _yutani_repr ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 03:21:38 +03:00
struct YutaniClass * self = ( struct YutaniClass * ) AS_INSTANCE ( argv [ 0 ] ) ;
char out [ 500 ] ;
size_t len = sprintf ( out , " Yutani(fd=%d,server=%s,display_width=%d,display_height=%d) " ,
fileno ( self - > yctx - > sock ) ,
self - > yctx - > server_ident ,
( int ) self - > yctx - > display_width ,
( int ) self - > yctx - > display_height ) ;
return OBJECT_VAL ( krk_copyString ( out , len ) ) ;
}
2021-01-21 15:20:59 +03:00
static KrkValue _yutani_init ( int argc , KrkValue argv [ ] , int hasKw ) {
if ( yctxInstance ) {
2021-02-16 12:50:17 +03:00
krk_runtimeError ( vm . exceptions - > valueError , " class 'Yutani' is a singleton and has already been initialized. " ) ;
2021-01-21 15:20:59 +03:00
return NONE_VAL ( ) ;
}
KrkInstance * self = AS_INSTANCE ( argv [ 0 ] ) ;
/* Connect and let's go. */
yutani_t * yctx = yutani_init ( ) ;
if ( ! yctx ) {
2021-02-16 12:50:17 +03:00
krk_runtimeError ( vm . exceptions - > ioError , " Failed to connect to compositor. " ) ;
2021-01-21 15:20:59 +03:00
return NONE_VAL ( ) ;
}
2021-01-23 09:31:38 +03:00
init_decorations ( ) ;
2021-01-23 03:26:04 +03:00
( ( struct YutaniClass * ) self ) - > yctx = yctx ;
2021-01-21 15:20:59 +03:00
yctxInstance = self ;
krk_attachNamedObject ( & module - > fields , " _yutani_t " , ( KrkObj * ) self ) ;
return argv [ 0 ] ;
}
2021-01-25 04:14:25 +03:00
# define CHECK_YUTANI() \
if ( argc < 1 | | ! krk_isInstanceOf ( argv [ 0 ] , Yutani ) ) \
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected Yutani " ) ; \
2021-01-25 04:14:25 +03:00
struct YutaniClass * self = ( struct YutaniClass * ) AS_INSTANCE ( argv [ 0 ] )
2021-02-16 12:50:17 +03:00
static KrkValue _yutani_display_width ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_YUTANI ( ) ;
return INTEGER_VAL ( self - > yctx - > display_width ) ;
2021-01-21 15:20:59 +03:00
}
2021-02-16 12:50:17 +03:00
static KrkValue _yutani_display_height ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_YUTANI ( ) ;
return INTEGER_VAL ( self - > yctx - > display_height ) ;
2021-01-21 15:20:59 +03:00
}
static KrkValue _yutani_poll ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_YUTANI ( ) ;
2021-01-21 15:20:59 +03:00
int sync = ( argc > 1 & & IS_BOOLEAN ( argv [ 1 ] ) ) ? AS_BOOLEAN ( argv [ 1 ] ) : 1 ;
yutani_msg_t * result ;
if ( sync ) {
2021-01-25 04:14:25 +03:00
result = yutani_poll ( self - > yctx ) ;
2021-01-21 15:20:59 +03:00
} else {
2021-01-25 04:14:25 +03:00
result = yutani_poll_async ( self - > yctx ) ;
2021-01-21 15:20:59 +03:00
}
if ( ! result ) return NONE_VAL ( ) ;
KrkInstance * out = krk_newInstance ( Message ) ;
krk_push ( OBJECT_VAL ( out ) ) ;
2021-01-23 03:26:04 +03:00
( ( struct MessageClass * ) out ) - > msg = result ;
2021-01-25 14:12:39 +03:00
krk_attachNamedValue ( & out - > fields , " type " , INTEGER_VAL ( result - > type ) ) ;
2021-01-21 15:20:59 +03:00
return krk_pop ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _yutani_wait_for ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_YUTANI ( ) ;
2021-02-16 12:50:17 +03:00
if ( argc ! = 2 | | ! IS_INTEGER ( argv [ 1 ] ) ) { krk_runtimeError ( vm . exceptions - > argumentError , " expected int for msgtype " ) ; return NONE_VAL ( ) ; }
2021-01-25 04:14:25 +03:00
yutani_msg_t * result = yutani_wait_for ( self - > yctx , AS_INTEGER ( argv [ 1 ] ) ) ;
2021-01-21 15:20:59 +03:00
KrkInstance * out = krk_newInstance ( Message ) ;
krk_push ( OBJECT_VAL ( out ) ) ;
2021-01-23 03:26:04 +03:00
( ( struct MessageClass * ) out ) - > msg = result ;
2021-01-25 14:12:39 +03:00
krk_attachNamedValue ( & out - > fields , " type " , INTEGER_VAL ( result - > type ) ) ;
2021-01-21 15:20:59 +03:00
return krk_pop ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _yutani_subscribe ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_YUTANI ( ) ;
yutani_subscribe_windows ( self - > yctx ) ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _yutani_unsubscribe ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_YUTANI ( ) ;
yutani_unsubscribe_windows ( self - > yctx ) ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _yutani_query_windows ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_YUTANI ( ) ;
yutani_query_windows ( self - > yctx ) ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _yutani_fileno ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_YUTANI ( ) ;
return INTEGER_VAL ( fileno ( self - > yctx - > sock ) ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _yutani_query ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_YUTANI ( ) ;
return INTEGER_VAL ( yutani_query ( self - > yctx ) ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _yutani_menu_process_event ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 14:12:39 +03:00
CHECK_YUTANI ( ) ;
if ( argc < 2 | | ! krk_isInstanceOf ( argv [ 1 ] , Message ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected Message " ) ;
2021-01-25 14:12:39 +03:00
struct MessageClass * msg = ( struct MessageClass * ) AS_INSTANCE ( argv [ 1 ] ) ;
return INTEGER_VAL ( menu_process_event ( self - > yctx , msg - > msg ) ) ;
}
2021-01-23 09:31:38 +03:00
# define GET_ARG(p,name,type) do { \
if ( hasKw & & krk_tableGet ( AS_DICT ( argv [ argc ] ) , OBJECT_VAL ( S ( # name ) ) , & name ) ) { \
if ( ! krk_isInstanceOf ( name , type ) ) \
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , # name " argument should be " # type " , not '%s' " , krk_typeName ( name ) ) ; \
2021-01-23 09:31:38 +03:00
} else if ( argc > p ) { \
name = argv [ p ] ; \
if ( ! krk_isInstanceOf ( name , type ) ) \
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , # name " argument should be " # type " , not '%s' " , krk_typeName ( name ) ) ; \
2021-01-23 09:31:38 +03:00
} \
} while ( 0 )
2021-01-24 13:35:39 +03:00
# define GFX_PROPERTY(name) \
2021-02-16 12:50:17 +03:00
static KrkValue _gfx_ # # name ( int argc , KrkValue argv [ ] , int hasKw ) { \
2021-01-24 13:35:39 +03:00
if ( argc ! = 1 | | ! krk_isInstanceOf ( argv [ 0 ] , GraphicsContext ) ) \
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " Expected GraphicsContext " ) ; \
2021-01-24 13:35:39 +03:00
struct GraphicsContext * self = ( struct GraphicsContext * ) AS_INSTANCE ( argv [ 0 ] ) ; \
return INTEGER_VAL ( self - > ctx - > name ) ; \
}
GFX_PROPERTY ( width ) ;
GFX_PROPERTY ( height ) ;
# define CHECK_GFX() \
if ( argc < 1 | | ! krk_isInstanceOf ( argv [ 0 ] , GraphicsContext ) ) \
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected GraphicsContext " ) ; \
2021-01-24 13:35:39 +03:00
struct GraphicsContext * self = ( struct GraphicsContext * ) AS_INSTANCE ( argv [ 0 ] )
2021-02-16 12:50:17 +03:00
static KrkValue _gfx_fill ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-24 13:35:39 +03:00
CHECK_GFX ( ) ;
if ( argc < 2 | | ! krk_isInstanceOf ( argv [ 1 ] , YutaniColor ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " fill() takes one color ( ) argument " ) ;
2021-01-24 13:35:39 +03:00
struct YutaniColor * color = ( struct YutaniColor * ) AS_INSTANCE ( argv [ 1 ] ) ;
draw_fill ( self - > ctx , color - > color ) ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _gfx_flip ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-24 13:35:39 +03:00
CHECK_GFX ( ) ;
if ( self - > doubleBuffered ) {
flip ( self - > ctx ) ;
}
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _gfx_blur ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-24 13:35:39 +03:00
CHECK_GFX ( ) ;
int radius = 2 ;
if ( argc > 1 & & IS_INTEGER ( argv [ 1 ] ) ) radius = AS_INTEGER ( argv [ 1 ] ) ;
2021-02-16 12:50:17 +03:00
else if ( argc > 1 ) return krk_runtimeError ( vm . exceptions - > typeError , " expected int " ) ;
2021-01-24 13:35:39 +03:00
blur_context_box ( self - > ctx , radius ) ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _gfx_line ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-24 13:35:39 +03:00
CHECK_GFX ( ) ;
if ( argc < 6 | |
! IS_INTEGER ( argv [ 1 ] ) | |
! IS_INTEGER ( argv [ 2 ] ) | |
! IS_INTEGER ( argv [ 3 ] ) | |
! IS_INTEGER ( argv [ 4 ] ) | |
! krk_isInstanceOf ( argv [ 5 ] , YutaniColor ) ) {
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " line() expects 4 ints and a color " ) ;
2021-01-24 13:35:39 +03:00
}
int32_t x0 = AS_INTEGER ( argv [ 1 ] ) ;
int32_t x1 = AS_INTEGER ( argv [ 2 ] ) ;
int32_t y0 = AS_INTEGER ( argv [ 3 ] ) ;
int32_t y1 = AS_INTEGER ( argv [ 4 ] ) ;
struct YutaniColor * color = ( struct YutaniColor * ) AS_INSTANCE ( argv [ 5 ] ) ;
if ( argc > 6 ) {
if ( IS_INTEGER ( argv [ 6 ] ) ) {
draw_line_thick ( self - > ctx , x0 , x1 , y0 , y1 , color - > color , AS_INTEGER ( argv [ 6 ] ) ) ;
} else if ( IS_FLOATING ( argv [ 6 ] ) ) {
draw_line_aa ( self - > ctx , x0 , x1 , y0 , y1 , color - > color , AS_FLOATING ( argv [ 6 ] ) ) ;
} else {
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " thickness must be int or float, not '%s' " , krk_typeName ( argv [ 6 ] ) ) ;
2021-01-24 13:35:39 +03:00
}
} else {
draw_line ( self - > ctx , x0 , x1 , y0 , y1 , color - > color ) ;
}
return NONE_VAL ( ) ;
}
static KrkValue _gfx_rect ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-24 15:47:50 +03:00
CHECK_GFX ( ) ;
2021-01-24 13:35:39 +03:00
if ( argc ! = 6 | |
! IS_INTEGER ( argv [ 1 ] ) | |
! IS_INTEGER ( argv [ 2 ] ) | |
! IS_INTEGER ( argv [ 3 ] ) | |
! IS_INTEGER ( argv [ 4 ] ) | |
! krk_isInstanceOf ( argv [ 5 ] , YutaniColor ) ) {
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " rect() expects 4 ints and a color " ) ;
2021-01-24 13:35:39 +03:00
}
int32_t x = AS_INTEGER ( argv [ 1 ] ) ;
int32_t y = AS_INTEGER ( argv [ 2 ] ) ;
uint16_t width = AS_INTEGER ( argv [ 3 ] ) ;
uint16_t height = AS_INTEGER ( argv [ 4 ] ) ;
struct YutaniColor * color = ( struct YutaniColor * ) AS_INSTANCE ( argv [ 5 ] ) ;
KrkValue solid = BOOLEAN_VAL ( 0 ) , radius = NONE_VAL ( ) ;
if ( hasKw ) {
krk_tableGet ( AS_DICT ( argv [ argc ] ) , OBJECT_VAL ( S ( " solid " ) ) , & solid ) ;
krk_tableGet ( AS_DICT ( argv [ argc ] ) , OBJECT_VAL ( S ( " radius " ) ) , & radius ) ;
}
if ( ! IS_BOOLEAN ( solid ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " solid must be bool " ) ;
2021-01-24 13:35:39 +03:00
if ( ! IS_NONE ( radius ) & & ! IS_INTEGER ( radius ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " radius must be int " ) ;
2021-01-25 04:14:25 +03:00
if ( ! IS_NONE ( radius ) & & AS_BOOLEAN ( solid ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " radius and solid can not be used together " ) ;
2021-01-24 13:35:39 +03:00
if ( AS_BOOLEAN ( solid ) ) {
draw_rectangle_solid ( self - > ctx , x , y , width , height , color - > color ) ;
} else if ( IS_INTEGER ( radius ) ) {
draw_rounded_rectangle ( self - > ctx , x , y , width , height , AS_INTEGER ( radius ) , color - > color ) ;
} else {
draw_rectangle ( self - > ctx , x , y , width , height , color - > color ) ;
}
return NONE_VAL ( ) ;
}
2021-01-24 15:47:50 +03:00
static KrkValue _gfx_draw_sprite ( int argc , KrkValue argv [ ] , int hasKw ) {
CHECK_GFX ( ) ;
if ( argc < 2 | | ! krk_isInstanceOf ( argv [ 1 ] , YutaniSprite ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected Sprite " ) ;
2021-01-24 15:47:50 +03:00
if ( argc < 4 | | ! IS_INTEGER ( argv [ 2 ] ) | | ! IS_INTEGER ( argv [ 3 ] ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected integer coordinate pair " ) ;
2021-01-24 15:47:50 +03:00
/* Potential kwargs: rotation:float, alpha:float, scale:(int,int)... */
KrkValue rotation = NONE_VAL ( ) , alpha = NONE_VAL ( ) , scale = NONE_VAL ( ) , color = NONE_VAL ( ) ;
if ( hasKw ) {
krk_tableGet ( AS_DICT ( argv [ argc ] ) , OBJECT_VAL ( S ( " alpha " ) ) , & alpha ) ;
krk_tableGet ( AS_DICT ( argv [ argc ] ) , OBJECT_VAL ( S ( " rotation " ) ) , & rotation ) ;
krk_tableGet ( AS_DICT ( argv [ argc ] ) , OBJECT_VAL ( S ( " scale " ) ) , & scale ) ;
krk_tableGet ( AS_DICT ( argv [ argc ] ) , OBJECT_VAL ( S ( " color " ) ) , & color ) ;
}
if ( ! IS_NONE ( alpha ) & & ! IS_FLOATING ( alpha ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " alpha must be float " ) ;
2021-01-24 15:47:50 +03:00
if ( ! IS_NONE ( rotation ) & & ! IS_FLOATING ( rotation ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " rotation must be float " ) ;
2021-01-24 15:47:50 +03:00
if ( ! IS_NONE ( color ) & & ! krk_isInstanceOf ( color , YutaniColor ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " color must be color " ) ;
2021-01-24 15:47:50 +03:00
if ( ! IS_NONE ( scale ) & & ( ! IS_TUPLE ( scale ) | | AS_TUPLE ( scale ) - > values . count ! = 2 | |
! IS_INTEGER ( AS_TUPLE ( scale ) - > values . values [ 0 ] ) | |
! IS_INTEGER ( AS_TUPLE ( scale ) - > values . values [ 1 ] ) ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " scale must be 2-tuple of ints " ) ;
2021-01-24 15:47:50 +03:00
if ( ! IS_NONE ( rotation ) + ! IS_NONE ( scale ) + ! IS_NONE ( color ) > 1 )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " can not combine rotation / scale / color " ) ;
2021-01-24 15:47:50 +03:00
if ( ( ! IS_NONE ( rotation ) | | ! IS_NONE ( color ) ) & & IS_NONE ( alpha ) )
alpha = FLOATING_VAL ( 1.0 ) ;
struct YutaniSprite * sprite = ( struct YutaniSprite * ) AS_INSTANCE ( argv [ 1 ] ) ;
int32_t x = AS_INTEGER ( argv [ 2 ] ) ;
int32_t y = AS_INTEGER ( argv [ 3 ] ) ;
if ( ! IS_NONE ( scale ) ) {
int32_t width = AS_INTEGER ( AS_TUPLE ( scale ) - > values . values [ 0 ] ) ;
int32_t height = AS_INTEGER ( AS_TUPLE ( scale ) - > values . values [ 1 ] ) ;
if ( IS_NONE ( alpha ) ) {
draw_sprite_scaled ( self - > ctx , & sprite - > sprite , x , y , width , height ) ;
} else {
draw_sprite_scaled_alpha ( self - > ctx , & sprite - > sprite , x , y , width , height , AS_FLOATING ( alpha ) ) ;
}
} else if ( IS_NONE ( alpha ) ) {
draw_sprite ( self - > ctx , & sprite - > sprite , x , y ) ;
} else if ( ! IS_NONE ( color ) ) {
draw_sprite_alpha_paint ( self - > ctx , & sprite - > sprite , x , y , AS_FLOATING ( alpha ) , ( ( struct YutaniColor * ) AS_INSTANCE ( color ) ) - > color ) ;
} else if ( ! IS_NONE ( rotation ) ) {
draw_sprite_rotate ( self - > ctx , & sprite - > sprite , x , y , AS_FLOATING ( rotation ) , AS_FLOATING ( alpha ) ) ;
} else {
draw_sprite_alpha ( self - > ctx , & sprite - > sprite , x , y , AS_FLOATING ( alpha ) ) ;
}
return NONE_VAL ( ) ;
}
static void _sprite_sweep ( KrkInstance * self ) {
struct YutaniSprite * sprite = ( struct YutaniSprite * ) self ;
if ( sprite - > sprite . masks ) free ( sprite - > sprite . masks ) ;
if ( sprite - > sprite . bitmap ) free ( sprite - > sprite . bitmap ) ;
if ( sprite - > ctx ) free ( sprite - > ctx ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _sprite_repr ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 03:21:38 +03:00
struct YutaniSprite * self = ( struct YutaniSprite * ) AS_INSTANCE ( argv [ 0 ] ) ;
KrkValue file ;
krk_tableGet ( & self - > inst . fields , OBJECT_VAL ( S ( " file " ) ) , & file ) ;
char out [ 500 ] ;
size_t len = sprintf ( out , " Sprite('%s',width=%d,height=%d) " ,
! IS_STRING ( file ) ? " " : AS_CSTRING ( file ) ,
( int ) self - > sprite . width ,
( int ) self - > sprite . height ) ;
return OBJECT_VAL ( krk_copyString ( out , len ) ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _sprite_init ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-24 15:47:50 +03:00
if ( argc < 1 | | ! krk_isInstanceOf ( argv [ 0 ] , YutaniSprite ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected sprite " ) ;
2021-01-24 15:47:50 +03:00
if ( argc < 2 | | ! IS_STRING ( argv [ 1 ] ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " Sprite() takes one str argument " ) ;
2021-01-24 15:47:50 +03:00
struct YutaniSprite * self = ( struct YutaniSprite * ) AS_INSTANCE ( argv [ 0 ] ) ;
int result = load_sprite ( & self - > sprite , AS_CSTRING ( argv [ 1 ] ) ) ;
if ( result ) {
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > ioError , " Sprite() could not be initialized " ) ;
2021-01-24 15:47:50 +03:00
}
self - > ctx = init_graphics_sprite ( & self - > sprite ) ;
2021-01-25 03:21:38 +03:00
krk_attachNamedValue ( & self - > inst . fields , " file " , argv [ 1 ] ) ;
2021-01-24 15:47:50 +03:00
return argv [ 0 ] ;
}
2021-01-25 04:14:25 +03:00
# define CHECK_WINDOW() \
if ( argc < 1 | | ! krk_isInstanceOf ( argv [ 0 ] , YutaniWindow ) ) \
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected Window " ) ; \
2021-01-25 04:14:25 +03:00
struct WindowClass * self = ( struct WindowClass * ) AS_INSTANCE ( argv [ 0 ] ) ; \
2021-02-16 12:50:17 +03:00
if ( ! self - > window ) return krk_runtimeError ( vm . exceptions - > valueError , " Window is closed " )
2021-01-25 04:14:25 +03:00
2021-02-16 12:50:17 +03:00
static KrkValue _window_repr ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_WINDOW ( ) ;
2021-01-25 03:21:38 +03:00
KrkValue title ;
krk_tableGet ( & self - > inst . fields , OBJECT_VAL ( S ( " title " ) ) , & title ) ;
char out [ 500 ] ;
size_t len = sprintf ( out , " Window(wid=%d,title=%s,width=%d,height=%d) " ,
self - > window - > wid ,
IS_NONE ( title ) ? " " : AS_CSTRING ( title ) ,
( int ) self - > window - > width ,
( int ) self - > window - > height ) ;
return OBJECT_VAL ( krk_copyString ( out , len ) ) ;
}
2021-01-23 09:31:38 +03:00
static KrkValue _window_init ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-02-16 12:50:17 +03:00
if ( ! yctxInstance ) return krk_runtimeError ( vm . exceptions - > valueError , " Compositor is not initialized " ) ;
2021-01-23 09:31:38 +03:00
if ( argc < 1 | | ! krk_isInstanceOf ( argv [ 0 ] , YutaniWindow ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " Failed to initialize window " ) ;
2021-01-23 09:31:38 +03:00
if ( argc < 3 | | ! IS_INTEGER ( argv [ 1 ] ) | | ! IS_INTEGER ( argv [ 2 ] ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > argumentError , " Expected at least two (integer) arguments ( width , height ) " ) ;
2021-01-23 09:31:38 +03:00
KrkInstance * _self = AS_INSTANCE ( argv [ 0 ] ) ;
struct WindowClass * self = ( struct WindowClass * ) _self ;
krk_integer_type width = AS_INTEGER ( argv [ 1 ] ) ;
krk_integer_type height = AS_INTEGER ( argv [ 2 ] ) ;
KrkValue flags = INTEGER_VAL ( 0 ) , title = NONE_VAL ( ) , icon = NONE_VAL ( ) , doublebuffer = BOOLEAN_VAL ( 0 ) ;
2021-02-16 12:50:17 +03:00
GET_ARG ( 3 , flags , vm . baseClasses - > intClass ) ;
GET_ARG ( 4 , title , vm . baseClasses - > strClass ) ;
GET_ARG ( 5 , icon , vm . baseClasses - > strClass ) ;
GET_ARG ( 6 , doublebuffer , vm . baseClasses - > boolClass ) ;
2021-01-23 09:31:38 +03:00
self - > window = yutani_window_create_flags ( ( ( struct YutaniClass * ) yctxInstance ) - > yctx ,
width , height , AS_INTEGER ( flags ) ) ;
self - > doubleBuffered = AS_BOOLEAN ( doublebuffer ) ;
if ( self - > doubleBuffered ) {
self - > ctx = init_graphics_yutani_double_buffer ( self - > window ) ;
} else {
self - > ctx = init_graphics_yutani ( self - > window ) ;
}
if ( ! IS_NONE ( title ) ) {
if ( ! IS_NONE ( icon ) ) {
yutani_window_advertise_icon ( ( ( struct YutaniClass * ) yctxInstance ) - > yctx , self - > window , AS_CSTRING ( title ) , AS_CSTRING ( icon ) ) ;
} else {
yutani_window_advertise ( ( ( struct YutaniClass * ) yctxInstance ) - > yctx , self - > window , AS_CSTRING ( title ) ) ;
}
}
krk_attachNamedValue ( & _self - > fields , " title " , title ) ;
krk_attachNamedValue ( & _self - > fields , " icon " , icon ) ;
krk_attachNamedValue ( & _self - > fields , " closed " , BOOLEAN_VAL ( 0 ) ) ;
return argv [ 0 ] ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _window_flip ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_WINDOW ( ) ;
2021-01-23 09:31:38 +03:00
if ( self - > doubleBuffered ) {
flip ( self - > ctx ) ;
}
yutani_flip ( ( ( struct YutaniClass * ) yctxInstance ) - > yctx , self - > window ) ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _window_move ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_WINDOW ( ) ;
2021-01-23 09:31:38 +03:00
if ( argc < 3 | | ! IS_INTEGER ( argv [ 1 ] ) | | ! IS_INTEGER ( argv [ 2 ] ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected two integer arguments " ) ;
2021-01-23 09:31:38 +03:00
yutani_window_move ( ( ( struct YutaniClass * ) yctxInstance ) - > yctx , self - > window , AS_INTEGER ( argv [ 1 ] ) , AS_INTEGER ( argv [ 2 ] ) ) ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _window_set_focused ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_WINDOW ( ) ;
2021-01-23 09:31:38 +03:00
if ( argc < 2 | | ! IS_INTEGER ( argv [ 1 ] ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected integer argument " ) ;
2021-01-23 09:31:38 +03:00
self - > window - > focused = AS_INTEGER ( argv [ 1 ] ) ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _window_close ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_WINDOW ( ) ;
yutani_close ( ( ( struct YutaniClass * ) yctxInstance ) - > yctx , self - > window ) ;
self - > window = NULL ;
release_graphics_yutani ( self - > ctx ) ;
self - > ctx = NULL ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _window_set_stack ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_WINDOW ( ) ;
2021-02-16 12:50:17 +03:00
if ( argc < 2 | | ! IS_INTEGER ( argv [ 1 ] ) ) return krk_runtimeError ( vm . exceptions - > typeError , " expected int for z-order " ) ;
2021-01-25 04:14:25 +03:00
int z = AS_INTEGER ( argv [ 1 ] ) ;
yutani_set_stack ( ( ( struct YutaniClass * ) yctxInstance ) - > yctx , self - > window , z ) ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _window_update_shape ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_WINDOW ( ) ;
2021-02-16 12:50:17 +03:00
if ( argc < 2 | | ! IS_INTEGER ( argv [ 1 ] ) ) return krk_runtimeError ( vm . exceptions - > typeError , " expected int for shape specifier " ) ;
2021-01-25 04:14:25 +03:00
int set_shape = AS_INTEGER ( argv [ 1 ] ) ;
yutani_window_update_shape ( ( ( struct YutaniClass * ) yctxInstance ) - > yctx , self - > window , set_shape ) ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _window_warp_mouse ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_WINDOW ( ) ;
if ( argc < 3 | | ! IS_INTEGER ( argv [ 1 ] ) | | ! IS_INTEGER ( argv [ 2 ] ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected two int values for x, y " ) ;
2021-01-25 04:14:25 +03:00
int32_t x = AS_INTEGER ( argv [ 1 ] ) ;
int32_t y = AS_INTEGER ( argv [ 2 ] ) ;
yutani_window_warp_mouse ( ( ( struct YutaniClass * ) yctxInstance ) - > yctx , self - > window , x , y ) ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _window_show_mouse ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_WINDOW ( ) ;
2021-02-16 12:50:17 +03:00
if ( argc < 2 | | ! IS_INTEGER ( argv [ 1 ] ) ) return krk_runtimeError ( vm . exceptions - > typeError , " expected int for show_mouse " ) ;
2021-01-25 04:14:25 +03:00
int show_mouse = AS_INTEGER ( argv [ 1 ] ) ;
yutani_window_show_mouse ( ( ( struct YutaniClass * ) yctxInstance ) - > yctx , self - > window , show_mouse ) ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _window_resize_start ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_WINDOW ( ) ;
2021-02-16 12:50:17 +03:00
if ( argc < 2 | | ! IS_INTEGER ( argv [ 1 ] ) ) return krk_runtimeError ( vm . exceptions - > typeError , " expected int for direction " ) ;
2021-01-25 04:14:25 +03:00
yutani_scale_direction_t direction = AS_INTEGER ( argv [ 1 ] ) ;
yutani_window_resize_start ( ( ( struct YutaniClass * ) yctxInstance ) - > yctx , self - > window , direction ) ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _window_resize ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_WINDOW ( ) ;
if ( argc < 3 | | ! IS_INTEGER ( argv [ 1 ] ) | | ! IS_INTEGER ( argv [ 2 ] ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected two int values for width, height " ) ;
2021-01-25 04:14:25 +03:00
uint32_t width = AS_INTEGER ( argv [ 1 ] ) ;
uint32_t height = AS_INTEGER ( argv [ 2 ] ) ;
yutani_window_resize ( ( ( struct YutaniClass * ) yctxInstance ) - > yctx , self - > window , width , height ) ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _window_resize_offer ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_WINDOW ( ) ;
if ( argc < 3 | | ! IS_INTEGER ( argv [ 1 ] ) | | ! IS_INTEGER ( argv [ 2 ] ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected two int values for width, height " ) ;
2021-01-25 04:14:25 +03:00
uint32_t width = AS_INTEGER ( argv [ 1 ] ) ;
uint32_t height = AS_INTEGER ( argv [ 2 ] ) ;
yutani_window_resize_offer ( ( ( struct YutaniClass * ) yctxInstance ) - > yctx , self - > window , width , height ) ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _window_resize_accept ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_WINDOW ( ) ;
if ( argc < 3 | | ! IS_INTEGER ( argv [ 1 ] ) | | ! IS_INTEGER ( argv [ 2 ] ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected two int values for width, height " ) ;
2021-01-25 04:14:25 +03:00
uint32_t width = AS_INTEGER ( argv [ 1 ] ) ;
uint32_t height = AS_INTEGER ( argv [ 2 ] ) ;
yutani_window_resize_accept ( ( ( struct YutaniClass * ) yctxInstance ) - > yctx , self - > window , width , height ) ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _window_resize_done ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_WINDOW ( ) ;
yutani_window_resize_done ( ( ( struct YutaniClass * ) yctxInstance ) - > yctx , self - > window ) ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _window_advertise ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_WINDOW ( ) ;
if ( argc < 2 | | ! IS_STRING ( argv [ 1 ] ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected string for title " ) ;
2021-01-25 04:14:25 +03:00
if ( argc > 2 & & ! IS_STRING ( argv [ 2 ] ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected string for icon " ) ;
2021-01-25 04:14:25 +03:00
if ( argc > 2 ) {
yutani_window_advertise_icon ( ( ( struct YutaniClass * ) yctxInstance ) - > yctx , self - > window , AS_CSTRING ( argv [ 1 ] ) , AS_CSTRING ( argv [ 2 ] ) ) ;
} else {
yutani_window_advertise ( ( ( struct YutaniClass * ) yctxInstance ) - > yctx , self - > window , AS_CSTRING ( argv [ 1 ] ) ) ;
}
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _window_special_request ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 04:14:25 +03:00
CHECK_WINDOW ( ) ;
2021-02-16 12:50:17 +03:00
if ( argc < 2 | | ! IS_INTEGER ( argv [ 1 ] ) ) return krk_runtimeError ( vm . exceptions - > typeError , " expected int for request " ) ;
2021-01-25 04:14:25 +03:00
uint32_t request = AS_INTEGER ( argv [ 1 ] ) ;
yutani_special_request ( ( ( struct YutaniClass * ) yctxInstance ) - > yctx , self - > window , request ) ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _window_reinit ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 14:12:39 +03:00
CHECK_WINDOW ( ) ;
reinit_graphics_yutani ( self - > ctx , self - > window ) ;
return NONE_VAL ( ) ;
}
2021-01-23 09:31:38 +03:00
# define WINDOW_PROPERTY(name) \
2021-02-16 12:50:17 +03:00
static KrkValue _window_ # # name ( int argc , KrkValue argv [ ] , int hasKw ) { \
2021-01-24 13:35:39 +03:00
if ( argc ! = 1 | | ! krk_isInstanceOf ( argv [ 0 ] , YutaniWindow ) ) \
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " Expected Window " ) ; \
2021-01-24 13:35:39 +03:00
struct WindowClass * self = ( struct WindowClass * ) AS_INSTANCE ( argv [ 0 ] ) ; \
2021-01-23 09:31:38 +03:00
return INTEGER_VAL ( self - > window - > name ) ; \
}
WINDOW_PROPERTY ( wid ) ;
2021-01-25 14:12:39 +03:00
WINDOW_PROPERTY ( x ) ;
WINDOW_PROPERTY ( y ) ;
2021-01-23 09:31:38 +03:00
WINDOW_PROPERTY ( focused ) ;
2021-02-16 12:50:17 +03:00
static KrkValue _decor_get_bounds ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-23 09:31:38 +03:00
if ( argc > 0 & & ! krk_isInstanceOf ( argv [ 0 ] , YutaniWindow ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected window " ) ;
2021-01-23 09:31:38 +03:00
struct decor_bounds bounds ;
decor_get_bounds ( ( argc > 0 ) ? ( ( struct WindowClass * ) AS_INSTANCE ( argv [ 0 ] ) ) - > window : NULL ,
& bounds ) ;
2021-02-16 12:50:17 +03:00
KrkValue result = krk_dict_of ( 0 , NULL , 0 ) ;
krk_push ( result ) ;
2021-01-23 09:31:38 +03:00
2021-02-16 12:50:17 +03:00
# define SET(val) krk_attachNamedValue(AS_DICT(result), #val, INTEGER_VAL(bounds. val));
2021-01-23 09:31:38 +03:00
2021-02-16 12:50:17 +03:00
SET ( top_height ) ;
SET ( bottom_height ) ;
SET ( left_width ) ;
SET ( right_width ) ;
SET ( width ) ;
SET ( height ) ;
2021-01-23 09:31:38 +03:00
2021-02-16 12:50:17 +03:00
return krk_pop ( ) ;
2021-01-23 09:31:38 +03:00
}
2021-02-16 12:50:17 +03:00
static KrkValue _decor_handle_event ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-23 09:31:38 +03:00
if ( argc < 1 | | ! krk_isInstanceOf ( argv [ 0 ] , Message ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected message " ) ;
2021-01-23 09:31:38 +03:00
return INTEGER_VAL ( decor_handle_event ( ( ( struct YutaniClass * ) yctxInstance ) - > yctx , ( ( struct MessageClass * ) AS_INSTANCE ( argv [ 0 ] ) ) - > msg ) ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _decor_render ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-23 09:31:38 +03:00
if ( argc < 1 | | ! krk_isInstanceOf ( argv [ 0 ] , YutaniWindow ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected window " ) ;
2021-01-23 09:31:38 +03:00
char * title = ( argc > 1 & & IS_STRING ( argv [ 1 ] ) ) ? AS_CSTRING ( argv [ 1 ] ) : NULL ;
if ( title = = NULL ) {
KrkValue winTitle ;
if ( ! krk_tableGet ( & AS_INSTANCE ( argv [ 0 ] ) - > fields , OBJECT_VAL ( S ( " title " ) ) , & winTitle ) | | ! IS_STRING ( winTitle ) ) {
title = " " ;
} else {
title = AS_CSTRING ( winTitle ) ;
}
}
render_decorations ( ( ( struct WindowClass * ) AS_INSTANCE ( argv [ 0 ] ) ) - > window ,
( ( struct WindowClass * ) AS_INSTANCE ( argv [ 0 ] ) ) - > ctx , title ) ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _decor_show_default_menu ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 14:12:39 +03:00
if ( argc < 1 | | ! krk_isInstanceOf ( argv [ 0 ] , YutaniWindow ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " show_default_menu() expects Window " ) ;
2021-01-25 14:12:39 +03:00
if ( argc < 3 | | ! IS_INTEGER ( argv [ 1 ] ) | | ! IS_INTEGER ( argv [ 2 ] ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " show_default_menu() expects int coordinate pair " ) ;
2021-01-25 14:12:39 +03:00
struct WindowClass * window = ( void * ) AS_INSTANCE ( argv [ 0 ] ) ;
int32_t x = AS_INTEGER ( argv [ 1 ] ) ;
int32_t y = AS_INTEGER ( argv [ 2 ] ) ;
decor_show_default_menu ( window - > window , x , y ) ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _yutani_color_init ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-24 13:35:39 +03:00
if ( argc < 4 | | ! IS_INTEGER ( argv [ 1 ] ) | | ! IS_INTEGER ( argv [ 2 ] ) | | ! IS_INTEGER ( argv [ 3 ] ) | |
2021-02-16 12:50:17 +03:00
( argc > 5 ) | | ( argc = = 5 & & ! IS_INTEGER ( argv [ 4 ] ) ) ) return krk_runtimeError ( vm . exceptions - > typeError , " color() expects three or four integer arguments " ) ;
if ( ! krk_isInstanceOf ( argv [ 0 ] , YutaniColor ) ) return krk_runtimeError ( vm . exceptions - > typeError , " expected color [__init__], not '%s' " , krk_typeName ( argv [ 0 ] ) ) ;
2021-01-24 13:35:39 +03:00
struct YutaniColor * self = ( struct YutaniColor * ) AS_INSTANCE ( argv [ 0 ] ) ;
if ( argc = = 5 ) {
self - > color = rgba ( AS_INTEGER ( argv [ 1 ] ) , AS_INTEGER ( argv [ 2 ] ) , AS_INTEGER ( argv [ 3 ] ) , AS_INTEGER ( argv [ 4 ] ) ) ;
} else {
self - > color = rgb ( AS_INTEGER ( argv [ 1 ] ) , AS_INTEGER ( argv [ 2 ] ) , AS_INTEGER ( argv [ 3 ] ) ) ;
}
return argv [ 0 ] ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _yutani_color_repr ( int argc , KrkValue argv [ ] , int hasKw ) {
if ( argc ! = 1 | | ! krk_isInstanceOf ( argv [ 0 ] , YutaniColor ) ) return krk_runtimeError ( vm . exceptions - > typeError , " expected color [__repr__], not '%s' " , krk_typeName ( argv [ 0 ] ) ) ;
2021-01-24 13:35:39 +03:00
struct YutaniColor * self = ( struct YutaniColor * ) AS_INSTANCE ( argv [ 0 ] ) ;
char tmp [ 30 ] ;
if ( _ALP ( self - > color ) ! = 255 ) {
sprintf ( tmp , " color<#%02x%02x%02x%02x> " , ( int ) _RED ( self - > color ) , ( int ) _GRE ( self - > color ) , ( int ) _BLU ( self - > color ) , ( int ) _ALP ( self - > color ) ) ;
} else {
sprintf ( tmp , " color<#%02x%02x%02x> " , ( int ) _RED ( self - > color ) , ( int ) _GRE ( self - > color ) , ( int ) _BLU ( self - > color ) ) ;
}
return OBJECT_VAL ( krk_copyString ( tmp , strlen ( tmp ) ) ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _yutani_color_str ( int argc , KrkValue argv [ ] , int hasKw ) {
if ( argc ! = 1 | | ! krk_isInstanceOf ( argv [ 0 ] , YutaniColor ) ) return krk_runtimeError ( vm . exceptions - > typeError , " expected color [__str__], not '%s' " , krk_typeName ( argv [ 0 ] ) ) ;
2021-01-24 13:35:39 +03:00
struct YutaniColor * self = ( struct YutaniColor * ) AS_INSTANCE ( argv [ 0 ] ) ;
char tmp [ 30 ] ;
if ( _ALP ( self - > color ) ! = 255 ) {
sprintf ( tmp , " #%02x%02x%02x%02x " , ( int ) _RED ( self - > color ) , ( int ) _GRE ( self - > color ) , ( int ) _BLU ( self - > color ) , ( int ) _ALP ( self - > color ) ) ;
} else {
sprintf ( tmp , " #%02x%02x%02x " , ( int ) _RED ( self - > color ) , ( int ) _GRE ( self - > color ) , ( int ) _BLU ( self - > color ) ) ;
}
return OBJECT_VAL ( krk_copyString ( tmp , strlen ( tmp ) ) ) ;
}
2021-01-25 05:36:38 +03:00
# define CHECK_FONT() \
if ( argc < 1 | | ! krk_isInstanceOf ( argv [ 0 ] , YutaniFont ) ) \
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected Font " ) ; \
2021-01-25 05:36:38 +03:00
struct YutaniFont * self = ( struct YutaniFont * ) AS_INSTANCE ( argv [ 0 ] )
static KrkValue _font_init ( int argc , KrkValue argv [ ] , int hasKw ) {
CHECK_FONT ( ) ;
2021-07-22 14:43:01 +03:00
if ( argc < 2 | | ! IS_STRING ( argv [ 1 ] ) )
return krk_runtimeError ( vm . exceptions - > typeError , " expected string for font name " ) ;
2021-01-25 05:36:38 +03:00
if ( argc < 3 | | ! IS_INTEGER ( argv [ 2 ] ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected int for font size " ) ;
2021-01-25 05:36:38 +03:00
KrkValue fontColor = NONE_VAL ( ) ;
if ( hasKw ) {
krk_tableGet ( AS_DICT ( argv [ argc ] ) , OBJECT_VAL ( S ( " color " ) ) , & fontColor ) ;
2021-02-16 12:50:17 +03:00
if ( ! krk_isInstanceOf ( fontColor , YutaniColor ) ) return krk_runtimeError ( vm . exceptions - > typeError , " expected color " ) ;
2021-01-25 05:36:38 +03:00
}
2021-07-22 14:43:01 +03:00
self - > fontData = tt_font_from_file ( AS_CSTRING ( argv [ 1 ] ) ) ;
if ( ! self - > fontData )
return krk_runtimeError ( vm . exceptions - > typeError , " failed to load font " ) ;
2021-01-25 05:36:38 +03:00
self - > fontSize = AS_INTEGER ( argv [ 2 ] ) ;
2021-07-22 14:43:01 +03:00
tt_set_size ( self - > fontData , self - > fontSize ) ;
2021-01-25 05:36:38 +03:00
self - > fontColor = IS_NONE ( fontColor ) ? rgb ( 0 , 0 , 0 ) : ( ( struct YutaniColor * ) AS_INSTANCE ( fontColor ) ) - > color ;
return argv [ 0 ] ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _font_size ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 14:12:39 +03:00
CHECK_FONT ( ) ;
return INTEGER_VAL ( self - > fontSize ) ;
}
2021-07-22 14:43:01 +03:00
static KrkValue _font_set_size ( int argc , KrkValue argv [ ] , int hasKw ) {
CHECK_FONT ( ) ;
if ( argc < 2 | | ! IS_INTEGER ( argv [ 1 ] ) )
return krk_runtimeError ( vm . exceptions - > typeError , " expected int for font size " ) ;
self - > fontSize = AS_INTEGER ( argv [ 1 ] ) ;
tt_set_size ( self - > fontData , self - > fontSize ) ;
return INTEGER_VAL ( self - > fontSize ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _font_draw_string ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 05:36:38 +03:00
CHECK_FONT ( ) ;
if ( argc < 2 | | ! krk_isInstanceOf ( argv [ 1 ] , GraphicsContext ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected GraphicsContext " ) ;
2021-01-25 05:36:38 +03:00
if ( argc < 3 | | ! IS_STRING ( argv [ 2 ] ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected str " ) ;
2021-01-25 05:36:38 +03:00
if ( argc < 5 | | ! IS_INTEGER ( argv [ 3 ] ) | | ! IS_INTEGER ( argv [ 4 ] ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected int coordinate pair " ) ;
2021-01-25 05:36:38 +03:00
gfx_context_t * ctx = ( ( struct GraphicsContext * ) AS_INSTANCE ( argv [ 1 ] ) ) - > ctx ;
const char * str = AS_CSTRING ( argv [ 2 ] ) ;
int32_t x = AS_INTEGER ( argv [ 3 ] ) ;
int32_t y = AS_INTEGER ( argv [ 4 ] ) ;
2021-07-22 14:43:01 +03:00
return INTEGER_VAL ( tt_draw_string ( ctx , self - > fontData , x , y , str , self - > fontColor ) ) ;
2021-01-25 05:36:38 +03:00
}
2021-02-16 12:50:17 +03:00
static KrkValue _font_width ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 05:36:38 +03:00
CHECK_FONT ( ) ;
if ( argc < 2 | | ! IS_STRING ( argv [ 1 ] ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected str " ) ;
2021-01-25 05:36:38 +03:00
const char * str = AS_CSTRING ( argv [ 1 ] ) ;
2021-07-22 14:43:01 +03:00
return INTEGER_VAL ( tt_string_width ( self - > fontData , str ) ) ;
2021-01-25 05:36:38 +03:00
}
2021-01-25 14:12:39 +03:00
static void _MenuBar_gcsweep ( KrkInstance * _self ) {
struct MenuBarClass * self = ( struct MenuBarClass * ) _self ;
if ( self - > menuBar . entries ) {
for ( size_t i = 0 ; self - > menuBar . entries [ i ] . title ; + + i ) {
free ( self - > menuBar . entries [ i ] . title ) ;
free ( self - > menuBar . entries [ i ] . action ) ;
}
free ( self - > menuBar . entries ) ;
}
}
static void _menubar_callback ( struct menu_bar * _self ) {
struct MenuBarClass * self = _self - > _private ;
KrkValue callback ;
if ( krk_tableGet ( & self - > inst . fields , OBJECT_VAL ( S ( " callback " ) ) , & callback ) ) {
2021-04-17 13:50:20 +03:00
krk_push ( callback ) ;
2021-01-25 14:12:39 +03:00
krk_push ( OBJECT_VAL ( self ) ) ;
2021-04-17 13:50:20 +03:00
krk_callStack ( 1 ) ;
2021-01-25 14:12:39 +03:00
}
}
2021-02-16 12:50:17 +03:00
static KrkValue _MenuBar_init ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 14:12:39 +03:00
if ( argc < 1 | | ! krk_isInstanceOf ( argv [ 0 ] , MenuBarClass ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected MenuBar " ) ;
2021-01-25 14:12:39 +03:00
if ( argc < 2 | | ! IS_TUPLE ( argv [ 1 ] ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected tuple of tuples " ) ;
2021-01-25 14:12:39 +03:00
struct MenuBarClass * self = ( struct MenuBarClass * ) AS_INSTANCE ( argv [ 0 ] ) ;
self - > menuBar . entries = malloc ( sizeof ( struct menu_bar_entries ) * ( AS_TUPLE ( argv [ 1 ] ) - > values . count + 1 ) ) ;
for ( size_t i = 0 ; i < AS_TUPLE ( argv [ 1 ] ) - > values . count ; + + i ) {
if ( ! IS_TUPLE ( AS_TUPLE ( argv [ 1 ] ) - > values . values [ i ] ) | |
AS_TUPLE ( AS_TUPLE ( argv [ 1 ] ) - > values . values [ i ] ) - > values . count ! = 2 | |
! IS_STRING ( AS_TUPLE ( AS_TUPLE ( argv [ 1 ] ) - > values . values [ i ] ) - > values . values [ 0 ] ) | |
! IS_STRING ( AS_TUPLE ( AS_TUPLE ( argv [ 1 ] ) - > values . values [ i ] ) - > values . values [ 1 ] ) ) {
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " invalid menu bar entry: expected (str,str) but %d is '%s' " ,
2021-01-25 14:12:39 +03:00
( int ) i , krk_typeName ( AS_TUPLE ( argv [ 1 ] ) - > values . values [ i ] ) ) ;
}
KrkString * title = AS_STRING ( AS_TUPLE ( AS_TUPLE ( argv [ 1 ] ) - > values . values [ i ] ) - > values . values [ 0 ] ) ;
KrkString * action = AS_STRING ( AS_TUPLE ( AS_TUPLE ( argv [ 1 ] ) - > values . values [ i ] ) - > values . values [ 1 ] ) ;
self - > menuBar . entries [ i ] . title = strdup ( title - > chars ) ;
self - > menuBar . entries [ i ] . action = strdup ( action - > chars ) ;
}
self - > menuBar . entries [ AS_TUPLE ( argv [ 1 ] ) - > values . count ] . title = NULL ;
self - > menuBar . entries [ AS_TUPLE ( argv [ 1 ] ) - > values . count ] . action = NULL ;
self - > menuBar . set = menu_set_create ( ) ;
self - > menuBar . _private = self ;
self - > menuBar . redraw_callback = _menubar_callback ;
krk_attachNamedValue ( & self - > inst . fields , " entries " , argv [ 1 ] ) ;
/* Give ourselves a dict to track the same information */
2021-02-16 12:50:17 +03:00
KrkValue dict = krk_dict_of ( 0 , NULL , 0 ) ;
2021-01-25 14:12:39 +03:00
krk_attachNamedValue ( & self - > inst . fields , " set " , dict ) ;
return argv [ 0 ] ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _MenuBar_place ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 14:12:39 +03:00
if ( argc < 1 | | ! krk_isInstanceOf ( argv [ 0 ] , MenuBarClass ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected MenuBar " ) ;
2021-01-25 14:12:39 +03:00
struct MenuBarClass * self = ( struct MenuBarClass * ) AS_INSTANCE ( argv [ 0 ] ) ;
if ( argc < 4 | | ! IS_INTEGER ( argv [ 1 ] ) | | ! IS_INTEGER ( argv [ 2 ] ) | | ! IS_INTEGER ( argv [ 3 ] ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected int for x, y, width " ) ;
2021-01-25 14:12:39 +03:00
if ( argc < 5 | | ! krk_isInstanceOf ( argv [ 4 ] , YutaniWindow ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected Window " ) ;
2021-01-25 14:12:39 +03:00
self - > menuBar . x = AS_INTEGER ( argv [ 1 ] ) ;
self - > menuBar . y = AS_INTEGER ( argv [ 2 ] ) ;
self - > menuBar . width = AS_INTEGER ( argv [ 3 ] ) ;
self - > menuBar . window = ( ( struct WindowClass * ) AS_INSTANCE ( argv [ 4 ] ) ) - > window ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _MenuBar_render ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 14:12:39 +03:00
if ( argc < 1 | | ! krk_isInstanceOf ( argv [ 0 ] , MenuBarClass ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected MenuBar " ) ;
2021-01-25 14:12:39 +03:00
struct MenuBarClass * self = ( struct MenuBarClass * ) AS_INSTANCE ( argv [ 0 ] ) ;
if ( argc < 2 | | ! krk_isInstanceOf ( argv [ 1 ] , GraphicsContext ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected GraphicsContext " ) ;
2021-01-25 14:12:39 +03:00
menu_bar_render ( & self - > menuBar , ( ( struct GraphicsContext * ) AS_INSTANCE ( argv [ 1 ] ) ) - > ctx ) ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _MenuBar_mouse_event ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 14:12:39 +03:00
if ( argc < 1 | | ! krk_isInstanceOf ( argv [ 0 ] , MenuBarClass ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected MenuBar " ) ;
2021-01-25 14:12:39 +03:00
struct MenuBarClass * self = ( struct MenuBarClass * ) AS_INSTANCE ( argv [ 0 ] ) ;
if ( argc < 3 | | ! krk_isInstanceOf ( argv [ 1 ] , YutaniWindow ) | |
! krk_isInstanceOf ( argv [ 2 ] , Message ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected Window and Message " ) ;
2021-01-25 14:12:39 +03:00
struct MessageClass * msg = ( ( struct MessageClass * ) AS_INSTANCE ( argv [ 2 ] ) ) ;
struct yutani_msg_window_mouse_event * me = ( struct yutani_msg_window_mouse_event * ) msg - > msg - > data ;
return INTEGER_VAL ( menu_bar_mouse_event ( ( ( struct YutaniClass * ) yctxInstance ) - > yctx ,
( ( struct WindowClass * ) AS_INSTANCE ( argv [ 1 ] ) ) - > window ,
& self - > menuBar , me , me - > new_x , me - > new_y ) ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _MenuBar_insert ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 14:12:39 +03:00
if ( argc < 1 | | ! krk_isInstanceOf ( argv [ 0 ] , MenuBarClass ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected MenuBar " ) ;
2021-01-25 14:12:39 +03:00
struct MenuBarClass * self = ( struct MenuBarClass * ) AS_INSTANCE ( argv [ 0 ] ) ;
if ( argc < 3 | | ! IS_STRING ( argv [ 1 ] ) | | ! krk_isInstanceOf ( argv [ 2 ] , MenuListClass ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected str and MenuList " ) ;
2021-01-25 14:12:39 +03:00
menu_set_insert ( self - > menuBar . set , AS_CSTRING ( argv [ 1 ] ) , ( ( struct MenuListClass * ) AS_INSTANCE ( argv [ 2 ] ) ) - > menuList ) ;
/* Also assign it to our dict */
KrkValue dict = NONE_VAL ( ) ;
krk_tableGet ( & self - > inst . fields , OBJECT_VAL ( S ( " set " ) ) , & dict ) ;
2021-02-16 12:50:17 +03:00
if ( IS_NONE ( dict ) | | ! krk_isInstanceOf ( dict , vm . baseClasses - > dictClass ) )
return krk_runtimeError ( vm . exceptions - > baseException , " Failed to get set entries? " ) ;
2021-01-25 14:12:39 +03:00
krk_tableSet ( AS_DICT ( dict ) , argv [ 1 ] , argv [ 2 ] ) ;
return NONE_VAL ( ) ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _MenuList_init ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 14:12:39 +03:00
if ( argc < 1 | | ! krk_isInstanceOf ( argv [ 0 ] , MenuListClass ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected MenuList " ) ;
2021-01-25 14:12:39 +03:00
struct MenuListClass * self = ( struct MenuListClass * ) AS_INSTANCE ( argv [ 0 ] ) ;
self - > menuList = menu_create ( ) ;
/* Give us a list to put entries in for GC tracking and retrieval by kuroko code */
2021-02-16 12:50:17 +03:00
KrkValue list = krk_list_of ( 0 , NULL , 0 ) ;
2021-01-25 14:12:39 +03:00
krk_attachNamedValue ( & self - > inst . fields , " entries " , list ) ;
return argv [ 0 ] ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _MenuList_insert ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 14:12:39 +03:00
if ( argc < 1 | | ! krk_isInstanceOf ( argv [ 0 ] , MenuListClass ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected MenuList " ) ;
2021-01-25 14:12:39 +03:00
struct MenuListClass * self = ( struct MenuListClass * ) AS_INSTANCE ( argv [ 0 ] ) ;
if ( argc < 2 | | ! krk_isInstanceOf ( argv [ 1 ] , MenuEntryClass ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " Expected MenuEntry " ) ;
2021-01-25 14:12:39 +03:00
/* Append to menu */
menu_insert ( self - > menuList , ( ( struct MenuEntryClass * ) AS_INSTANCE ( argv [ 1 ] ) ) - > menuEntry ) ;
/* Append to internal list */
KrkValue list = NONE_VAL ( ) ;
krk_tableGet ( & self - > inst . fields , OBJECT_VAL ( S ( " entries " ) ) , & list ) ;
2021-02-16 12:50:17 +03:00
if ( IS_NONE ( list ) | | ! krk_isInstanceOf ( list , vm . baseClasses - > listClass ) )
return krk_runtimeError ( vm . exceptions - > baseException , " Failed to get entries? " ) ;
2021-01-25 14:12:39 +03:00
krk_writeValueArray ( AS_LIST ( list ) , argv [ 1 ] ) ;
return NONE_VAL ( ) ;
}
static void _MenuEntry_callback_internal ( struct MenuEntry * _self ) {
struct MenuEntryClass * self = ( struct MenuEntryClass * ) _self - > _private ;
KrkValue callback = NONE_VAL ( ) ;
krk_tableGet ( & self - > inst . fields , OBJECT_VAL ( S ( " callback " ) ) , & callback ) ;
2021-04-17 13:50:20 +03:00
krk_push ( callback ) ;
2021-01-25 14:12:39 +03:00
krk_push ( OBJECT_VAL ( self ) ) ;
2021-04-17 13:50:20 +03:00
krk_callStack ( 1 ) ;
2021-01-25 14:12:39 +03:00
}
static KrkValue _MenuEntry_init ( int argc , KrkValue argv [ ] , int hasKw ) {
if ( argc < 1 | | ! krk_isInstanceOf ( argv [ 0 ] , MenuEntryClass ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected MenuEntry " ) ;
2021-01-25 14:12:39 +03:00
struct MenuEntryClass * self = ( struct MenuEntryClass * ) AS_INSTANCE ( argv [ 0 ] ) ;
if ( argc < 3 | | ! IS_STRING ( argv [ 1 ] ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected title and callback " ) ;
2021-01-25 14:12:39 +03:00
KrkValue icon = NONE_VAL ( ) , action = NONE_VAL ( ) ;
if ( hasKw ) {
krk_tableGet ( AS_DICT ( argv [ argc ] ) , OBJECT_VAL ( S ( " icon " ) ) , & icon ) ;
krk_tableGet ( AS_DICT ( argv [ argc ] ) , OBJECT_VAL ( S ( " action " ) ) , & action ) ;
if ( ! IS_NONE ( icon ) & & ! IS_STRING ( icon ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " icon must be str, not '%s' " , krk_typeName ( icon ) ) ;
2021-01-25 14:12:39 +03:00
if ( ! IS_NONE ( action ) & & ! IS_STRING ( action ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " action must be str, not '%s' " , krk_typeName ( action ) ) ;
2021-01-25 14:12:39 +03:00
}
self - > menuEntry = menu_create_normal (
IS_STRING ( icon ) ? AS_CSTRING ( icon ) : NULL ,
IS_STRING ( action ) ? AS_CSTRING ( action ) : NULL ,
AS_CSTRING ( argv [ 1 ] ) ,
_MenuEntry_callback_internal ) ;
self - > menuEntry - > _private = self ;
krk_attachNamedValue ( & self - > inst . fields , " callback " , argv [ 2 ] ) ;
return argv [ 0 ] ;
}
/* TODO properties: icon, action, title */
static KrkValue _MenuEntrySubmenu_init ( int argc , KrkValue argv [ ] , int hasKw ) {
if ( argc < 1 | | ! krk_isInstanceOf ( argv [ 0 ] , MenuEntrySubmenuClass ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected MenuEntrySubmenu " ) ;
2021-01-25 14:12:39 +03:00
struct MenuEntryClass * self = ( struct MenuEntryClass * ) AS_INSTANCE ( argv [ 0 ] ) ;
if ( argc < 2 | | ! IS_STRING ( argv [ 1 ] ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected title to be a str " ) ;
2021-01-25 14:12:39 +03:00
KrkValue icon = NONE_VAL ( ) , action = NONE_VAL ( ) ;
if ( hasKw ) {
krk_tableGet ( AS_DICT ( argv [ argc ] ) , OBJECT_VAL ( S ( " icon " ) ) , & icon ) ;
krk_tableGet ( AS_DICT ( argv [ argc ] ) , OBJECT_VAL ( S ( " action " ) ) , & action ) ;
if ( ! IS_NONE ( icon ) & & ! IS_STRING ( icon ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " icon must be str, not '%s' " , krk_typeName ( icon ) ) ;
2021-01-25 14:12:39 +03:00
if ( ! IS_NONE ( action ) & & ! IS_STRING ( action ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " action must be str, not '%s' " , krk_typeName ( action ) ) ;
2021-01-25 14:12:39 +03:00
}
self - > menuEntry = menu_create_submenu (
IS_STRING ( icon ) ? AS_CSTRING ( icon ) : NULL ,
IS_STRING ( action ) ? AS_CSTRING ( action ) : NULL ,
AS_CSTRING ( argv [ 1 ] ) ) ;
self - > menuEntry - > _private = self ;
return argv [ 0 ] ;
}
2021-02-16 12:50:17 +03:00
static KrkValue _MenuEntrySeparator_init ( int argc , KrkValue argv [ ] , int hasKw ) {
2021-01-25 14:12:39 +03:00
if ( argc < 1 | | ! krk_isInstanceOf ( argv [ 0 ] , MenuEntrySeparatorClass ) )
2021-02-16 12:50:17 +03:00
return krk_runtimeError ( vm . exceptions - > typeError , " expected MenuEntrySeparator " ) ;
2021-01-25 14:12:39 +03:00
struct MenuEntryClass * self = ( struct MenuEntryClass * ) AS_INSTANCE ( argv [ 0 ] ) ;
self - > menuEntry = menu_create_separator ( ) ;
self - > menuEntry - > _private = self ;
return argv [ 0 ] ;
}
2021-01-21 15:20:59 +03:00
KrkValue krk_module_onload__yutani ( void ) {
2021-02-16 12:50:17 +03:00
module = krk_newInstance ( vm . baseClasses - > moduleClass ) ;
2021-01-21 15:20:59 +03:00
/* Store it on the stack for now so we can do stuff that may trip GC
* and not lose it to garbage colletion . . . */
krk_push ( OBJECT_VAL ( module ) ) ;
/**
* class Message ( object ) :
* MSG_ . . . = . . . # Directly from the library headers .
*/
Message = krk_createClass ( module , " Message " , NULL ) ;
2021-01-23 03:26:04 +03:00
Message - > allocSize = sizeof ( struct MessageClass ) ;
Message - > _ongcsweep = _message_sweep ;
2021-01-21 15:20:59 +03:00
/* All the MSG_ constants */
2021-03-18 03:57:22 +03:00
# define TYPE(type) krk_attachNamedValue(&Message->methods, "MSG_" #type, INTEGER_VAL(YUTANI_MSG_ ## type))
2021-01-21 15:20:59 +03:00
TYPE ( HELLO ) ; TYPE ( WINDOW_NEW ) ; TYPE ( FLIP ) ; TYPE ( KEY_EVENT ) ; TYPE ( MOUSE_EVENT ) ;
TYPE ( WINDOW_MOVE ) ; TYPE ( WINDOW_CLOSE ) ; TYPE ( WINDOW_SHOW ) ; TYPE ( WINDOW_HIDE ) ;
TYPE ( WINDOW_STACK ) ; TYPE ( WINDOW_FOCUS_CHANGE ) ; TYPE ( WINDOW_MOUSE_EVENT ) ;
TYPE ( FLIP_REGION ) ; TYPE ( WINDOW_NEW_FLAGS ) ; TYPE ( RESIZE_REQUEST ) ;
TYPE ( RESIZE_OFFER ) ; TYPE ( RESIZE_ACCEPT ) ; TYPE ( RESIZE_BUFID ) ; TYPE ( RESIZE_DONE ) ;
TYPE ( WINDOW_ADVERTISE ) ; TYPE ( SUBSCRIBE ) ; TYPE ( UNSUBSCRIBE ) ; TYPE ( NOTIFY ) ;
TYPE ( QUERY_WINDOWS ) ; TYPE ( WINDOW_FOCUS ) ; TYPE ( WINDOW_DRAG_START ) ; TYPE ( WINDOW_WARP_MOUSE ) ;
TYPE ( WINDOW_SHOW_MOUSE ) ; TYPE ( WINDOW_RESIZE_START ) ; TYPE ( SESSION_END ) ;
TYPE ( KEY_BIND ) ; TYPE ( WINDOW_UPDATE_SHAPE ) ; TYPE ( CLIPBOARD ) ; TYPE ( GOODBYE ) ;
TYPE ( SPECIAL_REQUEST ) ; TYPE ( WELCOME ) ; TYPE ( WINDOW_INIT ) ;
# undef TYPE
/* Structure bindings */
2021-03-25 09:53:40 +03:00
krk_defineNative ( & Message - > methods , " __getattr__ " , _message_getattr ) ;
2021-01-21 15:20:59 +03:00
krk_finalizeClass ( Message ) ;
2021-01-25 03:21:38 +03:00
/**
* class color ( ) :
* rgb ( a ) value for use with graphics functions .
*/
2021-01-24 13:35:39 +03:00
YutaniColor = krk_createClass ( module , " color " , NULL ) ;
YutaniColor - > allocSize = sizeof ( struct YutaniColor ) ;
2021-01-25 05:36:38 +03:00
YutaniColor - > docstring = S ( " color(r,g,b,a=255) \n Representation of an RGB(A) color. " ) ;
2021-03-25 09:53:40 +03:00
krk_defineNative ( & YutaniColor - > methods , " __init__ " , _yutani_color_init ) ;
krk_defineNative ( & YutaniColor - > methods , " __repr__ " , _yutani_color_repr ) ;
krk_defineNative ( & YutaniColor - > methods , " __str__ " , _yutani_color_str ) ;
2021-01-24 13:35:39 +03:00
krk_finalizeClass ( YutaniColor ) ;
2021-01-21 15:20:59 +03:00
/**
* class Yutani ( object ) :
2021-01-23 03:26:04 +03:00
* yctx = yutani_t *
* display_width = yctx - > display_width
* display_height = yctx - > display_height
2021-01-21 15:20:59 +03:00
*
2021-01-23 03:26:04 +03:00
* def __init__ ( self ) : # Call yutani_init ( )
2021-01-21 15:20:59 +03:00
*/
Yutani = krk_createClass ( module , " Yutani " , NULL ) ;
2021-01-23 03:26:04 +03:00
Yutani - > allocSize = sizeof ( struct YutaniClass ) ;
2021-01-25 05:36:38 +03:00
Yutani - > docstring = S ( " Yutani() \n Establish a connection to the compositor display server. " ) ;
2021-03-25 09:53:40 +03:00
krk_defineNative ( & Yutani - > methods , " display_width " , _yutani_display_width ) - > flags | = KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY ;
krk_defineNative ( & Yutani - > methods , " display_height " , _yutani_display_height ) - > flags | = KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY ;
krk_defineNative ( & Yutani - > methods , " __repr__ " , _yutani_repr ) ;
krk_defineNative ( & Yutani - > methods , " __init__ " , _yutani_init ) ;
krk_defineNative ( & Yutani - > methods , " poll " , _yutani_poll ) ;
krk_defineNative ( & Yutani - > methods , " wait_for " , _yutani_wait_for ) ;
krk_defineNative ( & Yutani - > methods , " subscribe " , _yutani_subscribe ) ;
krk_defineNative ( & Yutani - > methods , " unsubscribe " , _yutani_unsubscribe ) ;
krk_defineNative ( & Yutani - > methods , " query_windows " , _yutani_query_windows ) ;
krk_defineNative ( & Yutani - > methods , " fileno " , _yutani_fileno ) ;
krk_defineNative ( & Yutani - > methods , " query " , _yutani_query ) ;
krk_defineNative ( & Yutani - > methods , " menu_process_event " , _yutani_menu_process_event ) ;
2021-01-25 04:14:25 +03:00
#if 0
2021-03-25 09:53:40 +03:00
krk_defineNative ( & Yutani - > methods , " focus_window " , _yutani_focus_window ) ;
krk_defineNative ( & Yutani - > methods , " session_end " , _yutani_session_end ) ;
krk_defineNative ( & Yutani - > methods , " key_bind " , _yutani_key_bind ) ;
2021-01-21 15:20:59 +03:00
# endif
krk_finalizeClass ( Yutani ) ;
2021-01-25 04:14:25 +03:00
/**
* class GraphicsContext ( ) :
* ctx = gfx_context_t *
*/
2021-01-24 13:35:39 +03:00
GraphicsContext = krk_createClass ( module , " GraphicsContext " , NULL ) ;
GraphicsContext - > allocSize = sizeof ( struct GraphicsContext ) ;
2021-03-25 09:53:40 +03:00
krk_defineNative ( & GraphicsContext - > methods , " width " , _gfx_width ) - > flags | = KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY ;
krk_defineNative ( & GraphicsContext - > methods , " height " , _gfx_height ) - > flags | = KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY ;
krk_defineNative ( & GraphicsContext - > methods , " fill " , _gfx_fill ) - > doc =
2021-01-25 05:36:38 +03:00
" GraphicsContext.fill(color) \n "
" Fill the entire context with the given color. " ;
2021-03-25 09:53:40 +03:00
krk_defineNative ( & GraphicsContext - > methods , " flip " , _gfx_flip ) - > doc =
2021-01-25 05:36:38 +03:00
" GraphicsContext.flip() \n "
" If the context is double-buffered, flip its backbuffer. " ;
2021-03-25 09:53:40 +03:00
krk_defineNative ( & GraphicsContext - > methods , " blur " , _gfx_blur ) - > doc =
2021-01-25 05:36:38 +03:00
" GraphicsContext.blur(radius=2) \n "
" Perform an in-place box blur on this graphics context. " ;
2021-03-25 09:53:40 +03:00
krk_defineNative ( & GraphicsContext - > methods , " line " , _gfx_line ) - > doc =
2021-01-25 05:36:38 +03:00
" GraphicsContext.line(x0,x1,y0,y1,color,thickness=None) \n "
" Draw a line between the given points. If thickness is not provided, uses a \n "
" a simple Bresenham algorithm. If thickness is an int, draws with a box-shaped pen. \n "
" If thickness is a float, draws using a point-distance antialiasing algorithm. " ;
2021-03-25 09:53:40 +03:00
krk_defineNative ( & GraphicsContext - > methods , " rect " , _gfx_rect ) - > doc =
2021-01-25 05:36:38 +03:00
" GraphicsContext.rect(x,y,width,height,color,solid=False,radius=None) \n "
" Draw a filled rectangle. If solid is True, paints the given color directly to \n "
" the underlying backbuffer with no alpha calculations. If radius is provided, \n "
" draws a rounded rectangle. " ;
2021-03-25 09:53:40 +03:00
krk_defineNative ( & GraphicsContext - > methods , " draw_sprite " , _gfx_draw_sprite ) - > doc =
2021-01-25 05:36:38 +03:00
" GraphicsContext.draw_sprite(sprite,x,y,alpha=None,rotation=None,scale=None,color=None) \n "
" Blit a sprite to this graphics context at the given coordinates. \n "
" alpha: float of opacity; 1.0 = fully opaque (default) \n "
" rotation: float of radians; when a rotation is given, the coordinates provided are \n "
" the center of the rendered sprite, rather than the upper left corner. \n "
" scale: (int,int) of final resolution of sprite; can not be used with rotation. \n "
" color: color to paint the sprite as, can not be used with rotation or scale; \n "
" used to paint a given color with this sprite as a 'brush'. Useful for \n "
" colored icons, such as those found in the panel. " ;
2021-01-24 13:35:39 +03:00
krk_finalizeClass ( GraphicsContext ) ;
2021-01-25 04:14:25 +03:00
/**
* class Window ( GraphicsContext ) :
* ctx = gfx_context_t *
* window = yutani_window_t *
*/
2021-01-24 13:35:39 +03:00
YutaniWindow = krk_createClass ( module , " Window " , GraphicsContext ) ;
2021-01-23 09:31:38 +03:00
YutaniWindow - > allocSize = sizeof ( struct WindowClass ) ;
2021-01-25 05:36:38 +03:00
YutaniWindow - > docstring = S ( " Window(width,height,flags=0,title=None,icon=None,doublebuffer=False) \n "
" Create a new window and initializes a graphics rendering context for it. " ) ;
2021-03-25 09:53:40 +03:00
krk_defineNative ( & YutaniWindow - > methods , " __repr__ " , _window_repr ) ;
krk_defineNative ( & YutaniWindow - > methods , " __init__ " , _window_init ) ;
krk_defineNative ( & YutaniWindow - > methods , " flip " , _window_flip ) ;
krk_defineNative ( & YutaniWindow - > methods , " move " , _window_move ) ;
krk_defineNative ( & YutaniWindow - > methods , " set_focused " , _window_set_focused ) ;
krk_defineNative ( & YutaniWindow - > methods , " close " , _window_close ) ;
krk_defineNative ( & YutaniWindow - > methods , " set_stack " , _window_set_stack ) ;
krk_defineNative ( & YutaniWindow - > methods , " special_request " , _window_special_request ) ;
krk_defineNative ( & YutaniWindow - > methods , " resize " , _window_resize ) ;
krk_defineNative ( & YutaniWindow - > methods , " resize_start " , _window_resize_start ) ;
krk_defineNative ( & YutaniWindow - > methods , " resize_done " , _window_resize_done ) ;
krk_defineNative ( & YutaniWindow - > methods , " resize_offer " , _window_resize_offer ) ;
krk_defineNative ( & YutaniWindow - > methods , " resize_accept " , _window_resize_accept ) ;
krk_defineNative ( & YutaniWindow - > methods , " update_shape " , _window_update_shape ) ;
krk_defineNative ( & YutaniWindow - > methods , " show_mouse " , _window_show_mouse ) ;
krk_defineNative ( & YutaniWindow - > methods , " warp_mouse " , _window_warp_mouse ) ;
krk_defineNative ( & YutaniWindow - > methods , " set_stack " , _window_set_stack ) ;
krk_defineNative ( & YutaniWindow - > methods , " advertise " , _window_advertise ) ;
krk_defineNative ( & YutaniWindow - > methods , " reinit " , _window_reinit ) ;
krk_defineNative ( & YutaniWindow - > methods , " wid " , _window_wid ) - > flags | = KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY ;
krk_defineNative ( & YutaniWindow - > methods , " x " , _window_x ) - > flags | = KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY ;
krk_defineNative ( & YutaniWindow - > methods , " y " , _window_y ) - > flags | = KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY ;
krk_defineNative ( & YutaniWindow - > methods , " focused " , _window_focused ) - > flags | = KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY ;
2021-01-23 09:31:38 +03:00
krk_finalizeClass ( YutaniWindow ) ;
2021-01-25 04:14:25 +03:00
/**
* class Sprite ( GraphicsContext ) :
* ctx = gfx_context_t *
* sprite = sprite_t
*/
2021-01-24 15:47:50 +03:00
YutaniSprite = krk_createClass ( module , " Sprite " , GraphicsContext ) ;
YutaniSprite - > allocSize = sizeof ( struct YutaniSprite ) ;
YutaniSprite - > _ongcsweep = _sprite_sweep ;
2021-01-25 05:36:38 +03:00
YutaniSprite - > docstring = S ( " Sprite(filename) \n Create a sprite from the requested texture file. " ) ;
2021-03-25 09:53:40 +03:00
krk_defineNative ( & YutaniSprite - > methods , " __repr__ " , _sprite_repr ) ;
krk_defineNative ( & YutaniSprite - > methods , " __init__ " , _sprite_init ) ;
2021-01-24 15:47:50 +03:00
krk_finalizeClass ( YutaniSprite ) ;
2021-01-25 05:36:38 +03:00
/**
* class Font ( ) :
* fontType , fontSize , fontGamma , fontStroke
*/
YutaniFont = krk_createClass ( module , " Font " , NULL ) ;
YutaniFont - > allocSize = sizeof ( struct YutaniFont ) ;
YutaniFont - > docstring = S ( " Font(type,size,gamma=1.7,stroke=0.75,color=color(0,0,0)) \n "
" Create a Font specification for rendering text. " ) ;
2021-03-25 09:53:40 +03:00
krk_defineNative ( & YutaniFont - > methods , " __init__ " , _font_init ) ;
krk_defineNative ( & YutaniFont - > methods , " draw_string " , _font_draw_string ) - > doc =
2021-01-25 05:36:38 +03:00
" Font.draw_string(gfxContext, string, x, y) \n "
" Draw text to a graphics context with this font. " ;
2021-03-25 09:53:40 +03:00
krk_defineNative ( & YutaniFont - > methods , " width " , _font_width ) - > doc =
2021-01-25 05:36:38 +03:00
" Font.width(string) \n "
" Calculate the rendered width of the given string when drawn with this font. " ;
2021-03-25 09:53:40 +03:00
krk_defineNative ( & YutaniFont - > methods , " size " , _font_size ) - > flags | = KRK_NATIVE_FLAGS_IS_DYNAMIC_PROPERTY ;
2021-07-22 14:43:01 +03:00
krk_defineNative ( & YutaniFont - > methods , " set_size " , _font_set_size ) ;
2021-01-25 05:36:38 +03:00
krk_finalizeClass ( YutaniFont ) ;
2021-01-25 14:12:39 +03:00
MenuBarClass = krk_createClass ( module , " MenuBar " , NULL ) ;
MenuBarClass - > allocSize = sizeof ( struct MenuBarClass ) ;
MenuBarClass - > _ongcsweep = _MenuBar_gcsweep ;
2021-03-25 09:53:40 +03:00
krk_defineNative ( & MenuBarClass - > methods , " __init__ " , _MenuBar_init ) ;
krk_defineNative ( & MenuBarClass - > methods , " place " , _MenuBar_place ) ;
krk_defineNative ( & MenuBarClass - > methods , " render " , _MenuBar_render ) ;
krk_defineNative ( & MenuBarClass - > methods , " mouse_event " , _MenuBar_mouse_event ) ;
krk_defineNative ( & MenuBarClass - > methods , " insert " , _MenuBar_insert ) ;
2021-01-25 14:12:39 +03:00
krk_finalizeClass ( MenuBarClass ) ;
MenuListClass = krk_createClass ( module , " MenuList " , NULL ) ;
MenuListClass - > allocSize = sizeof ( struct MenuListClass ) ;
2021-03-25 09:53:40 +03:00
krk_defineNative ( & MenuListClass - > methods , " __init__ " , _MenuList_init ) ;
krk_defineNative ( & MenuListClass - > methods , " insert " , _MenuList_insert ) ;
2021-01-25 14:12:39 +03:00
krk_finalizeClass ( MenuListClass ) ;
MenuEntryClass = krk_createClass ( module , " MenuEntry " , NULL ) ;
MenuEntryClass - > allocSize = sizeof ( struct MenuEntryClass ) ;
2021-03-25 09:53:40 +03:00
krk_defineNative ( & MenuEntryClass - > methods , " __init__ " , _MenuEntry_init ) ;
2021-01-25 14:12:39 +03:00
krk_finalizeClass ( MenuEntryClass ) ;
MenuEntrySubmenuClass = krk_createClass ( module , " MenuEntrySubmenu " , MenuEntryClass ) ;
2021-03-25 09:53:40 +03:00
krk_defineNative ( & MenuEntrySubmenuClass - > methods , " __init__ " , _MenuEntrySubmenu_init ) ;
2021-01-25 14:12:39 +03:00
krk_finalizeClass ( MenuEntrySubmenuClass ) ;
MenuEntrySeparatorClass = krk_createClass ( module , " MenuEntrySeparator " , MenuEntryClass ) ;
2021-03-25 09:53:40 +03:00
krk_defineNative ( & MenuEntrySeparatorClass - > methods , " __init__ " , _MenuEntrySeparator_init ) ;
2021-01-25 14:12:39 +03:00
krk_finalizeClass ( MenuEntrySeparatorClass ) ;
2021-03-25 09:53:40 +03:00
KrkInstance * Decorator = krk_newInstance ( vm . baseClasses - > objectClass ) ;
krk_attachNamedObject ( & module - > fields , " Decorator " , ( KrkObj * ) Decorator ) ;
krk_defineNative ( & Decorator - > fields , " get_bounds " , _decor_get_bounds ) ;
krk_defineNative ( & Decorator - > fields , " render " , _decor_render ) ;
krk_defineNative ( & Decorator - > fields , " handle_event " , _decor_handle_event ) ;
krk_defineNative ( & Decorator - > fields , " show_default_menu " , _decor_show_default_menu ) ;
# define ATTACH_CONSTANT(name) krk_attachNamedValue(&Decorator->fields, #name, INTEGER_VAL(name))
2021-01-25 14:12:39 +03:00
ATTACH_CONSTANT ( DECOR_OTHER ) ;
ATTACH_CONSTANT ( DECOR_CLOSE ) ;
ATTACH_CONSTANT ( DECOR_RESIZE ) ;
ATTACH_CONSTANT ( DECOR_MAXIMIZE ) ;
ATTACH_CONSTANT ( DECOR_RIGHT ) ;
ATTACH_CONSTANT ( DECOR_ACTIVE ) ;
ATTACH_CONSTANT ( DECOR_INACTIVE ) ;
ATTACH_CONSTANT ( DECOR_FLAG_DECORATED ) ;
ATTACH_CONSTANT ( DECOR_FLAG_NO_MAXIMIZE ) ;
ATTACH_CONSTANT ( DECOR_FLAG_TILED ) ;
ATTACH_CONSTANT ( DECOR_FLAG_TILE_LEFT ) ;
ATTACH_CONSTANT ( DECOR_FLAG_TILE_RIGHT ) ;
ATTACH_CONSTANT ( DECOR_FLAG_TILE_UP ) ;
ATTACH_CONSTANT ( DECOR_FLAG_TILE_DOWN ) ;
# undef ATTACH_CONSTANT
2021-01-23 09:31:38 +03:00
2021-01-21 15:20:59 +03:00
/* Pop the module object before returning; it'll get pushed again
* by the VM before the GC has a chance to run , so it ' s safe . */
assert ( AS_INSTANCE ( krk_pop ( ) ) = = module ) ;
return OBJECT_VAL ( module ) ;
}