mirror of
https://github.com/nicbarker/clay.git
synced 2025-04-15 10:48:04 +00:00
Finished first version of the bindings with working demo !!
This commit is contained in:
parent
b7e1d69ca6
commit
672927d387
Binary file not shown.
@ -19,18 +19,20 @@ raylib_measure_text :: (text: *Clay.String, config: *Clay.TextElementConfig) ->
|
||||
text_height := cast(float)config.fontSize;
|
||||
font_to_use := g_raylib_fonts[config.fontId].font;
|
||||
|
||||
for 0..text.length - 1 {
|
||||
if text.chars[it] == #char "\n" {
|
||||
max_text_width = c_max(max_text_width, line_text_width);
|
||||
line_text_width = 0;
|
||||
continue;
|
||||
}
|
||||
if text.length > 0 {
|
||||
for 0..(text.length - 1) {
|
||||
if text.chars[it] == #char "\n" {
|
||||
max_text_width = c_max(max_text_width, line_text_width);
|
||||
line_text_width = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
index := cast(s32) text.chars[it] - 32;
|
||||
if font_to_use.glyphs[index].advanceX != 0 {
|
||||
line_text_width += cast(float) font_to_use.glyphs[index].advanceX;
|
||||
} else {
|
||||
line_text_width += (font_to_use.recs[index].width + cast(float) font_to_use.glyphs[index].offsetX);
|
||||
index := cast(s32, text.chars[it]) - 32;
|
||||
if font_to_use.glyphs[index].advanceX != 0 {
|
||||
line_text_width += cast(float) font_to_use.glyphs[index].advanceX;
|
||||
} else {
|
||||
line_text_width += (font_to_use.recs[index].width + cast(float) font_to_use.glyphs[index].offsetX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,8 @@ using Basic :: #import "Basic";
|
||||
Clay :: #import,file "../../module.jai";
|
||||
Raylib :: #import "raylib-jai";
|
||||
|
||||
for_expansion :: Clay.for_expansion;;
|
||||
|
||||
#load "clay_renderer_raylib.jai";
|
||||
|
||||
FONT_ID_BODY_16 :: 0;
|
||||
@ -28,14 +30,60 @@ to_jai_string :: (str: Clay.String) -> string {
|
||||
return .{data = str.chars, count = cast(s64, str.length)};
|
||||
}
|
||||
|
||||
// handle_sidebar_interaction :: (
|
||||
// element_id: Clay.ElementId,
|
||||
// pointer_data: Clay.PointerData,
|
||||
// user_data: s64
|
||||
// ) #c_call {
|
||||
// // If this button was clicked
|
||||
// if pointer_data.state == .PRESSED_THIS_FRAME {
|
||||
// selected_document_index = user_data;
|
||||
// }
|
||||
// }
|
||||
|
||||
handle_clay_errors :: (error_data: Clay.ErrorData) #c_call {
|
||||
push_context {
|
||||
log_error("Clay Error : %", to_jai_string(error_data.errorText));
|
||||
log_error(
|
||||
"Clay Error [%]: % | %",
|
||||
error_data.errorType,
|
||||
to_jai_string(error_data.errorText),
|
||||
error_data.userData
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
render_header_button :: (text: string) {
|
||||
for Clay.Element(
|
||||
Clay.Layout(.{padding = .{16, 8}}),
|
||||
Clay.Rectangle(.{
|
||||
color = .{140, 140, 140, 255},
|
||||
cornerRadius = .{5, 5, 5, 5},
|
||||
})
|
||||
) {
|
||||
Clay.Text(text, Clay.TextConfig(.{
|
||||
fontId = FONT_ID_BODY_16,
|
||||
fontSize = 16,
|
||||
textColor = COLOR_WHITE,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
render_dropdown_menu_item :: (text: string) {
|
||||
for Clay.Element(
|
||||
Clay.Layout(.{padding = .{16, 16}})
|
||||
) {
|
||||
Clay.Text(text, Clay.TextConfig(.{
|
||||
fontId = FONT_ID_BODY_16,
|
||||
fontSize = 16,
|
||||
textColor = COLOR_WHITE,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
selected_document_index : int = 0;
|
||||
|
||||
main :: () {
|
||||
flags := Raylib.ConfigFlags.WINDOW_RESIZABLE | .WINDOW_HIGHDPI | .MSAA_4X_HINT | .VSYNC_HINT;
|
||||
flags := Raylib.ConfigFlags.WINDOW_RESIZABLE | .MSAA_4X_HINT | .VSYNC_HINT;
|
||||
raylib_initialize(1024, 768, "Introducing Clay Demo", flags);
|
||||
|
||||
clay_required_memory := Clay.MinMemorySize();
|
||||
@ -76,7 +124,7 @@ main :: () {
|
||||
};
|
||||
|
||||
Clay.BeginLayout();
|
||||
Clay.UI(
|
||||
for Clay.Element(
|
||||
Clay.ID("OuterContainer"),
|
||||
Clay.Rectangle(.{color = .{43, 41, 51, 255}}),
|
||||
Clay.Layout(.{
|
||||
@ -85,8 +133,8 @@ main :: () {
|
||||
padding = .{16, 16},
|
||||
childGap = 16,
|
||||
}),
|
||||
children = #code {
|
||||
Clay.UI(
|
||||
) {
|
||||
for Clay.Element(
|
||||
Clay.ID("HeaderBar"),
|
||||
Clay.Rectangle(content_background_config),
|
||||
Clay.Layout(.{
|
||||
@ -100,33 +148,148 @@ main :: () {
|
||||
y = .CENTER,
|
||||
}
|
||||
}),
|
||||
children = #code {
|
||||
Clay.UI(
|
||||
) {
|
||||
for Clay.Element(
|
||||
Clay.ID("FileButton"),
|
||||
Clay.Layout(.{padding = .{16, 8}}),
|
||||
Clay.Rectangle(.{
|
||||
color = .{140, 140, 140, 255},
|
||||
cornerRadius = .{5, 5, 5, 5},
|
||||
}),
|
||||
children = #code {
|
||||
) {
|
||||
Clay.Text("File", Clay.TextConfig(.{
|
||||
fontId = FONT_ID_BODY_16,
|
||||
fontSize = 16,
|
||||
textColor = Clay.Color.{255, 255, 255, 255},
|
||||
fontId = FONT_ID_BODY_16,
|
||||
fontSize = 16,
|
||||
textColor = COLOR_WHITE,
|
||||
}));
|
||||
|
||||
file_menu_visible := Clay.PointerOver(Clay.GetElementId("FileButton")) ||
|
||||
Clay.PointerOver(Clay.GetElementId("FileMenu"));
|
||||
|
||||
Clay.PointerOver(Clay.GetElementId("FileMenu"));
|
||||
|
||||
if file_menu_visible {
|
||||
|
||||
for Clay.Element(
|
||||
Clay.ID("FileMenu"),
|
||||
Clay.Floating(.{attachment = .{parent = .LEFT_BOTTOM}}),
|
||||
Clay.Layout(.{padding = .{0, 8}})
|
||||
) {
|
||||
for Clay.Element(
|
||||
Clay.Layout(.{
|
||||
layoutDirection=.TOP_TO_BOTTOM,
|
||||
sizing = .{width = Clay.SizingFixed(200)}
|
||||
}),
|
||||
Clay.Rectangle(.{
|
||||
color = .{40, 40, 40, 255},
|
||||
cornerRadius = .{8, 8, 8, 8}
|
||||
})
|
||||
) {
|
||||
// Render dropdown items here
|
||||
render_dropdown_menu_item("New");
|
||||
render_dropdown_menu_item("Open");
|
||||
render_dropdown_menu_item("Close");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// Render header buttons
|
||||
render_header_button("Edit");
|
||||
for Clay.Element(Clay.Layout(.{
|
||||
sizing = .{Clay.SizingGrow(), Clay.SizingGrow()}})) {}
|
||||
render_header_button("Upload");
|
||||
render_header_button("Media");
|
||||
render_header_button("Support");
|
||||
}
|
||||
);
|
||||
|
||||
for Clay.Element(
|
||||
Clay.ID("LowerContent"),
|
||||
Clay.Layout(.{sizing = layout_expand, childGap = 16}),
|
||||
) {
|
||||
for Clay.Element(
|
||||
Clay.ID("Sidebar"),
|
||||
Clay.Rectangle(content_background_config),
|
||||
Clay.Layout(.{
|
||||
layoutDirection = .TOP_TO_BOTTOM,
|
||||
padding = .{16, 16},
|
||||
childGap = 8,
|
||||
sizing = .{
|
||||
width = Clay.SizingFixed(250),
|
||||
height = Clay.SizingGrow(),
|
||||
}
|
||||
})
|
||||
) {
|
||||
for document : documents {
|
||||
sidebar_button_layout := Clay.LayoutConfig.{
|
||||
sizing = .{width = Clay.SizingGrow()},
|
||||
padding = .{16, 16},
|
||||
};
|
||||
|
||||
if it_index == selected_document_index {
|
||||
for Clay.Element(
|
||||
Clay.Layout(sidebar_button_layout),
|
||||
Clay.Rectangle(.{
|
||||
color = .{120, 120, 120, 255},
|
||||
cornerRadius = .{8, 8, 8, 8},
|
||||
})
|
||||
) {
|
||||
Clay.Text(document.title, Clay.TextConfig(.{
|
||||
fontId = FONT_ID_BODY_16,
|
||||
fontSize = 20,
|
||||
textColor = COLOR_WHITE,
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
id := tprint("Parnets %", it_index);
|
||||
is_hovered := Clay.PointerOver(Clay.GetElementId(id));
|
||||
if is_hovered && Raylib.IsMouseButtonPressed(0) {
|
||||
selected_document_index = it_index;
|
||||
}
|
||||
|
||||
for Clay.Element(
|
||||
Clay.ID(id)
|
||||
) {
|
||||
for Clay.Element(
|
||||
Clay.Layout(sidebar_button_layout),
|
||||
ifx is_hovered then Clay.Rectangle(.{
|
||||
color = .{120, 120, 120, 120},
|
||||
cornerRadius = .{8, 8, 8, 8},
|
||||
}) else .{}
|
||||
) {
|
||||
Clay.Text(document.title, Clay.TextConfig(.{
|
||||
fontId = FONT_ID_BODY_16,
|
||||
fontSize = 20,
|
||||
textColor = COLOR_WHITE
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for Clay.Element(
|
||||
Clay.ID("MainContent"),
|
||||
Clay.Rectangle(content_background_config),
|
||||
Clay.Scroll(.{vertical = true}),
|
||||
Clay.Layout(.{
|
||||
layoutDirection = .TOP_TO_BOTTOM,
|
||||
childGap = 16,
|
||||
padding = .{16, 16},
|
||||
sizing = layout_expand,
|
||||
}),
|
||||
) {
|
||||
selected_document := documents[selected_document_index];
|
||||
Clay.Text(selected_document.title, Clay.TextConfig(.{
|
||||
fontId = FONT_ID_BODY_16,
|
||||
fontSize = 24,
|
||||
textColor = COLOR_WHITE,
|
||||
}));
|
||||
Clay.Text(selected_document.contents, Clay.TextConfig(.{
|
||||
fontId = FONT_ID_BODY_16,
|
||||
fontSize = 24,
|
||||
textColor = COLOR_WHITE
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render_commands := Clay.EndLayout();
|
||||
|
||||
@ -134,6 +297,7 @@ main :: () {
|
||||
Raylib.ClearBackground(Raylib.BLACK);
|
||||
clay_raylib_render(render_commands);
|
||||
Raylib.EndDrawing();
|
||||
}
|
||||
|
||||
reset_temporary_storage();
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
#import "Basic";
|
||||
|
||||
|
||||
test :: () -> bool #must #expand {
|
||||
print("one\n");
|
||||
|
||||
`defer print("two\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
main :: () {
|
||||
print("ichi\n");
|
||||
if test() {
|
||||
print("ni\n");
|
||||
if test() {
|
||||
print("san\n");
|
||||
}
|
||||
}
|
||||
print("yon\n");
|
||||
}
|
@ -2,11 +2,15 @@ AT_COMPILE_TIME :: true;
|
||||
|
||||
SOURCE_PATH :: "source";
|
||||
|
||||
// These have custom declaration in module.jai
|
||||
DECLARATIONS_TO_OMIT :: string.[
|
||||
// These have custom declaration in module.jai
|
||||
"Clay_Vector2",
|
||||
"Clay__ElementConfigType",
|
||||
"Clay__AlignClay__ElementConfigType",
|
||||
|
||||
// These are not supported yet
|
||||
"Clay_OnHover",
|
||||
"Clay_Hovered",
|
||||
];
|
||||
|
||||
#if AT_COMPILE_TIME {
|
||||
|
@ -34,13 +34,19 @@ TypedConfig :: struct {
|
||||
}
|
||||
|
||||
make_string :: (str: string) -> String {
|
||||
return .{cast(u64, str.count), str.data};
|
||||
clay_string := String.{cast(u64, str.count), str.data};
|
||||
return clay_string;
|
||||
}
|
||||
|
||||
// The way of handling this is inspired by the odin bindings
|
||||
UI :: (configs: ..TypedConfig, $children: Code = #code {}, $call := #caller_code) {
|
||||
global_counter := 0;
|
||||
|
||||
for_expansion :: (configs_array: InternalElementConfigArray, body: Code, _: For_Flags) #expand {
|
||||
// Jai forces the definition of these
|
||||
`it_index := 0;
|
||||
`it := 0;
|
||||
|
||||
_OpenElement();
|
||||
for config : configs {
|
||||
for config : configs_array.configs {
|
||||
if config.type == {
|
||||
case .ID;
|
||||
_AttachId(config.id);
|
||||
@ -56,35 +62,14 @@ UI :: (configs: ..TypedConfig, $children: Code = #code {}, $call := #caller_code
|
||||
}
|
||||
_ElementPostConfiguration();
|
||||
|
||||
#insert,scope(call) children;
|
||||
#insert body;
|
||||
|
||||
_CloseElement();
|
||||
}
|
||||
|
||||
// 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();
|
||||
// }
|
||||
|
||||
|
||||
Element :: (configs: ..TypedConfig) -> InternalElementConfigArray #expand {
|
||||
return .{configs};
|
||||
}
|
||||
|
||||
ID :: (label: string, index: u32 = 0) -> TypedConfig {
|
||||
return .{type = .ID, id = _HashString(make_string(label), index, 0)};
|
||||
@ -101,6 +86,14 @@ Rectangle :: (config: RectangleElementConfig) -> TypedConfig {
|
||||
};
|
||||
}
|
||||
|
||||
Floating :: (config: FloatingElementConfig) -> TypedConfig {
|
||||
return .{type = .FLOATING_CONTAINER, config = _StoreFloatingElementConfig(config)};
|
||||
}
|
||||
|
||||
Scroll :: (config: ScrollElementConfig) -> TypedConfig {
|
||||
return .{type = .SCROLL_CONTAINER, config = _StoreScrollElementConfig(config)};
|
||||
}
|
||||
|
||||
Text :: (text: string, config: *TextElementConfig) {
|
||||
_OpenTextElement(make_string(text), config);
|
||||
}
|
||||
@ -121,12 +114,23 @@ GetElementId :: (str: string) -> ElementId {
|
||||
return GetElementId(make_string(str));
|
||||
}
|
||||
|
||||
// OnHover :: (onHoverFunction: #type (elementId: ElementId, pointerData: PointerData, userData: s64) -> void #c_call, userData: s64) -> TypedConfig {
|
||||
// OnHover(onHoverFunction, userData);
|
||||
// return TypedConfig.{
|
||||
// type = .NONE,
|
||||
// };
|
||||
// }
|
||||
|
||||
#scope_module
|
||||
|
||||
Math :: #import "Math";
|
||||
Compiler :: #import "Compiler";
|
||||
ProgramPrint :: #import "Program_Print";
|
||||
|
||||
InternalElementConfigArray :: struct {
|
||||
configs: [] TypedConfig;
|
||||
}
|
||||
|
||||
#if OS == .WINDOWS {
|
||||
#load "windows.jai";
|
||||
} else {
|
||||
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// This file was auto-generated using the following command:
|
||||
//
|
||||
// jai generate.jai - -compile
|
||||
// jai ./generate.jai - -compile
|
||||
//
|
||||
|
||||
|
||||
@ -551,8 +551,7 @@ BeginLayout :: () -> void #foreign clay "Clay_BeginLayout";
|
||||
EndLayout :: () -> RenderCommandArray #foreign clay "Clay_EndLayout";
|
||||
GetElementId :: (idString: String) -> ElementId #foreign clay "Clay_GetElementId";
|
||||
GetElementIdWithIndex :: (idString: String, index: u32) -> ElementId #foreign clay "Clay_GetElementIdWithIndex";
|
||||
Hovered :: () -> bool #foreign clay "Clay_Hovered";
|
||||
OnHover :: (onHoverFunction: #type (elementId: ElementId, pointerData: PointerData, userData: s64) -> void #c_call, userData: s64) -> void #foreign clay "Clay_OnHover";
|
||||
|
||||
PointerOver :: (elementId: ElementId) -> bool #foreign clay "Clay_PointerOver";
|
||||
GetScrollContainerData :: (id: ElementId) -> ScrollContainerData #foreign clay "Clay_GetScrollContainerData";
|
||||
SetMeasureTextFunction :: (measureTextFunction: #type (text: *String, config: *TextElementConfig) -> Dimensions #c_call) -> void #foreign clay "Clay_SetMeasureTextFunction";
|
||||
|
Loading…
Reference in New Issue
Block a user