diff --git a/src/main.c3 b/src/main.c3 index 1d678b7..42f38a9 100644 --- a/src/main.c3 +++ b/src/main.c3 @@ -132,10 +132,8 @@ fn int main(String[] args) io::printn("press button1"); } //ui.layout_next_column()!!; - if (toggle) { - if (ui.button("button2", ugui::Rect{0,0,30,30})!!.mouse_release) { - io::printn("release button2"); - } + 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) { diff --git a/src/ugui_button.c3 b/src/ugui_button.c3 index 4572ed0..e1d9fb6 100644 --- a/src/ugui_button.c3 +++ b/src/ugui_button.c3 @@ -14,39 +14,39 @@ fn ElemEvents! Ctx.button(&ctx, String label, Rect size, bool state = false) Id id = ctx.gen_id(label)!; Elem *parent = ctx.get_parent()!; - Elem *c_elem = ctx.get_elem(id)!; + Elem *elem = ctx.get_elem(id)!; // add it to the tree ctx.tree.add(id, ctx.active_div)!; - if (c_elem.flags.is_new) { - c_elem.type = ETYPE_BUTTON; - c_elem.button.color = uint_to_rgba(0x0000ffff); - } else if (c_elem.type != ETYPE_BUTTON) { + if (elem.flags.is_new) { + elem.type = ETYPE_BUTTON; + elem.button.color = uint_to_rgba(0x0000ffff); + } else if (elem.type != ETYPE_BUTTON) { return UgError.WRONG_ELEMENT_TYPE?; } - c_elem.bounds = ctx.position_element(parent, size, true); + elem.bounds = ctx.position_element(parent, size, true); // if the bounds are null the element is outside the div view, // no interaction should occur so just return - if (c_elem.bounds.is_null()) { return ElemEvents{}; } + if (elem.bounds.is_null()) { return ElemEvents{}; } - c_elem.events = ctx.get_elem_events(c_elem); - if (c_elem.events.mouse_hover) { + elem.events = ctx.get_elem_events(elem); + if (elem.events.mouse_hover) { if (parent.flags.has_focus) { - c_elem.flags.has_focus = true; - c_elem.button.color = uint_to_rgba(0x00ff00ff); + elem.flags.has_focus = true; + elem.button.color = uint_to_rgba(0x00ff00ff); } } else { - c_elem.button.color = uint_to_rgba(0x0000ffff); + elem.button.color = uint_to_rgba(0x0000ffff); } if (state) { - c_elem.button.color = uint_to_rgba(0xff00ffff); + elem.button.color = uint_to_rgba(0xff00ffff); } // Draw the button - ctx.push_rect(c_elem.bounds, c_elem.button.color, do_border: true, do_radius: true)!; + ctx.push_rect(elem.bounds, elem.button.color, do_border: true, do_radius: true)!; - return c_elem.events; + return elem.events; } diff --git a/src/ugui_core.c3 b/src/ugui_core.c3 index 8a54b29..8bc082a 100644 --- a/src/ugui_core.c3 +++ b/src/ugui_core.c3 @@ -134,7 +134,7 @@ struct Ctx { } } - Rect div_scissor; + Rect div_scissor; // the current div bounds used for scissor test isz active_div; // tree node indicating the current active div } @@ -186,11 +186,11 @@ macro Ctx.get_elem(&ctx, Id id) { Elem empty_elem; bool is_new; - Elem* c_elem; - c_elem = ctx.cache.get_or_insert(&empty_elem, id, &is_new)!; - c_elem.flags = (ElemFlags)0; - c_elem.flags.is_new = is_new; - return c_elem; + Elem* elem; + elem = ctx.cache.get_or_insert(&empty_elem, id, &is_new)!; + elem.flags = (ElemFlags)0; + elem.flags.is_new = is_new; + return elem; } // this searches an element in the cache by label, it does not create a new element @@ -242,15 +242,15 @@ fn void! Ctx.frame_begin(&ctx) { // 2. Get the root element from the cache and update it - Elem* c_elem = ctx.get_elem(ROOT_ID)!; + Elem* elem = ctx.get_elem(ROOT_ID)!; // The root should have the updated flag only if the size of the window // was changed between frames, this propagates an element size recalculation // down the element tree - c_elem.flags.updated = ctx.input.events.resize; + elem.flags.updated = ctx.input.events.resize; // if the window has focus then the root element also has focus, no other // computation needed, child elements need to check the mouse positon and // other stuff - c_elem.flags.has_focus = ctx.has_focus; + elem.flags.has_focus = ctx.has_focus; Elem def_root = { .id = ROOT_ID, @@ -266,10 +266,10 @@ fn void! Ctx.frame_begin(&ctx) .h = ctx.height, } }, - .flags = c_elem.flags, + .flags = elem.flags, }; - *c_elem = def_root; + *elem = def_root; // 3. Push the root element into the element tree ctx.active_div = ctx.tree.add(ROOT_ID, 0)!; diff --git a/src/ugui_div.c3 b/src/ugui_div.c3 index ea10c0a..9647a84 100644 --- a/src/ugui_div.c3 +++ b/src/ugui_div.c3 @@ -23,7 +23,9 @@ struct ElemDiv { Rect children_bounds; // current frame children bounds Rect pcb; // previous frame children bounds Point origin_r, origin_c; - Color bgcolor; + // the id of the active element, this field is set and reset by the elements themselves and it is + // used to keep track of which element should handle some input events between frames + Id active_id; } fn void! Ctx.div_begin(&ctx, String label, Rect size, bool scroll_x = false, bool scroll_y = false) @@ -31,49 +33,48 @@ fn void! Ctx.div_begin(&ctx, String label, Rect size, bool scroll_x = false, boo Id id = ctx.gen_id(label)!; Elem* parent = ctx.get_parent()!; - Elem* c_elem = ctx.get_elem(id)!; + Elem* elem = ctx.get_elem(id)!; isz div_node = ctx.tree.add(id, ctx.active_div)!; ctx.active_div = div_node; - bool is_new = c_elem.flags.is_new; + bool is_new = elem.flags.is_new; - if (c_elem.flags.is_new) { - c_elem.type = ETYPE_DIV; - } else if (c_elem.type != ETYPE_DIV) { + if (elem.flags.is_new) { + elem.type = ETYPE_DIV; + } else if (elem.type != ETYPE_DIV) { return UgError.WRONG_ELEMENT_TYPE?; } - c_elem.div.scroll_x.enabled = scroll_x; - c_elem.div.scroll_y.enabled = scroll_y; + elem.div.scroll_x.enabled = scroll_x; + elem.div.scroll_y.enabled = scroll_y; // 2. layout the element - c_elem.bounds = ctx.position_element(parent, size); - c_elem.div.children_bounds = c_elem.bounds; - c_elem.div.bgcolor = ctx.style.bgcolor; + elem.bounds = ctx.position_element(parent, size); + elem.div.children_bounds = elem.bounds; // update the ctx scissor - ctx.div_scissor = c_elem.bounds; - ctx.push_scissor(c_elem.bounds)!; + ctx.div_scissor = elem.bounds; + ctx.push_scissor(elem.bounds)!; // 4. Fill the div fields - c_elem.div.origin_c = Point{ - .x = c_elem.bounds.x, - .y = c_elem.bounds.y, + elem.div.origin_c = Point{ + .x = elem.bounds.x, + .y = elem.bounds.y, }; - c_elem.div.origin_r = c_elem.div.origin_c; - c_elem.div.layout = parent.div.layout; + elem.div.origin_r = elem.div.origin_c; + elem.div.layout = parent.div.layout; // Add the background to the draw stack bool do_border = parent.div.layout == LAYOUT_FLOATING; - ctx.push_rect(c_elem.bounds, c_elem.div.bgcolor, do_border: do_border)!; + ctx.push_rect(elem.bounds, ctx.style.bgcolor, do_border: do_border)!; - c_elem.events = ctx.get_elem_events(c_elem); + elem.events = ctx.get_elem_events(elem); // TODO: check active // TODO: check resizeable if (parent.flags.has_focus) { - if (point_in_rect(ctx.input.mouse.pos, c_elem.bounds)) { - c_elem.flags.has_focus = true; + if (point_in_rect(ctx.input.mouse.pos, elem.bounds)) { + elem.flags.has_focus = true; } } @@ -83,12 +84,12 @@ fn void! Ctx.div_end(&ctx) { // swap the children bounds Elem* parent = ctx.get_parent()!; - Elem* c_elem = ctx.get_elem_by_tree_idx(ctx.active_div)!; - c_elem.div.pcb = c_elem.div.children_bounds; + Elem* elem = ctx.get_elem_by_tree_idx(ctx.active_div)!; + elem.div.pcb = elem.div.children_bounds; - c_elem.events = ctx.get_elem_events(c_elem); + elem.events = ctx.get_elem_events(elem); - Rect cb = c_elem.div.pcb; + Rect cb = elem.div.pcb; // children bounds bottom-right corner Point cbc = { .x = cb.x + cb.w, @@ -96,44 +97,43 @@ fn void! Ctx.div_end(&ctx) }; // div bounds bottom-right corner Point bc = { - .x = c_elem.bounds.x + c_elem.bounds.w, - .y = c_elem.bounds.y + c_elem.bounds.h, + .x = elem.bounds.x + elem.bounds.w, + .y = elem.bounds.y + elem.bounds.h, }; - // set the scrollbar flag, is used in layout // horizontal overflow - c_elem.div.scroll_x.on = cbc.x > bc.x && c_elem.div.scroll_x.enabled; + elem.div.scroll_x.on = cbc.x > bc.x && elem.div.scroll_x.enabled; // vertical overflow - c_elem.div.scroll_y.on = cbc.y > bc.y && c_elem.div.scroll_y.enabled; + elem.div.scroll_y.on = cbc.y > bc.y && elem.div.scroll_y.enabled; - short wdim = c_elem.div.scroll_y.focus ? SCROLLBAR_DIM*3 : SCROLLBAR_DIM; - short hdim = c_elem.div.scroll_x.focus ? SCROLLBAR_DIM*3 : SCROLLBAR_DIM; + short wdim = elem.div.scroll_y.on ? (elem.div.scroll_y.focus ? SCROLLBAR_DIM*3 : SCROLLBAR_DIM) : 0; + short hdim = elem.div.scroll_x.on ? (elem.div.scroll_x.focus ? SCROLLBAR_DIM*3 : SCROLLBAR_DIM) : 0; - if (c_elem.div.scroll_y.on) { + if (elem.div.scroll_y.on) { Rect vslider = { - .x = c_elem.bounds.x + c_elem.bounds.w - wdim, - .y = c_elem.bounds.y, + .x = elem.bounds.x + elem.bounds.w - wdim, + .y = elem.bounds.y, .w = wdim, - .h = c_elem.bounds.h, + .h = elem.bounds.h - hdim, }; - Layout prev_l = c_elem.div.layout; - c_elem.div.layout = LAYOUT_ABSOLUTE; - ctx.slider_ver("div_scrollbar_vertical", vslider, &c_elem.div.scroll_y.value, max((float)bc.y / cbc.y, (float)0.15))!; - c_elem.div.layout = prev_l; + Layout prev_l = elem.div.layout; + elem.div.layout = LAYOUT_ABSOLUTE; + ctx.slider_ver("div_scrollbar_vertical", vslider, &elem.div.scroll_y.value, max((float)bc.y / cbc.y, (float)0.15))!; + elem.div.layout = prev_l; } - if (c_elem.div.scroll_x.on) { + if (elem.div.scroll_x.on) { Rect hslider = { - .x = c_elem.bounds.x, - .y = c_elem.bounds.y + c_elem.bounds.h - hdim, - .w = c_elem.bounds.w, + .x = elem.bounds.x, + .y = elem.bounds.y + elem.bounds.h - hdim, + .w = elem.bounds.w - wdim, .h = hdim, }; - Layout prev_l = c_elem.div.layout; - c_elem.div.layout = LAYOUT_ABSOLUTE; - ctx.slider_hor("div_scrollbar_horizontal", hslider, &c_elem.div.scroll_x.value, max((float)bc.x / cbc.x, (float)0.15))!; - c_elem.div.layout = prev_l; + Layout prev_l = elem.div.layout; + elem.div.layout = LAYOUT_ABSOLUTE; + ctx.slider_hor("div_scrollbar_horizontal", hslider, &elem.div.scroll_x.value, max((float)bc.x / cbc.x, (float)0.15))!; + elem.div.layout = prev_l; } // the active_div returns to the parent of the current one diff --git a/src/ugui_input.c3 b/src/ugui_input.c3 index 92d31a7..0c4421e 100644 --- a/src/ugui_input.c3 +++ b/src/ugui_input.c3 @@ -45,13 +45,13 @@ macro Ctx.mouse_pressed(&ctx) => ctx.input.mouse.updated & ctx.input.mouse.down; macro Ctx.mouse_released(&ctx) => ctx.input.mouse.updated & ~ctx.input.mouse.down; macro Ctx.mouse_down(&ctx) => ctx.input.mouse.down; -const MouseButtons BTN_NONE = (MouseButtons)0u; -const MouseButtons BTN_ANY = (MouseButtons)(uint.max); -const MouseButtons BTN_LEFT = {.btn_left = true}; +const MouseButtons BTN_NONE = (MouseButtons)0u; +const MouseButtons BTN_ANY = (MouseButtons)(uint.max); +const MouseButtons BTN_LEFT = {.btn_left = true}; const MouseButtons BTN_MIDDLE = {.btn_middle = true}; -const MouseButtons BTN_RIGHT = {.btn_right = true}; -const MouseButtons BTN_4 = {.btn_4 = true}; -const MouseButtons BTN_5 = {.btn_5 = true}; +const MouseButtons BTN_RIGHT = {.btn_right = true}; +const MouseButtons BTN_4 = {.btn_4 = true}; +const MouseButtons BTN_5 = {.btn_5 = true}; // FIXME: hthis compairson could be done with a cast using MouseButtons.inner // property but I could not figure out how @@ -63,7 +63,7 @@ macro ElemEvents Ctx.get_elem_events(&ctx, Elem *elem) { // TODO: add the other events // FIXME: active should be elsewhere - bool active = elem.events.mouse_hold || ctx.is_hovered(elem); + bool active = ctx.is_hovered(elem); ElemEvents ev = { .mouse_hover = ctx.is_hovered(elem), .mouse_press = active & ctx.is_mouse_pressed(BTN_ANY), diff --git a/src/ugui_slider.c3 b/src/ugui_slider.c3 index 28fd6a4..81671db 100644 --- a/src/ugui_slider.c3 +++ b/src/ugui_slider.c3 @@ -27,45 +27,45 @@ fn ElemEvents! Ctx.slider_hor(&ctx, Id id = ctx.gen_id(label)!; Elem *parent = ctx.get_parent()!; - Elem *c_elem = ctx.get_elem(id)!; + Elem *elem = ctx.get_elem(id)!; // add it to the tree ctx.tree.add(id, ctx.active_div)!; // 1. Fill the element fields - if (c_elem.flags.is_new) { - c_elem.type = ETYPE_SLIDER; - } else if (c_elem.type != ETYPE_SLIDER) { + if (elem.flags.is_new) { + elem.type = ETYPE_SLIDER; + } else if (elem.type != ETYPE_SLIDER) { return UgError.WRONG_ELEMENT_TYPE?; } // 2. Layout - c_elem.bounds = ctx.position_element(parent, size, true); + elem.bounds = ctx.position_element(parent, size, true); // handle width - short hw = (short)(c_elem.bounds.w * hpercent); + short hw = (short)(elem.bounds.w * hpercent); Rect handle = { - .x = calc_slider(c_elem.bounds.x, c_elem.bounds.w-hw, *value), - .y = c_elem.bounds.y, + .x = calc_slider(elem.bounds.x, elem.bounds.w-hw, *value), + .y = elem.bounds.y, .w = hw, - .h = c_elem.bounds.h, + .h = elem.bounds.h, }; - c_elem.slider.handle = handle; + elem.slider.handle = handle; Point m = ctx.input.mouse.pos; - c_elem.events = ctx.get_elem_events(c_elem); + elem.events = ctx.get_elem_events(elem); - if (parent.flags.has_focus && c_elem.events.mouse_hover && - point_in_rect(m, handle) && c_elem.events.mouse_hold) { - *value = calc_value(c_elem.bounds.x, m.x, c_elem.bounds.w, hw); - c_elem.slider.handle.x = calc_slider(c_elem.bounds.x, c_elem.bounds.w-hw, *value); - c_elem.events.update = true; + if (parent.flags.has_focus && elem.events.mouse_hover && + point_in_rect(m, handle) && elem.events.mouse_hold) { + *value = calc_value(elem.bounds.x, m.x, elem.bounds.w, hw); + elem.slider.handle.x = calc_slider(elem.bounds.x, elem.bounds.w-hw, *value); + elem.events.update = true; } // Draw the slider background and handle - ctx.push_rect(c_elem.bounds, bgcolor)!; - ctx.push_rect(c_elem.slider.handle, handlecolor)!; + ctx.push_rect(elem.bounds, bgcolor)!; + ctx.push_rect(elem.slider.handle, handlecolor)!; - return c_elem.events; + return elem.events; } /* @@ -91,46 +91,46 @@ fn ElemEvents! Ctx.slider_ver(&ctx, Id id = ctx.gen_id(label)!; Elem *parent = ctx.get_parent()!; - Elem *c_elem = ctx.get_elem(id)!; + Elem *elem = ctx.get_elem(id)!; // add it to the tree ctx.tree.add(id, ctx.active_div)!; // 1. Fill the element fields - if (c_elem.flags.is_new) { - c_elem.type = ETYPE_SLIDER; - } else if (c_elem.type != ETYPE_SLIDER) { + if (elem.flags.is_new) { + elem.type = ETYPE_SLIDER; + } else if (elem.type != ETYPE_SLIDER) { return UgError.WRONG_ELEMENT_TYPE?; } // 2. Layout - c_elem.bounds = ctx.position_element(parent, size, true); + elem.bounds = ctx.position_element(parent, size, true); // handle height - short hh = (short)(c_elem.bounds.h * hpercent); + short hh = (short)(elem.bounds.h * hpercent); Rect handle = { - .x = c_elem.bounds.x, - .y = calc_slider(c_elem.bounds.y, c_elem.bounds.h-hh, *value), - .w = c_elem.bounds.w, + .x = elem.bounds.x, + .y = calc_slider(elem.bounds.y, elem.bounds.h-hh, *value), + .w = elem.bounds.w, .h = hh, }; - c_elem.slider.handle = handle; + elem.slider.handle = handle; Point m = ctx.input.mouse.pos; - c_elem.events = ctx.get_elem_events(c_elem); + elem.events = ctx.get_elem_events(elem); - if (parent.flags.has_focus && c_elem.events.mouse_hover && + if (parent.flags.has_focus && elem.events.mouse_hover && point_in_rect(m, handle) && - c_elem.events.mouse_hold) { - *value = calc_value(c_elem.bounds.y, m.y, c_elem.bounds.h, hh); - c_elem.slider.handle.y = calc_slider(c_elem.bounds.y, c_elem.bounds.h-hh, *value); - c_elem.events.update = true; + elem.events.mouse_hold) { + *value = calc_value(elem.bounds.y, m.y, elem.bounds.h, hh); + elem.slider.handle.y = calc_slider(elem.bounds.y, elem.bounds.h-hh, *value); + elem.events.update = true; } // Draw the slider background and handle - ctx.push_rect(c_elem.bounds, bgcolor)!; - ctx.push_rect(c_elem.slider.handle, handlecolor)!; + ctx.push_rect(elem.bounds, bgcolor)!; + ctx.push_rect(elem.slider.handle, handlecolor)!; - return c_elem.events; + return elem.events; } macro short calc_slider(ushort off, ushort dim, float value) => (short)off + (short)(dim * value); diff --git a/src/ugui_text.c3 b/src/ugui_text.c3 index 58da02f..02413ae 100644 --- a/src/ugui_text.c3 +++ b/src/ugui_text.c3 @@ -7,20 +7,20 @@ fn void! Ctx.text_unbounded(&ctx, String label, String text) Id id = ctx.gen_id(label)!; Elem *parent = ctx.get_parent()!; - Elem *c_elem = ctx.get_elem(id)!; + 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 - c_elem.type = ETYPE_TEXT; + elem.type = ETYPE_TEXT; // if the element is new or the parent was updated then redo layout Rect text_size = ctx.get_text_bounds(text)!; // 2. Layout - c_elem.bounds = ctx.position_element(parent, text_size, true); + elem.bounds = ctx.position_element(parent, text_size, true); // 3. Fill the button specific fields - c_elem.text.str = text; + elem.text.str = text; - ctx.push_string(c_elem.bounds, text)!; + ctx.push_string(elem.bounds, text)!; }