usg/src/MainMenu/Renderer.zig

129 lines
4.5 KiB
Zig

const std = @import("std");
const SDL = @import("sdl2");
const MainMenu = @import("../MainMenu.zig");
const MenuTab = @import("MenuTab.zig");
const range = @import("../utils.zig").range;
pub const Renderer = @import("../Renderer.zig");
const color = @import("../color.zig");
const Self = @This();
renderer: *Renderer,
const skew = 13;
const y_spacing = 20;
const x_spacing = 300;
const width = 300;
const height = 60;
pub fn init(renderer: *Renderer) Self {
return Self{
.renderer = renderer,
};
}
pub fn render(self: Self, main_menu: MainMenu) void {
const tabs = [_]usize{
main_menu.getPrevTab(),
main_menu.tab,
main_menu.getNextTab(),
};
const wsize = self.renderer.getOutputSize();
const screen_width = @intCast(i32, wsize.width);
const screen_height = @intCast(i32, wsize.height);
for (tabs) |u_tab, u_tab_i| {
//const tab = @intCast(i32, u_tab);
const tab_i = @intCast(i32, u_tab_i);
const curr_tab = main_menu.tab_list[u_tab];
// Auxiliary variables to claculate the center of the screen
const total_spacing: i32 = (tabs.len - 1) * x_spacing;
const total_width: i32 = tabs.len * width;
// Current selection vertical offset
const sel_y_offset = y_spacing * 12;
// Number of items below selection
const n_sel_below = @intCast(usize, @divExact((screen_height - sel_y_offset), (height + y_spacing)));
// Number of items below selection
const n_sel_above = @intCast(usize, @divExact((sel_y_offset), (height + y_spacing)));
// Move it from the left to the center
const centering = @divExact((screen_width - (total_width + total_spacing)), 2);
const x = tab_i * (width + x_spacing) + centering;
// Transparency depending on tab at the middle
var alpha: u8 = 255;
if (tab_i == 1) {
alpha = 255;
}
// Current selection
{
const y = @intCast(i32, sel_y_offset);
// TODO: The shadow should be static, it is easier like this rn tho
if (tab_i == 1) {
// Shadow
self.renderer.setColor(0, 0, 0, 30);
self.renderer.fillRectangleEx(x + 10, y + 10, width, height, skew);
}
self.renderMenu(x, y, curr_tab, curr_tab.sel, alpha, true);
}
for (range(n_sel_below)) |_, i| {
const aux_sel: i32 = @intCast(i32, i + 1);
const curr_sel: usize = main_menu.getSelIdx(aux_sel);
const y = @intCast(i32, sel_y_offset + ((y_spacing + height) * (aux_sel)));
self.renderMenu(x - ((skew + 8) * aux_sel), y, curr_tab, curr_sel, alpha, false);
}
for (range(n_sel_above)) |_, i| {
const aux_sel: i32 = -@intCast(i32, i + 1);
const curr_sel: usize = main_menu.getSelIdx(aux_sel);
const y = @intCast(i32, sel_y_offset + ((y_spacing + height) * (aux_sel)));
self.renderMenu(x - ((skew + 8) * aux_sel), y, curr_tab, curr_sel, alpha, false);
}
// Tab header
self.renderer.setColor(curr_tab.color[0], curr_tab.color[1], curr_tab.color[2], alpha);
self.renderer.fillRectangleEx(x - 25, 10, width + 50, height + 50, skew);
}
// TODO: Set the Color depending on the Main Menu color
self.renderer.setColorF(0.91, 0.85, 0.65, 0.50);
self.renderer.fillRectangleEx(-150, 0, @divTrunc(wsize.width, 3), wsize.height, skew);
self.renderer.fillRectangleEx(@intCast(i32, screen_width) - 300, 0, @divTrunc(wsize.width, 3), wsize.height, skew);
}
fn renderMenu(self: Self, x: i32, y: i32, tab: MenuTab, sel: usize, a: u8, selected: bool) void {
// White background
self.renderer.setColor(255, 255, 255, a);
self.renderer.fillRectangleEx(x, y, width, height, skew);
//_ = sel;
if (selected) {
// Set color if selected
self.renderer.setColor(tab.color[0], tab.color[1], tab.color[2], a);
} else {
// Set black color, not selected
self.renderer.setColor(0, 0, 0, a);
}
const margin = 20;
//self.renderer.setColorF(1, 1, 1, 1);
var text = Renderer.Texture.fromText(tab.contents[sel].name, height - margin * 2);
self.renderer.renderTexture(text, x + margin, y + margin);
//self.renderer.fillRectangleEx(x + margin, y + margin, width - margin * 2, height - margin * 2, skew);
self.renderer.fillRectangleEx(x + width - 6, y, 6, height, skew);
self.renderer.fillRectangleEx(x + width - 12, y, 3, height, skew);
}