clay/bindings/jai/module.jai

134 lines
4.4 KiB
Plaintext
Raw Normal View History

2024-12-22 17:20:31 +00:00
Vector2 :: Math.Vector2;
ElementConfigType :: enum s32 {
NONE :: 0;
RECTANGLE :: 1;
BORDER_CONTAINER :: 2;
FLOATING_CONTAINER :: 4;
SCROLL_CONTAINER :: 8;
IMAGE :: 16;
TEXT :: 32;
CUSTOM :: 64;
CLAY__ELEMENT_CONFIG_TYPE_NONE :: NONE;
CLAY__ELEMENT_CONFIG_TYPE_RECTANGLE :: RECTANGLE;
CLAY__ELEMENT_CONFIG_TYPE_BORDER_CONTAINER :: BORDER_CONTAINER;
CLAY__ELEMENT_CONFIG_TYPE_FLOATING_CONTAINER :: FLOATING_CONTAINER;
CLAY__ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER :: SCROLL_CONTAINER;
CLAY__ELEMENT_CONFIG_TYPE_IMAGE :: IMAGE;
CLAY__ELEMENT_CONFIG_TYPE_TEXT :: TEXT;
CLAY__ELEMENT_CONFIG_TYPE_CUSTOM :: CUSTOM;
// Jai bindings specific types, please don't assume any value in those
// a it might change if the enums above overlap with it
// TODO Check if these values need to be powers of two
ID :: 256;
LAYOUT :: 257;
}
// This is passed to UI so that we can omit layout
TypedConfig :: struct {
type: ElementConfigType;
config: *void;
id: ElementId;
}
2024-12-31 13:35:03 +00:00
make_string :: (str: string) -> String {
return .{cast(u64, str.count), str.data};
}
// The way of handling this is inspired by the odin bindings
UI :: (configs: ..TypedConfig, $children: Code = #code {}, $call := #caller_code) {
2024-12-31 13:35:03 +00:00
_OpenElement();
for config : configs {
if config.type == {
case .ID;
_AttachId(config.id);
case .LAYOUT;
_AttachLayoutConfig(cast(*LayoutConfig, config.config));
case;
// config.config is a *void, it stores the address of the pointer that is stored in the union
// as ElementConfigUnion is a union of structs. We can't cast pointers directly to structs,
// we first cast the address of the *void and then dereference it.
// Maybe there's a cast modifier to avoid this, but I don't know it (no_check and trunc didn't work).
_AttachElementConfig(cast(*ElementConfigUnion, *config.config).*, config.type);
}
}
2024-12-31 13:35:03 +00:00
_ElementPostConfiguration();
#insert,scope(call) children;
2024-12-31 13:35:03 +00:00
_CloseElement();
2024-12-31 13:35:03 +00:00
}
// Not sure yet wich of these two methods is better
// Idealy there should be a way to mimic the style of how it's done in C
// ElementScope :: (configs: ..TypedConfig) #expand {
// _OpenElement();
// for config : configs {
// if config.type == {
// case .ID;
// _AttachId(config.id);
// case .LAYOUT;
// _AttachLayoutConfig(cast(*LayoutConfig, config.config));
// case;
// // config.config is a *void, it stores the address of the pointer that is stored in the union
// // as ElementConfigUnion is a union of structs. We can't cast pointers directly to structs,
// // we first cast the address of the *void and then dereference it.
// // Maybe there's a cast modifier to avoid this, but I don't know it (no_check and trunc didn't work).
// _AttachElementConfig(cast(*ElementConfigUnion, *config.config).*, config.type);
// }
// }
// _ElementPostConfiguration();
// `defer _CloseElement();
// }
ID :: (label: string, index: u32 = 0) -> TypedConfig {
return .{type = .ID, id = _HashString(make_string(label), index, 0)};
2024-12-31 13:35:03 +00:00
}
Layout :: (config: LayoutConfig) -> TypedConfig {
return .{type = .LAYOUT, config = _StoreLayoutConfig(config)};
2024-12-31 13:35:03 +00:00
}
Rectangle :: (config: RectangleElementConfig) -> TypedConfig {
2024-12-31 13:35:03 +00:00
return .{
type = .RECTANGLE,
config = _StoreRectangleElementConfig(config)
2024-12-31 13:35:03 +00:00
};
}
Text :: (text: string, config: *TextElementConfig) {
_OpenTextElement(make_string(text), config);
}
TextConfig :: (config: TextElementConfig) -> *TextElementConfig {
return _StoreTextElementConfig(config);
}
2024-12-31 13:35:03 +00:00
SizingGrow :: (size_min_max: SizingMinMax = .{}) -> SizingAxis {
return .{type = .GROW, size = .{minMax = size_min_max}};
}
SizingFixed :: (size: float) -> SizingAxis {
return .{type = .FIXED, size = .{minMax = .{size, size}}};
}
GetElementId :: (str: string) -> ElementId {
return GetElementId(make_string(str));
}
2024-12-22 17:20:31 +00:00
#scope_module
Math :: #import "Math";
2024-12-31 13:35:03 +00:00
Compiler :: #import "Compiler";
ProgramPrint :: #import "Program_Print";
2024-12-22 17:20:31 +00:00
2024-12-22 10:49:53 +00:00
#if OS == .WINDOWS {
#load "windows.jai";
} else {
2024-12-22 17:20:31 +00:00
assert(false);
2024-12-22 10:49:53 +00:00
}