ugui.c3l/src/main.c3

303 lines
7.7 KiB
Plaintext
Raw Normal View History

2024-10-29 22:45:47 +01:00
import std::io;
import vtree;
import cache;
import ugui;
import rl;
2024-12-01 00:25:43 +01:00
import std::time;
import std::collections::ringbuffer;
2024-12-16 17:06:46 +01:00
import std::core::string;
2024-12-01 00:25:43 +01:00
def Times = ringbuffer::RingBuffer(<time::NanoDuration, 128>);
fn void Times.print_stats(&times)
{
time::NanoDuration min, max, avg, x;
min = times.get(0);
for (usz i = 0; i < times.written; i++) {
x = times.get(i);
if (x < min) { min = x; }
if (x > max) { max = x; }
avg += x;
}
avg = (NanoDuration)((ulong)avg/128.0);
io::printfn("min=%s, max=%s, avg=%s", min, max, avg);
}
2024-10-29 22:45:47 +01:00
2024-12-16 17:06:46 +01:00
struct TimeStats {
time::NanoDuration min, max, avg;
}
fn TimeStats Times.get_stats(&times)
{
time::NanoDuration min, max, avg, x;
min = times.get(0);
for (usz i = 0; i < times.written; i++) {
x = times.get(i);
if (x < min) { min = x; }
if (x > max) { max = x; }
avg += x;
}
avg = (NanoDuration)((ulong)avg/128.0);
return TimeStats{.min = min, .max = max, .avg = avg};
}
2024-12-16 13:54:53 +01:00
const ZString FONT_FS = `
#version 330
// Input vertex attributes (from vertex shader)
in vec2 fragTexCoord;
in vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;
// Output fragment color
out vec4 finalColor;
void main()
{
vec4 alpha = texture(texture0, fragTexCoord);
finalColor = colDiffuse*fragColor;
finalColor.a *= alpha.r;
}
`;
2024-10-29 22:45:47 +01:00
fn int main(String[] args)
{
2024-11-17 21:36:46 +01:00
ugui::Ctx ui;
ui.init()!!;
2024-12-17 11:26:59 +01:00
ui.load_font("font1", "resources/hack-nerd.ttf", 16)!!;
2024-10-29 22:45:47 +01:00
short width = 800;
short height = 450;
rl::set_config_flags(rl::FLAG_WINDOW_RESIZABLE);
rl::init_window(width, height, "Ugui Test");
2024-11-17 21:36:46 +01:00
ui.input_window_size(width, height)!!;
2024-11-20 17:12:01 +01:00
rl::set_target_fps(60);
rl::enable_event_waiting();
2024-10-29 22:45:47 +01:00
isz frame;
2024-12-01 00:25:43 +01:00
bool toggle = true;
time::Clock clock;
Times ui_times;
Times draw_times;
// font stuff
2024-12-16 13:54:53 +01:00
rl::Shader font_shader = rl::load_shader_from_memory(null, FONT_FS);
2024-12-16 17:06:46 +01:00
rl::Image font_atlas;
rl::Texture2D font_texture;
ugui::Id font_id = ui.get_font_id("font1");
2024-10-29 22:45:47 +01:00
// Main loop
while (!rl::window_should_close()) {
2024-12-01 00:25:43 +01:00
clock.mark();
2024-12-13 14:42:15 +01:00
2024-10-31 00:04:49 +01:00
/* Start Input Handling */
2024-10-29 22:45:47 +01:00
if (rl::is_window_resized()) {
width = (short)rl::get_screen_width();
height = (short)rl::get_screen_height();
2024-11-17 21:36:46 +01:00
ui.input_window_size(width, height)!!;
2024-10-29 22:45:47 +01:00
}
2024-11-17 21:36:46 +01:00
ui.input_changefocus(rl::is_window_focused());
2024-10-29 22:45:47 +01:00
2024-11-17 21:36:46 +01:00
rl::Vector2 mpos = rl::get_mouse_position();
ui.input_mouse_abs((short)mpos.x, (short)mpos.y);
2024-10-29 22:45:47 +01:00
ugui::MouseButtons buttons;
buttons.btn_left = rl::is_mouse_button_down(rl::MOUSE_BUTTON_LEFT);
buttons.btn_right = rl::is_mouse_button_down(rl::MOUSE_BUTTON_RIGHT);
buttons.btn_middle = rl::is_mouse_button_down(rl::MOUSE_BUTTON_MIDDLE);
2024-11-17 21:36:46 +01:00
ui.input_mouse_button(buttons);
2024-10-31 00:04:49 +01:00
/* End Input Handling */
2024-10-29 22:45:47 +01:00
2024-10-31 00:04:49 +01:00
/* Start UI Handling */
2024-11-17 21:36:46 +01:00
ui.frame_begin()!!;
2024-10-29 22:45:47 +01:00
// main div, fill the whole window
2024-11-17 21:36:46 +01:00
ui.div_begin("main", ugui::Rect{.w=ui.width/2})!!;
2024-10-29 22:45:47 +01:00
{|
2024-12-01 00:25:43 +01:00
2024-11-17 21:36:46 +01:00
ui.layout_set_row()!!;
2024-12-17 11:26:59 +01:00
if (ui.button("button0", ugui::Rect{0,0,30,30}, toggle)!!.mouse_press) {
2024-10-31 00:04:49 +01:00
io::printn("press button0");
2024-12-01 00:25:43 +01:00
toggle = !toggle;
2024-10-29 22:45:47 +01:00
}
2024-11-17 21:36:46 +01:00
//ui.layout_next_column()!!;
if (ui.button("button1", ugui::Rect{0,0,30,30})!!.mouse_press) {
2024-10-31 00:04:49 +01:00
io::printn("press button1");
}
2024-11-17 21:36:46 +01:00
//ui.layout_next_column()!!;
2024-12-01 00:25:43 +01:00
if (toggle) {
if (ui.button("button2", ugui::Rect{0,0,30,30})!!.mouse_release) {
io::printn("release button2");
}
2024-10-31 00:04:49 +01:00
}
2024-12-18 14:58:40 +01:00
static float slider1;
if (ui.slider_ver("slider", ugui::Rect{0,0,30,100}, &slider1)!!.update) {
io::printfn("slider: %f", slider1);
2024-10-31 13:04:30 +01:00
}
2024-12-11 01:14:14 +01:00
ui.text_unbounded("text1", "Ciao Mamma\nAbilità ⚡")!!;
2024-10-29 22:45:47 +01:00
|};
2024-11-17 21:36:46 +01:00
ui.div_end()!!;
2024-12-01 00:25:43 +01:00
2024-12-18 14:58:40 +01:00
ui.div_begin("second", ugui::DIV_FILL, scroll_x: true, scroll_y: true)!!;
2024-11-07 18:35:20 +01:00
{|
2024-11-17 21:36:46 +01:00
ui.layout_set_column()!!;
2024-12-18 14:58:40 +01:00
static float slider2 = 0.5;
if (ui.slider_ver("slider", ugui::Rect{0,0,30,100}, &slider2)!!.update) {
2024-12-18 14:58:40 +01:00
io::printfn("other slider: %f", slider2);
2024-11-07 18:35:20 +01:00
}
ui.button("button0", ugui::Rect{0,0,50,50})!!;
ui.button("button1", ugui::Rect{0,0,50,50})!!;
ui.button("button2", ugui::Rect{0,0,50,50})!!;
ui.button("button3", ugui::Rect{0,0,50,50})!!;
2024-12-17 11:26:59 +01:00
if (toggle) {
ui.button("button4", ugui::Rect{0,0,50,50})!!;
ui.button("button5", ugui::Rect{0,0,50,50})!!;
ui.button("button6", ugui::Rect{0,0,50,50})!!;
ui.button("button7", ugui::Rect{0,0,50,50})!!;
2024-12-17 11:26:59 +01:00
}
2024-12-18 14:58:40 +01:00
ui.layout_next_column()!!;
ui.layout_set_row()!!;
static float f1, f2;
ui.slider_hor("hs1", ugui::Rect{0,0,100,30}, &f1)!!;
ui.slider_hor("hs2", ugui::Rect{0,0,100,30}, &f2)!!;
2024-11-07 18:35:20 +01:00
|};
2024-11-17 21:36:46 +01:00
ui.div_end()!!;
2024-11-07 18:35:20 +01:00
2024-12-16 17:06:46 +01:00
// Timings counter
TimeStats dts = draw_times.get_stats();
TimeStats uts = ui_times.get_stats();
ui.layout_set_floating()!!;
2024-12-17 11:26:59 +01:00
ui.div_begin("fps", ugui::Rect{0, ui.height-60, 200, 60})!!;
2024-12-16 17:06:46 +01:00
{|
ui.layout_set_row()!!;
2024-12-17 11:26:59 +01:00
ui.text_unbounded("ui avg", string::tformat("ui avg: %s\ndraw avg: %s\nTOT: %s", uts.avg, dts.avg, uts.avg+dts.avg))!!;
2024-12-16 17:06:46 +01:00
|};
ui.div_end()!!;
2024-11-17 21:36:46 +01:00
ui.frame_end()!!;
2024-10-31 00:04:49 +01:00
/* End UI Handling */
2024-12-01 00:25:43 +01:00
ui_times.push(clock.mark());
2024-12-17 11:26:59 +01:00
//ui_times.print_stats();
2024-10-29 22:45:47 +01:00
2024-10-31 00:04:49 +01:00
/* Start UI Drawing */
2024-10-29 22:45:47 +01:00
rl::begin_drawing();
// ClearBackground(BLACK);
rl::Color c;
2024-12-12 15:46:24 +01:00
rl::Rectangle r;
2024-11-17 21:36:46 +01:00
for (Cmd* cmd; (cmd = ui.cmd_queue.dequeue() ?? null) != null;) {
2024-10-29 22:45:47 +01:00
switch (cmd.type) {
case ugui::CmdType.CMD_RECT:
c = rl::Color{
2024-12-16 17:06:46 +01:00
.r = cmd.rect.color.r,
.g = cmd.rect.color.g,
.b = cmd.rect.color.b,
.a = cmd.rect.color.a,
2024-10-29 22:45:47 +01:00
};
2024-12-12 15:46:24 +01:00
r = rl::Rectangle{
.x = cmd.rect.rect.x,
.y = cmd.rect.rect.y,
.height = cmd.rect.rect.h,
.width = cmd.rect.rect.w,
};
2024-12-16 17:06:46 +01:00
float rad = cmd.rect.radius;
2024-12-13 14:42:15 +01:00
// for some weird-ass reason the straight forward inverse formula does not work
2024-12-16 17:06:46 +01:00
float roundness = r.width > r.height ? (2.1*rad)/r.height : (2.1*rad)/r.width;
2024-12-13 14:42:15 +01:00
rl::draw_rectangle_rounded(r, roundness, 0, c);
2024-12-11 01:14:14 +01:00
case ugui::CmdType.CMD_UPDATE_ATLAS:
2024-12-16 17:06:46 +01:00
if (cmd.update_atlas.id != font_id) { break; }
//rl::unload_image(font_atlas);
2024-12-11 01:14:14 +01:00
font_atlas.data = cmd.update_atlas.raw_buffer;
font_atlas.width = cmd.update_atlas.width;
font_atlas.height = cmd.update_atlas.height;
font_atlas.mipmaps = 1;
//font_atlas.format = rl::PixelFormat.PIXELFORMAT_UNCOMPRESSED_GRAYSCALE;
font_atlas.format = 1;
if (rl::is_texture_ready(font_texture)) {
rl::unload_texture(font_texture);
}
font_texture = rl::load_texture_from_image(font_atlas);
case ugui::CmdType.CMD_SPRITE:
if (cmd.sprite.texture_id != font_id) { break; }
2024-12-11 01:14:14 +01:00
rl::Rectangle source = {
.x = cmd.sprite.texture_rect.x,
.y = cmd.sprite.texture_rect.y,
.width = cmd.sprite.texture_rect.w,
.height = cmd.sprite.texture_rect.h,
};
rl::Vector2 position = {
.x = cmd.sprite.rect.x,
2024-12-11 20:39:06 +01:00
.y = cmd.sprite.rect.y,
2024-12-11 01:14:14 +01:00
};
2024-12-16 13:54:53 +01:00
rl::begin_shader_mode(font_shader);
2024-12-11 01:14:14 +01:00
rl::draw_texture_rec(font_texture, source, position, rl::WHITE);
2024-12-16 13:54:53 +01:00
rl::end_shader_mode();
2024-12-15 22:29:07 +01:00
case ugui::CmdType.CMD_SCISSOR:
if (cmd.scissor.rect.w == 0 && cmd.scissor.rect.h == 0) {
rl::end_scissor_mode();
} else {
rl::begin_scissor_mode(cmd.scissor.rect.x, cmd.scissor.rect.y, cmd.scissor.rect.w, cmd.scissor.rect.h);
}
2024-10-29 22:45:47 +01:00
default:
2024-12-11 01:14:14 +01:00
io::printfn("Unknown cmd type: %s", cmd.type);
2024-10-29 22:45:47 +01:00
}
}
2024-12-01 00:25:43 +01:00
draw_times.push(clock.mark());
2024-12-17 11:26:59 +01:00
//draw_times.print_stats();
2024-10-29 22:45:47 +01:00
rl::end_drawing();
2024-12-01 00:25:43 +01:00
/* End Drawing */
2024-10-29 22:45:47 +01:00
}
rl::close_window();
2024-11-17 21:36:46 +01:00
ui.free();
2024-10-29 22:45:47 +01:00
return 0;
}
2024-10-31 00:04:49 +01:00
/*
2024-10-29 22:45:47 +01:00
fn void! test_vtree() @test
{
vtree::VTree(<String>) vt;
vt.init(10)!!;
defer vt.free();
2024-10-29 22:45:47 +01:00
assert(vt.size() == 10, "Size is incorrect");
2024-10-29 22:45:47 +01:00
isz ref = vt.add("Ciao Mamma", 0)!!;
String s = vt.get(ref)!!;
assert(s == "Ciao Mamma", "String is incorrect");
isz par = vt.parentof(0)!!;
assert(ref == par, "Not Root");
2024-10-29 22:45:47 +01:00
vt.print();
2024-10-29 22:45:47 +01:00
}
def StrCache = cache::Cache(<int, String, 256>);
fn void! test_cache() @test
{
StrCache cc;
cc.init()!!;
defer cc.free();
String*! r = cc.search(1);
if (catch ex = r) {
if (ex != SearchResult.MISSING) {
return ex?;
}
}
r = cc.get_or_insert(&&"Ciao Mamma", 1)!;
assert(*r!! == "Ciao Mamma", "incorrect string");
}
2024-10-31 00:04:49 +01:00
*/