work on button with label

c3
Alessandro Mauri 5 days ago
parent ca691d1294
commit a0c6a3b2cb
  1. 17
      src/main.c3
  2. 41
      src/ugui_button.c3
  3. 32
      src/ugui_core.c3
  4. 4
      src/ugui_div.c3
  5. 10
      src/ugui_font.c3
  6. 8
      src/ugui_text.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()!!;

@ -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;
}

@ -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,

@ -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 = {

@ -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();
}
}

@ -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)!;
}

Loading…
Cancel
Save