a lot of work on sliders

c3
Alessandro Mauri 1 week ago
parent c0e9565bf6
commit 8d4b353e88
  1. 19
      src/main.c3
  2. 5
      src/ugui_button.c3
  3. 9
      src/ugui_data.c3
  4. 164
      src/ugui_div.c3
  5. 34
      src/ugui_impl.c3
  6. 9
      src/ugui_input.c3
  7. 4
      src/ugui_layout.c3
  8. 111
      src/ugui_slider.c3
  9. 17
      src/ugui_text.c3

@ -138,21 +138,21 @@ fn int main(String[] args)
io::printn("release button2"); io::printn("release button2");
} }
} }
if (ui.slider_ver("slider", ugui::Rect{0,0,30,100})!!.update) { static float slider1;
ugui::Elem* e = ui.get_elem_by_label("slider")!!; if (ui.slider_ver("slider", ugui::Rect{0,0,30,100}, &slider1)!!.update) {
io::printfn("slider: %f", e.slider.value); io::printfn("slider: %f", slider1);
} }
ui.text_unbounded("text1", "Ciao Mamma\nAbilità ⚡")!!; ui.text_unbounded("text1", "Ciao Mamma\nAbilità ⚡")!!;
|}; |};
ui.div_end()!!; ui.div_end()!!;
ui.div_begin("second", ugui::DIV_FILL, scroll_y: true)!!; ui.div_begin("second", ugui::DIV_FILL, scroll_x: true, scroll_y: true)!!;
{| {|
ui.layout_set_column()!!; ui.layout_set_column()!!;
if (ui.slider_ver("slider_other", ugui::Rect{0,0,30,100})!!.update) { static float slider2 = 0.5;
ugui::Elem* e = ui.get_elem_by_label("slider_other")!!; if (ui.slider_ver("slider_other", ugui::Rect{0,0,30,100}, &slider2)!!.update) {
io::printfn("other slider: %f", e.slider.value); io::printfn("other slider: %f", slider2);
} }
ui.button("button10", ugui::Rect{0,0,50,50})!!; ui.button("button10", ugui::Rect{0,0,50,50})!!;
ui.button("button11", ugui::Rect{0,0,50,50})!!; ui.button("button11", ugui::Rect{0,0,50,50})!!;
@ -164,6 +164,11 @@ fn int main(String[] args)
ui.button("button16", ugui::Rect{0,0,50,50})!!; ui.button("button16", ugui::Rect{0,0,50,50})!!;
ui.button("button17", ugui::Rect{0,0,50,50})!!; ui.button("button17", ugui::Rect{0,0,50,50})!!;
} }
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)!!;
|}; |};
ui.div_end()!!; ui.div_end()!!;

@ -33,10 +33,7 @@ fn ElemEvents! Ctx.button(&ctx, String label, Rect size, bool state = false)
return UgError.WRONG_ELEMENT_TYPE?; return UgError.WRONG_ELEMENT_TYPE?;
} }
// if the element is new or the parent was updated then redo layout c_elem.bounds = ctx.position_element(parent, size, true);
if (needs_layout) {
c_elem.bounds = ctx.position_element(parent, size, true);
}
// if the bounds are null the element is outside the div view, // if the bounds are null the element is outside the div view,
// no interaction should occur so just return // no interaction should occur so just return

@ -47,12 +47,6 @@ bitstruct ElemEvents : uint {
bool update : 7; bool update : 7;
} }
// slider element
struct ElemSlider {
float value;
Rect handle;
}
struct ElemText { struct ElemText {
char* str; char* str;
} }
@ -100,9 +94,6 @@ macro Color uint_to_rgba(uint $u) {
const Rect DIV_FILL = { .x = 0, .y = 0, .w = 0, .h = 0 }; const Rect DIV_FILL = { .x = 0, .y = 0, .w = 0, .h = 0 };
macro abs(a) { return a < 0 ? -a : a; }
macro clamp(x, min, max) { return x < min ? min : (x > max ? max : x); }
const uint STACK_STEP = 10; const uint STACK_STEP = 10;
const uint MAX_ELEMS = 128; const uint MAX_ELEMS = 128;
const uint MAX_CMDS = 256; const uint MAX_CMDS = 256;

@ -1,6 +1,7 @@
module ugui; module ugui;
import std::io; import std::io;
import std::math;
enum DivLayout { enum DivLayout {
LAYOUT_ROW, LAYOUT_ROW,
@ -19,7 +20,8 @@ struct ElemDiv {
float value_x; float value_x;
float value_y; float value_y;
} }
Rect children_bounds; Rect children_bounds; // current frame children bounds
Rect pcb; // previous frame children bounds
Point origin_r, origin_c; Point origin_r, origin_c;
Color bgcolor; Color bgcolor;
} }
@ -38,12 +40,12 @@ fn void! Ctx.div_begin(&ctx, String label, Rect size, bool scroll_x = false, boo
{ {
Id id = label.hash(); Id id = label.hash();
Elem *parent = ctx.get_parent()!; Elem* parent = ctx.get_parent()!;
Elem* c_elem = ctx.get_elem(id)!; Elem* c_elem = ctx.get_elem(id)!;
isz div_node = ctx.tree.add(id, ctx.active_div)!; isz div_node = ctx.tree.add(id, ctx.active_div)!;
ctx.active_div = div_node; ctx.active_div = div_node;
bool needs_layout = c_elem.flags.is_new || parent.flags.updated; bool is_new = c_elem.flags.is_new;
if (c_elem.flags.is_new) { if (c_elem.flags.is_new) {
*c_elem = DIV_DEFAULTS; *c_elem = DIV_DEFAULTS;
@ -53,86 +55,104 @@ fn void! Ctx.div_begin(&ctx, String label, Rect size, bool scroll_x = false, boo
c_elem.div.scroll.can_x = scroll_x; c_elem.div.scroll.can_x = scroll_x;
c_elem.div.scroll.can_y = scroll_y; c_elem.div.scroll.can_y = scroll_y;
// do layout and update flags only if the element was updated // 2. layout the element
if (needs_layout) { c_elem.bounds = ctx.position_element(parent, size);
// 2. layout the element c_elem.div.children_bounds = c_elem.bounds;
c_elem.bounds = ctx.position_element(parent, size); c_elem.div.bgcolor = ctx.style.bgcolor;
c_elem.div.children_bounds = c_elem.bounds;
c_elem.div.bgcolor = ctx.style.bgcolor; // 4. Fill the div fields
c_elem.div.origin_c = Point{
// 3. Mark the element as updated .x = c_elem.bounds.x,
c_elem.flags.updated = true; .y = c_elem.bounds.y,
// 4. Fill the div fields };
c_elem.div.origin_c = Point{ c_elem.div.origin_r = c_elem.div.origin_c;
.x = c_elem.bounds.x, c_elem.div.layout = parent.div.layout;
.y = c_elem.bounds.y,
};
c_elem.div.origin_r = c_elem.div.origin_c;
c_elem.div.layout = parent.div.layout;
}
// Add the background to the draw stack // Add the background to the draw stack
bool do_border = parent.div.layout == LAYOUT_FLOATING; 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(c_elem.bounds, c_elem.div.bgcolor, do_border: do_border)!;
c_elem.events = ctx.get_elem_events(c_elem);
// TODO: check active // TODO: check active
// TODO: check resizeable // TODO: check resizeable
// check and draw scroll bars // FIXME: we cannot use slider elements as scrollbars because of id management
if (!c_elem.bounds.contains(c_elem.div.children_bounds)) { // scrollbars
Point cbc = { Rect cb = c_elem.div.pcb;
.x = c_elem.div.children_bounds.x + c_elem.div.children_bounds.w, // children bounds bottom-right corner
.y = c_elem.div.children_bounds.y + c_elem.div.children_bounds.h, Point cbc = {
.x = cb.x + cb.w,
.y = cb.y + cb.h,
};
// 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,
};
// set the scrollbar flag, is used in layout
// vertical overflow
c_elem.div.scroll.on_y = cbc.y > bc.y && c_elem.div.scroll.can_y;
// horizontal overflow
c_elem.div.scroll.on_x = cbc.x > bc.x && c_elem.div.scroll.can_x;
if (c_elem.div.scroll.on_y) {
Rect vslider = {
.x = c_elem.bounds.x + c_elem.bounds.w - 10,
.y = c_elem.bounds.y,
.w = 10,
.h = c_elem.bounds.h,
}; };
Point bc = {
.x = c_elem.bounds.x + c_elem.bounds.w, short hh = (short)(max((float)bc.y / cbc.y, (float)0.15) * c_elem.bounds.h);
.y = c_elem.bounds.y + c_elem.bounds.h, Rect vhandle = {
.x = c_elem.bounds.x + c_elem.bounds.w - 10,
.y = calc_slider(c_elem.bounds.y, c_elem.bounds.h-hh, c_elem.div.scroll.value_y),
.w = 10,
.h = hh,
}; };
// vertical overflow, check and draw scroll bar
if (cbc.y > bc.y && c_elem.div.scroll.can_y) { Point m = ctx.input.mouse.pos;
// set the scrollbar flag, is used in layout if (parent.flags.has_focus && c_elem.events.mouse_hover &&
c_elem.div.scroll.on_y = true; c_elem.events.mouse_hold && point_in_rect(m, vhandle)) {
vhandle.y = calc_slider(c_elem.bounds.y, c_elem.bounds.h-hh, c_elem.div.scroll.value_y);
Rect vslider = { c_elem.div.scroll.value_y = calc_value(c_elem.bounds.y, m.y, c_elem.bounds.h, hh);
.x = c_elem.bounds.x + c_elem.bounds.w - 10, c_elem.flags.updated = true;
.y = c_elem.bounds.y,
.w = 10,
.h = c_elem.bounds.h,
};
float vh = max((float)bc.y / cbc.y, (float)0.15);
Rect vhandle = {
.x = c_elem.bounds.x + c_elem.bounds.w - 10,
.y = (short)(c_elem.bounds.y + (int)(c_elem.bounds.h*(1-vh) * c_elem.div.scroll.value_y)),
.w = 10,
.h = (short)(c_elem.bounds.h * vh),
};
c_elem.events = ctx.get_elem_events(c_elem);
if (parent.flags.has_focus && c_elem.events.mouse_hover && c_elem.events.mouse_hold && point_in_rect(ctx.input.mouse.pos, vhandle)) {
short y = (short)clamp(ctx.input.mouse.pos.y - vhandle.h/2, vslider.y, vslider.y + vslider.h - vhandle.h);
vhandle.y = y;
float v = (float)(vhandle.y-vslider.y) / (float)(vslider.h-vhandle.h);
c_elem.div.scroll.value_y = v;
c_elem.flags.updated = true;
c_elem.div.origin_c = Point{
.x = c_elem.bounds.x,
.y = c_elem.bounds.y,
};
c_elem.div.origin_r = c_elem.div.origin_c;
}
ctx.push_rect(vslider, uint_to_rgba(0x999999ff))!;
ctx.push_rect(vhandle, uint_to_rgba(0x9999ffff))!;
} else {
c_elem.div.scroll.on_y = false;
} }
ctx.push_rect(vslider, uint_to_rgba(0x999999ff))!;
ctx.push_rect(vhandle, uint_to_rgba(0x9999ffff))!;
} }
// if the bounds are outside of the view then allocate space for scrollbars if (c_elem.div.scroll.on_x) {
DivLayout old_layout = c_elem.div.layout; Rect hslider = {
c_elem.div.layout = LAYOUT_FLOATING; .x = c_elem.bounds.x,
c_elem.div.layout = old_layout; .y = c_elem.bounds.y + c_elem.bounds.h - 10,
.w = c_elem.bounds.w,
.h = 10,
};
short hw = (short)(max((float)bc.x / cbc.x, (float)0.15) * c_elem.bounds.w);
Rect hhandle = {
.x = calc_slider(c_elem.bounds.x, c_elem.bounds.w-hw, c_elem.div.scroll.value_x),
.y = c_elem.bounds.y + c_elem.bounds.h - 10,
.w = hw,
.h = 10,
};
Point m = ctx.input.mouse.pos;
if (parent.flags.has_focus && c_elem.events.mouse_hover &&
c_elem.events.mouse_hold && point_in_rect(m, hhandle)) {
hhandle.x = calc_slider(c_elem.bounds.x, c_elem.bounds.w-hw, c_elem.div.scroll.value_x);
c_elem.div.scroll.value_x = calc_value(c_elem.bounds.x, m.x, c_elem.bounds.w, hw);
c_elem.flags.updated = true;
}
ctx.push_rect(hslider, uint_to_rgba(0x999999ff))!;
ctx.push_rect(hhandle, uint_to_rgba(0x9999ffff))!;
}
if (parent.flags.has_focus) { if (parent.flags.has_focus) {
if (point_in_rect(ctx.input.mouse.pos, c_elem.bounds)) { if (point_in_rect(ctx.input.mouse.pos, c_elem.bounds)) {
@ -144,6 +164,10 @@ fn void! Ctx.div_begin(&ctx, String label, Rect size, bool scroll_x = false, boo
fn void! Ctx.div_end(&ctx) fn void! Ctx.div_end(&ctx)
{ {
// swap the children bounds
Elem* c_elem = ctx.get_elem_by_tree_idx(ctx.active_div)!;
c_elem.div.pcb = c_elem.div.children_bounds;
// the active_div returns to the parent of the current one // the active_div returns to the parent of the current one
ctx.active_div = ctx.tree.parentof(ctx.active_div)!; ctx.active_div = ctx.tree.parentof(ctx.active_div)!;
} }

@ -85,26 +85,24 @@ fn void! Ctx.frame_begin(&ctx)
// other stuff // other stuff
c_elem.flags.has_focus = ctx.has_focus; c_elem.flags.has_focus = ctx.has_focus;
if (c_elem.flags.is_new || c_elem.flags.updated) { Elem def_root = {
Elem def_root = { .id = ROOT_ID,
.id = ROOT_ID, .type = ETYPE_DIV,
.type = ETYPE_DIV, .bounds = {
.bounds = { .w = ctx.width,
.h = ctx.height,
},
.div = {
.layout = LAYOUT_ROW,
.children_bounds = {
.w = ctx.width, .w = ctx.width,
.h = ctx.height, .h = ctx.height,
}, }
.div = { },
.layout = LAYOUT_ROW, .flags = c_elem.flags,
.children_bounds = { };
.w = ctx.width,
.h = ctx.height, *c_elem = def_root;
}
},
.flags = c_elem.flags,
};
*c_elem = def_root;
}
// 3. Push the root element into the element tree // 3. Push the root element into the element tree
ctx.active_div = ctx.tree.add(ROOT_ID, 0)!; ctx.active_div = ctx.tree.add(ROOT_ID, 0)!;

@ -1,6 +1,7 @@
module ugui; module ugui;
import std::io; import std::io;
import std::math;
// TODO: this could be a bitstruct // TODO: this could be a bitstruct
bitstruct InputEvents : uint { bitstruct InputEvents : uint {
@ -84,8 +85,8 @@ fn void Ctx.input_mouse_button(&ctx, MouseButtons buttons)
// Mouse was moved, report absolute position // Mouse was moved, report absolute position
fn void Ctx.input_mouse_abs(&ctx, short x, short y) fn void Ctx.input_mouse_abs(&ctx, short x, short y)
{ {
ctx.input.mouse.pos.x = clamp(x, 0u16, ctx.width); ctx.input.mouse.pos.x = math::clamp(x, 0u16, ctx.width);
ctx.input.mouse.pos.y = clamp(y, 0u16, ctx.height); ctx.input.mouse.pos.y = math::clamp(y, 0u16, ctx.height);
short dx, dy; short dx, dy;
dx = x - ctx.input.mouse.pos.x; dx = x - ctx.input.mouse.pos.x;
@ -107,8 +108,8 @@ fn void Ctx.input_mouse_delta(&ctx, short dx, short dy)
mx = ctx.input.mouse.pos.x + dx; mx = ctx.input.mouse.pos.x + dx;
my = ctx.input.mouse.pos.y + dy; my = ctx.input.mouse.pos.y + dy;
ctx.input.mouse.pos.x = clamp(mx, 0u16, ctx.width); ctx.input.mouse.pos.x = math::clamp(mx, 0u16, ctx.width);
ctx.input.mouse.pos.y = clamp(my, 0u16, ctx.height); ctx.input.mouse.pos.y = math::clamp(my, 0u16, ctx.height);
ctx.input.events.mouse_move = true; ctx.input.events.mouse_move = true;
} }

@ -140,10 +140,10 @@ fn Rect Ctx.position_element(&ctx, Elem *parent, Rect rect, bool style = false)
Point off; Point off;
Rect* cb = &div.children_bounds; Rect* cb = &div.children_bounds;
if (div.scroll.can_x && div.scroll.on_x) { if (div.scroll.can_x && div.scroll.on_x) {
off.x = (short)(cb.w * div.scroll.value_x); off.x = (short)((float)(div.pcb.w - parent.bounds.w) * div.scroll.value_x);
} }
if (div.scroll.can_y && div.scroll.on_y) { if (div.scroll.can_y && div.scroll.on_y) {
off.y = (short)((float)(cb.h - parent.bounds.h) * div.scroll.value_y); off.y = (short)((float)(div.pcb.h - parent.bounds.h) * div.scroll.value_y);
} }
Rect view = { Rect view = {
.x = parent.bounds.x + off.x, .x = parent.bounds.x + off.x,

@ -1,15 +1,28 @@
module ugui; module ugui;
import std::io; import std::io;
import std::math;
// slider element
struct ElemSlider {
Rect handle;
}
const Elem SLIDER_DEFAULT = {
.type = ETYPE_SLIDER,
};
/* handle /* handle
* +----+-----+---------------------+ * +----+-----+---------------------+
* | |#####| | * | |#####| |
* +----+-----+---------------------+ * +----+-----+---------------------+
*/ */
fn ElemEvents! Ctx.slider_hor(&ctx, String label, Rect size) <*
@require value != null
*>
fn ElemEvents! Ctx.slider_hor(&ctx, String label, Rect size, float* value)
{ {
Id id = label.hash(); Id id = label.hash();
Elem *parent = ctx.get_parent()!; Elem *parent = ctx.get_parent()!;
Elem *c_elem = ctx.get_elem(id)!; Elem *c_elem = ctx.get_elem(id)!;
@ -17,29 +30,33 @@ fn ElemEvents! Ctx.slider_hor(&ctx, String label, Rect size)
ctx.tree.add(id, ctx.active_div)!; ctx.tree.add(id, ctx.active_div)!;
// 1. Fill the element fields // 1. Fill the element fields
c_elem.type = ETYPE_SLIDER; if (c_elem.flags.is_new) {
*c_elem = SLIDER_DEFAULT;
// if the element is new or the parent was updated then redo layout } else if (c_elem.type != SLIDER_DEFAULT.type) {
if (c_elem.flags.is_new || parent.flags.updated) { return UgError.WRONG_ELEMENT_TYPE?;
// 2. Layout
c_elem.bounds = ctx.position_element(parent, size, true);
c_elem.slider.handle = Rect{
.x = (short)(c_elem.bounds.x + (int)(c_elem.bounds.w*(1.0-0.25) * c_elem.slider.value)),
.y = c_elem.bounds.y,
.w = (short)(c_elem.bounds.w * 0.25),
.h = c_elem.bounds.h,
};
} }
// 2. Layout
c_elem.bounds = ctx.position_element(parent, size, true);
// handle width
short hw = (short)(c_elem.bounds.w * 0.25);
Rect handle = {
.x = calc_slider(c_elem.bounds.x, c_elem.bounds.w-hw, *value),
.y = c_elem.bounds.y,
.w = hw,
.h = c_elem.bounds.h,
};
c_elem.slider.handle = handle;
Point m = ctx.input.mouse.pos;
c_elem.events = ctx.get_elem_events(c_elem); c_elem.events = ctx.get_elem_events(c_elem);
if (parent.flags.has_focus && c_elem.events.mouse_hover) {
if (point_in_rect(ctx.input.mouse.pos, c_elem.slider.handle) && c_elem.events.mouse_hold) { if (parent.flags.has_focus && c_elem.events.mouse_hover &&
short x = (short)clamp(ctx.input.mouse.pos.x - c_elem.slider.handle.w/2, c_elem.bounds.x, c_elem.bounds.x + c_elem.bounds.w - c_elem.slider.handle.w); point_in_rect(m, handle) && c_elem.events.mouse_hold) {
float v = (float)(c_elem.slider.handle.x-c_elem.bounds.x) / (float)(c_elem.bounds.w-c_elem.slider.handle.w); *value = calc_value(c_elem.bounds.x, m.x, c_elem.bounds.w, hw);
c_elem.slider.handle.x = x; c_elem.slider.handle.x = calc_slider(c_elem.bounds.x, c_elem.bounds.w-hw, *value);
c_elem.slider.value = v; c_elem.events.update = true;
c_elem.events.update = true;
}
} }
// Draw the slider background and handle // Draw the slider background and handle
@ -63,7 +80,7 @@ fn ElemEvents! Ctx.slider_hor(&ctx, String label, Rect size)
* | | * | |
* +-+ * +-+
*/ */
fn ElemEvents! Ctx.slider_ver(&ctx, String label, Rect size) fn ElemEvents! Ctx.slider_ver(&ctx, String label, Rect size, float* value)
{ {
Id id = label.hash(); Id id = label.hash();
@ -73,29 +90,34 @@ fn ElemEvents! Ctx.slider_ver(&ctx, String label, Rect size)
ctx.tree.add(id, ctx.active_div)!; ctx.tree.add(id, ctx.active_div)!;
// 1. Fill the element fields // 1. Fill the element fields
c_elem.type = ETYPE_SLIDER; if (c_elem.flags.is_new) {
*c_elem = SLIDER_DEFAULT;
// if the element is new or the parent was updated then redo layout } else if (c_elem.type != SLIDER_DEFAULT.type) {
if (c_elem.flags.is_new || parent.flags.updated) { return UgError.WRONG_ELEMENT_TYPE?;
// 2. Layout
c_elem.bounds = ctx.position_element(parent, size, true);
c_elem.slider.handle = Rect{
.x = c_elem.bounds.x,
.y = (short)(c_elem.bounds.y + (int)(c_elem.bounds.h*(1.0-0.25) * c_elem.slider.value)),
.w = c_elem.bounds.w,
.h = (short)(c_elem.bounds.h * 0.25),
};
} }
// 2. Layout
c_elem.bounds = ctx.position_element(parent, size, true);
// handle height
short hh = (short)(c_elem.bounds.h * 0.25);
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,
.h = hh,
};
c_elem.slider.handle = handle;
Point m = ctx.input.mouse.pos;
c_elem.events = ctx.get_elem_events(c_elem); c_elem.events = ctx.get_elem_events(c_elem);
if (parent.flags.has_focus && c_elem.events.mouse_hover) {
if (point_in_rect(ctx.input.mouse.pos, c_elem.slider.handle) && c_elem.events.mouse_hold) { if (parent.flags.has_focus && c_elem.events.mouse_hover &&
short y = (short)clamp(ctx.input.mouse.pos.y - c_elem.slider.handle.h/2, c_elem.bounds.y, c_elem.bounds.y + c_elem.bounds.h - c_elem.slider.handle.h); point_in_rect(m, handle) &&
float v = (float)(c_elem.slider.handle.y-c_elem.bounds.y) / (float)(c_elem.bounds.h-c_elem.slider.handle.h); c_elem.events.mouse_hold) {
c_elem.slider.handle.y = y; *value = calc_value(c_elem.bounds.y, m.y, c_elem.bounds.h, hh);
c_elem.slider.value = v; c_elem.slider.handle.y = calc_slider(c_elem.bounds.y, c_elem.bounds.h-hh, *value);
c_elem.events.update = true; c_elem.events.update = true;
}
} }
// Draw the slider background and handle // Draw the slider background and handle
@ -106,3 +128,6 @@ fn ElemEvents! Ctx.slider_ver(&ctx, String label, Rect size)
return c_elem.events; return c_elem.events;
} }
macro short calc_slider(ushort off, ushort dim, float value) => (short)off + (short)(dim * value);
macro float calc_value(ushort off, ushort mouse, ushort dim, ushort slider) => math::clamp((float)(mouse-off-slider/2)/(float)(dim-slider), 0.0f, 1.0f);

@ -15,19 +15,12 @@ fn void! Ctx.text_unbounded(&ctx, String label, String text)
// this resets the flags // this resets the flags
c_elem.type = ETYPE_TEXT; c_elem.type = ETYPE_TEXT;
short baseline = (short)ctx.font.ascender;
short line_height = (short)ctx.font.ascender - (short)ctx.font.descender;
short line_gap = (short)ctx.font.linegap;
// if the element is new or the parent was updated then redo layout // if the element is new or the parent was updated then redo layout
if (c_elem.flags.is_new || parent.flags.updated) { Rect text_size = ctx.get_text_bounds(text)!;
Rect text_size = ctx.get_text_bounds(text)!; // 2. Layout
c_elem.bounds = ctx.position_element(parent, text_size, true);
// 2. Layout // 3. Fill the button specific fields
c_elem.bounds = ctx.position_element(parent, text_size, true); c_elem.text.str = text;
// 3. Fill the button specific fields
c_elem.text.str = text;
}
ctx.push_string(c_elem.bounds, text)!; ctx.push_string(c_elem.bounds, text)!;
} }

Loading…
Cancel
Save