mirror of
https://github.com/nicbarker/clay.git
synced 2025-01-24 02:16:03 +00:00
216 lines
9.7 KiB
Odin
216 lines
9.7 KiB
Odin
package main
|
|
|
|
import clay "../../clay-odin"
|
|
import "core:math"
|
|
import "vendor:raylib"
|
|
|
|
RaylibFont :: struct {
|
|
fontId: u16,
|
|
font: raylib.Font,
|
|
}
|
|
|
|
clayColorToRaylibColor :: proc(color: clay.Color) -> raylib.Color {
|
|
return raylib.Color{cast(u8)color.r, cast(u8)color.g, cast(u8)color.b, cast(u8)color.a}
|
|
}
|
|
|
|
raylibFonts := [10]RaylibFont{}
|
|
|
|
measureText :: proc "c" (text: ^clay.String, config: ^clay.TextElementConfig) -> clay.Dimensions {
|
|
// Measure string size for Font
|
|
textSize: clay.Dimensions = {0, 0}
|
|
|
|
maxTextWidth: f32 = 0
|
|
lineTextWidth: f32 = 0
|
|
|
|
textHeight: f32 = cast(f32)config.fontSize
|
|
fontToUse := raylibFonts[config.fontId].font
|
|
|
|
for i := 0; i < cast(int)text.length; i += 1 {
|
|
if (text.chars[i] == '\n') {
|
|
maxTextWidth = math.max(maxTextWidth, lineTextWidth)
|
|
lineTextWidth = 0
|
|
continue
|
|
}
|
|
index: i32 = cast(i32)text.chars[i] - 32
|
|
if (fontToUse.glyphs[index].advanceX != 0) {
|
|
lineTextWidth += cast(f32)fontToUse.glyphs[index].advanceX
|
|
} else {
|
|
lineTextWidth += (fontToUse.recs[index].width + cast(f32)fontToUse.glyphs[index].offsetX)
|
|
}
|
|
}
|
|
|
|
maxTextWidth = math.max(maxTextWidth, lineTextWidth)
|
|
|
|
textSize.width = maxTextWidth / 2
|
|
textSize.height = textHeight
|
|
|
|
return textSize
|
|
}
|
|
|
|
clayRaylibRender :: proc(renderCommands: ^clay.ClayArray(clay.RenderCommand)) {
|
|
for i := 0; i < cast(int)renderCommands.length; i += 1 {
|
|
renderCommand := clay.RenderCommandArray_Get(renderCommands, cast(i32)i)
|
|
boundingBox := renderCommand.boundingBox
|
|
switch (renderCommand.commandType)
|
|
{
|
|
case clay.RenderCommandType.None:
|
|
{}
|
|
case clay.RenderCommandType.Text:
|
|
{
|
|
// Raylib uses standard C strings so isn't compatible with cheap slices, we need to clone the string to append null terminator
|
|
text := renderCommand.text
|
|
cloned := make([]u8, text.length + 1, context.temp_allocator)
|
|
copy(cloned[0:text.length], text.chars[0:text.length])
|
|
cloned[text.length] = 0
|
|
fontToUse: raylib.Font = raylibFonts[renderCommand.config.textElementConfig.fontId].font
|
|
raylib.DrawTextEx(
|
|
fontToUse,
|
|
cstring(raw_data(cloned)),
|
|
raylib.Vector2{boundingBox.x, boundingBox.y},
|
|
cast(f32)renderCommand.config.textElementConfig.fontSize,
|
|
cast(f32)renderCommand.config.textElementConfig.letterSpacing,
|
|
clayColorToRaylibColor(renderCommand.config.textElementConfig.textColor),
|
|
)
|
|
}
|
|
case clay.RenderCommandType.Image:
|
|
{
|
|
// TODO image handling
|
|
imageTexture := cast(^raylib.Texture2D)renderCommand.config.imageElementConfig.imageData
|
|
raylib.DrawTextureEx(imageTexture^, raylib.Vector2{boundingBox.x, boundingBox.y}, 0, boundingBox.width / cast(f32)imageTexture.width, raylib.WHITE)
|
|
}
|
|
case clay.RenderCommandType.ScissorStart:
|
|
{
|
|
raylib.BeginScissorMode(
|
|
cast(i32)math.round(boundingBox.x),
|
|
cast(i32)math.round(boundingBox.y),
|
|
cast(i32)math.round(boundingBox.width),
|
|
cast(i32)math.round(boundingBox.height),
|
|
)
|
|
}
|
|
case clay.RenderCommandType.ScissorEnd:
|
|
{
|
|
raylib.EndScissorMode()
|
|
}
|
|
case clay.RenderCommandType.Rectangle:
|
|
{
|
|
config: ^clay.RectangleElementConfig = renderCommand.config.rectangleElementConfig
|
|
if (config.cornerRadius.topLeft > 0) {
|
|
radius: f32 = (config.cornerRadius.topLeft * 2) / (boundingBox.width > boundingBox.height ? boundingBox.height : boundingBox.width)
|
|
raylib.DrawRectangleRounded(
|
|
raylib.Rectangle{boundingBox.x, boundingBox.y, boundingBox.width, boundingBox.height},
|
|
radius,
|
|
8,
|
|
clayColorToRaylibColor(config.color),
|
|
)
|
|
} else {
|
|
raylib.DrawRectangle(
|
|
cast(i32)boundingBox.x,
|
|
cast(i32)boundingBox.y,
|
|
cast(i32)boundingBox.width,
|
|
cast(i32)boundingBox.height,
|
|
clayColorToRaylibColor(config.color),
|
|
)
|
|
}
|
|
}
|
|
case clay.RenderCommandType.Border:
|
|
{
|
|
config := renderCommand.config.borderElementConfig
|
|
// Left border
|
|
if (config.left.width > 0) {
|
|
raylib.DrawRectangle(
|
|
cast(i32)math.round(boundingBox.x),
|
|
cast(i32)math.round(boundingBox.y + config.cornerRadius.topLeft),
|
|
cast(i32)config.left.width,
|
|
cast(i32)math.round(boundingBox.height - config.cornerRadius.topLeft - config.cornerRadius.bottomLeft),
|
|
clayColorToRaylibColor(config.left.color),
|
|
)
|
|
}
|
|
// Right border
|
|
if (config.right.width > 0) {
|
|
raylib.DrawRectangle(
|
|
cast(i32)math.round(boundingBox.x + boundingBox.width - cast(f32)config.right.width),
|
|
cast(i32)math.round(boundingBox.y + config.cornerRadius.topRight),
|
|
cast(i32)config.right.width,
|
|
cast(i32)math.round(boundingBox.height - config.cornerRadius.topRight - config.cornerRadius.bottomRight),
|
|
clayColorToRaylibColor(config.right.color),
|
|
)
|
|
}
|
|
// Top border
|
|
if (config.top.width > 0) {
|
|
raylib.DrawRectangle(
|
|
cast(i32)math.round(boundingBox.x + config.cornerRadius.topLeft),
|
|
cast(i32)math.round(boundingBox.y),
|
|
cast(i32)math.round(boundingBox.width - config.cornerRadius.topLeft - config.cornerRadius.topRight),
|
|
cast(i32)config.top.width,
|
|
clayColorToRaylibColor(config.top.color),
|
|
)
|
|
}
|
|
// Bottom border
|
|
if (config.bottom.width > 0) {
|
|
raylib.DrawRectangle(
|
|
cast(i32)math.round(boundingBox.x + config.cornerRadius.bottomLeft),
|
|
cast(i32)math.round(boundingBox.y + boundingBox.height - cast(f32)config.bottom.width),
|
|
cast(i32)math.round(boundingBox.width - config.cornerRadius.bottomLeft - config.cornerRadius.bottomRight),
|
|
cast(i32)config.bottom.width,
|
|
clayColorToRaylibColor(config.bottom.color),
|
|
)
|
|
}
|
|
if (config.cornerRadius.topLeft > 0) {
|
|
raylib.DrawRing(
|
|
raylib.Vector2{math.round(boundingBox.x + config.cornerRadius.topLeft), math.round(boundingBox.y + config.cornerRadius.topLeft)},
|
|
math.round(config.cornerRadius.topLeft - cast(f32)config.top.width),
|
|
config.cornerRadius.topLeft,
|
|
180,
|
|
270,
|
|
10,
|
|
clayColorToRaylibColor(config.top.color),
|
|
)
|
|
}
|
|
if (config.cornerRadius.topRight > 0) {
|
|
raylib.DrawRing(
|
|
raylib.Vector2{math.round(boundingBox.x + boundingBox.width - config.cornerRadius.topRight), math.round(boundingBox.y + config.cornerRadius.topRight)},
|
|
math.round(config.cornerRadius.topRight - cast(f32)config.top.width),
|
|
config.cornerRadius.topRight,
|
|
270,
|
|
360,
|
|
10,
|
|
clayColorToRaylibColor(config.top.color),
|
|
)
|
|
}
|
|
if (config.cornerRadius.bottomLeft > 0) {
|
|
raylib.DrawRing(
|
|
raylib.Vector2 {
|
|
math.round(boundingBox.x + config.cornerRadius.bottomLeft),
|
|
math.round(boundingBox.y + boundingBox.height - config.cornerRadius.bottomLeft),
|
|
},
|
|
math.round(config.cornerRadius.bottomLeft - cast(f32)config.top.width),
|
|
config.cornerRadius.bottomLeft,
|
|
90,
|
|
180,
|
|
10,
|
|
clayColorToRaylibColor(config.bottom.color),
|
|
)
|
|
}
|
|
if (config.cornerRadius.bottomRight > 0) {
|
|
raylib.DrawRing(
|
|
raylib.Vector2 {
|
|
math.round(boundingBox.x + boundingBox.width - config.cornerRadius.bottomRight),
|
|
math.round(boundingBox.y + boundingBox.height - config.cornerRadius.bottomRight),
|
|
},
|
|
math.round(config.cornerRadius.bottomRight - cast(f32)config.bottom.width),
|
|
config.cornerRadius.bottomRight,
|
|
0.1,
|
|
90,
|
|
10,
|
|
clayColorToRaylibColor(config.bottom.color),
|
|
)
|
|
}
|
|
}
|
|
case clay.RenderCommandType.Custom:
|
|
{
|
|
// Implement custom element rendering here
|
|
}
|
|
}
|
|
}
|
|
}
|