mirror of
				https://github.com/nicbarker/clay.git
				synced 2025-11-04 00:26:17 +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
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |