const rl = @import("raylib"); const Rect = rl.Rectangle; pub const AlignX = enum { left, center, right }; pub const AlignY = enum { top, center, bottom }; // ----------------- Positioning functions ----------------- // pub fn position(rect: rl.Rectangle) rl.Vector2 { return rl.Vector2.init(rect.x, rect.y); } pub fn positionAt(rect: rl.Rectangle, normalised_position: rl.Vector2) rl.Vector2 { return rl.Vector2.init( rect.x + normalised_position.x * rect.width, rect.y + normalised_position.y * rect.height ); } pub fn size(rect: rl.Rectangle) rl.Vector2 { return rl.Vector2.init(rect.width, rect.height); } pub fn isInside(rect: rl.Rectangle, x: f32, y: f32) bool { return (rect.x <= x and x < rect.x + rect.width) and (rect.y < y and y < rect.y + rect.height); } pub fn isInsideVec2(rect: rl.Rectangle, vec2: rl.Vector2) bool { return isInside(rect, vec2.x, vec2.y); } pub fn top(rect: rl.Rectangle) f32 { return rect.y; } pub fn bottom(rect: rl.Rectangle) f32 { return rect.y + rect.height; } pub fn left(rect: rl.Rectangle) f32 { return rect.x; } pub fn right(rect: rl.Rectangle) f32 { return rect.x + rect.width; } pub fn verticalSplit(rect: rl.Rectangle, left_side_width: f32) [2]rl.Rectangle { var left_side = rect; left_side.width = left_side_width; var right_side = rect; right_side.x += left_side_width; right_side.width -= left_side_width; return .{ left_side, right_side }; } pub fn horizontalSplit(rect: rl.Rectangle, top_side_height: f32) [2]rl.Rectangle { var top_side = rect; top_side.height = top_side_height; var bottom_side = rect; bottom_side.y += top_side_height; bottom_side.height -= top_side_height; return .{ top_side, bottom_side }; } pub fn center(rect: Rect) rl.Vector2 { return rl.Vector2{ .x = rect.x + rect.width / 2, .y = rect.y + rect.height / 2, }; } pub fn bottomLeft(rect: Rect) rl.Vector2 { return rl.Vector2.init(left(rect), bottom(rect)); } pub fn bottomRight(rect: Rect) rl.Vector2 { return rl.Vector2.init(right(rect), bottom(rect)); } pub fn topLeft(rect: Rect) rl.Vector2 { return rl.Vector2.init(left(rect), top(rect)); } pub fn topRight(rect: Rect) rl.Vector2 { return rl.Vector2.init(right(rect), top(rect)); } // ----------------- Shrinking/Growing functions ----------------- // pub fn shrink(rect: Rect, amount: f32) rl.Rectangle { return Rect.init( rect.x + amount, rect.y + amount, rect.width - 2 * amount, rect.height - 2 * amount ); } pub fn grow(rect: Rect, amount: f32) rl.Rectangle { return shrink(rect, -amount); } pub fn shrinkY(rect: Rect, amount: f32) rl.Rectangle { return Rect.init( rect.x, rect.y + amount, rect.width, rect.height - 2 * amount ); } pub fn growY(rect: Rect, amount: f32) rl.Rectangle { return shrinkY(rect, -amount); } pub fn shrinkX(rect: Rect, amount: f32) rl.Rectangle { return Rect.init( rect.x + amount, rect.y, rect.width - 2 * amount, rect.height ); } pub fn growX(rect: Rect, amount: f32) rl.Rectangle { return shrinkX(rect, -amount); } pub fn shrinkTop(rect: Rect, amount: f32) rl.Rectangle { return Rect.init( rect.x, rect.y + amount, rect.width, rect.height - amount ); } pub fn growTop(rect: Rect, amount: f32) rl.Rectangle { return shrinkTop(rect, -amount); } pub fn shrinkBottom(rect: Rect, amount: f32) rl.Rectangle { return Rect.init( rect.x, rect.y, rect.width, rect.height - amount ); } pub fn growBottom(rect: Rect, amount: f32) rl.Rectangle { return shrinkBottom(rect, -amount); } pub fn shrinkLeft(rect: Rect, amount: f32) rl.Rectangle { return Rect.init( rect.x + amount, rect.y, rect.width - amount, rect.height ); } pub fn growLeft(rect: Rect, amount: f32) rl.Rectangle { return shrinkLeft(rect, -amount); } pub fn shrinkRight(rect: Rect, amount: f32) rl.Rectangle { return Rect.init( rect.x, rect.y, rect.width - amount, rect.height ); } pub fn growRight(rect: Rect, amount: f32) rl.Rectangle { return shrinkRight(rect, -amount); } // ----------------- Other functions (idk) ----------------- // pub fn initCentered(rect: Rect, width: f32, height: f32) Rect { const unused_width = rect.width - width; const unused_height = rect.height - height; return Rect.init(rect.x + unused_width / 2, rect.y + unused_height / 2, width, height); } pub fn aligned(rect: Rect, align_x: AlignX, align_y: AlignY) rl.Vector2 { const x = switch(align_x) { .left => rect.x, .center => rect.x + rect.width/2, .right => rect.x + rect.width, }; const y = switch(align_y) { .top => rect.y, .center => rect.y + rect.height/2, .bottom => rect.y + rect.height, }; return rl.Vector2.init(x, y); } pub fn intersect(rect: Rect, other: Rect) Rect { const left_pos = @max(left(rect), left(other)); const top_pos = @max(top(rect), top(other)); const right_pos = @min(right(rect), right(other)); const bottom_pos = @min(bottom(rect), bottom(other)); return Rect{ .x = left_pos, .y = top_pos, .width = right_pos - left_pos, .height = bottom_pos - top_pos }; }