Skip to content

Instantly share code, notes, and snippets.

@matias-eduardo
Last active March 1, 2021 07:24
Show Gist options
  • Save matias-eduardo/c3079e2f4e7db5a27dc48de0aa205641 to your computer and use it in GitHub Desktop.
Save matias-eduardo/c3079e2f4e7db5a27dc48de0aa205641 to your computer and use it in GitHub Desktop.
Small script to create an OSX window with Odin. [WIP]
package main
import "core:fmt"
foreign import objc "system:objc"
foreign import cg "system.CoreGraphics.framework"
@force foreign import _appkit "system:Appkit.framework"
main :: proc() {
@(default_calling_convention="c") foreign objc {
@(link_name="objc_msgSend") msg :: proc(rawptr) -> rawptr ---;
@(link_name="objc_getClass") cls :: proc(name: cstring) -> (id: rawptr) ---;
@(link_name="sel_getUid") sel :: proc(str: cstring) -> (sel: rawptr) ---;
}
@(default_calling_convention="c") foreign cg {
CGDisplayPixelsWide :: proc(display_id: u32) -> (pixel_width: u32) ---;
CGDisplayPixelsHigh :: proc(display_id: u32) -> (pixel_height: u32) ---;
CGMainDisplayID :: proc() -> (display_id: u32) ---;
}
// app = [NSApplication, sharedApplication]
cls_NSApplication : rawptr = cls("NSApplication");
sel_sharedApplication : rawptr = sel("sharedApplication");
sig_NSApplication_sharedApplication :: #type proc "c" (cls: rawptr, sel: rawptr) -> (app: rawptr);
NSApplication_sharedApplication := cast(sig_NSApplication_sharedApplication)msg;
app : rawptr = NSApplication_sharedApplication(cls = cls_NSApplication, sel = sel_sharedApplication);
assert(app != nil);
fmt.println("app:", app);
// [app, setActivationPolicy:NSApplicationActivationPolicyRegular]
long :: i32 when (ODIN_OS == "windows" || size_of(rawptr) == 4) else i64;
NSApplicationActivationPolicy :: enum long { Regular = 0, Accessory = 1, Prohibited = 2 };
sel_setActivationPolicy : rawptr = sel("setActivationPolicy:");
sig_NSApplication_setActivationPolicy :: #type proc "c" (
app: rawptr,
sel: rawptr,
policy: NSApplicationActivationPolicy
) -> (ok: bool);
NSApplication_setActivationPolicy := cast(sig_NSApplication_setActivationPolicy)msg;
{
ok : bool = NSApplication_setActivationPolicy(
app = app,
sel = sel_setActivationPolicy,
policy = NSApplicationActivationPolicy.Regular
);
assert(ok == true);
}
// new_window = [NSWindow, alloc]
cls_NSWindow : rawptr = cls("NSWindow");
sel_alloc : rawptr = sel("alloc");
sig_NSWindow_alloc :: #type proc "c" (cls: rawptr, sel: rawptr) -> (new_window: rawptr);
NSWindow_alloc := cast(sig_NSWindow_alloc)msg;
new_window : rawptr = NSWindow_alloc(cls_NSWindow, sel_alloc);
assert(new_window != nil);
fmt.println("new_window:", new_window);
// window = [
// new_window,
// initWithContentRect:frameRect,
// styleMask:NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskResizable,
// backing:NSBackingStoreBuffered,
// defer:NO
// ]
sel_initWithContentRect_styleMask_backing_defer : rawptr = sel("initWithContentRect:styleMask:backing:defer:");
main_display_id : u32 = CGMainDisplayID();
fmt.println("main_display_id:", main_display_id);
display_px_width : u32 = CGDisplayPixelsWide(main_display_id);
fmt.println("display width:", display_px_width);
display_px_height : u32 = CGDisplayPixelsHigh(main_display_id);
fmt.println("display height:", display_px_height);
NSRect :: struct { x, y, w, h: f64 };
contentRect : NSRect = { w = 600, h = 500 };
contentRect.x = (f64(display_px_width) / 2) - (contentRect.w / 2);
contentRect.y = (f64(display_px_height) / 2) - (contentRect.h / 2);
ulong :: u32 when (ODIN_OS == "windows" || size_of(rawptr) == 4) else u64;
NSWindowStyleMask :: enum ulong {
Titled,
Closable,
Miniaturizable,
Resizable
};
styleMask : ulong = cast(ulong)bit_set[NSWindowStyleMask]{
.Titled,
.Closable,
.Miniaturizable,
.Resizable
};
fmt.printf("styleMask bit_set: %b\n", styleMask);
NSBackingStoreType :: enum u32 { Buffered = 2 };
sig_NSWindow_initWithContentRect_styleMask_backing_defer :: #type proc "c" (
ns_window: rawptr,
sel: rawptr,
contentRect: NSRect,
styleMask: ulong,
backing: NSBackingStoreType,
defer_flag: bool
) -> (window: rawptr);
NSWindow_initWithContentRect_styleMask_backing_defer := cast(sig_NSWindow_initWithContentRect_styleMask_backing_defer)msg;
window : rawptr = NSWindow_initWithContentRect_styleMask_backing_defer(
ns_window = new_window,
sel = sel_initWithContentRect_styleMask_backing_defer,
contentRect = contentRect,
styleMask = styleMask,
backing = NSBackingStoreType.Buffered,
defer_flag = false
);
fmt.println("window:", window);
// title_string = [NSString, stringWithUTF8String:"Hello from Odin"]
cls_NSString : rawptr = cls("NSString");
sel_stringWithUTF8String : rawptr = sel("stringWithUTF8String:");
sig_NSString_stringWithUTF8String :: #type proc "c" (cls: rawptr, sel: rawptr, str: cstring) -> (ns_str: rawptr);
NSString_stringWithUTF8String := cast(sig_NSString_stringWithUTF8String)msg;
title_string : rawptr = NSString_stringWithUTF8String(
cls = cls_NSString,
sel = sel_stringWithUTF8String,
str = "Hello from Odin"
);
fmt.println("title_string:", title_string);
// [new_window, setTitle:@"Hello from Odin"]
sel_setTitle : rawptr = sel("setTitle:");
sig_NSWindow_setTitle :: #type proc "c" (window: rawptr, sel: rawptr, title: rawptr);
NSWindow_setTitle := cast(sig_NSWindow_setTitle)msg;
NSWindow_setTitle(window = window, sel = sel_setTitle, title = title_string);
// [window makeKeyAndOrderFront:nil];
sel_makeKeyAndOrderFront : rawptr = sel("makeKeyAndOrderFront:");
sig_NSWindow_makeKeyAndOrderFront :: #type proc "c" (window: rawptr, sel: rawptr, sender: rawptr);
NSWindow_makeKeyAndOrderFront := cast(sig_NSWindow_makeKeyAndOrderFront)msg;
NSWindow_makeKeyAndOrderFront(
window = window,
sel = sel_makeKeyAndOrderFront,
sender = window
);
// [app activateIgnoringOtherApps:YES];
sel_activateIgnoringOtherApps : rawptr = sel("activateIgnoringOtherApps:");
sig_NSApp_activateIgnoringOtherApps :: #type proc "c" (app: rawptr, sel: rawptr, flag: bool);
NSApp_activateIgnoringOtherApps := cast(sig_NSApp_activateIgnoringOtherApps)msg;
NSApp_activateIgnoringOtherApps(app = app, sel = sel_activateIgnoringOtherApps, flag = true);
// [app, run]
sel_run : rawptr = sel("run");
sig_NSApp_run :: #type proc "c" (app: rawptr, sel: rawptr);
NSApp_run := cast(sig_NSApp_run)msg;
NSApp_run(app = app, sel = sel_run);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment