clean up (kinda) and refactor
This commit is contained in:
parent
154f3399a4
commit
f4fa4159c9
1 changed files with 149 additions and 129 deletions
278
src/main.zig
278
src/main.zig
|
@ -17,45 +17,30 @@ pub fn main() !void {
|
||||||
raylib.SetTextureFilter(global_font.texture, raylib.TEXTURE_FILTER_BILINEAR);
|
raylib.SetTextureFilter(global_font.texture, raylib.TEXTURE_FILTER_BILINEAR);
|
||||||
|
|
||||||
var background = Background.init();
|
var background = Background.init();
|
||||||
var column = Column.init(
|
var crossmenu = CrossMenu.init(allocator);
|
||||||
allocator,
|
defer crossmenu.deinit();
|
||||||
raylib.LoadTexture("icon-mask.png"),
|
|
||||||
raylib.LoadTexture("icon-normal-2.png"),
|
|
||||||
"Game",
|
|
||||||
);
|
|
||||||
defer column.deinit();
|
|
||||||
|
|
||||||
var item1 = Item.init(
|
const game_column = try crossmenu.appendColumn(.{
|
||||||
raylib.LoadTexture("menu/game/CometCrash/ICON0.PNG"),
|
.icon = raylib.LoadTexture("icon-mask.png"),
|
||||||
"Comet Crash",
|
.normal = raylib.LoadTexture("icon-normal-2.png"),
|
||||||
"3/1/2025 23:11",
|
.title = "Game",
|
||||||
);
|
});
|
||||||
var item2 = Item.init(
|
|
||||||
raylib.LoadTexture("menu/game/LBP1/ICON0.PNG"),
|
try game_column.appendItem(.{
|
||||||
"LittleBigPlanet",
|
.icon = raylib.LoadTexture("menu/game/CometCrash/ICON0.PNG"),
|
||||||
"3/1/2025 23:15",
|
.title = "Comet Crash",
|
||||||
);
|
.subtitle = "3/1/2025 23:11",
|
||||||
var item3 = Item.init(
|
});
|
||||||
raylib.LoadTexture("menu/game/LBP2/ICON0.PNG"),
|
|
||||||
"LittleBigPlanet 2",
|
try game_column.appendItem(.{
|
||||||
"3/1/2025 23:26",
|
.icon = raylib.LoadTexture("menu/game/LBP1/ICON0.PNG"),
|
||||||
);
|
.title = "LittleBigPlanet",
|
||||||
var item4 = Item.init(
|
.subtitle = "3/1/2025 23:15",
|
||||||
raylib.LoadTexture("menu/game/LBP3/ICON0.PNG"),
|
});
|
||||||
"LittleBigPlanet 3",
|
|
||||||
"3/1/2025 23:48",
|
|
||||||
);
|
|
||||||
try column.appendItem(&item1);
|
|
||||||
try column.appendItem(&item2);
|
|
||||||
try column.appendItem(&item3);
|
|
||||||
try column.appendItem(&item4);
|
|
||||||
column.refresh(false);
|
|
||||||
|
|
||||||
icon_shader = raylib.LoadShaderFromMemory(0, @embedFile("shaders/icon.fs"));
|
icon_shader = raylib.LoadShaderFromMemory(0, @embedFile("shaders/icon.fs"));
|
||||||
defer raylib.UnloadShader(icon_shader);
|
defer raylib.UnloadShader(icon_shader);
|
||||||
|
|
||||||
// const mask_loc = raylib.GetShaderLocation(shader, "textureMask");
|
|
||||||
// const normal_loc = raylib.GetShaderLocation(icon_shader, "textureNormal");
|
|
||||||
const light_dir_loc = raylib.GetShaderLocation(icon_shader, "lightDir");
|
const light_dir_loc = raylib.GetShaderLocation(icon_shader, "lightDir");
|
||||||
const light_color_loc = raylib.GetShaderLocation(icon_shader, "lightColor");
|
const light_color_loc = raylib.GetShaderLocation(icon_shader, "lightColor");
|
||||||
const ambient_color_loc = raylib.GetShaderLocation(icon_shader, "ambientColor");
|
const ambient_color_loc = raylib.GetShaderLocation(icon_shader, "ambientColor");
|
||||||
|
@ -68,7 +53,7 @@ pub fn main() !void {
|
||||||
|
|
||||||
raylib.SetShaderValue(icon_shader, light_dir_loc, &raylib.Vector3{ .x = 0.5, .y = 0, .z = 0 }, raylib.SHADER_UNIFORM_VEC3);
|
raylib.SetShaderValue(icon_shader, light_dir_loc, &raylib.Vector3{ .x = 0.5, .y = 0, .z = 0 }, raylib.SHADER_UNIFORM_VEC3);
|
||||||
raylib.SetShaderValue(icon_shader, light_color_loc, &raylib.Vector4{ .x = 1, .y = 1, .z = 1, .w = 1.5 }, raylib.SHADER_UNIFORM_VEC4);
|
raylib.SetShaderValue(icon_shader, light_color_loc, &raylib.Vector4{ .x = 1, .y = 1, .z = 1, .w = 1.5 }, raylib.SHADER_UNIFORM_VEC4);
|
||||||
raylib.SetShaderValue(icon_shader, ambient_color_loc, &raylib.Vector4{ .x = 0.90, .y = 0.82, .z = 0.98, .w = 0.8 }, raylib.SHADER_UNIFORM_VEC4);
|
raylib.SetShaderValue(icon_shader, ambient_color_loc, &raylib.Vector4{ .x = 0.94, .y = 0.97, .z = 0.98, .w = 0.8 }, raylib.SHADER_UNIFORM_VEC4);
|
||||||
|
|
||||||
raylib.SetTargetFPS(120);
|
raylib.SetTargetFPS(120);
|
||||||
while (!raylib.WindowShouldClose()) {
|
while (!raylib.WindowShouldClose()) {
|
||||||
|
@ -76,31 +61,29 @@ pub fn main() !void {
|
||||||
screen_width = @floatFromInt(raylib.GetScreenWidth());
|
screen_width = @floatFromInt(raylib.GetScreenWidth());
|
||||||
screen_height = @floatFromInt(raylib.GetScreenHeight());
|
screen_height = @floatFromInt(raylib.GetScreenHeight());
|
||||||
scales.recalculate();
|
scales.recalculate();
|
||||||
column.refresh(false);
|
crossmenu.refresh(false);
|
||||||
}
|
}
|
||||||
if (raylib.IsKeyPressed('D')) debug_draw = !debug_draw;
|
if (raylib.IsKeyPressed('D')) debug_draw = !debug_draw;
|
||||||
if (raylib.IsKeyPressed('S')) raylib.TakeScreenshot("screenshot.png");
|
if (raylib.IsKeyPressed('S')) raylib.TakeScreenshot("screenshot.png");
|
||||||
|
|
||||||
datetime.update();
|
datetime.update();
|
||||||
background.update();
|
background.update();
|
||||||
column.update();
|
crossmenu.update();
|
||||||
|
|
||||||
raylib.BeginDrawing();
|
raylib.BeginDrawing();
|
||||||
defer raylib.EndDrawing();
|
defer raylib.EndDrawing();
|
||||||
|
|
||||||
background.draw();
|
background.draw();
|
||||||
column.draw();
|
crossmenu.draw();
|
||||||
|
|
||||||
if (debug_draw) {
|
if (debug_draw) {
|
||||||
drawDebugGrid();
|
drawDebugGrid();
|
||||||
|
|
||||||
const debug_text = try std.fmt.allocPrint(allocator,
|
const debug_text = try std.fmt.allocPrint(allocator,
|
||||||
\\screen size = {d}x{d}
|
\\screen size = {d}x{d}
|
||||||
\\selected = {d}
|
|
||||||
, .{
|
, .{
|
||||||
screen_width,
|
screen_width,
|
||||||
screen_height,
|
screen_height,
|
||||||
column.selected,
|
|
||||||
});
|
});
|
||||||
defer allocator.free(debug_text);
|
defer allocator.free(debug_text);
|
||||||
raylib.DrawText(@ptrCast(debug_text), 2, 2, 8, raylib.GREEN);
|
raylib.DrawText(@ptrCast(debug_text), 2, 2, 8, raylib.GREEN);
|
||||||
|
@ -245,24 +228,68 @@ fn drawDebugGrid() void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const CrossMenu = struct {
|
||||||
|
allocator: Allocator,
|
||||||
|
columns: std.ArrayListUnmanaged(Column) = .empty,
|
||||||
|
selected: usize = 0,
|
||||||
|
|
||||||
|
pub fn init(allocator: Allocator) CrossMenu {
|
||||||
|
return .{ .allocator = allocator };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *CrossMenu) void {
|
||||||
|
for (self.columns.items) |*column| column.deinit();
|
||||||
|
self.columns.deinit(self.allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn refresh(self: *CrossMenu, comptime animate: bool) void {
|
||||||
|
for (self.columns.items) |*column| column.refresh(animate);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(self: *CrossMenu) void {
|
||||||
|
for (self.columns.items) |*column| column.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw(self: *CrossMenu) void {
|
||||||
|
for (self.columns.items) |*column| column.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn appendColumn(self: *CrossMenu, options: Column.Options) !*Column {
|
||||||
|
const column = try self.columns.addOne(self.allocator);
|
||||||
|
column.* = Column.init(self.allocator, options);
|
||||||
|
return column;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// TODO item actions
|
// TODO item actions
|
||||||
// TODO item groups
|
// TODO item groups
|
||||||
// TODO item group sort
|
// TODO item group sort
|
||||||
pub const Column = struct {
|
pub const Column = struct {
|
||||||
icon: raylib.Texture2D,
|
items: std.ArrayList(Item),
|
||||||
normal: ?raylib.Texture2D = null,
|
|
||||||
title: []const u8,
|
|
||||||
|
|
||||||
items: std.ArrayList(*Item),
|
|
||||||
selected: usize = 0,
|
selected: usize = 0,
|
||||||
|
|
||||||
pub fn init(allocator: Allocator, icon: raylib.Texture2D, normal: ?raylib.Texture2D, title: []const u8) Column {
|
icon: Image,
|
||||||
raylib.SetTextureFilter(icon, raylib.TEXTURE_FILTER_BILINEAR);
|
title: Text,
|
||||||
|
|
||||||
|
pub const Options = struct {
|
||||||
|
icon: raylib.Texture2D,
|
||||||
|
normal: ?raylib.Texture2D = null,
|
||||||
|
title: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn init(allocator: Allocator, options: Options) Column {
|
||||||
|
raylib.SetTextureFilter(options.icon, raylib.TEXTURE_FILTER_BILINEAR);
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.icon = icon,
|
|
||||||
.normal = normal,
|
|
||||||
.title = title,
|
|
||||||
.items = .init(allocator),
|
.items = .init(allocator),
|
||||||
|
.icon = .{
|
||||||
|
.texture = options.icon,
|
||||||
|
.normal = options.normal,
|
||||||
|
},
|
||||||
|
.title = .{
|
||||||
|
.string = options.title,
|
||||||
|
.align_h = .center,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,43 +298,36 @@ pub const Column = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(self: *Column) void {
|
pub fn draw(self: *Column) void {
|
||||||
var icon = Image{
|
self.icon.box = .{
|
||||||
.texture = self.icon,
|
.x = scales.column_position_center.x,
|
||||||
.normal = self.normal,
|
.y = scales.column_position_center.y,
|
||||||
.box = .{
|
.w = scales.icon_width,
|
||||||
.x = scales.column_position_center.x,
|
.h = scales.icon_height,
|
||||||
.y = scales.column_position_center.y,
|
|
||||||
.w = scales.icon_width,
|
|
||||||
.h = scales.icon_height,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var title = Text{
|
self.title.font_size = scales.column_title_font_size;
|
||||||
.string = self.title,
|
self.title.box = .{
|
||||||
.font_size = scales.column_title_font_size,
|
.x = self.icon.box.x - 8,
|
||||||
.font_spacing = 1,
|
.y = self.icon.box.y + self.icon.box.h + 6,
|
||||||
.box = .{
|
.w = self.icon.box.w + 16,
|
||||||
.x = icon.box.x - 8,
|
.h = scales.column_title_font_size,
|
||||||
.y = icon.box.y + icon.box.h + 6,
|
|
||||||
.w = icon.box.w + 16,
|
|
||||||
.h = scales.column_title_font_size,
|
|
||||||
},
|
|
||||||
.align_h = .center,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for (self.items.items) |item| item.draw();
|
for (self.items.items) |*item| item.draw();
|
||||||
|
|
||||||
icon.draw();
|
self.icon.draw();
|
||||||
title.draw();
|
self.title.draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn appendItem(self: *Column, item: *Item) !void {
|
pub fn appendItem(self: *Column, options: Item.Options) !void {
|
||||||
try self.items.append(item);
|
const item = try self.items.addOne();
|
||||||
|
item.* = Item.init(self.items.allocator, options);
|
||||||
self.refresh(false);
|
self.refresh(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insertItem(self: *Column, idx: usize, item: *Item) !void {
|
pub fn insertItem(self: *Column, idx: usize, options: Item.Options) !void {
|
||||||
try self.items.insert(idx, item);
|
const items = try self.items.addManyAt(idx, 1);
|
||||||
|
items[0] = Item.init(self.items.allocator, options);
|
||||||
self.refresh(false);
|
self.refresh(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,13 +347,13 @@ pub const Column = struct {
|
||||||
|
|
||||||
fn refresh(self: *Column, comptime animate: bool) void {
|
fn refresh(self: *Column, comptime animate: bool) void {
|
||||||
var y = scales.column_item_before_start - (scales.icon_height + scales.column_item_spacing) * @as(f32, @floatFromInt(self.selected));
|
var y = scales.column_item_before_start - (scales.icon_height + scales.column_item_spacing) * @as(f32, @floatFromInt(self.selected));
|
||||||
for (self.items.items[0..self.selected]) |item| {
|
for (self.items.items[0..self.selected]) |*item| {
|
||||||
item.position.set(animate, .{ .x = scales.column_position_center.x, .y = y });
|
item.position.set(animate, .{ .x = scales.column_position_center.x, .y = y });
|
||||||
item.icon_scale.set(animate, 1.0);
|
item.icon_scale.set(animate, 1.0);
|
||||||
y += scales.icon_height + scales.column_item_spacing;
|
y += scales.icon_height + scales.column_item_spacing;
|
||||||
}
|
}
|
||||||
y = scales.column_item_after_start;
|
y = scales.column_item_after_start;
|
||||||
for (self.items.items[self.selected..], self.selected..) |item, i| {
|
for (self.items.items[self.selected..], self.selected..) |*item, i| {
|
||||||
const icon_scale = if (i == self.selected) scales.column_selected_item_icon_scale else 1.0;
|
const icon_scale = if (i == self.selected) scales.column_selected_item_icon_scale else 1.0;
|
||||||
item.position.set(animate, .{ .x = scales.column_position_center.x, .y = y });
|
item.position.set(animate, .{ .x = scales.column_position_center.x, .y = y });
|
||||||
item.icon_scale.set(animate, icon_scale);
|
item.icon_scale.set(animate, icon_scale);
|
||||||
|
@ -347,17 +367,30 @@ pub const Item = struct {
|
||||||
position: Tweener(raylib.Vector2, .{}) = .{},
|
position: Tweener(raylib.Vector2, .{}) = .{},
|
||||||
icon_scale: Tweener(f32, 1.0) = .{},
|
icon_scale: Tweener(f32, 1.0) = .{},
|
||||||
|
|
||||||
icon: raylib.Texture2D,
|
icon: Image,
|
||||||
title: []const u8,
|
title: Text,
|
||||||
subtitle: []const u8,
|
subtitle: Text,
|
||||||
|
|
||||||
|
pub const Options = struct {
|
||||||
|
icon: raylib.Texture2D,
|
||||||
|
title: []const u8,
|
||||||
|
subtitle: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn init(_: Allocator, options: Options) Item {
|
||||||
|
raylib.SetTextureFilter(options.icon, raylib.TEXTURE_FILTER_BILINEAR);
|
||||||
|
raylib.SetTextureWrap(options.icon, raylib.TEXTURE_WRAP_CLAMP);
|
||||||
|
|
||||||
pub fn init(texture: raylib.Texture2D, title: []const u8, subtitle: []const u8) Item {
|
|
||||||
raylib.SetTextureFilter(texture, raylib.TEXTURE_FILTER_BILINEAR);
|
|
||||||
raylib.SetTextureWrap(texture, raylib.TEXTURE_WRAP_CLAMP);
|
|
||||||
return .{
|
return .{
|
||||||
.icon = texture,
|
.icon = .{ .texture = options.icon },
|
||||||
.title = title,
|
.title = .{
|
||||||
.subtitle = subtitle,
|
.string = options.title,
|
||||||
|
.align_v = .right,
|
||||||
|
},
|
||||||
|
.subtitle = .{
|
||||||
|
.string = options.subtitle,
|
||||||
|
.align_v = .left,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,45 +398,32 @@ pub const Item = struct {
|
||||||
const position = self.position.update();
|
const position = self.position.update();
|
||||||
const icon_scale = self.icon_scale.update();
|
const icon_scale = self.icon_scale.update();
|
||||||
|
|
||||||
var icon = Image{
|
self.icon.box = .{
|
||||||
.texture = self.icon,
|
.x = position.x - scales.icon_width / 2.0 * (icon_scale - 1),
|
||||||
.box = .{
|
.y = position.y,
|
||||||
.x = position.x - scales.icon_width / 2.0 * (icon_scale - 1),
|
.w = scales.icon_width * icon_scale,
|
||||||
.y = position.y,
|
.h = scales.icon_height * icon_scale,
|
||||||
.w = scales.icon_width * icon_scale,
|
|
||||||
.h = scales.icon_height * icon_scale,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var title = Text{
|
self.title.font_size = scales.item_title_font_size;
|
||||||
.string = self.title,
|
self.title.box = .{
|
||||||
.box = .{
|
.x = self.icon.box.x + 8 + self.icon.box.w,
|
||||||
.x = icon.box.x + 8 + icon.box.w,
|
.y = self.icon.box.y,
|
||||||
.y = icon.box.y,
|
.w = 300,
|
||||||
.w = 300,
|
.h = self.icon.box.h / 2.0 - 2,
|
||||||
.h = icon.box.h / 2.0 - 2,
|
|
||||||
},
|
|
||||||
.font_size = scales.item_title_font_size,
|
|
||||||
.font_spacing = 1,
|
|
||||||
.align_v = .right,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var subtitle = Text{
|
self.subtitle.font_size = scales.item_subtitle_font_size;
|
||||||
.string = self.subtitle,
|
self.subtitle.box = .{
|
||||||
.box = .{
|
.x = self.icon.box.x + 8 + self.icon.box.w,
|
||||||
.x = icon.box.x + 8 + icon.box.w,
|
.y = self.icon.box.y + self.icon.box.h / 2.0 + 1,
|
||||||
.y = icon.box.y + icon.box.h / 2.0 + 1,
|
.w = 200,
|
||||||
.w = 200,
|
.h = self.icon.box.h / 2.0 - 2,
|
||||||
.h = icon.box.h / 2.0 - 2,
|
|
||||||
},
|
|
||||||
.font_size = scales.item_subtitle_font_size,
|
|
||||||
.font_spacing = 1,
|
|
||||||
.align_v = .left,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
icon.draw();
|
self.icon.draw();
|
||||||
title.draw();
|
self.title.draw();
|
||||||
subtitle.draw();
|
self.subtitle.draw();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -603,15 +623,15 @@ pub const BoundingBox = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A texture within a bounding box. Positions and scales based on configurable parameters.
|
/// A texture within a bounding box. Positions and scales based on configurable parameters.
|
||||||
/// Will not crop texture if using `Mode.original`.
|
/// Despite the BoundingBox name, will never crop the texture, even when using `Mode.original`.
|
||||||
pub const Image = struct {
|
pub const Image = struct {
|
||||||
box: BoundingBox,
|
box: BoundingBox = undefined,
|
||||||
texture: raylib.Texture2D,
|
texture: raylib.Texture2D,
|
||||||
normal: ?raylib.Texture2D = null,
|
normal: ?raylib.Texture2D = null,
|
||||||
|
|
||||||
mode: Mode = .fit,
|
mode: Mode = .fit,
|
||||||
align_w: Align = .center,
|
|
||||||
align_h: Align = .center,
|
align_h: Align = .center,
|
||||||
|
align_v: Align = .center,
|
||||||
|
|
||||||
pub fn draw(self: *Image) void {
|
pub fn draw(self: *Image) void {
|
||||||
const width: f32 = @floatFromInt(self.texture.width);
|
const width: f32 = @floatFromInt(self.texture.width);
|
||||||
|
@ -624,12 +644,12 @@ pub const Image = struct {
|
||||||
.fill => @max(width_scale, height_scale),
|
.fill => @max(width_scale, height_scale),
|
||||||
};
|
};
|
||||||
const position = raylib.Vector2{
|
const position = raylib.Vector2{
|
||||||
.x = switch (self.align_w) {
|
.x = switch (self.align_h) {
|
||||||
.left => 0,
|
.left => 0,
|
||||||
.center => self.box.x + self.box.w / 2.0 - (width * scale) / 2.0,
|
.center => self.box.x + self.box.w / 2.0 - (width * scale) / 2.0,
|
||||||
.right => self.box.x + self.box.w - width * scale,
|
.right => self.box.x + self.box.w - width * scale,
|
||||||
},
|
},
|
||||||
.y = switch (self.align_h) {
|
.y = switch (self.align_v) {
|
||||||
.left => 0,
|
.left => 0,
|
||||||
.center => self.box.y + self.box.h / 2.0 - (height * scale) / 2.0,
|
.center => self.box.y + self.box.h / 2.0 - (height * scale) / 2.0,
|
||||||
.right => self.box.y + self.box.h - height * scale,
|
.right => self.box.y + self.box.h - height * scale,
|
||||||
|
@ -661,10 +681,10 @@ pub const Image = struct {
|
||||||
// TODO ellipsize text
|
// TODO ellipsize text
|
||||||
// TODO clip text and scroll
|
// TODO clip text and scroll
|
||||||
pub const Text = struct {
|
pub const Text = struct {
|
||||||
box: BoundingBox,
|
box: BoundingBox = undefined,
|
||||||
string: []const u8,
|
string: []const u8,
|
||||||
font_size: f32,
|
font_size: f32 = undefined,
|
||||||
font_spacing: f32,
|
font_spacing: f32 = 1,
|
||||||
|
|
||||||
align_h: Align = .left,
|
align_h: Align = .left,
|
||||||
align_v: Align = .left,
|
align_v: Align = .left,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue