2024-12-22 17:20:31 +00:00
|
|
|
|
|
|
|
Vector2 :: Math.Vector2;
|
|
|
|
|
2025-01-01 15:19:52 +00:00
|
|
|
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 {
|
2025-01-02 22:19:31 +00:00
|
|
|
clay_string := String.{cast(u64, str.count), str.data};
|
|
|
|
return clay_string;
|
2024-12-31 13:35:03 +00:00
|
|
|
}
|
|
|
|
|
2025-01-02 22:19:31 +00:00
|
|
|
global_counter := 0;
|
|
|
|
|
|
|
|
for_expansion :: (configs_array: InternalElementConfigArray, body: Code, _: For_Flags) #expand {
|
|
|
|
// Jai forces the definition of these
|
|
|
|
`it_index := 0;
|
|
|
|
`it := 0;
|
|
|
|
|
2024-12-31 13:35:03 +00:00
|
|
|
_OpenElement();
|
2025-01-02 22:19:31 +00:00
|
|
|
for config : configs_array.configs {
|
2025-01-01 15:19:52 +00:00
|
|
|
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();
|
|
|
|
|
2025-01-02 22:19:31 +00:00
|
|
|
#insert body;
|
2024-12-31 13:35:03 +00:00
|
|
|
|
2025-01-01 18:28:22 +00:00
|
|
|
_CloseElement();
|
2024-12-31 13:35:03 +00:00
|
|
|
}
|
|
|
|
|
2025-01-02 22:19:31 +00:00
|
|
|
Element :: (configs: ..TypedConfig) -> InternalElementConfigArray #expand {
|
|
|
|
return .{configs};
|
|
|
|
}
|
2025-01-01 18:28:22 +00:00
|
|
|
|
2025-01-01 15:19:52 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2025-01-01 15:19:52 +00:00
|
|
|
Layout :: (config: LayoutConfig) -> TypedConfig {
|
|
|
|
return .{type = .LAYOUT, config = _StoreLayoutConfig(config)};
|
2024-12-31 13:35:03 +00:00
|
|
|
}
|
|
|
|
|
2025-01-01 15:19:52 +00:00
|
|
|
Rectangle :: (config: RectangleElementConfig) -> TypedConfig {
|
2024-12-31 13:35:03 +00:00
|
|
|
return .{
|
|
|
|
type = .RECTANGLE,
|
2025-01-01 15:19:52 +00:00
|
|
|
config = _StoreRectangleElementConfig(config)
|
2024-12-31 13:35:03 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2025-01-02 22:19:31 +00:00
|
|
|
Floating :: (config: FloatingElementConfig) -> TypedConfig {
|
|
|
|
return .{type = .FLOATING_CONTAINER, config = _StoreFloatingElementConfig(config)};
|
|
|
|
}
|
|
|
|
|
|
|
|
Scroll :: (config: ScrollElementConfig) -> TypedConfig {
|
|
|
|
return .{type = .SCROLL_CONTAINER, config = _StoreScrollElementConfig(config)};
|
|
|
|
}
|
|
|
|
|
2025-01-01 18:28:22 +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}};
|
|
|
|
}
|
|
|
|
|
2025-01-01 18:28:22 +00:00
|
|
|
SizingFixed :: (size: float) -> SizingAxis {
|
|
|
|
return .{type = .FIXED, size = .{minMax = .{size, size}}};
|
|
|
|
}
|
|
|
|
|
|
|
|
GetElementId :: (str: string) -> ElementId {
|
|
|
|
return GetElementId(make_string(str));
|
|
|
|
}
|
|
|
|
|
2025-01-02 22:19:31 +00:00
|
|
|
// OnHover :: (onHoverFunction: #type (elementId: ElementId, pointerData: PointerData, userData: s64) -> void #c_call, userData: s64) -> TypedConfig {
|
|
|
|
// OnHover(onHoverFunction, userData);
|
|
|
|
// return TypedConfig.{
|
|
|
|
// type = .NONE,
|
|
|
|
// };
|
|
|
|
// }
|
|
|
|
|
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
|
|
|
|
2025-01-02 22:19:31 +00:00
|
|
|
InternalElementConfigArray :: struct {
|
|
|
|
configs: [] TypedConfig;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|