gg: native rendering mode on macOS

pull/8292/head
Alexander Medvednikov 2021-01-23 10:25:40 +01:00
parent a3908414e4
commit d991712b3c
32 changed files with 492 additions and 152 deletions

View File

@ -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]`

View File

@ -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/',

View File

@ -57,4 +57,4 @@ fn start_client() ?&websocket.Client {
println(term.red('error on listen $err')) println(term.red('error on listen $err'))
} }
return ws return ws
} }

View File

@ -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

View File

@ -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) {

33
thirdparty/sokol/sokol_app2.h vendored 100644
View File

@ -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

View File

@ -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)
} }

View File

@ -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 {

View File

@ -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)

View File

@ -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);
}

View File

@ -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
} }

View File

@ -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)
} }

View File

@ -52,4 +52,4 @@ const (
.send_low_size, .send_low_size,
.send_timeout, .send_timeout,
] ]
) )

View File

@ -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) {
println('os.log: ' + s) //$if macos {
// Use NSLog() on macos
//C.darwin_log(s)
//} $else {
println('os.log: ' + s)
//}
} }
[deprecated] [deprecated]

View File

@ -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)

View File

@ -0,0 +1,7 @@
/*
NSString* nsstring(string s);
void darwin_log(string s) {
NSLog(nsstring(s));
}
*/

View File

@ -3,235 +3,221 @@ module sapp
import sokol.gfx import sokol.gfx
pub const ( pub const (
used_import = gfx.used_import used_import = gfx.used_import
) )
// Android needs a global reference to `g_desc` // Android needs a global reference to `g_desc`
__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()

View File

@ -2,93 +2,93 @@ 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
height int // the preferred height of the window / canvas
width int /* the preferred width of the window / canvas */ sample_count int // MSAA sample count
height int /* the preferred height of the window / canvas */ swap_interval int // the preferred swap interval (ignored on some platforms)
sample_count int /* MSAA sample count */ high_dpi bool // whether the rendering canvas is full-resolution on HighDPI displays
swap_interval int /* the preferred swap interval (ignored on some platforms) */ fullscreen bool // whether the window should be created in fullscreen mode
high_dpi bool /* whether the rendering canvas is full-resolution on HighDPI displays */ alpha bool // whether the framebuffer should have an alpha channel (ignored on some platforms)
fullscreen bool /* whether the window should be created in fullscreen mode */ window_title byteptr // the window title as UTF-8 encoded string
alpha bool /* whether the framebuffer should have an alpha channel (ignored on some platforms) */ user_cursor bool // if true, user is expected to manage cursor image in SAPP_EVENTTYPE_UPDATE_CURSOR
window_title byteptr /* the window title as UTF-8 encoded string */ enable_clipboard bool // enable clipboard access, default is false
user_cursor bool /* if true, user is expected to manage cursor image in SAPP_EVENTTYPE_UPDATE_CURSOR */ clipboard_size int // max size of clipboard content in bytes
enable_clipboard bool /* enable clipboard access, default is false */ html5_canvas_name byteptr // the name (id) of the HTML5 canvas element, default is "canvas"
clipboard_size int /* max size of clipboard content in bytes */ html5_canvas_resize bool // if true, the HTML5 canvas size is set to sapp_desc.width/height, otherwise canvas size is tracked
html5_preserve_drawing_buffer bool // HTML5 only: whether to preserve default framebuffer content between frames
html5_canvas_name byteptr /* the name (id) of the HTML5 canvas element, default is "canvas" */ html5_premultiplied_alpha bool // HTML5 only: whether the rendered pixels use premultiplied alpha convention
html5_canvas_resize bool /* if true, the HTML5 canvas size is set to sapp_desc.width/height, otherwise canvas size is tracked */ html5_ask_leave_site bool // initial state of the internal html5_ask_leave_site flag (see sapp_html5_ask_leave_site())
html5_preserve_drawing_buffer bool /* HTML5 only: whether to preserve default framebuffer content between frames */ ios_keyboard_resizes_canvas bool // if true, showing the iOS keyboard shrinks the canvas
html5_premultiplied_alpha bool /* HTML5 only: whether the rendered pixels use premultiplied alpha convention */ gl_force_gles2 bool // if true, setup GLES2/WebGL even if GLES3/WebGL2 is available
html5_ask_leave_site bool /* initial state of the internal html5_ask_leave_site flag (see sapp_html5_ask_leave_site()) */ native_render bool
ios_keyboard_resizes_canvas bool /* if true, showing the iOS keyboard shrinks the canvas */
gl_force_gles2 bool /* if true, setup GLES2/WebGL even if GLES3/WebGL2 is available */
} }
pub struct Event { pub struct Event {
pub: pub:
frame_count u64 frame_count u64
typ EventType typ EventType
key_code KeyCode key_code KeyCode
char_code u32 char_code u32
key_repeat bool key_repeat bool
modifiers u32 modifiers u32
mouse_button MouseButton mouse_button MouseButton
mouse_x f32 mouse_x f32
mouse_y f32 mouse_y f32
mouse_dx f32 mouse_dx f32
mouse_dy f32 mouse_dy f32
scroll_x f32 scroll_x f32
scroll_y f32 scroll_y f32
num_touches int num_touches int
touches [8]C.sapp_touchpoint touches [8]C.sapp_touchpoint
window_width int window_width int
window_height int window_height int
framebuffer_width int framebuffer_width int
framebuffer_height int framebuffer_height int
} }
pub struct C.sapp_event { pub struct C.sapp_event {
pub: pub:
frame_count u64 frame_count u64
@type EventType @type EventType
key_code KeyCode key_code KeyCode
char_code u32 char_code u32
key_repeat bool key_repeat bool
modifiers u32 modifiers u32
mouse_button MouseButton mouse_button MouseButton
mouse_x f32 mouse_x f32
mouse_y f32 mouse_y f32
mouse_dx f32 mouse_dx f32
mouse_dy f32 mouse_dy f32
scroll_x f32 scroll_x f32
scroll_y f32 scroll_y f32
num_touches int num_touches int
touches [8]C.sapp_touchpoint touches [8]C.sapp_touchpoint
window_width int window_width int
window_height int window_height int
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 {
pub: pub:
identifier u64 identifier u64
pos_x f32 pos_x f32
pos_y f32 pos_y f32
changed bool changed bool
} }

View File

@ -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()

View File

@ -185,4 +185,4 @@ fn main() {
interpolation_string_prefix_expr() interpolation_string_prefix_expr()
utf8_string_interpolation() utf8_string_interpolation()
string_interpolation_str_evaluation() string_interpolation_str_evaluation()
} }

View File

@ -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)

View File

@ -47,4 +47,4 @@ fn pointer_array_slice(mut a []int) {
fn test_pointer_array_slice() { fn test_pointer_array_slice() {
mut arr := [1,2,3] mut arr := [1,2,3]
pointer_array_slice(mut arr) pointer_array_slice(mut arr)
} }

View File

@ -100,4 +100,4 @@ fn generic_t_is_with_else<T>(raw_data string) ?T {
} $else { } $else {
return T{} return T{}
} }
} }

View File

@ -82,4 +82,4 @@ fn test_defer_with_anon_fn() {
} }
x() x()
return return
} }

View File

@ -2,4 +2,4 @@ fn filter_in_map_test() {
x := [['']] x := [['']]
y := x.map(it.filter(it != '')) y := x.map(it.filter(it != ''))
assert y[0].len == 0 assert y[0].len == 0
} }

View File

@ -23,4 +23,4 @@ fn test_imported_symbols_functions() {
fn test_imported_symbols_constants() { fn test_imported_symbols_constants() {
assert module_name == 'geometry' assert module_name == 'geometry'
} }

View File

@ -32,4 +32,4 @@ fn test_as() {
assert false assert false
} }
} }
} }

View File

@ -13,4 +13,4 @@ fn test_operator_overloading() {
fn test_str_method() { fn test_str_method() {
one := Point {x:1, y:2} one := Point {x:1, y:2}
assert '$one' == '1 2' assert '$one' == '1 2'
} }

View File

@ -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
// //

View File

@ -225,4 +225,4 @@ fn color_multiply(c u32, level f32) u32 {
a = if a > 1.0 { 1.0 } else { a } a = if a > 1.0 { 1.0 } else { a }
return (u32(r * 255) << 24) | (u32(g * 255) << 16) | (u32(b * 255) << 8) | u32(a * 255) return (u32(r * 255) << 24) | (u32(g * 255) << 16) | (u32(b * 255) << 8) | u32(a * 255)
} }

View File

@ -118,4 +118,4 @@ fn (mut bmp BitMap) draw_text_block(text string, block Text_block) {
} }
bmp.space_cw = old_space_cw bmp.space_cw = old_space_cw
} }

View File

@ -1096,4 +1096,4 @@ fn tst(){
//dprintln( tf.get_u32().hex() ) //dprintln( tf.get_u32().hex() )
//dprintln( tf.get_2dot14() ) //dprintln( tf.get_2dot14() )
//dprintln( tf.get_fixed() ) //dprintln( tf.get_fixed() )
} }