gg: native rendering mode on macOS
							parent
							
								
									a3908414e4
								
							
						
					
					
						commit
						d991712b3c
					
				|  | @ -8,7 +8,7 @@ | ||||||
| - Consts can now be declared outside of `const()` blocks: `const x = 0`. | - Consts can now be declared outside of `const()` blocks: `const x = 0`. | ||||||
| - Overloading of  `>`, `<`, `!=`, `==`, `<=` and `>=` operators. | - Overloading of  `>`, `<`, `!=`, `==`, `<=` and `>=` operators. | ||||||
| - New struct updating syntax: `User{ ...u, name: 'new' }` to replace `{ u | name: 'new' }`. | - New struct updating syntax: `User{ ...u, name: 'new' }` to replace `{ u | name: 'new' }`. | ||||||
| - `byte.str()` has been fixed and works like with all other numbers. `byte.ascii_str()` has been added. | - `byte.str()` has been fixed and works like all other numbers. `byte.ascii_str()` has been added. | ||||||
| - Smart cast in for loops: `for mut x is string {}`. | - Smart cast in for loops: `for mut x is string {}`. | ||||||
| - `[noinit]` struct attribute to disallow direct struct initialization with `Foo{}`. | - `[noinit]` struct attribute to disallow direct struct initialization with `Foo{}`. | ||||||
| - Array decompose: `[1, 2, 3]...` is now `...[1, 2, 3]` | - Array decompose: `[1, 2, 3]...` is now `...[1, 2, 3]` | ||||||
|  |  | ||||||
|  | @ -22,6 +22,7 @@ const ( | ||||||
| 		'vlib/bitfield/', | 		'vlib/bitfield/', | ||||||
| 		'vlib/builtin/array.v', | 		'vlib/builtin/array.v', | ||||||
| 		'vlib/builtin/array_test.v', | 		'vlib/builtin/array_test.v', | ||||||
|  | 		'vlib/builtin/string.v', | ||||||
| 		'vlib/builtin/map.v', | 		'vlib/builtin/map.v', | ||||||
| 		'vlib/math/bits/bits.v', | 		'vlib/math/bits/bits.v', | ||||||
| 		'vlib/orm/', | 		'vlib/orm/', | ||||||
|  |  | ||||||
|  | @ -174,7 +174,7 @@ FONS_DEF void fonsDrawDebug(FONScontext* s, float x, float y); | ||||||
| 
 | 
 | ||||||
| #undef FONS_USE_FREETYPE | #undef FONS_USE_FREETYPE | ||||||
| 
 | 
 | ||||||
| //#define FONS_USE_FREETYPE
 | //#define FONS_USE_FREETYPE 1
 | ||||||
| 
 | 
 | ||||||
| #ifdef FONS_USE_FREETYPE | #ifdef FONS_USE_FREETYPE | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -971,6 +971,7 @@ typedef struct sapp_desc { | ||||||
|     bool html5_ask_leave_site;          /* initial state of the internal html5_ask_leave_site flag (see sapp_html5_ask_leave_site()) */ |     bool html5_ask_leave_site;          /* initial state of the internal html5_ask_leave_site flag (see sapp_html5_ask_leave_site()) */ | ||||||
|     bool ios_keyboard_resizes_canvas;   /* if true, showing the iOS keyboard shrinks the canvas */ |     bool ios_keyboard_resizes_canvas;   /* if true, showing the iOS keyboard shrinks the canvas */ | ||||||
|     bool gl_force_gles2;                /* if true, setup GLES2/WebGL even if GLES3/WebGL2 is available */ |     bool gl_force_gles2;                /* if true, setup GLES2/WebGL even if GLES3/WebGL2 is available */ | ||||||
|  |    bool native_render; | ||||||
| } sapp_desc; | } sapp_desc; | ||||||
| 
 | 
 | ||||||
| /* user-provided functions */ | /* user-provided functions */ | ||||||
|  | @ -1360,12 +1361,18 @@ inline int sapp_run(const sapp_desc& desc) { return sapp_run(&desc); } | ||||||
| } | } | ||||||
| @end | @end | ||||||
| 
 | 
 | ||||||
|  |     @interface MyView2 : NSView | ||||||
|  |     @end | ||||||
|  | 
 | ||||||
|  |    MyView2* g_view; | ||||||
|  | 
 | ||||||
| // A custom NSWindow interface to handle events in borderless windows.
 | // A custom NSWindow interface to handle events in borderless windows.
 | ||||||
| @implementation SokolWindow | @implementation SokolWindow | ||||||
| - (BOOL)canBecomeKeyWindow { return YES; } // needed for NSWindowStyleMaskBorderless
 | - (BOOL)canBecomeKeyWindow { return YES; } // needed for NSWindowStyleMaskBorderless
 | ||||||
| - (BOOL)canBecomeMainWindow { return YES; } | - (BOOL)canBecomeMainWindow { return YES; } | ||||||
| @end | @end | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| @interface _sapp_macos_app_delegate : NSObject<NSApplicationDelegate> | @interface _sapp_macos_app_delegate : NSObject<NSApplicationDelegate> | ||||||
| @end | @end | ||||||
| @interface _sapp_macos_window_delegate : NSObject<NSWindowDelegate> | @interface _sapp_macos_window_delegate : NSObject<NSWindowDelegate> | ||||||
|  | @ -1846,6 +1853,7 @@ typedef struct { | ||||||
|     char window_title[_SAPP_MAX_TITLE_LENGTH];      /* UTF-8 */ |     char window_title[_SAPP_MAX_TITLE_LENGTH];      /* UTF-8 */ | ||||||
|     wchar_t window_title_wide[_SAPP_MAX_TITLE_LENGTH];   /* UTF-32 or UCS-2 */ |     wchar_t window_title_wide[_SAPP_MAX_TITLE_LENGTH];   /* UTF-32 or UCS-2 */ | ||||||
|     sapp_keycode keycodes[SAPP_MAX_KEYCODES]; |     sapp_keycode keycodes[SAPP_MAX_KEYCODES]; | ||||||
|  | bool   native_render; | ||||||
| } _sapp_t; | } _sapp_t; | ||||||
| static _sapp_t _sapp; | static _sapp_t _sapp; | ||||||
| 
 | 
 | ||||||
|  | @ -2235,7 +2243,23 @@ _SOKOL_PRIVATE void _sapp_call_init(void) { | ||||||
|     _sapp.init_called = true; |     _sapp.init_called = true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| _SOKOL_PRIVATE void _sapp_call_frame(void) { | _SOKOL_PRIVATE void _sapp_call_frame(void) { | ||||||
|  | 	if (_sapp.native_render) { | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |     if (_sapp.init_called && !_sapp.cleanup_called) { | ||||||
|  |         if (_sapp.desc.frame_cb) { | ||||||
|  |             _sapp.desc.frame_cb(); | ||||||
|  |         } | ||||||
|  |         else if (_sapp.desc.frame_userdata_cb) { | ||||||
|  |             _sapp.desc.frame_userdata_cb(_sapp.desc.user_data); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | _SOKOL_PRIVATE void _sapp_call_frame2(void) { | ||||||
|     if (_sapp.init_called && !_sapp.cleanup_called) { |     if (_sapp.init_called && !_sapp.cleanup_called) { | ||||||
|         if (_sapp.desc.frame_cb) { |         if (_sapp.desc.frame_cb) { | ||||||
|             _sapp.desc.frame_cb(); |             _sapp.desc.frame_cb(); | ||||||
|  | @ -2328,6 +2352,7 @@ _SOKOL_PRIVATE void _sapp_init_state(const sapp_desc* desc) { | ||||||
|     _sapp.dpi_scale = 1.0f; |     _sapp.dpi_scale = 1.0f; | ||||||
|     _sapp.fullscreen = _sapp.desc.fullscreen; |     _sapp.fullscreen = _sapp.desc.fullscreen; | ||||||
|     _sapp.mouse.shown = true; |     _sapp.mouse.shown = true; | ||||||
|  |     _sapp.native_render = _sapp.desc.native_render; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| _SOKOL_PRIVATE void _sapp_discard_state(void) { | _SOKOL_PRIVATE void _sapp_discard_state(void) { | ||||||
|  | @ -2740,6 +2765,27 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) { | ||||||
|     _sapp.macos.window.title = [NSString stringWithUTF8String:_sapp.window_title]; |     _sapp.macos.window.title = [NSString stringWithUTF8String:_sapp.window_title]; | ||||||
|     _sapp.macos.window.acceptsMouseMovedEvents = YES; |     _sapp.macos.window.acceptsMouseMovedEvents = YES; | ||||||
|     _sapp.macos.window.restorable = YES; |     _sapp.macos.window.restorable = YES; | ||||||
|  | 	_sapp.macos.window.backgroundColor = [NSColor whiteColor]; | ||||||
|  | 
 | ||||||
|  | 	// Quit menu
 | ||||||
|  | 	NSMenu* menu_bar = [[NSMenu alloc] init]; | ||||||
|  | NSMenuItem* app_menu_item = [[NSMenuItem alloc] init]; | ||||||
|  | [menu_bar addItem:app_menu_item]; | ||||||
|  | NSApp.mainMenu = menu_bar; | ||||||
|  | NSMenu* app_menu = [[NSMenu alloc] init]; | ||||||
|  | NSString* window_title_as_nsstring = [NSString stringWithUTF8String:_sapp.window_title]; | ||||||
|  | // `quit_title` memory will be owned by the NSMenuItem, so no need to release it ourselves
 | ||||||
|  | NSString* quit_title =  [@"Quit " stringByAppendingString:window_title_as_nsstring]; | ||||||
|  | NSMenuItem* quit_menu_item = [[NSMenuItem alloc] | ||||||
|  | 	initWithTitle:quit_title | ||||||
|  | 	action:@selector(terminate:) | ||||||
|  | 	keyEquivalent:@"q"]; | ||||||
|  | [app_menu addItem:quit_menu_item]; | ||||||
|  | app_menu_item.submenu = app_menu; | ||||||
|  | _SAPP_OBJC_RELEASE( window_title_as_nsstring ); | ||||||
|  | _SAPP_OBJC_RELEASE( app_menu ); | ||||||
|  | _SAPP_OBJC_RELEASE( app_menu_item ); | ||||||
|  | _SAPP_OBJC_RELEASE( menu_bar ); | ||||||
| 
 | 
 | ||||||
|     _sapp.macos.win_dlg = [[_sapp_macos_window_delegate alloc] init]; |     _sapp.macos.win_dlg = [[_sapp_macos_window_delegate alloc] init]; | ||||||
|     _sapp.macos.window.delegate = _sapp.macos.win_dlg; |     _sapp.macos.window.delegate = _sapp.macos.win_dlg; | ||||||
|  | @ -2796,6 +2842,7 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) { | ||||||
|         _sapp.macos.window.contentView = _sapp.macos.view; |         _sapp.macos.window.contentView = _sapp.macos.view; | ||||||
|         [_sapp.macos.window makeFirstResponder:_sapp.macos.view]; |         [_sapp.macos.window makeFirstResponder:_sapp.macos.view]; | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|         NSTimer* timer_obj = [NSTimer timerWithTimeInterval:0.001 |         NSTimer* timer_obj = [NSTimer timerWithTimeInterval:0.001 | ||||||
|             target:_sapp.macos.view |             target:_sapp.macos.view | ||||||
|             selector:@selector(timerFired:) |             selector:@selector(timerFired:) | ||||||
|  | @ -2814,6 +2861,40 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) { | ||||||
|         [_sapp.macos.window center]; |         [_sapp.macos.window center]; | ||||||
|     } |     } | ||||||
|    */ |    */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |        ///////////////////////////////////////////////////////
 | ||||||
|  | 
 | ||||||
|  |    CGRect wRect = _sapp.macos.window.frame; | ||||||
|  | NSView *contentView  =_sapp.macos.window.contentView; | ||||||
|  | CGRect cRect = contentView.frame; | ||||||
|  | 
 | ||||||
|  | CGRect rect = CGRectMake(wRect.origin.x, wRect.origin.y, cRect.size.width, cRect.size.height); | ||||||
|  | NSWindow *overlayWindow = [[NSWindow alloc]initWithContentRect:rect | ||||||
|  |                                                      styleMask:NSBorderlessWindowMask | ||||||
|  |                                                        backing:NSBackingStoreBuffered | ||||||
|  |                                                          defer:NO]; | ||||||
|  | //overlayWindow.backgroundColor = [NSColor whiteColor];
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //overlayWindow.backgroundColor = [[NSColor whiteColor] colorWithAlphaComponent:0];
 | ||||||
|  | [overlayWindow setOpaque:YES]; | ||||||
|  | [_sapp.macos.window setIgnoresMouseEvents:NO]; | ||||||
|  | //[_sapp.macos.window setOpaque:NO];
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //overlayWindow.alphaValue =0.1f;///.1f;
 | ||||||
|  | 
 | ||||||
|  | g_view = [[MyView2 alloc] init]; | ||||||
|  |         overlayWindow.contentView = g_view; | ||||||
|  | 
 | ||||||
|  | [   contentView addSubview:g_view]; | ||||||
|  | //[    _sapp.macos.window addChildWindow:overlayWindow ordered:NSWindowAbove];
 | ||||||
|  | 
 | ||||||
|  |    //////////////////////////////////
 | ||||||
|  | 
 | ||||||
|     [_sapp.macos.window center]; |     [_sapp.macos.window center]; | ||||||
|     [_sapp.macos.window makeKeyAndOrderFront:nil]; |     [_sapp.macos.window makeKeyAndOrderFront:nil]; | ||||||
|     _sapp_macos_update_dimensions(); |     _sapp_macos_update_dimensions(); | ||||||
|  | @ -2832,6 +2913,8 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) { | ||||||
| } | } | ||||||
| @end | @end | ||||||
| 
 | 
 | ||||||
|  | #include "/Users/alex/code/v/thirdparty/sokol/sokol_app2.h" | ||||||
|  | 
 | ||||||
| @implementation _sapp_macos_window_delegate | @implementation _sapp_macos_window_delegate | ||||||
| - (BOOL)windowShouldClose:(id)sender { | - (BOOL)windowShouldClose:(id)sender { | ||||||
|     _SOKOL_UNUSED(sender); |     _SOKOL_UNUSED(sender); | ||||||
|  | @ -2884,6 +2967,7 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) { | ||||||
| } | } | ||||||
| @end | @end | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| @implementation _sapp_macos_view | @implementation _sapp_macos_view | ||||||
| #if defined(SOKOL_GLCORE33) | #if defined(SOKOL_GLCORE33) | ||||||
| /* NOTE: this is a hack/fix when the initial window size has been clipped by
 | /* NOTE: this is a hack/fix when the initial window size has been clipped by
 | ||||||
|  | @ -2912,9 +2996,13 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) { | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | //int g_is_native = 0;
 | ||||||
|  | 
 | ||||||
| - (void)drawRect:(NSRect)rect { | - (void)drawRect:(NSRect)rect { | ||||||
|     _SOKOL_UNUSED(rect); |     _SOKOL_UNUSED(rect); | ||||||
|     _sapp_macos_frame(); |     _sapp_macos_frame(); | ||||||
|  | //   puts("drawRect() metal");
 | ||||||
|  | //   NSLog(@"rect %@", NSStringFromRect(rect));
 | ||||||
|     #if !defined(SOKOL_METAL) |     #if !defined(SOKOL_METAL) | ||||||
|     [[_sapp.macos.view openGLContext] flushBuffer]; |     [[_sapp.macos.view openGLContext] flushBuffer]; | ||||||
|     #endif |     #endif | ||||||
|  | @ -2929,6 +3017,10 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) { | ||||||
| - (BOOL)acceptsFirstResponder { | - (BOOL)acceptsFirstResponder { | ||||||
|     return YES; |     return YES; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | 	- (BOOL)acceptsFirstMouse:(NSEvent *)event { | ||||||
|  | 		return YES; | ||||||
|  | 	} | ||||||
| - (void)updateTrackingAreas { | - (void)updateTrackingAreas { | ||||||
|     if (_sapp.macos.tracking_area != nil) { |     if (_sapp.macos.tracking_area != nil) { | ||||||
|         [self removeTrackingArea:_sapp.macos.tracking_area]; |         [self removeTrackingArea:_sapp.macos.tracking_area]; | ||||||
|  | @ -2953,6 +3045,7 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| - (void)mouseExited:(NSEvent*)event { | - (void)mouseExited:(NSEvent*)event { | ||||||
|  | 	// NSLog(@"mouse exited");
 | ||||||
|     if (0 == _sapp.macos.mouse_buttons) { |     if (0 == _sapp.macos.mouse_buttons) { | ||||||
|         _sapp_macos_mouse_event(SAPP_EVENTTYPE_MOUSE_LEAVE, SAPP_MOUSEBUTTON_INVALID, _sapp_macos_mod(event.modifierFlags)); |         _sapp_macos_mouse_event(SAPP_EVENTTYPE_MOUSE_LEAVE, SAPP_MOUSEBUTTON_INVALID, _sapp_macos_mod(event.modifierFlags)); | ||||||
|     } |     } | ||||||
|  | @ -3002,11 +3095,13 @@ _SOKOL_PRIVATE void _sapp_macos_frame(void) { | ||||||
|     _sapp_macos_mouse_event(SAPP_EVENTTYPE_MOUSE_MOVE, SAPP_MOUSEBUTTON_INVALID , _sapp_macos_mod(event.modifierFlags)); |     _sapp_macos_mouse_event(SAPP_EVENTTYPE_MOUSE_MOVE, SAPP_MOUSEBUTTON_INVALID , _sapp_macos_mod(event.modifierFlags)); | ||||||
| } | } | ||||||
| - (void)mouseDragged:(NSEvent*)event { | - (void)mouseDragged:(NSEvent*)event { | ||||||
|  | 	//puts("(void)mouseDragged");
 | ||||||
|     if (_sapp.mouse.locked) { |     if (_sapp.mouse.locked) { | ||||||
|         _sapp.mouse.dx = [event deltaX]; |         _sapp.mouse.dx = [event deltaX]; | ||||||
|         _sapp.mouse.dy = [event deltaY]; |         _sapp.mouse.dy = [event deltaY]; | ||||||
|     } |     } | ||||||
|     _sapp_macos_mouse_event(SAPP_EVENTTYPE_MOUSE_MOVE, SAPP_MOUSEBUTTON_INVALID , _sapp_macos_mod(event.modifierFlags)); |    // QTODO hack INVALID=>MIDDLE macos bug
 | ||||||
|  |     _sapp_macos_mouse_event(SAPP_EVENTTYPE_MOUSE_MOVE, SAPP_MOUSEBUTTON_MIDDLE , _sapp_macos_mod(event.modifierFlags)); | ||||||
| } | } | ||||||
| - (void)rightMouseDragged:(NSEvent*)event { | - (void)rightMouseDragged:(NSEvent*)event { | ||||||
|     if (_sapp.mouse.locked) { |     if (_sapp.mouse.locked) { | ||||||
|  |  | ||||||
|  | @ -0,0 +1,33 @@ | ||||||
|  | 
 | ||||||
|  | @implementation MyView2 | ||||||
|  | 
 | ||||||
|  | // Alternative drawRect which calls a frame function with native Cocoa calls
 | ||||||
|  | - (void)drawRect:(NSRect)rect { | ||||||
|  |     _sapp_call_frame2(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //- (BOOL)isOpaque {
 | ||||||
|  | //    return NO;
 | ||||||
|  | //}
 | ||||||
|  | 
 | ||||||
|  | - (BOOL)canBecomeKeyView { | ||||||
|  |     return YES; | ||||||
|  | } | ||||||
|  | - (BOOL)acceptsFirstResponder { | ||||||
|  |     return YES; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | - (void)mouseExited:(NSEvent*)event { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | - (void)mouseDown:(NSEvent*)event { | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | - (BOOL)acceptsFirstMouse:(NSEvent *)event { | ||||||
|  | 	return YES; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @end | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @ -1,10 +1,10 @@ | ||||||
| module fontstash | module fontstash | ||||||
| 
 | 
 | ||||||
| #flag -I @VROOT/thirdparty/fontstash | #flag -I @VROOT/thirdparty/fontstash | ||||||
| 
 |  | ||||||
| #define FONTSTASH_IMPLEMENTATION | #define FONTSTASH_IMPLEMENTATION | ||||||
| #include "fontstash.h" | #include "fontstash.h" | ||||||
| 
 | #flag -I /usr/local/Cellar/freetype/2.10.2/include/freetype2 | ||||||
|  | //#flag -lfreetype
 | ||||||
| pub const ( | pub const ( | ||||||
| 	// TODO: fontstash.used_import is used to keep v from warning about unused imports
 | 	// TODO: fontstash.used_import is used to keep v from warning about unused imports
 | ||||||
| 	used_import = 1 | 	used_import = 1 | ||||||
|  | @ -22,7 +22,7 @@ pub fn delete_internal(s &C.FONScontext) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| [inline] | [inline] | ||||||
| pub fn (s &C.FONScontext) set_error_callback(callback fn(uptr voidptr, error int, val int), uptr voidptr) { | pub fn (s &C.FONScontext) set_error_callback(callback fn (voidptr, int, int), uptr voidptr) { | ||||||
| 	C.fonsSetErrorCallback(s, callback, uptr) | 	C.fonsSetErrorCallback(s, callback, uptr) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -156,4 +156,3 @@ pub fn (s &C.FONScontext) validate_texture(dirty &int) int { | ||||||
| pub fn (s &C.FONScontext) draw_debug(x f32, y f32) { | pub fn (s &C.FONScontext) draw_debug(x f32, y f32) { | ||||||
| 	C.fonsDrawDebug(s, x, y) | 	C.fonsDrawDebug(s, x, y) | ||||||
| } | } | ||||||
| 
 |  | ||||||
|  |  | ||||||
							
								
								
									
										24
									
								
								vlib/gg/gg.v
								
								
								
								
							
							
						
						
									
										24
									
								
								vlib/gg/gg.v
								
								
								
								
							|  | @ -40,6 +40,7 @@ pub: | ||||||
| 	bg_color          gx.Color | 	bg_color          gx.Color | ||||||
| 	init_fn           FNCb      = voidptr(0) | 	init_fn           FNCb      = voidptr(0) | ||||||
| 	frame_fn          FNCb      = voidptr(0) | 	frame_fn          FNCb      = voidptr(0) | ||||||
|  | 	native_frame_fn   FNCb      = voidptr(0) | ||||||
| 	cleanup_fn        FNCb      = voidptr(0) | 	cleanup_fn        FNCb      = voidptr(0) | ||||||
| 	fail_fn           FNFail    = voidptr(0) | 	fail_fn           FNFail    = voidptr(0) | ||||||
| 	event_fn          FNEvent   = voidptr(0) | 	event_fn          FNEvent   = voidptr(0) | ||||||
|  | @ -65,6 +66,7 @@ pub: | ||||||
| 	font_bytes_bold   []byte | 	font_bytes_bold   []byte | ||||||
| 	font_bytes_mono   []byte | 	font_bytes_mono   []byte | ||||||
| 	font_bytes_italic []byte | 	font_bytes_italic []byte | ||||||
|  | 	native_rendering  bool // Cocoa on macOS/iOS, GDI+ on Windows
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub struct Context { | pub struct Context { | ||||||
|  | @ -75,6 +77,8 @@ mut: | ||||||
| 	image_cache   []Image | 	image_cache   []Image | ||||||
| 	needs_refresh bool = true | 	needs_refresh bool = true | ||||||
| 	ticks         int | 	ticks         int | ||||||
|  | pub: | ||||||
|  | 	native_rendering bool | ||||||
| pub mut: | pub mut: | ||||||
| 	scale f32 = 1.0 | 	scale f32 = 1.0 | ||||||
| 	// will get set to 2.0 for retina, will remain 1.0 for normal
 | 	// will get set to 2.0 for retina, will remain 1.0 for normal
 | ||||||
|  | @ -169,6 +173,9 @@ fn gg_init_sokol_window(user_data voidptr) { | ||||||
| 		g.config.init_fn(g.config.user_data) | 		g.config.init_fn(g.config.user_data) | ||||||
| 	} | 	} | ||||||
| 	// Create images now that we can do that after sg is inited
 | 	// Create images now that we can do that after sg is inited
 | ||||||
|  | 	if g.native_rendering { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
| 	for i in 0 .. g.image_cache.len { | 	for i in 0 .. g.image_cache.len { | ||||||
| 		g.image_cache[i].init_sokol_image() | 		g.image_cache[i].init_sokol_image() | ||||||
| 	} | 	} | ||||||
|  | @ -179,6 +186,9 @@ fn gg_frame_fn(user_data voidptr) { | ||||||
| 	if ctx.config.frame_fn == voidptr(0) { | 	if ctx.config.frame_fn == voidptr(0) { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  | 	if ctx.native_rendering { | ||||||
|  | 		// return
 | ||||||
|  | 	} | ||||||
| 	if ctx.ui_mode && !ctx.needs_refresh { | 	if ctx.ui_mode && !ctx.needs_refresh { | ||||||
| 		// Draw 3 more frames after the "stop refresh" command
 | 		// Draw 3 more frames after the "stop refresh" command
 | ||||||
| 		ctx.ticks++ | 		ctx.ticks++ | ||||||
|  | @ -256,6 +266,7 @@ pub fn new_context(cfg Config) &Context { | ||||||
| 		render_text: cfg.font_path != '' || cfg.font_bytes_normal.len > 0 | 		render_text: cfg.font_path != '' || cfg.font_bytes_normal.len > 0 | ||||||
| 		ft: 0 | 		ft: 0 | ||||||
| 		ui_mode: cfg.ui_mode | 		ui_mode: cfg.ui_mode | ||||||
|  | 		native_rendering: cfg.native_rendering | ||||||
| 	} | 	} | ||||||
| 	g.set_bg_color(cfg.bg_color) | 	g.set_bg_color(cfg.bg_color) | ||||||
| 	// C.printf('new_context() %p\n', cfg.user_data)
 | 	// C.printf('new_context() %p\n', cfg.user_data)
 | ||||||
|  | @ -273,6 +284,7 @@ pub fn new_context(cfg Config) &Context { | ||||||
| 		sample_count: cfg.sample_count | 		sample_count: cfg.sample_count | ||||||
| 		high_dpi: true | 		high_dpi: true | ||||||
| 		fullscreen: cfg.fullscreen | 		fullscreen: cfg.fullscreen | ||||||
|  | 		native_render: cfg.native_rendering | ||||||
| 	} | 	} | ||||||
| 	if cfg.use_ortho { | 	if cfg.use_ortho { | ||||||
| 	} else { | 	} else { | ||||||
|  | @ -292,6 +304,12 @@ pub fn (mut ctx Context) set_bg_color(c gx.Color) { | ||||||
| 
 | 
 | ||||||
| // TODO: Fix alpha
 | // TODO: Fix alpha
 | ||||||
| pub fn (ctx &Context) draw_rect(x f32, y f32, w f32, h f32, c gx.Color) { | pub fn (ctx &Context) draw_rect(x f32, y f32, w f32, h f32, c gx.Color) { | ||||||
|  | 	$if macos { | ||||||
|  | 		if ctx.native_rendering { | ||||||
|  | 			C.darwin_draw_rect(x, ctx.height - (y + h), w, h, c) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 	if c.a != 255 { | 	if c.a != 255 { | ||||||
| 		sgl.load_pipeline(ctx.timage_pip) | 		sgl.load_pipeline(ctx.timage_pip) | ||||||
| 	} | 	} | ||||||
|  | @ -357,6 +375,12 @@ pub fn (ctx &Context) draw_circle_line(x f32, y f32, r int, segments int, c gx.C | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn (ctx &Context) draw_circle(x f32, y f32, r f32, c gx.Color) { | pub fn (ctx &Context) draw_circle(x f32, y f32, r f32, c gx.Color) { | ||||||
|  | 	$if macos { | ||||||
|  | 		if ctx.native_rendering { | ||||||
|  | 			C.darwin_draw_circle(x - r + 1, ctx.height - (y + r + 3), r, c) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 	if ctx.scale == 1 { | 	if ctx.scale == 1 { | ||||||
| 		ctx.draw_circle_with_segments(x, y, r, 10, c) | 		ctx.draw_circle_with_segments(x, y, r, 10, c) | ||||||
| 	} else { | 	} else { | ||||||
|  |  | ||||||
|  | @ -2,3 +2,19 @@ module gg | ||||||
| 
 | 
 | ||||||
| #include "@VROOT/vlib/gg/gg_darwin.m" | #include "@VROOT/vlib/gg/gg_darwin.m" | ||||||
| fn C.gg_get_screen_size() Size | fn C.gg_get_screen_size() Size | ||||||
|  | 
 | ||||||
|  | fn C.darwin_draw_string(x int, y int, s string) | ||||||
|  | 
 | ||||||
|  | fn C.darwin_text_width(s string) int | ||||||
|  | 
 | ||||||
|  | fn C.darwin_window_refresh() | ||||||
|  | 
 | ||||||
|  | fn C.darwin_draw_rect(f32, f32, f32, f32) | ||||||
|  | 
 | ||||||
|  | fn C.darwin_create_image() Image | ||||||
|  | 
 | ||||||
|  | fn C.darwin_draw_image(f32, f32, f32, f32, &Image) | ||||||
|  | 
 | ||||||
|  | fn C.darwin_draw_circle(f32, f32, f32) | ||||||
|  | 
 | ||||||
|  | //, gx.Color c)
 | ||||||
|  |  | ||||||
|  | @ -1,5 +1,18 @@ | ||||||
| #include <Cocoa/Cocoa.h> | #include <Cocoa/Cocoa.h> | ||||||
| 
 | 
 | ||||||
|  | NSColor* nscolor(gx__Color c) { | ||||||
|  |         float red= (float)c.r / 255.0f; | ||||||
|  |         float green= (float)c.g / 255.0f; | ||||||
|  |         float blue= (float)c.b / 255.0f; | ||||||
|  |         return [NSColor colorWithDeviceRed:red green:green blue:blue alpha:1.0f]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | NSString* nsstring(string s) { | ||||||
|  |         return [ [ NSString alloc ] initWithBytesNoCopy:s.str  length:s.len | ||||||
|  |           encoding:NSUTF8StringEncoding freeWhenDone: false]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| gg__Size gg_get_screen_size() { | gg__Size gg_get_screen_size() { | ||||||
| 	NSScreen *screen = [NSScreen mainScreen]; | 	NSScreen *screen = [NSScreen mainScreen]; | ||||||
| 	NSDictionary *description = [screen deviceDescription]; | 	NSDictionary *description = [screen deviceDescription]; | ||||||
|  | @ -12,3 +25,101 @@ gg__Size gg_get_screen_size() { | ||||||
| 	return res; | 	return res; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void darwin_draw_string(int x, int y, string s, gx__TextCfg cfg) { | ||||||
|  | 	 NSFont*       font = [NSFont userFontOfSize: 0]; //cfg.size]; | ||||||
|  |  // # NSFont*    font = [NSFont fontWithName:@"Roboto Mono" size:cfg.size]; | ||||||
|  |  if (cfg.mono) { | ||||||
|  |          // # font = [NSFont fontWithName:@"Roboto Mono" size:cfg.size]; | ||||||
|  |          font = [NSFont fontWithName:@"Menlo" size:cfg.size-5]; | ||||||
|  |  } | ||||||
|  | if (cfg.bold) { | ||||||
|  |         font = [[NSFontManager sharedFontManager] convertFont:font toHaveTrait:NSBoldFontMask]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	NSDictionary* attr = @{ | ||||||
|  | NSForegroundColorAttributeName: nscolor(cfg.color), | ||||||
|  | //NSParagraphStyleAttributeName: paragraphStyle, | ||||||
|  | NSFontAttributeName: font, | ||||||
|  | }; | ||||||
|  | 	[nsstring(s) drawAtPoint:NSMakePoint(x,y-15) withAttributes:attr]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int darwin_text_width(string s) { | ||||||
|  | 	// println('text_width "$s" len=$s.len') | ||||||
|  | 	NSString* n = @""; | ||||||
|  | 	if (s.len == 1) { | ||||||
|  | 	        // println('len=1') | ||||||
|  | 	       n=[NSString stringWithFormat:@"%c" , s.str[0]]; | ||||||
|  | 	} | ||||||
|  | 	else { | ||||||
|  | 		n = nsstring(s); | ||||||
|  | 	} | ||||||
|  | 	/* | ||||||
|  | 	# if (!defaultFont){ | ||||||
|  | 	# defaultFont = [NSFont userFontOfSize: ui__DEFAULT_FONT_SIZE]; | ||||||
|  | 	# } | ||||||
|  | 	# NSDictionary *attrs = @{ | ||||||
|  | 	# NSFontAttributeName: defaultFont, | ||||||
|  | 	# }; | ||||||
|  | 	*/ | ||||||
|  | 	NSSize size = [n sizeWithAttributes:nil]; | ||||||
|  | 	// # printf("!!!%f\n", ceil(size.width)); | ||||||
|  | 	return (int)(ceil(size.width)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void darwin_draw_rect(float x, float y, float width, float height, gx__Color c) { | ||||||
|  | 	NSColor* color = nscolor(c); | ||||||
|  | 	NSRect rect = NSMakeRect(x, y, width, height); | ||||||
|  | 	[color setFill]; | ||||||
|  | 	NSRectFill(rect); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void darwin_window_refresh() { | ||||||
|  | 	//[g_view setNeedsDisplay:YES]; | ||||||
|  | 	  // update UI on the main thread TODO separate fn | ||||||
|  |         dispatch_async(dispatch_get_main_queue(), ^{ | ||||||
|  | 			[g_view setNeedsDisplay:YES]; | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  | 	//puts("refresh"); | ||||||
|  | 	//[g_view drawRect:NSMakeRect(0,0,2000,2000)]; | ||||||
|  | 	//[[NSGraphicsContext currentContext] flushGraphics]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | gg__Image darwin_create_image(string path_) { | ||||||
|  | 	 // file = file.trim_space() | ||||||
|  | 	NSString* path = nsstring(path_); | ||||||
|  | 	 NSImage* img = [[NSImage alloc] initWithContentsOfFile:path]; | ||||||
|  | 	if (img == 0) { | ||||||
|  | 	} | ||||||
|  | 	 NSSize size = [img size]; | ||||||
|  | 	gg__Image res; | ||||||
|  | 	 res.width =  size.width; | ||||||
|  | 	 res.height =  size.height; | ||||||
|  | 	res.path = path_; | ||||||
|  | 	res.ok = true; | ||||||
|  | 	//printf("inited img width=%d\n", res.width) ; | ||||||
|  | 	// need __brige_retained so that the pointer is not freed by ARC | ||||||
|  | 	 res.data = (__bridge_retained voidptr)(img); | ||||||
|  | 	return res; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void darwin_draw_image(float x, float y, float w, float h, gg__Image* img) { | ||||||
|  | 	NSImage* i= (__bridge NSImage*)(img->data); | ||||||
|  | 	[i drawInRect:NSMakeRect(x,y,w,h)]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void darwin_draw_circle(float x, float y, float d,  gx__Color color) { | ||||||
|  | 	NSColor*        c = nscolor(color); | ||||||
|  | 	NSRect        rect = NSMakeRect(x, y, d * 2, d * 2); | ||||||
|  | 	NSBezierPath* circlePath = [NSBezierPath bezierPath]; | ||||||
|  | 	[circlePath appendBezierPathWithOvalInRect: rect]; | ||||||
|  | 	[c setFill]; | ||||||
|  | 	// [circlePath stroke]; | ||||||
|  | 	[circlePath fill]; | ||||||
|  | 	// NSRectFill(rect); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | @ -28,6 +28,21 @@ fn C.sg_isvalid() bool | ||||||
| 
 | 
 | ||||||
| // TODO return ?Image
 | // TODO return ?Image
 | ||||||
| pub fn (mut ctx Context) create_image(file string) Image { | pub fn (mut ctx Context) create_image(file string) Image { | ||||||
|  | 	// println('\ncreate_image("$file")')
 | ||||||
|  | 	if !os.exists(file) { | ||||||
|  | 		return Image{} | ||||||
|  | 	} | ||||||
|  | 	$if macos { | ||||||
|  | 		if ctx.native_rendering { | ||||||
|  | 			// return C.darwin_create_image(file)
 | ||||||
|  | 			mut img := C.darwin_create_image(file) | ||||||
|  | 			// println('created macos image: $img.path w=$img.width')
 | ||||||
|  | 			// C.printf('p = %p\n', img.data)
 | ||||||
|  | 			img.id = ctx.image_cache.len | ||||||
|  | 			ctx.image_cache << img | ||||||
|  | 			return img | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 	if !C.sg_isvalid() { | 	if !C.sg_isvalid() { | ||||||
| 		// Sokol is not initialized yet, add stbi object to a queue/cache
 | 		// Sokol is not initialized yet, add stbi object to a queue/cache
 | ||||||
| 		// ctx.image_queue << file
 | 		// ctx.image_queue << file
 | ||||||
|  | @ -142,6 +157,18 @@ pub fn (ctx &Context) draw_image(x f32, y f32, width f32, height f32, img_ &Imag | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	img := ctx.image_cache[img_.id] // fetch the image from cache
 | 	img := ctx.image_cache[img_.id] // fetch the image from cache
 | ||||||
|  | 	$if macos { | ||||||
|  | 		if ctx.native_rendering { | ||||||
|  | 			if img_.width == 0 { | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 			if !os.exists(img_.path) { | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 			C.darwin_draw_image(x, ctx.height - (y + height), width, height, img_) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 	if !img.simg_ok { | 	if !img.simg_ok { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -35,6 +35,13 @@ struct FTConfig { | ||||||
| 	bytes_italic          []byte | 	bytes_italic          []byte | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | struct StringToRender { | ||||||
|  | 	x    int | ||||||
|  | 	y    int | ||||||
|  | 	text string | ||||||
|  | 	cfg  gx.TextCfg | ||||||
|  | } | ||||||
|  | 
 | ||||||
| fn new_ft(c FTConfig) ?&FT { | fn new_ft(c FTConfig) ?&FT { | ||||||
| 	if c.font_path == '' { | 	if c.font_path == '' { | ||||||
| 		if c.bytes_normal.len > 0 { | 		if c.bytes_normal.len > 0 { | ||||||
|  | @ -150,6 +157,17 @@ fn (ctx &Context) set_cfg(cfg gx.TextCfg) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn (ctx &Context) draw_text(x int, y int, text_ string, cfg gx.TextCfg) { | pub fn (ctx &Context) draw_text(x int, y int, text_ string, cfg gx.TextCfg) { | ||||||
|  | 	$if macos { | ||||||
|  | 		if ctx.native_rendering { | ||||||
|  | 			if cfg.align == gx.align_right { | ||||||
|  | 				width := ctx.text_width(text_) | ||||||
|  | 				C.darwin_draw_string(x - width, ctx.height - y, text_, cfg) | ||||||
|  | 			} else { | ||||||
|  | 				C.darwin_draw_string(x, ctx.height - y, text_, cfg) | ||||||
|  | 			} | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 	if !ctx.font_inited { | 	if !ctx.font_inited { | ||||||
| 		eprintln('gg: draw_text(): font not initialized') | 		eprintln('gg: draw_text(): font not initialized') | ||||||
| 		return | 		return | ||||||
|  | @ -177,6 +195,11 @@ pub fn (ft &FT) flush() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn (ctx &Context) text_width(s string) int { | pub fn (ctx &Context) text_width(s string) int { | ||||||
|  | 	$if macos { | ||||||
|  | 		if ctx.native_rendering { | ||||||
|  | 			return C.darwin_text_width(s) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 	// ctx.set_cfg(cfg) TODO
 | 	// ctx.set_cfg(cfg) TODO
 | ||||||
| 	if !ctx.font_inited { | 	if !ctx.font_inited { | ||||||
| 		return 0 | 		return 0 | ||||||
|  | @ -187,6 +210,13 @@ pub fn (ctx &Context) text_width(s string) int { | ||||||
| 		return int((buf[2] - buf[0]) / ctx.scale) + | 		return int((buf[2] - buf[0]) / ctx.scale) + | ||||||
| 			ctx.text_width('i') // TODO fix this in fontstash?
 | 			ctx.text_width('i') // TODO fix this in fontstash?
 | ||||||
| 	} | 	} | ||||||
|  | 	res := int((buf[2] - buf[0]) / ctx.scale) | ||||||
|  | 	// println('TW "$s" = $res')
 | ||||||
|  | 	$if macos { | ||||||
|  | 		if ctx.native_rendering { | ||||||
|  | 			return res * 2 | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 	return int((buf[2] - buf[0]) / ctx.scale) | 	return int((buf[2] - buf[0]) / ctx.scale) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -457,7 +457,12 @@ pub fn walk(path string, f fn (string)) { | ||||||
| 
 | 
 | ||||||
| // log will print "os.log: "+`s` ...
 | // log will print "os.log: "+`s` ...
 | ||||||
| pub fn log(s string) { | pub fn log(s string) { | ||||||
|  | 	//$if macos {
 | ||||||
|  | 		// Use NSLog() on macos
 | ||||||
|  | 		//C.darwin_log(s)
 | ||||||
|  | 	//} $else {
 | ||||||
| 		println('os.log: ' + s) | 		println('os.log: ' + s) | ||||||
|  | 	//}
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| [deprecated] | [deprecated] | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ | ||||||
| // that can be found in the LICENSE file.
 | // that can be found in the LICENSE file.
 | ||||||
| module os | module os | ||||||
| 
 | 
 | ||||||
|  | #include "@VROOT/vlib/os/os_darwin.m" | ||||||
| pub const ( | pub const ( | ||||||
| 	sys_write         = 4 | 	sys_write         = 4 | ||||||
| 	sys_open          = 5 | 	sys_open          = 5 | ||||||
|  | @ -12,3 +13,5 @@ pub const ( | ||||||
| 	sys_open_nocancel = 398 | 	sys_open_nocancel = 398 | ||||||
| 	sys_stat64        = 338 | 	sys_stat64        = 338 | ||||||
| ) | ) | ||||||
|  | 
 | ||||||
|  | fn C.darwin_log(s string) | ||||||
|  |  | ||||||
|  | @ -0,0 +1,7 @@ | ||||||
|  | /* | ||||||
|  | NSString* nsstring(string s); | ||||||
|  | 
 | ||||||
|  | void darwin_log(string s) { | ||||||
|  | 	NSLog(nsstring(s)); | ||||||
|  | } | ||||||
|  | */ | ||||||
|  | @ -10,228 +10,214 @@ pub const ( | ||||||
| __global ( g_desc C.sapp_desc ) | __global ( g_desc C.sapp_desc ) | ||||||
| 
 | 
 | ||||||
| pub fn create_desc() C.sg_desc { | pub fn create_desc() C.sg_desc { | ||||||
| 	mtl_desc := C.sg_mtl_context_desc { | 	mtl_desc := C.sg_mtl_context_desc{ | ||||||
| 		device: metal_get_device() | 		device: metal_get_device() | ||||||
| 		renderpass_descriptor_cb: metal_get_renderpass_descriptor | 		renderpass_descriptor_cb: metal_get_renderpass_descriptor | ||||||
| 		drawable_cb: metal_get_drawable | 		drawable_cb: metal_get_drawable | ||||||
| 	} | 	} | ||||||
| 	d3d11_desc := C.sg_d3d11_context_desc { | 	d3d11_desc := C.sg_d3d11_context_desc{ | ||||||
| 		device: d3d11_get_device() | 		device: d3d11_get_device() | ||||||
| 		device_context: d3d11_get_device_context() | 		device_context: d3d11_get_device_context() | ||||||
| 		render_target_view_cb: d3d11_get_render_target_view | 		render_target_view_cb: d3d11_get_render_target_view | ||||||
| 		depth_stencil_view_cb: d3d11_get_depth_stencil_view | 		depth_stencil_view_cb: d3d11_get_depth_stencil_view | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	/* |  | ||||||
| 	// Old Sokol
 |  | ||||||
| 	return C.sg_desc{ |  | ||||||
| 		mtl_device: sapp.metal_get_device() |  | ||||||
| 		mtl_renderpass_descriptor_cb: sapp.metal_get_renderpass_descriptor |  | ||||||
| 		mtl_drawable_cb: sapp.metal_get_drawable |  | ||||||
| 		d3d11_device: sapp.d3d11_get_device() |  | ||||||
| 		d3d11_device_context: sapp.d3d11_get_device_context() |  | ||||||
| 		d3d11_render_target_view_cb: sapp.d3d11_get_render_target_view |  | ||||||
| 		d3d11_depth_stencil_view_cb: sapp.d3d11_get_depth_stencil_view |  | ||||||
| 	} |  | ||||||
| 	*/ |  | ||||||
| 
 |  | ||||||
| 	return C.sg_desc{ | 	return C.sg_desc{ | ||||||
| 		context: C.sg_context_desc{ | 		context: C.sg_context_desc{ | ||||||
| 			metal: mtl_desc | 			metal: mtl_desc | ||||||
| 			d3d11: d3d11_desc | 			d3d11: d3d11_desc | ||||||
| 		} | 		} | ||||||
| 		image_pool_size:1000 | 		image_pool_size: 1000 | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* returns true after sokol-app has been initialized */ | // returns true after sokol-app has been initialized
 | ||||||
| [inline] | [inline] | ||||||
| pub fn isvalid() bool { | pub fn isvalid() bool { | ||||||
| 	return C.sapp_isvalid() | 	return C.sapp_isvalid() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* returns the current framebuffer width in pixels */ | // returns the current framebuffer width in pixels
 | ||||||
| [inline] | [inline] | ||||||
| pub fn width() int { | pub fn width() int { | ||||||
| 	return C.sapp_width() | 	return C.sapp_width() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* returns the current framebuffer height in pixels */ | // returns the current framebuffer height in pixels
 | ||||||
| [inline] | [inline] | ||||||
| pub fn height() int { | pub fn height() int { | ||||||
| 	return C.sapp_height() | 	return C.sapp_height() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* returns true when high_dpi was requested and actually running in a high-dpi scenario */ | // returns true when high_dpi was requested and actually running in a high-dpi scenario
 | ||||||
| [inline] | [inline] | ||||||
| pub fn high_dpi() bool { | pub fn high_dpi() bool { | ||||||
| 	return C.sapp_high_dpi() | 	return C.sapp_high_dpi() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* returns the dpi scaling factor (window pixels to framebuffer pixels) */ | // returns the dpi scaling factor (window pixels to framebuffer pixels)
 | ||||||
| [inline] | [inline] | ||||||
| pub fn dpi_scale() f32 { | pub fn dpi_scale() f32 { | ||||||
| 	return C.sapp_dpi_scale() | 	return C.sapp_dpi_scale() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* show or hide the mobile device onscreen keyboard */ | // show or hide the mobile device onscreen keyboard
 | ||||||
| [inline] | [inline] | ||||||
| pub fn show_keyboard(visible bool) { | pub fn show_keyboard(visible bool) { | ||||||
| 	C.sapp_show_keyboard(visible) | 	C.sapp_show_keyboard(visible) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* return true if the mobile device onscreen keyboard is currently shown */ | // return true if the mobile device onscreen keyboard is currently shown
 | ||||||
| [inline] | [inline] | ||||||
| pub fn keyboard_shown() bool { | pub fn keyboard_shown() bool { | ||||||
| 	return C.sapp_keyboard_shown() | 	return C.sapp_keyboard_shown() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* show or hide the mouse cursor */ | // show or hide the mouse cursor
 | ||||||
| [inline] | [inline] | ||||||
| pub fn show_mouse(visible bool) { | pub fn show_mouse(visible bool) { | ||||||
| 	C.sapp_show_mouse(visible) | 	C.sapp_show_mouse(visible) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* show or hide the mouse cursor */ | // show or hide the mouse cursor
 | ||||||
| [inline] | [inline] | ||||||
| pub fn mouse_shown() bool { | pub fn mouse_shown() bool { | ||||||
| 	return C.sapp_mouse_shown() | 	return C.sapp_mouse_shown() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* return the userdata pointer optionally provided in sapp_desc */ | // return the userdata pointer optionally provided in sapp_desc
 | ||||||
| [inline] | [inline] | ||||||
| pub fn userdata() voidptr { | pub fn userdata() voidptr { | ||||||
| 	return C.sapp_userdata() | 	return C.sapp_userdata() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* return a copy of the sapp_desc structure */ | // return a copy of the sapp_desc structure
 | ||||||
| [inline] | [inline] | ||||||
| pub fn query_desc() C.sapp_desc { | pub fn query_desc() C.sapp_desc { | ||||||
| 	return C.sapp_query_desc() | 	return C.sapp_query_desc() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* initiate a "soft quit" (sends SAPP_EVENTTYPE_QUIT_REQUESTED) */ | // initiate a "soft quit" (sends SAPP_EVENTTYPE_QUIT_REQUESTED)
 | ||||||
| [inline] | [inline] | ||||||
| pub fn request_quit() { | pub fn request_quit() { | ||||||
| 	C.sapp_request_quit() | 	C.sapp_request_quit() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* cancel a pending quit (when SAPP_EVENTTYPE_QUIT_REQUESTED has been received) */ | // cancel a pending quit (when SAPP_EVENTTYPE_QUIT_REQUESTED has been received)
 | ||||||
| [inline] | [inline] | ||||||
| pub fn cancel_quit() { | pub fn cancel_quit() { | ||||||
| 	C.sapp_cancel_quit() | 	C.sapp_cancel_quit() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* intiate a "hard quit" (quit application without sending SAPP_EVENTTYPE_QUIT_REQUSTED) */ | // intiate a "hard quit" (quit application without sending SAPP_EVENTTYPE_QUIT_REQUSTED)
 | ||||||
| [inline] | [inline] | ||||||
| pub fn quit() { | pub fn quit() { | ||||||
| 	C.sapp_quit() | 	C.sapp_quit() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* call from inside event callback to consume the current event (don't forward to platform) */ | // call from inside event callback to consume the current event (don't forward to platform)
 | ||||||
| [inline] | [inline] | ||||||
| pub fn consume_event() { | pub fn consume_event() { | ||||||
| 	C.sapp_consume_event() | 	C.sapp_consume_event() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* get the current frame counter (for comparison with sapp_event.frame_count) */ | // get the current frame counter (for comparison with sapp_event.frame_count)
 | ||||||
| [inline] | [inline] | ||||||
| pub fn frame_count() u64 { | pub fn frame_count() u64 { | ||||||
| 	return C.sapp_frame_count() | 	return C.sapp_frame_count() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* write string into clipboard */ | // write string into clipboard
 | ||||||
| [inline] | [inline] | ||||||
| pub fn set_clipboard_string(str byteptr) { | pub fn set_clipboard_string(str byteptr) { | ||||||
| 	C.sapp_set_clipboard_string(str) | 	C.sapp_set_clipboard_string(str) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* read string from clipboard (usually during SAPP_EVENTTYPE_CLIPBOARD_PASTED) */ | // read string from clipboard (usually during SAPP_EVENTTYPE_CLIPBOARD_PASTED)
 | ||||||
| [inline] | [inline] | ||||||
| pub fn get_clipboard_string() byteptr { | pub fn get_clipboard_string() byteptr { | ||||||
| 	return C.sapp_get_clipboard_string() | 	return C.sapp_get_clipboard_string() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* special run-function for SOKOL_NO_ENTRY (in standard mode this is an empty stub) */ | // special run-function for SOKOL_NO_ENTRY (in standard mode this is an empty stub)
 | ||||||
| [inline] | [inline] | ||||||
| pub fn run(desc &C.sapp_desc) int { | pub fn run(desc &C.sapp_desc) int { | ||||||
| 	g_desc = desc | 	g_desc = desc | ||||||
| 	return C.sapp_run(desc) | 	return C.sapp_run(desc) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* GL: return true when GLES2 fallback is active (to detect fallback from GLES3) */ | // GL: return true when GLES2 fallback is active (to detect fallback from GLES3)
 | ||||||
| [inline] | [inline] | ||||||
| pub fn gles2() bool { | pub fn gles2() bool { | ||||||
| 	return C.sapp_gles2() | 	return C.sapp_gles2() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* HTML5: enable or disable the hardwired "Leave Site?" dialog box */ | // HTML5: enable or disable the hardwired "Leave Site?" dialog box
 | ||||||
| [inline] | [inline] | ||||||
| pub fn html5_ask_leave_site(ask bool) { | pub fn html5_ask_leave_site(ask bool) { | ||||||
| 	C.sapp_html5_ask_leave_site(ask) | 	C.sapp_html5_ask_leave_site(ask) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Metal: get ARC-bridged pointer to Metal device object */ | // Metal: get ARC-bridged pointer to Metal device object
 | ||||||
| [inline] | [inline] | ||||||
| pub fn metal_get_device() voidptr { | pub fn metal_get_device() voidptr { | ||||||
| 	return C.sapp_metal_get_device() | 	return C.sapp_metal_get_device() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Metal: get ARC-bridged pointer to this frame's renderpass descriptor */ | // Metal: get ARC-bridged pointer to this frame's renderpass descriptor
 | ||||||
| [inline] | [inline] | ||||||
| pub fn metal_get_renderpass_descriptor() voidptr { | pub fn metal_get_renderpass_descriptor() voidptr { | ||||||
| 	return C.sapp_metal_get_renderpass_descriptor() | 	return C.sapp_metal_get_renderpass_descriptor() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Metal: get ARC-bridged pointer to current drawable */ | // Metal: get ARC-bridged pointer to current drawable
 | ||||||
| [inline] | [inline] | ||||||
| pub fn metal_get_drawable() voidptr { | pub fn metal_get_drawable() voidptr { | ||||||
| 	return C.sapp_metal_get_drawable() | 	return C.sapp_metal_get_drawable() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* macOS: get ARC-bridged pointer to macOS NSWindow */ | // macOS: get ARC-bridged pointer to macOS NSWindow
 | ||||||
| [inline] | [inline] | ||||||
| pub fn macos_get_window() voidptr { | pub fn macos_get_window() voidptr { | ||||||
| 	return C.sapp_macos_get_window() | 	return C.sapp_macos_get_window() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* iOS: get ARC-bridged pointer to iOS UIWindow */ | // iOS: get ARC-bridged pointer to iOS UIWindow
 | ||||||
| [inline] | [inline] | ||||||
| pub fn ios_get_window() voidptr { | pub fn ios_get_window() voidptr { | ||||||
| 	return C.sapp_ios_get_window() | 	return C.sapp_ios_get_window() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* D3D11: get pointer to ID3D11Device object */ | // D3D11: get pointer to ID3D11Device object
 | ||||||
| [inline] | [inline] | ||||||
| pub fn d3d11_get_device() voidptr { | pub fn d3d11_get_device() voidptr { | ||||||
| 	return C.sapp_d3d11_get_device() | 	return C.sapp_d3d11_get_device() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* D3D11: get pointer to ID3D11DeviceContext object */ | // D3D11: get pointer to ID3D11DeviceContext object
 | ||||||
| [inline] | [inline] | ||||||
| pub fn d3d11_get_device_context() voidptr { | pub fn d3d11_get_device_context() voidptr { | ||||||
| 	return C.sapp_d3d11_get_device_context() | 	return C.sapp_d3d11_get_device_context() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* D3D11: get pointer to ID3D11RenderTargetView object */ | // D3D11: get pointer to ID3D11RenderTargetView object
 | ||||||
| [inline] | [inline] | ||||||
| pub fn d3d11_get_render_target_view() voidptr { | pub fn d3d11_get_render_target_view() voidptr { | ||||||
| 	return C.sapp_d3d11_get_render_target_view() | 	return C.sapp_d3d11_get_render_target_view() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* D3D11: get pointer to ID3D11DepthStencilView */ | // D3D11: get pointer to ID3D11DepthStencilView
 | ||||||
| [inline] | [inline] | ||||||
| pub fn d3d11_get_depth_stencil_view() voidptr { | pub fn d3d11_get_depth_stencil_view() voidptr { | ||||||
| 	return C.sapp_d3d11_get_depth_stencil_view() | 	return C.sapp_d3d11_get_depth_stencil_view() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Win32: get the HWND window handle */ | // Win32: get the HWND window handle
 | ||||||
| [inline] | [inline] | ||||||
| pub fn win32_get_hwnd() voidptr { | pub fn win32_get_hwnd() voidptr { | ||||||
| 	return C.sapp_win32_get_hwnd() | 	return C.sapp_win32_get_hwnd() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Android: get native activity handle */ | // Android: get native activity handle
 | ||||||
| [inline] | [inline] | ||||||
| pub fn android_get_native_activity() voidptr { | pub fn android_get_native_activity() voidptr { | ||||||
| 	return C.sapp_android_get_native_activity() | 	return C.sapp_android_get_native_activity() | ||||||
|  |  | ||||||
|  | @ -2,38 +2,36 @@ module sapp | ||||||
| 
 | 
 | ||||||
| pub struct C.sapp_desc { | pub struct C.sapp_desc { | ||||||
| pub: | pub: | ||||||
| 	init_cb fn()					// these are the user-provided callbacks without user data
 | 	init_cb                       fn () // these are the user-provided callbacks without user data
 | ||||||
| 	frame_cb fn() | 	frame_cb                      fn () | ||||||
| 	cleanup_cb fn() | 	cleanup_cb                    fn () | ||||||
| 	event_cb fn(&C.sapp_event) //&sapp_event)
 | 	event_cb                      fn (&C.sapp_event) //&sapp_event)
 | ||||||
| 	fail_cb fn(byteptr) | 	fail_cb                       fn (byteptr) | ||||||
| 
 |  | ||||||
| 	user_data                     voidptr // these are the user-provided callbacks with user data
 | 	user_data                     voidptr // these are the user-provided callbacks with user data
 | ||||||
| 	init_userdata_cb fn(voidptr) | 	init_userdata_cb              fn (voidptr) | ||||||
| 	frame_userdata_cb fn(voidptr) | 	frame_userdata_cb             fn (voidptr) | ||||||
| 	cleanup_userdata_cb fn(voidptr) | 	cleanup_userdata_cb           fn (voidptr) | ||||||
| 	event_userdata_cb fn(&C.sapp_event, voidptr) | 	event_userdata_cb             fn (&C.sapp_event, voidptr) | ||||||
| 	fail_userdata_cb fn(byteptr,voidptr) | 	fail_userdata_cb              fn (byteptr, voidptr) | ||||||
| 
 | 	width                         int     // the preferred width of the window / canvas
 | ||||||
|     width int                          /* the preferred width of the window / canvas */ | 	height                        int     // the preferred height of the window / canvas
 | ||||||
|     height int                         /* the preferred height of the window / canvas */ | 	sample_count                  int     // MSAA sample count
 | ||||||
|     sample_count int                   /* MSAA sample count */ | 	swap_interval                 int     // the preferred swap interval (ignored on some platforms)
 | ||||||
|     swap_interval int                  /* the preferred swap interval (ignored on some platforms) */ | 	high_dpi                      bool    // whether the rendering canvas is full-resolution on HighDPI displays
 | ||||||
|     high_dpi bool                      /* whether the rendering canvas is full-resolution on HighDPI displays */ | 	fullscreen                    bool    // whether the window should be created in fullscreen mode
 | ||||||
|     fullscreen bool                    /* whether the window should be created in fullscreen mode */ | 	alpha                         bool    // whether the framebuffer should have an alpha channel (ignored on some platforms)
 | ||||||
|     alpha bool                         /* whether the framebuffer should have an alpha channel (ignored on some platforms) */ | 	window_title                  byteptr // the window title as UTF-8 encoded string
 | ||||||
|     window_title byteptr	           /* the window title as UTF-8 encoded string */ | 	user_cursor                   bool    // if true, user is expected to manage cursor image in SAPP_EVENTTYPE_UPDATE_CURSOR
 | ||||||
|     user_cursor bool                   /* if true, user is expected to manage cursor image in SAPP_EVENTTYPE_UPDATE_CURSOR */ | 	enable_clipboard              bool    // enable clipboard access, default is false
 | ||||||
|     enable_clipboard bool              /* enable clipboard access, default is false */ | 	clipboard_size                int     // max size of clipboard content in bytes
 | ||||||
|     clipboard_size int                 /* max size of clipboard content in bytes */ | 	html5_canvas_name             byteptr // the name (id) of the HTML5 canvas element, default is "canvas"
 | ||||||
| 
 | 	html5_canvas_resize           bool    // if true, the HTML5 canvas size is set to sapp_desc.width/height, otherwise canvas size is tracked
 | ||||||
|     html5_canvas_name byteptr          /* the name (id) of the HTML5 canvas element, default is "canvas" */ | 	html5_preserve_drawing_buffer bool    // HTML5 only: whether to preserve default framebuffer content between frames
 | ||||||
|     html5_canvas_resize bool           /* if true, the HTML5 canvas size is set to sapp_desc.width/height, otherwise canvas size is tracked */ | 	html5_premultiplied_alpha     bool    // HTML5 only: whether the rendered pixels use premultiplied alpha convention
 | ||||||
|     html5_preserve_drawing_buffer bool /* HTML5 only: whether to preserve default framebuffer content between frames */ | 	html5_ask_leave_site          bool    // initial state of the internal html5_ask_leave_site flag (see sapp_html5_ask_leave_site())
 | ||||||
|     html5_premultiplied_alpha bool     /* HTML5 only: whether the rendered pixels use premultiplied alpha convention */ | 	ios_keyboard_resizes_canvas   bool    // if true, showing the iOS keyboard shrinks the canvas
 | ||||||
|     html5_ask_leave_site bool          /* initial state of the internal html5_ask_leave_site flag (see sapp_html5_ask_leave_site()) */ | 	gl_force_gles2                bool    // if true, setup GLES2/WebGL even if GLES3/WebGL2 is available
 | ||||||
|     ios_keyboard_resizes_canvas bool   /* if true, showing the iOS keyboard shrinks the canvas */ | 	native_render                 bool | ||||||
|     gl_force_gles2 bool                /* if true, setup GLES2/WebGL even if GLES3/WebGL2 is available */ |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub struct Event { | pub struct Event { | ||||||
|  | @ -81,8 +79,10 @@ pub: | ||||||
| 	framebuffer_width  int | 	framebuffer_width  int | ||||||
| 	framebuffer_height int | 	framebuffer_height int | ||||||
| } | } | ||||||
|  | 
 | ||||||
| pub fn (e &C.sapp_event) str() string { | pub fn (e &C.sapp_event) str() string { | ||||||
|     return 'evt: frame_count=$e.frame_count, type=${e.@type}' | 	t := e.@type | ||||||
|  | 	return 'evt: frame_count=$e.frame_count, type=$t' | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub struct C.sapp_touchpoint { | pub struct C.sapp_touchpoint { | ||||||
|  |  | ||||||
|  | @ -314,11 +314,9 @@ fn (mut v Builder) setup_ccompiler_options(ccompiler string) { | ||||||
| 	// Min macos version is mandatory I think?
 | 	// Min macos version is mandatory I think?
 | ||||||
| 	if v.pref.os == .macos { | 	if v.pref.os == .macos { | ||||||
| 		ccoptions.post_args << '-mmacosx-version-min=10.7' | 		ccoptions.post_args << '-mmacosx-version-min=10.7' | ||||||
| 	} | 	} else if v.pref.os == .ios { | ||||||
| 	if v.pref.os == .ios { |  | ||||||
| 		ccoptions.post_args << '-miphoneos-version-min=10.0' | 		ccoptions.post_args << '-miphoneos-version-min=10.0' | ||||||
| 	} | 	} else if v.pref.os == .windows { | ||||||
| 	if v.pref.os == .windows { |  | ||||||
| 		ccoptions.post_args << '-municode' | 		ccoptions.post_args << '-municode' | ||||||
| 	} | 	} | ||||||
| 	cflags := v.get_os_cflags() | 	cflags := v.get_os_cflags() | ||||||
|  |  | ||||||
|  | @ -1964,8 +1964,8 @@ fn (mut p Parser) const_decl() ast.ConstDecl { | ||||||
| 		} | 		} | ||||||
| 		pos := p.tok.position() | 		pos := p.tok.position() | ||||||
| 		name := p.check_name() | 		name := p.check_name() | ||||||
| 		if util.contains_capital(name) { | 		if false && util.contains_capital(name) { | ||||||
| 			p.warn_with_pos('const names cannot contain uppercase letters, use snake_case instead', | 			p.warn_with_pos('$p.file_name_dir const names cannot contain uppercase letters, use snake_case instead', | ||||||
| 				pos) | 				pos) | ||||||
| 		} | 		} | ||||||
| 		full_name := p.prepend_mod(name) | 		full_name := p.prepend_mod(name) | ||||||
|  |  | ||||||
|  | @ -98,6 +98,11 @@ fn str_replace2() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn reassign_str() { | fn reassign_str() { | ||||||
|  | 	mut z := '1' + '2' | ||||||
|  | 	if true { | ||||||
|  | 		println('KEK') | ||||||
|  | 		z = 'foo' | ||||||
|  | 	} | ||||||
| 	mut x := 'a' | 	mut x := 'a' | ||||||
| 	x = 'b' // nothing has to be freed here
 | 	x = 'b' // nothing has to be freed here
 | ||||||
| 	//
 | 	//
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue