mirror of
https://github.com/nicbarker/clay.git
synced 2025-04-15 10:48:04 +00:00
Added first version of Jai bindings
This commit is contained in:
parent
83ded6995e
commit
4699018599
1
bindings/jai/.gitignore
vendored
Normal file
1
bindings/jai/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.build/
|
BIN
bindings/jai/clay-jai/windows/clay.lib
Normal file
BIN
bindings/jai/clay-jai/windows/clay.lib
Normal file
Binary file not shown.
464
bindings/jai/generate.jai
Normal file
464
bindings/jai/generate.jai
Normal file
@ -0,0 +1,464 @@
|
||||
AT_COMPILE_TIME :: true;
|
||||
|
||||
SOURCE_PATH :: "source";
|
||||
|
||||
#if AT_COMPILE_TIME {
|
||||
#run,stallable {
|
||||
Compiler.set_build_options_dc(.{do_output=false});
|
||||
options := Compiler.get_build_options();
|
||||
args := options.compile_time_command_line;
|
||||
if !generate_bindings(args, options.minimum_os_version) {
|
||||
Compiler.compiler_set_workspace_status(.FAILED);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#import "System";
|
||||
|
||||
main :: () {
|
||||
set_working_directory(path_strip_filename(get_path_of_running_executable()));
|
||||
if !generate_bindings(get_command_line_arguments(), #run get_build_options().minimum_os_version) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Build_Type :: enum {
|
||||
STATIC_LIBRARY;
|
||||
DYNAMIC_LIBRARY;
|
||||
EXECUTABLE;
|
||||
OBJ_FILE;
|
||||
}
|
||||
|
||||
build_cpp_static_lib :: #bake_arguments build_cpp(type = .STATIC_LIBRARY);
|
||||
build_cpp_dynamic_lib :: #bake_arguments build_cpp(type = .DYNAMIC_LIBRARY);
|
||||
build_cpp_executable :: #bake_arguments build_cpp(type = .EXECUTABLE);
|
||||
|
||||
// This is a modified version of the procedure from BuildCpp. It will assume a clang-like compiler if you add something to compiler_executable_path.
|
||||
build_cpp :: (
|
||||
output_basename: string,
|
||||
files: ..string,
|
||||
type: Build_Type,
|
||||
debug := false,
|
||||
extra: [] string = .[],
|
||||
library_files: [] string = .[],
|
||||
target := OS,
|
||||
compiler_executable_path := "",
|
||||
ar_executable_path := "",
|
||||
working_directory := "",
|
||||
loc := #caller_location
|
||||
) -> bool {
|
||||
Basic.auto_release_temp();
|
||||
Basic.push_allocator(Basic.temp);
|
||||
|
||||
arguments: [..] string;
|
||||
|
||||
output_filename: string;
|
||||
if target == .WINDOWS && compiler_executable_path == "" {
|
||||
if #complete type == {
|
||||
case .STATIC_LIBRARY;
|
||||
output_filename = Basic.tprint("%.lib", output_basename);
|
||||
case .DYNAMIC_LIBRARY;
|
||||
output_filename = Basic.tprint("%.dll", output_basename);
|
||||
case .EXECUTABLE;
|
||||
output_filename = Basic.tprint("%.exe", output_basename);
|
||||
case .OBJ_FILE;
|
||||
output_filename = Basic.tprint("%.obj", output_basename);
|
||||
}
|
||||
|
||||
#if OS == .WINDOWS {
|
||||
String.path_overwrite_separators(output_filename, #char "\\");
|
||||
|
||||
vc_path, linker_path := WindowsResources.find_visual_studio_in_a_ridiculous_garbage_way();
|
||||
|
||||
kit_root := WindowsResources.find_windows_kit_root();
|
||||
if !kit_root {
|
||||
Compiler.compiler_report("Unable to find Windows Kit root; can't compile.\n", loc);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
Compiler.compiler_report("Unable to find Visual Studio; can't compile.\n", loc);
|
||||
vc_path, linker_path: string;
|
||||
kit_root: string;
|
||||
return false; // Visual studio is not available in non-windows OS.
|
||||
}
|
||||
|
||||
linker := String.join(linker_path, "\\", "cl.exe");
|
||||
Basic.array_add(*arguments, linker);
|
||||
|
||||
Basic.array_add(*arguments, "/nologo");
|
||||
|
||||
// Include directories:
|
||||
vc_include_path := String.join(vc_path, "\\..\\..\\include");
|
||||
kit_root_include := String.replace(kit_root, "Lib", "Include");
|
||||
Basic.array_add(*arguments,
|
||||
Basic.tprint("/I%", vc_include_path),
|
||||
Basic.tprint("/I%\\um", kit_root_include),
|
||||
Basic.tprint("/I%\\ucrt", kit_root_include),
|
||||
Basic.tprint("/I%\\shared", kit_root_include),
|
||||
);
|
||||
|
||||
// Definitions:
|
||||
Basic.array_add(*arguments, "/DWIN32");
|
||||
if debug {
|
||||
Basic.array_add(*arguments, "/DDEBUG");
|
||||
}
|
||||
|
||||
// Compiler options:
|
||||
if debug {
|
||||
Basic.array_add(*arguments, "/Od"); // Disable optimizations.
|
||||
} else {
|
||||
Basic.array_add(*arguments,
|
||||
"/O2", // Maximize speed.
|
||||
"/Oi", // Enable intrinsics.
|
||||
);
|
||||
}
|
||||
Basic.array_add(*arguments, "/W3");
|
||||
|
||||
if debug {
|
||||
Basic.array_add(*arguments,
|
||||
"/DEBUG", // Generate debug info.
|
||||
"/Zi", // Generate pdb file.
|
||||
Basic.tprint("/Fd%.pdb", output_basename), // Sets name of pdb file.
|
||||
);
|
||||
}
|
||||
|
||||
Basic.array_add(*arguments,
|
||||
"-diagnostics:caret",
|
||||
"-diagnostics:column"
|
||||
);
|
||||
|
||||
Basic.array_add(*arguments, .. extra);
|
||||
|
||||
// Add files:
|
||||
objs: [..] string;
|
||||
Basic.array_reserve(*objs, files.count);
|
||||
for files {
|
||||
src := String.copy_temporary_string(it);
|
||||
String.path_overwrite_separators(src);
|
||||
Basic.array_add(*arguments, src);
|
||||
|
||||
Basic.array_add(*objs, Basic.tprint("%.obj", String.path_strip_extension(String.path_filename(it))));
|
||||
}
|
||||
|
||||
// Make sure to cleanup the resulting obj files.
|
||||
defer {
|
||||
if type != .OBJ_FILE {
|
||||
for objs File.file_delete(it);
|
||||
}
|
||||
|
||||
if type == .DYNAMIC_LIBRARY then File.file_delete(Basic.tprint("%.exp", output_basename));
|
||||
}
|
||||
|
||||
if type == .STATIC_LIBRARY || type == .OBJ_FILE {
|
||||
Basic.array_add(*arguments, "/c"); // Compile without linking.
|
||||
} else {
|
||||
Basic.array_add(*arguments, "/link");
|
||||
|
||||
// Linker options:
|
||||
if type == .DYNAMIC_LIBRARY {
|
||||
Basic.array_add(*arguments, "/DLL");
|
||||
}
|
||||
Basic.array_add(*arguments,
|
||||
"/MACHINE:AMD64",
|
||||
Basic.tprint("/OUT:%", output_filename),
|
||||
Basic.tprint("/libpath:%", vc_path),
|
||||
Basic.tprint("/libpath:%\\um\\x64", kit_root),
|
||||
Basic.tprint("/libpath:%\\ucrt\\x64", kit_root),
|
||||
);
|
||||
}
|
||||
|
||||
Basic.array_add(*arguments, .. library_files);
|
||||
|
||||
Basic.log("%", Process.get_quoted_command_string(arguments));
|
||||
result, output_string, error_string := Process.run_command(..arguments, capture_and_return_output = true, print_captured_output = true, working_directory = working_directory);
|
||||
|
||||
if result.exit_code {
|
||||
Compiler.compiler_report(Basic.tprint("Compiler failed with exit code '%'.\n", result.exit_code), loc);
|
||||
return false;
|
||||
}
|
||||
|
||||
if type == .STATIC_LIBRARY {
|
||||
// Create library:
|
||||
Basic.array_reset_keeping_memory(*arguments);
|
||||
|
||||
librarian := String.join(linker_path, "\\lib.exe");
|
||||
|
||||
Basic.array_add(*arguments, librarian, "/nologo");
|
||||
Basic.array_add(*arguments, ..objs);
|
||||
Basic.array_add(*arguments, Basic.tprint("/OUT:%", output_filename));
|
||||
|
||||
Basic.log("%", Process.get_quoted_command_string(arguments));
|
||||
result, output_string, error_string := Process.run_command(..arguments, capture_and_return_output = true, print_captured_output = true, working_directory = working_directory);
|
||||
|
||||
if result.exit_code {
|
||||
Compiler.compiler_report(Basic.tprint("Librarian failed with exit code '%'.\n", result.exit_code), loc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if #complete type == {
|
||||
case .STATIC_LIBRARY;
|
||||
#if OS == .WINDOWS {
|
||||
output_filename = Basic.tprint("%.lib", output_basename);
|
||||
} else {
|
||||
output_filename = Basic.tprint("%.a", output_basename);
|
||||
}
|
||||
|
||||
case .OBJ_FILE;
|
||||
output_filename = Basic.tprint("%.o", output_basename);
|
||||
case .DYNAMIC_LIBRARY;
|
||||
if target == {
|
||||
case .WINDOWS; output_filename = Basic.tprint("%.dll", output_basename);
|
||||
case .MACOS; output_filename = Basic.tprint("%.dylib", output_basename);
|
||||
case .LINUX; #through;
|
||||
case .ANDROID; output_filename = Basic.tprint("%.so", output_basename);
|
||||
case .NONE; #if OS == .WINDOWS then output_filename = Basic.tprint("%.dll", output_basename); else assert(false);
|
||||
case; assert(false);
|
||||
}
|
||||
case .EXECUTABLE;
|
||||
output_filename = Basic.copy_temporary_string(output_basename);
|
||||
}
|
||||
|
||||
#if OS == .WINDOWS {
|
||||
String.path_overwrite_separators(output_filename, #char "\\");
|
||||
}
|
||||
|
||||
compiler := compiler_executable_path;
|
||||
ar := ar_executable_path;
|
||||
if !compiler || (type == .STATIC_LIBRARY && !ar) {
|
||||
is_cpp_project := false;
|
||||
for files {
|
||||
if String.ends_with(it, ".cpp") {
|
||||
is_cpp_project = true; // Use c++ compiler, so we link the required c++ runtime libraries by default.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if !compiler {
|
||||
if is_cpp_project {
|
||||
// @Cleanup: Could be simplified to the following, but that currently triggers a compiler bug. -rluba, 2024-01-23
|
||||
// compiler = ifx to_string(getenv("CXX")) else "clang++";
|
||||
compiler = to_string(getenv("CXX"));
|
||||
if !compiler compiler ="clang++";
|
||||
} else {
|
||||
compiler = to_string(getenv("CC"));
|
||||
if !compiler compiler ="clang";
|
||||
}
|
||||
}
|
||||
|
||||
if !ar ar = "ar";
|
||||
|
||||
}
|
||||
|
||||
Basic.array_add(*arguments, compiler);
|
||||
|
||||
if debug {
|
||||
Basic.array_add(*arguments, "-g", "-Og");
|
||||
} else {
|
||||
Basic.array_add(*arguments, "-O3");
|
||||
}
|
||||
|
||||
Basic.array_add(*arguments, ..extra);
|
||||
|
||||
if type == .STATIC_LIBRARY || type == .OBJ_FILE {
|
||||
array_add(*arguments, "-c");
|
||||
} else {
|
||||
if type == .DYNAMIC_LIBRARY {
|
||||
array_add(*arguments, "-shared", "-fpic");
|
||||
}
|
||||
|
||||
if target == .MACOS {
|
||||
if type == {
|
||||
case .DYNAMIC_LIBRARY;
|
||||
array_add(*arguments, "-install_name", tprint("@rpath/%", output_filename));
|
||||
case .EXECUTABLE;
|
||||
array_add(*arguments, "-rpath", "@loader_path");
|
||||
}
|
||||
}
|
||||
|
||||
array_add(*arguments, "-o", output_filename);
|
||||
}
|
||||
|
||||
// Add files:
|
||||
objs: [..] string;
|
||||
array_reserve(*objs, files.count);
|
||||
for files {
|
||||
src := copy_temporary_string(it);
|
||||
String.path_overwrite_separators(src);
|
||||
array_add(*arguments, src);
|
||||
|
||||
array_add(*objs, tprint("%.o", String.path_basename(it)));
|
||||
}
|
||||
|
||||
// Make sure to cleanup the resulting obj files.
|
||||
defer {
|
||||
if type != .OBJ_FILE {
|
||||
for objs File.file_delete(it);
|
||||
}
|
||||
}
|
||||
|
||||
array_add(*arguments, .. library_files);
|
||||
|
||||
log("%", Process.get_quoted_command_string(arguments));
|
||||
result, output_string, error_string := Process.run_command(..arguments, capture_and_return_output = true, print_captured_output = true, working_directory = working_directory);
|
||||
|
||||
if result.exit_code {
|
||||
Compiler.compiler_report(tprint("Compiler failed with exit code '%'.\n", result.exit_code), loc);
|
||||
return false;
|
||||
}
|
||||
|
||||
if type == .STATIC_LIBRARY {
|
||||
File.file_delete(output_filename); // ar only adds/updates the archive, but does not delete files from it.
|
||||
|
||||
// Create library:
|
||||
array_reset_keeping_memory(*arguments);
|
||||
array_add(*arguments,
|
||||
ar,
|
||||
"-rc", // replace or insert files into the archive, do not warn if archive needs to be created.
|
||||
output_filename,
|
||||
);
|
||||
|
||||
array_add(*arguments, ..objs);
|
||||
|
||||
// Run archiver command:
|
||||
log("%", Process.get_quoted_command_string(arguments));
|
||||
result, output_string, error_string := Process.run_command(..arguments, capture_and_return_output = true, print_captured_output = true, working_directory = working_directory);
|
||||
|
||||
if result.exit_code {
|
||||
Compiler.compiler_report(tprint("Archive command failed with exit code '%'.\n", result.exit_code), loc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
enum_cpp_files :: (path: string, recursive:=false) -> [..] string {
|
||||
files: [..] string;
|
||||
|
||||
visitor :: (info: *FileUtils.File_Visit_Info, files: *[..] string) {
|
||||
extension := String.path_extension(info.full_name);
|
||||
if extension == "cpp" || extension == "c" {
|
||||
Basic.array_add(files, String.copy_string(info.full_name));
|
||||
}
|
||||
}
|
||||
|
||||
FileUtils.visit_files(path, recursive=recursive, *files, visitor);
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
free_cpp_files :: (files: [] string) {
|
||||
for files Basic.free(it);
|
||||
Basic.array_free(files);
|
||||
}
|
||||
|
||||
|
||||
generate_bindings :: (args: [] string, minimum_os_version: type_of(Compiler.Build_Options.minimum_os_version)) -> bool {
|
||||
compile := Basic.array_find(args, "-compile");
|
||||
compile_debug := Basic.array_find(args, "-debug");
|
||||
|
||||
if compile {
|
||||
could_copy := FileUtils.copy_file("../../clay.h", "source/clay.h");
|
||||
if !could_copy then return false;
|
||||
|
||||
source_file := Basic.tprint("%/clay.c", SOURCE_PATH);
|
||||
|
||||
success := true;
|
||||
#if OS == .WINDOWS {
|
||||
File.make_directory_if_it_does_not_exist("clay-jai/windows", true);
|
||||
|
||||
// Can't use this because clay doesn't support MSVC
|
||||
success &&= build_cpp_static_lib(
|
||||
"clay-jai/windows/clay",
|
||||
source_file,
|
||||
debug = compile_debug,
|
||||
target=.NONE,
|
||||
compiler_executable_path="clang",
|
||||
ar_executable_path="llvm-ar",
|
||||
);
|
||||
|
||||
// {
|
||||
// command := Process.break_command_into_strings("clang -c -o clay-jai/windows/clay.lib -static source/clay.c");
|
||||
// result, out, error := Process.run_command(..command, capture_and_return_output = true);
|
||||
|
||||
// write_string(out);
|
||||
// if result.exit_code != 0
|
||||
// {
|
||||
// write_string("Failed to build clay. Do you have clang installed ?\n");
|
||||
// write_string(error);
|
||||
// success = false;
|
||||
// }
|
||||
// }
|
||||
|
||||
// {
|
||||
// command := Process.break_command_into_strings("clang -c -o clay-jai/windows/clay.dll -dynamic source/clay.c");
|
||||
// result, out, error := Process.run_command(..command, capture_and_return_output = true);
|
||||
|
||||
// write_string(out);
|
||||
// if result.exit_code != 0
|
||||
// {
|
||||
// write_string("Failed to build clay. Do you have clang installed ?\n");
|
||||
// write_string(error);
|
||||
// success = false;
|
||||
// }
|
||||
// }
|
||||
} else {
|
||||
// TODO MacOS
|
||||
// TODO Linux
|
||||
assert(false);
|
||||
}
|
||||
|
||||
if !success then return false;
|
||||
}
|
||||
|
||||
output_filename: string;
|
||||
options: Generator.Generate_Bindings_Options;
|
||||
{
|
||||
using options;
|
||||
|
||||
#if OS == .WINDOWS {
|
||||
Basic.array_add(*libpaths, "clay-jai/windows");
|
||||
output_filename = "windows.jai";
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
Basic.array_add(*libnames, "clay");
|
||||
Basic.array_add(*include_paths, SOURCE_PATH);
|
||||
Basic.array_add(*source_files, Basic.tprint("%/clay.h", SOURCE_PATH));
|
||||
Basic.array_add(*strip_prefixes, "Clay_");
|
||||
|
||||
auto_detect_enum_prefixes = true;
|
||||
log_stripped_declarations = true;
|
||||
generate_compile_time_struct_checks = false;
|
||||
}
|
||||
|
||||
could_generate := Generator.generate_bindings(options, output_filename);
|
||||
|
||||
File.file_delete("source/clay.h");
|
||||
|
||||
return could_generate;
|
||||
}
|
||||
|
||||
#scope_file
|
||||
|
||||
using Basic :: #import "Basic";
|
||||
Generator :: #import "Bindings_Generator";
|
||||
Compiler :: #import "Compiler";
|
||||
File :: #import "File";
|
||||
FileUtils :: #import "File_Utilities";
|
||||
BuildCpp :: #import "BuildCpp";
|
||||
Process :: #import "Process";
|
||||
String :: #import "String";
|
||||
WindowsResources :: #import "Windows_Resources";
|
||||
|
||||
#if OS == .WINDOWS {
|
||||
Windows :: #import "Windows";
|
||||
getenv :: Windows.getenv;
|
||||
} else {
|
||||
Posix :: #import "POSIX";
|
||||
getenv :: Posix.getenv;
|
||||
}
|
5
bindings/jai/module.jai
Normal file
5
bindings/jai/module.jai
Normal file
@ -0,0 +1,5 @@
|
||||
#if OS == .WINDOWS {
|
||||
#load "windows.jai";
|
||||
} else {
|
||||
assert(false)
|
||||
}
|
2
bindings/jai/source/clay.c
Normal file
2
bindings/jai/source/clay.c
Normal file
@ -0,0 +1,2 @@
|
||||
#define CLAY_IMPLEMENTATION
|
||||
#include "clay.h"
|
392
bindings/jai/windows.jai
Normal file
392
bindings/jai/windows.jai
Normal file
@ -0,0 +1,392 @@
|
||||
//
|
||||
// This file was auto-generated using the following command:
|
||||
//
|
||||
// jai ./generate.jai - -compile
|
||||
//
|
||||
|
||||
|
||||
|
||||
// Utility Structs -------------------------
|
||||
// Note: Clay_String is not guaranteed to be null terminated. It may be if created from a literal C string,
|
||||
// but it is also used to represent slices.
|
||||
String :: struct {
|
||||
length: s32;
|
||||
chars: *u8;
|
||||
}
|
||||
|
||||
StringArray :: struct {
|
||||
capacity: u32;
|
||||
length: u32;
|
||||
internalArray: *String;
|
||||
}
|
||||
|
||||
Arena :: struct {
|
||||
label: String;
|
||||
nextAllocation: u64;
|
||||
capacity: u64;
|
||||
memory: *u8;
|
||||
}
|
||||
|
||||
Dimensions :: struct {
|
||||
width: float;
|
||||
height: float;
|
||||
}
|
||||
|
||||
Vector2 :: struct {
|
||||
x: float;
|
||||
y: float;
|
||||
}
|
||||
|
||||
Color :: struct {
|
||||
r: float;
|
||||
g: float;
|
||||
b: float;
|
||||
a: float;
|
||||
}
|
||||
|
||||
BoundingBox :: struct {
|
||||
x: float;
|
||||
y: float;
|
||||
width: float;
|
||||
height: float;
|
||||
}
|
||||
|
||||
// baseId + offset = id
|
||||
ElementId :: struct {
|
||||
id: u32;
|
||||
offset: u32;
|
||||
baseId: u32;
|
||||
stringId: String;
|
||||
}
|
||||
|
||||
CornerRadius :: struct {
|
||||
topLeft: float;
|
||||
topRight: float;
|
||||
bottomLeft: float;
|
||||
bottomRight: float;
|
||||
}
|
||||
|
||||
ElementConfigType :: enum s32 {
|
||||
RECTANGLE :: 1;
|
||||
BORDER_CONTAINER :: 2;
|
||||
FLOATING_CONTAINER :: 4;
|
||||
SCROLL_CONTAINER :: 8;
|
||||
IMAGE :: 16;
|
||||
TEXT :: 32;
|
||||
CUSTOM :: 64;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Element Configs ---------------------------
|
||||
// Layout
|
||||
LayoutDirection :: enum s32 {
|
||||
LEFT_TO_RIGHT :: 0;
|
||||
TOP_TO_BOTTOM :: 1;
|
||||
|
||||
CLAY_LEFT_TO_RIGHT :: LEFT_TO_RIGHT;
|
||||
CLAY_TOP_TO_BOTTOM :: TOP_TO_BOTTOM;
|
||||
}
|
||||
|
||||
LayoutAlignmentX :: enum s32 {
|
||||
LEFT :: 0;
|
||||
RIGHT :: 1;
|
||||
CENTER :: 2;
|
||||
|
||||
CLAY_ALIGN_X_LEFT :: LEFT;
|
||||
CLAY_ALIGN_X_RIGHT :: RIGHT;
|
||||
CLAY_ALIGN_X_CENTER :: CENTER;
|
||||
}
|
||||
|
||||
LayoutAlignmentY :: enum s32 {
|
||||
TOP :: 0;
|
||||
BOTTOM :: 1;
|
||||
CENTER :: 2;
|
||||
|
||||
CLAY_ALIGN_Y_TOP :: TOP;
|
||||
CLAY_ALIGN_Y_BOTTOM :: BOTTOM;
|
||||
CLAY_ALIGN_Y_CENTER :: CENTER;
|
||||
}
|
||||
|
||||
SizingType :: enum s32 {
|
||||
FIT :: 0;
|
||||
GROW :: 1;
|
||||
PERCENT :: 2;
|
||||
FIXED :: 3;
|
||||
|
||||
CLAY__SIZING_TYPE_FIT :: FIT;
|
||||
CLAY__SIZING_TYPE_GROW :: GROW;
|
||||
CLAY__SIZING_TYPE_PERCENT :: PERCENT;
|
||||
CLAY__SIZING_TYPE_FIXED :: FIXED;
|
||||
}
|
||||
|
||||
ChildAlignment :: struct {
|
||||
x: LayoutAlignmentX;
|
||||
y: LayoutAlignmentY;
|
||||
}
|
||||
|
||||
SizingMinMax :: struct {
|
||||
min: float;
|
||||
max: float;
|
||||
}
|
||||
|
||||
SizingAxis :: struct {
|
||||
union {
|
||||
sizeMinMax: SizingMinMax;
|
||||
sizePercent: float;
|
||||
}
|
||||
|
||||
type: SizingType;
|
||||
}
|
||||
|
||||
Sizing :: struct {
|
||||
width: SizingAxis;
|
||||
height: SizingAxis;
|
||||
}
|
||||
|
||||
Padding :: struct {
|
||||
x: u16;
|
||||
y: u16;
|
||||
}
|
||||
|
||||
LayoutConfig :: struct {
|
||||
sizing: Sizing;
|
||||
padding: Padding;
|
||||
childGap: u16;
|
||||
childAlignment: ChildAlignment;
|
||||
layoutDirection: LayoutDirection;
|
||||
}
|
||||
|
||||
CLAY_LAYOUT_DEFAULT: LayoutConfig #elsewhere clay;
|
||||
|
||||
// Rectangle
|
||||
RectangleElementConfig :: struct {
|
||||
color: Color;
|
||||
cornerRadius: CornerRadius;
|
||||
}
|
||||
|
||||
// Text
|
||||
TextElementConfigWrapMode :: enum s32 {
|
||||
WORDS :: 0;
|
||||
NEWLINES :: 1;
|
||||
NONE :: 2;
|
||||
|
||||
CLAY_TEXT_WRAP_WORDS :: WORDS;
|
||||
CLAY_TEXT_WRAP_NEWLINES :: NEWLINES;
|
||||
CLAY_TEXT_WRAP_NONE :: NONE;
|
||||
}
|
||||
|
||||
TextElementConfig :: struct {
|
||||
textColor: Color;
|
||||
fontId: u16;
|
||||
fontSize: u16;
|
||||
letterSpacing: u16;
|
||||
lineHeight: u16;
|
||||
wrapMode: TextElementConfigWrapMode;
|
||||
}
|
||||
|
||||
// Image
|
||||
ImageElementConfig :: struct {
|
||||
imageData: *void;
|
||||
sourceDimensions: Dimensions;
|
||||
}
|
||||
|
||||
// Floating
|
||||
FloatingAttachPointType :: enum s32 {
|
||||
LEFT_TOP :: 0;
|
||||
LEFT_CENTER :: 1;
|
||||
LEFT_BOTTOM :: 2;
|
||||
CENTER_TOP :: 3;
|
||||
CENTER_CENTER :: 4;
|
||||
CENTER_BOTTOM :: 5;
|
||||
RIGHT_TOP :: 6;
|
||||
RIGHT_CENTER :: 7;
|
||||
RIGHT_BOTTOM :: 8;
|
||||
|
||||
CLAY_ATTACH_POINT_LEFT_TOP :: LEFT_TOP;
|
||||
CLAY_ATTACH_POINT_LEFT_CENTER :: LEFT_CENTER;
|
||||
CLAY_ATTACH_POINT_LEFT_BOTTOM :: LEFT_BOTTOM;
|
||||
CLAY_ATTACH_POINT_CENTER_TOP :: CENTER_TOP;
|
||||
CLAY_ATTACH_POINT_CENTER_CENTER :: CENTER_CENTER;
|
||||
CLAY_ATTACH_POINT_CENTER_BOTTOM :: CENTER_BOTTOM;
|
||||
CLAY_ATTACH_POINT_RIGHT_TOP :: RIGHT_TOP;
|
||||
CLAY_ATTACH_POINT_RIGHT_CENTER :: RIGHT_CENTER;
|
||||
CLAY_ATTACH_POINT_RIGHT_BOTTOM :: RIGHT_BOTTOM;
|
||||
}
|
||||
|
||||
FloatingAttachPoints :: struct {
|
||||
element: FloatingAttachPointType;
|
||||
parent: FloatingAttachPointType;
|
||||
}
|
||||
|
||||
PointerCaptureMode :: enum s32 {
|
||||
CAPTURE :: 0;
|
||||
|
||||
PASSTHROUGH :: 1;
|
||||
|
||||
CLAY_POINTER_CAPTURE_MODE_CAPTURE :: CAPTURE;
|
||||
|
||||
CLAY_POINTER_CAPTURE_MODE_PASSTHROUGH :: PASSTHROUGH;
|
||||
}
|
||||
|
||||
FloatingElementConfig :: struct {
|
||||
offset: Vector2;
|
||||
expand: Dimensions;
|
||||
zIndex: u16;
|
||||
parentId: u32;
|
||||
attachment: FloatingAttachPoints;
|
||||
pointerCaptureMode: PointerCaptureMode;
|
||||
}
|
||||
|
||||
// Custom
|
||||
CustomElementConfig :: struct {
|
||||
customData: *void;
|
||||
}
|
||||
|
||||
// Scroll
|
||||
ScrollElementConfig :: struct {
|
||||
horizontal: bool;
|
||||
vertical: bool;
|
||||
}
|
||||
|
||||
// Border
|
||||
Border :: struct {
|
||||
width: u32;
|
||||
color: Color;
|
||||
}
|
||||
|
||||
BorderElementConfig :: struct {
|
||||
left: Border;
|
||||
right: Border;
|
||||
top: Border;
|
||||
bottom: Border;
|
||||
betweenChildren: Border;
|
||||
cornerRadius: CornerRadius;
|
||||
}
|
||||
|
||||
ElementConfigUnion :: union {
|
||||
rectangleElementConfig: *RectangleElementConfig;
|
||||
textElementConfig: *TextElementConfig;
|
||||
imageElementConfig: *ImageElementConfig;
|
||||
floatingElementConfig: *FloatingElementConfig;
|
||||
customElementConfig: *CustomElementConfig;
|
||||
scrollElementConfig: *ScrollElementConfig;
|
||||
borderElementConfig: *BorderElementConfig;
|
||||
}
|
||||
|
||||
ElementConfig :: struct {
|
||||
type: ElementConfigType;
|
||||
config: ElementConfigUnion;
|
||||
}
|
||||
|
||||
// Miscellaneous Structs & Enums ---------------------------------
|
||||
ScrollContainerData :: struct {
|
||||
// Note: This is a pointer to the real internal scroll position, mutating it may cause a change in final layout.
|
||||
// Intended for use with external functionality that modifies scroll position, such as scroll bars or auto scrolling.
|
||||
scrollPosition: *Vector2;
|
||||
scrollContainerDimensions: Dimensions;
|
||||
contentDimensions: Dimensions;
|
||||
config: ScrollElementConfig;
|
||||
|
||||
// Indicates whether an actual scroll container matched the provided ID or if the default struct was returned.
|
||||
found: bool;
|
||||
}
|
||||
|
||||
RenderCommandType :: enum s32 {
|
||||
NONE :: 0;
|
||||
RECTANGLE :: 1;
|
||||
BORDER :: 2;
|
||||
TEXT :: 3;
|
||||
IMAGE :: 4;
|
||||
SCISSOR_START :: 5;
|
||||
SCISSOR_END :: 6;
|
||||
CUSTOM :: 7;
|
||||
|
||||
CLAY_RENDER_COMMAND_TYPE_NONE :: NONE;
|
||||
CLAY_RENDER_COMMAND_TYPE_RECTANGLE :: RECTANGLE;
|
||||
CLAY_RENDER_COMMAND_TYPE_BORDER :: BORDER;
|
||||
CLAY_RENDER_COMMAND_TYPE_TEXT :: TEXT;
|
||||
CLAY_RENDER_COMMAND_TYPE_IMAGE :: IMAGE;
|
||||
CLAY_RENDER_COMMAND_TYPE_SCISSOR_START :: SCISSOR_START;
|
||||
CLAY_RENDER_COMMAND_TYPE_SCISSOR_END :: SCISSOR_END;
|
||||
CLAY_RENDER_COMMAND_TYPE_CUSTOM :: CUSTOM;
|
||||
}
|
||||
|
||||
RenderCommand :: struct {
|
||||
boundingBox: BoundingBox;
|
||||
config: ElementConfigUnion;
|
||||
text: String; // TODO I wish there was a way to avoid having to have this on every render command
|
||||
id: u32;
|
||||
commandType: RenderCommandType;
|
||||
}
|
||||
|
||||
RenderCommandArray :: struct {
|
||||
capacity: u32;
|
||||
length: u32;
|
||||
internalArray: *RenderCommand;
|
||||
}
|
||||
|
||||
PointerDataInteractionState :: enum s32 {
|
||||
PRESSED_THIS_FRAME :: 0;
|
||||
PRESSED :: 1;
|
||||
RELEASED_THIS_FRAME :: 2;
|
||||
RELEASED :: 3;
|
||||
|
||||
CLAY_POINTER_DATA_PRESSED_THIS_FRAME :: PRESSED_THIS_FRAME;
|
||||
CLAY_POINTER_DATA_PRESSED :: PRESSED;
|
||||
CLAY_POINTER_DATA_RELEASED_THIS_FRAME :: RELEASED_THIS_FRAME;
|
||||
CLAY_POINTER_DATA_RELEASED :: RELEASED;
|
||||
}
|
||||
|
||||
PointerData :: struct {
|
||||
position: Vector2;
|
||||
state: PointerDataInteractionState;
|
||||
}
|
||||
|
||||
// Function Forward Declarations ---------------------------------
|
||||
// Public API functions ---
|
||||
MinMemorySize :: (__args: ..Any) -> u32 #foreign clay "Clay_MinMemorySize";
|
||||
CreateArenaWithCapacityAndMemory :: (capacity: u32, offset: *void) -> Arena #foreign clay "Clay_CreateArenaWithCapacityAndMemory";
|
||||
SetPointerState :: (position: Vector2, pointerDown: bool) -> void #foreign clay "Clay_SetPointerState";
|
||||
Initialize :: (arena: Arena, layoutDimensions: Dimensions) -> void #foreign clay "Clay_Initialize";
|
||||
UpdateScrollContainers :: (enableDragScrolling: bool, scrollDelta: Vector2, deltaTime: float) -> void #foreign clay "Clay_UpdateScrollContainers";
|
||||
SetLayoutDimensions :: (dimensions: Dimensions) -> void #foreign clay "Clay_SetLayoutDimensions";
|
||||
BeginLayout :: (__args: ..Any) -> void #foreign clay "Clay_BeginLayout";
|
||||
EndLayout :: (__args: ..Any) -> RenderCommandArray #foreign clay "Clay_EndLayout";
|
||||
GetElementId :: (idString: String) -> ElementId #foreign clay "Clay_GetElementId";
|
||||
GetElementIdWithIndex :: (idString: String, index: u32) -> ElementId #foreign clay "Clay_GetElementIdWithIndex";
|
||||
Hovered :: (__args: ..Any) -> bool #foreign clay "Clay_Hovered";
|
||||
OnHover :: (onHoverFunction: #type (elementId: ElementId, pointerData: PointerData, userData: s64) -> void #c_call, userData: s64) -> void #foreign clay "Clay_OnHover";
|
||||
GetScrollContainerData :: (id: ElementId) -> ScrollContainerData #foreign clay "Clay_GetScrollContainerData";
|
||||
SetMeasureTextFunction :: (measureTextFunction: #type (text: *String, config: *TextElementConfig) -> Dimensions #c_call) -> void #foreign clay "Clay_SetMeasureTextFunction";
|
||||
SetQueryScrollOffsetFunction :: (queryScrollOffsetFunction: #type (elementId: u32) -> Vector2 #c_call) -> void #foreign clay "Clay_SetQueryScrollOffsetFunction";
|
||||
RenderCommandArray_Get :: (array: *RenderCommandArray, index: s32) -> *RenderCommand #foreign clay "Clay_RenderCommandArray_Get";
|
||||
SetDebugModeEnabled :: (enabled: bool) -> void #foreign clay "Clay_SetDebugModeEnabled";
|
||||
SetCullingEnabled :: (enabled: bool) -> void #foreign clay "Clay_SetCullingEnabled";
|
||||
|
||||
// Internal API functions required by macros
|
||||
OpenElement :: (__args: ..Any) -> void #foreign clay "Clay__OpenElement";
|
||||
CloseElement :: (__args: ..Any) -> void #foreign clay "Clay__CloseElement";
|
||||
|
||||
ElementPostConfiguration :: (__args: ..Any) -> void #foreign clay "Clay__ElementPostConfiguration";
|
||||
AttachId :: (id: ElementId) -> void #foreign clay "Clay__AttachId";
|
||||
AttachLayoutConfig :: (config: *LayoutConfig) -> void #foreign clay "Clay__AttachLayoutConfig";
|
||||
AttachElementConfig :: (config: ElementConfigUnion, type: ElementConfigType) -> void #foreign clay "Clay__AttachElementConfig";
|
||||
|
||||
HashString :: (key: String, offset: u32, seed: u32) -> ElementId #foreign clay "Clay__HashString";
|
||||
Noop :: (__args: ..Any) -> void #foreign clay "Clay__Noop";
|
||||
OpenTextElement :: (text: String, textConfig: *TextElementConfig) -> void #foreign clay "Clay__OpenTextElement";
|
||||
|
||||
Clay__debugViewHighlightColor: Color #elsewhere clay;
|
||||
Clay__debugViewWidth: u32 #elsewhere clay;
|
||||
Clay__debugMaxElementsLatch: bool #elsewhere clay;
|
||||
|
||||
#scope_file
|
||||
|
||||
clay :: #library,no_dll "clay-jai/windows/clay";
|
Loading…
Reference in New Issue
Block a user