diff --git a/src/main.c3 b/src/main.c3 index 2a1a5d9..311bd85 100644 --- a/src/main.c3 +++ b/src/main.c3 @@ -121,7 +121,6 @@ fn int main(String[] args) // main div, fill the whole window ui.div_begin("main", ugui::Rect{.w=ui.width/2})!!; {| - ui.layout_set_column()!!; if (ui.button("button0", ugui::Rect{0,0,30,30}, toggle)!!.mouse_press) { io::printn("press button0"); @@ -135,12 +134,20 @@ fn int main(String[] args) if (ui.button("button2", ugui::Rect{0,0,30,30})!!.mouse_release) { io::printn("release button2"); } - static float slider1; - if (ui.slider_ver("slider", ugui::Rect{0,0,30,100}, &slider1)!!.update) { - io::printfn("slider: %f", slider1); - } + + ui.layout_set_row()!!; + ui.layout_next_row()!!; + static float rf, gf, bf, af; + ui.slider_ver("slider_r", ugui::Rect{0,0,30,100}, &rf)!!; + ui.slider_ver("slider_g", ugui::Rect{0,0,30,100}, &gf)!!; + ui.slider_ver("slider_b", ugui::Rect{0,0,30,100}, &bf)!!; + ui.slider_ver("slider_a", ugui::Rect{0,0,30,100}, &af)!!; + ui.layout_next_column()!!; ui.text_unbounded("text1", "Ciao Mamma\nAbilità ⚡")!!; + + ui.layout_next_column()!!; + ui.button_label("Continua!")!!; |}; ui.div_end()!!; diff --git a/src/ugui_button.c3 b/src/ugui_button.c3 index 598389a..e605c91 100644 --- a/src/ugui_button.c3 +++ b/src/ugui_button.c3 @@ -42,3 +42,44 @@ fn ElemEvents! Ctx.button(&ctx, String label, Rect size, bool state = false) return elem.events; } + +fn ElemEvents! Ctx.button_label(&ctx, String label, Rect size = Rect{0,0,short.max,short.max}, bool state = false) +{ + Id id = ctx.gen_id(label)!; + + Elem *parent = ctx.get_parent()!; + Elem *elem = ctx.get_elem(id)!; + // add it to the tree + ctx.tree.add(id, ctx.active_div)!; + + // 1. Fill the element fields + // this resets the flags + elem.type = ETYPE_BUTTON; + + short line_height = (short)ctx.font.ascender - (short)ctx.font.descender; + Rect text_size = ctx.get_text_bounds(label)!; + Rect btn_size = rect_add(text_size, Rect{0,0,10,10}); + + // 2. Layout + elem.bounds = ctx.position_element(parent, btn_size, true); + if (elem.bounds.is_null()) { return ElemEvents{}; } + + Color col = uint_to_rgba(0x0000ffff); + elem.events = ctx.get_elem_events(elem); + if (state) { + col = uint_to_rgba(0xff0000ff); + } else if (ctx.elem_focus(elem) || elem.events.mouse_hover) { + col = uint_to_rgba(0xff00ffff); + } + + // Draw the button + text_size.x = elem.bounds.x; + text_size.y = elem.bounds.y; + Point off = ctx.center_text(text_size, elem.bounds); + text_size.x += off.x; + text_size.y += off.y; + ctx.push_rect(elem.bounds, col, do_border: true, do_radius: true)!; + ctx.push_string(text_size, label)!; + + return elem.events; +} diff --git a/src/ugui_core.c3 b/src/ugui_core.c3 index 065af5d..9e0905c 100644 --- a/src/ugui_core.c3 +++ b/src/ugui_core.c3 @@ -46,10 +46,6 @@ bitstruct ElemEvents : uint { bool update : 7; } -struct ElemText { - char* str; -} - // element structure struct Elem { Id id; @@ -169,6 +165,16 @@ macro bool Rect.collides(Rect a, Rect b) macro bool Rect.is_null(r) => r.x == 0 && r.y == 0 && r.x == 0 && r.w == 0; +macro Rect rect_add(Rect r1, Rect r2) +{ + return Rect{ + .x = r1.x + r2.x, + .y = r1.y + r2.y, + .w = r1.w + r2.w, + .h = r1.h + r2.h, + }; +} + // return a pointer to the parent of the current active div fn Elem*! Ctx.get_parent(&ctx) { @@ -334,19 +340,19 @@ macro bool Ctx.elem_focus(&ctx, Elem *elem) // TODO: add other events // FIXME: this does not work with touch -macro ElemEvents Ctx.get_elem_events(&ctx, Elem *elem) +// FIXME: hacked together, please do better +fn ElemEvents Ctx.get_elem_events(&ctx, Elem *elem) { - //io::printfn("id %x, focus id %x", elem.id, ctx.focus_id); - bool hover = ctx.is_hovered(elem); bool focus = ctx.focus_id == elem.id || (hover && ctx.is_mouse_pressed(BTN_LEFT)); - - if (hover) { - ctx.hover_id = elem.id; - } - if (focus) { - ctx.focus_id = elem.id; + + if (ctx.is_mouse_pressed(BTN_ANY) && !hover){ + focus = false; + if (ctx.focus_id == elem.id) ctx.focus_id = 0; } + + if (hover) { ctx.hover_id = elem.id; } + if (focus) { ctx.focus_id = elem.id; } ElemEvents ev = { .mouse_hover = hover, diff --git a/src/ugui_div.c3 b/src/ugui_div.c3 index 709c8eb..f46eb15 100644 --- a/src/ugui_div.c3 +++ b/src/ugui_div.c3 @@ -100,8 +100,8 @@ fn void! Ctx.div_end(&ctx) Id hsid = ctx.gen_id("div_scrollbar_horizontal")!; Id vsid = ctx.gen_id("div_scrollbar_vertical")!; - short wdim = elem.div.scroll_y.on ? (ctx.focus_id == vsid ? SCROLLBAR_DIM*3 : SCROLLBAR_DIM) : 0; - short hdim = elem.div.scroll_x.on ? (ctx.focus_id == hsid ? SCROLLBAR_DIM*3 : SCROLLBAR_DIM) : 0; + short wdim = elem.div.scroll_y.on ? (ctx.focus_id == vsid || ctx.hover_id == vsid ? SCROLLBAR_DIM*3 : SCROLLBAR_DIM) : 0; + short hdim = elem.div.scroll_x.on ? (ctx.focus_id == hsid || ctx.hover_id == hsid ? SCROLLBAR_DIM*3 : SCROLLBAR_DIM) : 0; if (elem.div.scroll_y.on) { Rect vslider = { diff --git a/src/ugui_font.c3 b/src/ugui_font.c3 index 6843da0..c9be65d 100644 --- a/src/ugui_font.c3 +++ b/src/ugui_font.c3 @@ -212,8 +212,16 @@ fn Rect! Ctx.get_text_bounds(&ctx, String text) return text_bounds; } +fn Point Ctx.center_text(&ctx, Rect text_bounds, Rect bounds) +{ + short dw = bounds.w - text_bounds.w; + short dh = bounds.h - text_bounds.h; + + return Point{.x = dw/2, .y = dh/2}; +} + // TODO: check if the font is present in the context fn Id Ctx.get_font_id(&ctx, String label) { return (Id)label.hash(); -} \ No newline at end of file +} diff --git a/src/ugui_text.c3 b/src/ugui_text.c3 index 02413ae..18628e0 100644 --- a/src/ugui_text.c3 +++ b/src/ugui_text.c3 @@ -2,6 +2,10 @@ module ugui; import std::io; +struct ElemText { + char* str; +} + fn void! Ctx.text_unbounded(&ctx, String label, String text) { Id id = ctx.gen_id(label)!; @@ -14,13 +18,13 @@ fn void! Ctx.text_unbounded(&ctx, String label, String text) // 1. Fill the element fields // this resets the flags elem.type = ETYPE_TEXT; + elem.text.str = text; // if the element is new or the parent was updated then redo layout Rect text_size = ctx.get_text_bounds(text)!; // 2. Layout elem.bounds = ctx.position_element(parent, text_size, true); - // 3. Fill the button specific fields - elem.text.str = text; + if (elem.bounds.is_null()) { return; } ctx.push_string(elem.bounds, text)!; }