-- Copyright (c) 2024 - Ognjen 'xolatile' Milan Robovic -- -- GNU General Public Licence (version 3 or later) with core, ui; package body ui is ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ sprite : array (style, codex) of core.sprite; glyphs : array (style) of core.glyphs; ------------------------------------------------------------------------------------------ procedure select_text_box (text : in string; x, y, width, height : in integer) is begin if core.cursor.x > x and core.cursor.x < x + width and core.cursor.y > y and core.cursor.y < y + height then core.write_text_box (text); end if; end select_text_box; ------------------------------------------------------------------------------------------ procedure draw (index : in codex; x, y : in integer) is begin core.zoom := 1.0; core.draw (sprite (active, index), x, y); core.zoom := 2.0; end draw; ------------------------------------------------------------------------------------------ procedure crop (index : in codex; x, y, u, v, width, height : in integer) is begin core.zoom := 1.0; core.crop (sprite (active, index), x, y, u, v, width, height); core.zoom := 2.0; end crop; ------------------------------------------------------------------------------------------ procedure draw_horizontally (index : in codex; x, y, width : in integer) is base : constant integer := sprite (active, index).width; begin for move in 0 .. width / base - 1 loop draw (index, x + move * base, y); end loop; -- crop (index, x + (width / base) * base, y, 0, 0, width mod base, sprite (active, index).height); end draw_horizontally; ------------------------------------------------------------------------------------------ procedure draw_vertically (index : in codex; x, y, height : in integer) is base : constant integer := sprite (active, index).height; begin for move in 0 .. height / base - 1 loop draw (index, x, y + move * base); end loop; -- crop (index, x, y + (height / base) * base, 0, 0, sprite (active, index).width, height mod base); end draw_vertically; ------------------------------------------------------------------------------------------ procedure draw_background (index : in codex; x, y, width, height : in integer) is base_width : integer := sprite (active, index).width; base_height : integer := sprite (active, index).height; crop_width : integer := width mod base_width; crop_height : integer := height mod base_height; begin for move_y in 0 .. height / base_height - 1 loop for move_x in 0 .. width / base_width - 1 loop draw (index, x + move_x * base_width, y + move_y * base_height); end loop; -- crop (index, x + width - crop_width, y + move_y * base_height, 0, 0, crop_width, base_height); end loop; -- for move_x in 0 .. width / base_width - 1 loop crop (index, x + move_x * base_width, y + height - crop_height, 0, 0, base_width, crop_height); end loop; -- crop (index, x + width - crop_width, y + height - crop_height, 0, 0, crop_width, crop_height); end draw_background; ------------------------------------------------------------------------------------------ procedure configure is procedure load_ui (index : in style; folder_path : in string) is begin glyphs (index) := core.import_glyphs ("./sprite/ui/" & folder_path & "/font.png", (if index = default then 16 else 24), 0); -- for this in codex loop sprite (index, this) := core.import_sprite ("./sprite/ui/" & folder_path & core.lowercase (codex'image (this)) & ".png", 1, 1); end loop; end load_ui; begin core.echo (core.comment, "Configuring UI components..."); -- load_ui (default, "default/"); load_ui (steam, "steam/"); end configure; ------------------------------------------------------------------------------------------ procedure draw_icon (data : in core.sprite; description : in string; x, y : in integer) is begin draw (icon, x, y); select_text_box (description, x, y, core.icon, core.icon); -- core.zoom := 1.0; core.draw (data, x, y); core.zoom := 2.0; -- end draw_icon; ------------------------------------------------------------------------------------------ procedure draw_overicon (description : in string; x, y : in integer) is begin draw (overicon, x, y); select_text_box (description, x, y, core.icon, core.icon); end draw_overicon; ------------------------------------------------------------------------------------------ procedure draw_text_box (x, y, width, height : in integer) is offset : constant integer := sprite (active, text_middle).width; begin draw_background (text_middle, x + offset, y + offset, width - 2 * offset, height - 2 * offset); -- draw_horizontally (text_upper, x + offset, y, width - 2 * offset); draw_horizontally (text_lower, x + offset, y + height - offset, width - 2 * offset); draw_vertically (text_left, x, y + offset, height - 2 * offset); draw_vertically (text_right, x + width - offset, y + offset, height - 2 * offset); -- draw (text_upper_left, x, y); draw (text_upper_right, x + width - offset, y); draw (text_lower_left, x, y + height - offset); draw (text_lower_right, x + width - offset, y + height - offset); -- core.write (core.read_text_box, x, y, glyphs (active)); -- select_text_box ("", x, y, width, height); end draw_text_box; ------------------------------------------------------------------------------------------ procedure draw_frame (description : in string; x, y, width, height : in integer) is offset_x : constant integer := sprite (active, frame_middle).width; offset_y : constant integer := sprite (active, frame_middle).height; begin if height < core.icon or width < core.icon then return; end if; -- draw_background (frame_middle, x + offset_x, y + offset_y, width - 2 * offset_x, height - 2 * offset_y); -- draw_horizontally (frame_upper, x + offset_x, y, width - 2 * offset_x); draw_horizontally (frame_lower, x + offset_x, y + height - offset_y, width - 2 * offset_x); draw_vertically (frame_left, x, y + offset_y, height - 2 * offset_y); draw_vertically (frame_right, x + width - offset_x, y + offset_y, height - 2 * offset_y); -- draw (frame_upper_left, x, y); draw (frame_upper_right, x + width - sprite (active, frame_upper_right).width, y); draw (frame_lower_left, x, y + height - sprite (active, frame_lower_left).height); draw (frame_lower_right, x + width - sprite (active, frame_lower_right).width, y + height - sprite (active, frame_lower_right).height); -- select_text_box (description, x, y, width, height); end draw_frame; ------------------------------------------------------------------------------------------ procedure draw_title_bar (x, y, width : in integer; title : in string) is middle_width : constant integer := width - sprite (active, title_bar_left).width - sprite (active, title_bar_right).width; begin draw (title_bar_left, x, y - sprite (active, title_bar_left).height); draw (title_bar_right, x + middle_width + sprite (active, title_bar_left).width, y - sprite (active, title_bar_right).height); -- draw_horizontally (title_bar_middle, x + sprite (active, title_bar_left).width, y - sprite (active, title_bar_middle).height, middle_width); -- core.write (title, x + sprite (active, title_bar_left).width / 2, y - sprite (active, title_bar_middle).height / 2 - 4, glyphs (active)); -- select_text_box ("", x, y - sprite (active, title_bar_middle).height, width, sprite (active, title_bar_middle).height); end draw_title_bar; ------------------------------------------------------------------------------------------ procedure draw_scroll_bar (x, y, height : in integer; offset : in integer) is middle_height : constant integer := height - sprite (active, scroll_bar_upper).height - sprite (active, scroll_bar_lower).height; begin draw (scroll_bar_upper, x, y); draw (scroll_bar_lower, x, y + middle_height + sprite (active, scroll_bar_upper).height); -- draw_vertically (scroll_bar_middle, x, y + sprite (active, scroll_bar_upper).height, middle_height); end draw_scroll_bar; ------------------------------------------------------------------------------------------ procedure draw_menu (x, y, width, height : in integer; background : in boolean) is offset : constant integer := sprite (active, none).width; begin if width < sprite (active, corner_upper_left).width + sprite (active, corner_upper_right).width or width < sprite (active, corner_lower_left).width + sprite (active, corner_lower_right).width or height < sprite (active, corner_upper_left).height + sprite (active, corner_lower_left).height or height < sprite (active, corner_upper_right).height + sprite (active, corner_lower_right).height then return; end if; -- if background then draw_background (main_background, x + offset, y + offset, width - 2 * offset, height - 2 * offset); end if; -- declare upper : constant integer := width - sprite (active, corner_upper_left).width - sprite (active, corner_upper_right).width; lower : constant integer := width - sprite (active, corner_lower_left).width - sprite (active, corner_lower_right).width; left : constant integer := height - sprite (active, corner_upper_left).height - sprite (active, corner_lower_left).height; right : constant integer := height - sprite (active, corner_upper_right).height - sprite (active, corner_lower_right).height; begin draw_horizontally (border_upper, x + sprite (active, corner_upper_left).width, y, upper); draw_horizontally (border_lower, x + sprite (active, corner_lower_left).width, y + height - sprite (active, border_lower).height, lower); draw_vertically (border_left, x, y + sprite (active, corner_upper_left).height, left); draw_vertically (border_right, x + width - sprite (active, border_right).width, y + sprite (active, corner_upper_right).height, right); end; -- draw (corner_upper_left, x, y); draw (corner_upper_right, x + width - sprite (active, corner_upper_right).width, y); draw (corner_lower_left, x, y + height - sprite (active, corner_lower_left).height); draw (corner_lower_right, x + width - sprite (active, corner_lower_right).width, y + height - sprite (active, corner_lower_right).height); -- select_text_box ("", x, y, width, height); end draw_menu; ------------------------------------------------------------------------------------------ procedure draw_tiny_menu (x, y, width, height : in integer; background : in boolean) is offset : constant integer := sprite (active, none).width; begin if width < sprite (active, tiny_corner_upper_left).width + sprite (active, tiny_corner_upper_right).width or width < sprite (active, tiny_corner_lower_left).width + sprite (active, tiny_corner_lower_right).width or height < sprite (active, tiny_corner_upper_left).height + sprite (active, tiny_corner_lower_left).height or height < sprite (active, tiny_corner_upper_right).height + sprite (active, tiny_corner_lower_right).height then return; end if; -- if background then draw_background (main_background, x + offset, y + offset, width - 2 * offset, height - 2 * offset); end if; -- declare upper : constant integer := width - sprite (active, tiny_corner_upper_left).width - sprite (active, tiny_corner_upper_right).width; lower : constant integer := width - sprite (active, tiny_corner_lower_left).width - sprite (active, tiny_corner_lower_right).width; left : constant integer := height - sprite (active, tiny_corner_upper_left).height - sprite (active, tiny_corner_lower_left).height; right : constant integer := height - sprite (active, tiny_corner_upper_right).height - sprite (active, tiny_corner_lower_right).height; begin draw_horizontally (tiny_border_upper, x + sprite (active, tiny_corner_upper_left).width, y, upper); draw_horizontally (tiny_border_lower, x + sprite (active, tiny_corner_lower_left).width, y + height - sprite (active, tiny_border_lower).height, lower); draw_vertically (tiny_border_left, x, y + sprite (active, tiny_corner_upper_left).height, left); draw_vertically (tiny_border_right, x + width - sprite (active, tiny_border_right).width, y + sprite (active, tiny_corner_upper_right).height, right); end; -- draw (tiny_corner_upper_left, x, y); draw (tiny_corner_upper_right, x + width - sprite (active, tiny_corner_upper_right).width, y); draw (tiny_corner_lower_left, x, y + height - sprite (active, tiny_corner_lower_left).height); draw (tiny_corner_lower_right, x + width - sprite (active, tiny_corner_lower_right).width, y + height - sprite (active, tiny_corner_lower_right).height); -- select_text_box ("", x, y, width, height); end draw_tiny_menu; ------------------------------------------------------------------------------------------ procedure draw_icon_menu (description : in string; x, y, width, height : in integer) is offset_x : constant integer := sprite (active, icon_upper_left).width; offset_y : constant integer := sprite (active, icon_upper_left).height; begin if height < 2 * sprite (active, icon_upper_left).height or width < 2 * sprite (active, icon_upper_left).width then return; end if; -- draw_horizontally (icon_upper, x + offset_x, y, width - 2 * offset_x); draw_horizontally (icon_lower, x + offset_x, y + height - offset_y, width - 2 * offset_x); draw_vertically (icon_left, x, y + offset_y, height - 2 * offset_y); draw_vertically (icon_right, x + width - offset_x, y + offset_y, height - 2 * offset_y); -- draw (icon_upper_left, x, y); draw (icon_upper_right, x + width - sprite (active, icon_upper_right).width, y); draw (icon_lower_left, x, y + height - sprite (active, icon_lower_left).height); draw (icon_lower_right, x + width - sprite (active, icon_lower_right).width, y + height - sprite (active, icon_lower_right).height); -- select_text_box (description, x, y, width, height); end draw_icon_menu; ------------------------------------------------------------------------------------------ procedure draw_state_box (x, y : in integer) is begin ui.write ("Cursor X :" & core.cursor.x'image, x, y + 0); ui.write ("Cursor Y :" & core.cursor.y'image, x, y + 32); ui.write ("Cursor Mode :" & core.cursor_mode'image, x, y + 64); ui.write ("Camera X :" & core.camera.x'image, x, y + 96); ui.write ("Camera Y :" & core.camera.y'image, x, y + 128); ui.write ("Global Time :" & core.global_time'image, x, y + 160); ui.write ("Gameplay Time :" & core.gameplay_time'image, x, y + 192); ui.write ("Animation Time :" & core.animation_time'image, x, y + 224); ui.write ("Framerate :" & core.framerate'image, x, y + 256); end draw_state_box; ------------------------------------------------------------------------------------------ procedure write (text : in string; x, y : in integer) is begin core.write (text, x, y, glyphs (active)); end write; ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ end ui;