Merge branch 'c3' of https://git.alemauri.eu/alema/ugui into c3
This commit is contained in:
commit
a00e39f36b
@ -9,10 +9,6 @@ module cache{Key, Value, SIZE};
|
|||||||
* the elements that were not recently used.
|
* the elements that were not recently used.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// FIXME: this module should really allocate all resources on an arena or temp
|
|
||||||
// allocator, since all memory allocations are connected and freeing
|
|
||||||
// happens at the same time
|
|
||||||
|
|
||||||
import std::core::mem;
|
import std::core::mem;
|
||||||
import std::core::mem::allocator;
|
import std::core::mem::allocator;
|
||||||
import std::collections::bitset;
|
import std::collections::bitset;
|
||||||
@ -79,6 +75,7 @@ fn Value*? Cache.search(&cache, Key id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* HIT, set as recently used */
|
/* HIT, set as recently used */
|
||||||
|
//io::printfn("HIT: %d [%d]", entry.value, entry.key);
|
||||||
cache.used[entry.value] = true;
|
cache.used[entry.value] = true;
|
||||||
return &(cache.pool[entry.value]);
|
return &(cache.pool[entry.value]);
|
||||||
}
|
}
|
||||||
@ -99,16 +96,19 @@ fn void Cache.remove(&cache, Key id)
|
|||||||
/* If there is no free space left then just return the first position */
|
/* If there is no free space left then just return the first position */
|
||||||
fn usz Cache.get_free_spot(&cache) @private
|
fn usz Cache.get_free_spot(&cache) @private
|
||||||
{
|
{
|
||||||
|
// TODO: in the upgrade to c3 1.7.5 use @bitsof()
|
||||||
const BITS = $typeof(cache.present.data[0]).sizeof*8;
|
const BITS = $typeof(cache.present.data[0]).sizeof*8;
|
||||||
foreach (idx, d: cache.present.data) {
|
foreach (idx, d: cache.present.data) {
|
||||||
if (d.clz() != BITS) {
|
if (d != $typeof(d).max) {
|
||||||
return idx*BITS + BITS-d.clz();
|
usz spot = idx*BITS + BITS-d.clz();
|
||||||
|
if (cache.used[spot]) unreachable("free spot is not actually free: %d", spot);
|
||||||
|
return spot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Value*? Cache.insert_at(&cache, Value *g, Key id, usz index) @private
|
fn Value*? Cache.insert_at(&cache, Value* g, Key id, usz index) @private
|
||||||
{
|
{
|
||||||
// TODO: verify index, g and id
|
// TODO: verify index, g and id
|
||||||
Value* spot;
|
Value* spot;
|
||||||
|
@ -97,9 +97,7 @@ macro Ctx.push_cmd(&ctx, Cmd *cmd, int z_index)
|
|||||||
default: return ctx.cmd_queue.enqueue(cmd);
|
default: return ctx.cmd_queue.enqueue(cmd);
|
||||||
}
|
}
|
||||||
if (cull_rect(rect, ctx.div_scissor)) {
|
if (cull_rect(rect, ctx.div_scissor)) {
|
||||||
// io::print("NOPE: ");
|
// println("NOPE: ", cmd.rect.rect, cmd.z_index);
|
||||||
// io::print(cmd.rect.rect);
|
|
||||||
// io::printn(cmd.z_index);
|
|
||||||
// unreachable();
|
// unreachable();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -165,10 +165,9 @@ macro Id @compute_id(...)
|
|||||||
// resets all flags except is_new which is set accordingly
|
// resets all flags except is_new which is set accordingly
|
||||||
fn Elem*? Ctx.get_elem(&ctx, Id id, ElemType type)
|
fn Elem*? Ctx.get_elem(&ctx, Id id, ElemType type)
|
||||||
{
|
{
|
||||||
Elem empty_elem;
|
|
||||||
bool is_new;
|
bool is_new;
|
||||||
Elem* elem;
|
Elem* elem;
|
||||||
elem = ctx.cache.get_or_insert(&empty_elem, id, &is_new)!;
|
elem = ctx.cache.get_or_insert(&&(Elem){}, id, &is_new)!;
|
||||||
elem.flags = (ElemFlags)0;
|
elem.flags = (ElemFlags)0;
|
||||||
elem.flags.is_new = is_new;
|
elem.flags.is_new = is_new;
|
||||||
elem.id = id;
|
elem.id = id;
|
||||||
|
@ -55,8 +55,11 @@ macro Size Layout.total_height(&el)
|
|||||||
// Returns the width and height of a @FIT() element based on it's wanted size (min/max)
|
// Returns the width and height of a @FIT() element based on it's wanted size (min/max)
|
||||||
// and the content size, this function is used to both update the parent's children size and
|
// and the content size, this function is used to both update the parent's children size and
|
||||||
// give the dimensions of a fit element
|
// give the dimensions of a fit element
|
||||||
|
// TODO: test and cleanup this function
|
||||||
macro Point Layout.get_dimensions(&el)
|
macro Point Layout.get_dimensions(&el)
|
||||||
{
|
{
|
||||||
|
// if the direction is ROW then the text is placed horizontally with the children
|
||||||
|
if (el.dir == ROW) {
|
||||||
Size content_width = el.children.w + el.text.width;
|
Size content_width = el.children.w + el.text.width;
|
||||||
Size width = el.w.combine(content_width);
|
Size width = el.w.combine(content_width);
|
||||||
short final_width = width.greater();
|
short final_width = width.greater();
|
||||||
@ -67,6 +70,27 @@ macro Point Layout.get_dimensions(&el)
|
|||||||
text_height = @exact((short)(el.text.area / text_width)).combine(el.text.height).min;
|
text_height = @exact((short)(el.text.area / text_width)).combine(el.text.height).min;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Size content_height = el.children.h.comb_max(@exact(text_height));
|
||||||
|
Size height = el.h.combine(content_height);
|
||||||
|
short final_height = height.greater();
|
||||||
|
|
||||||
|
Point dim = {
|
||||||
|
.x = final_width + el.content_offset.x + el.content_offset.w,
|
||||||
|
.y = final_height + el.content_offset.y + el.content_offset.h,
|
||||||
|
};
|
||||||
|
return dim;
|
||||||
|
} else {
|
||||||
|
// if the direction is COLUMN the text and children are one on top of the other
|
||||||
|
Size content_width = el.children.w.comb_max(el.text.width);
|
||||||
|
Size width = el.w.combine(content_width);
|
||||||
|
short final_width = width.greater();
|
||||||
|
|
||||||
|
short text_height;
|
||||||
|
if (el.text.area != 0) {
|
||||||
|
short text_width = @exact(final_width).combine(el.text.width).min;
|
||||||
|
text_height = @exact((short)(el.text.area / text_width)).combine(el.text.height).min;
|
||||||
|
}
|
||||||
|
|
||||||
Size content_height = el.children.h + @exact(text_height);
|
Size content_height = el.children.h + @exact(text_height);
|
||||||
Size height = el.h.combine(content_height);
|
Size height = el.h.combine(content_height);
|
||||||
short final_height = height.greater();
|
short final_height = height.greater();
|
||||||
@ -76,6 +100,7 @@ macro Point Layout.get_dimensions(&el)
|
|||||||
.y = final_height + el.content_offset.y + el.content_offset.h,
|
.y = final_height + el.content_offset.y + el.content_offset.h,
|
||||||
};
|
};
|
||||||
return dim;
|
return dim;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The content space of the element
|
// The content space of the element
|
||||||
|
@ -30,10 +30,6 @@ struct SpriteAtlas {
|
|||||||
bool should_update;
|
bool should_update;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ElemSprite {
|
|
||||||
Id id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// name: some examples are "icons" or "images"
|
// name: some examples are "icons" or "images"
|
||||||
fn void? SpriteAtlas.init(&this, String name, AtlasType type, ushort width, ushort height)
|
fn void? SpriteAtlas.init(&this, String name, AtlasType type, ushort width, ushort height)
|
||||||
{
|
{
|
||||||
@ -109,47 +105,3 @@ fn void? Ctx.import_sprite_file_qoi(&ctx, String name, String path, SpriteType t
|
|||||||
|
|
||||||
ctx.sprite_atlas.insert(name, type, pixels, (ushort)desc.width, (ushort)desc.height, (ushort)desc.width)!;
|
ctx.sprite_atlas.insert(name, type, pixels, (ushort)desc.width, (ushort)desc.height, (ushort)desc.width)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
macro Ctx.sprite(&ctx, String name, Point off = {0,0}, ...)
|
|
||||||
=> ctx.sprite_id(@compute_id($vasplat), name, off);
|
|
||||||
fn void? Ctx.sprite_id(&ctx, Id id, String name, Point off)
|
|
||||||
{
|
|
||||||
id = ctx.gen_id(id)!;
|
|
||||||
|
|
||||||
Elem *parent = ctx.get_parent()!;
|
|
||||||
Elem *elem = ctx.get_elem(id, ETYPE_SPRITE)!;
|
|
||||||
|
|
||||||
Style* style = ctx.styles.get_style(@str_hash("sprite"));
|
|
||||||
Sprite* sprite = ctx.sprite_atlas.get(name)!;
|
|
||||||
|
|
||||||
Rect uv = { sprite.u, sprite.v, sprite.w, sprite.h };
|
|
||||||
Rect bounds = { 0, 0, sprite.w, sprite.h };
|
|
||||||
|
|
||||||
elem.bounds = ctx.layout_element(parent, bounds.off(off), style);
|
|
||||||
elem.sprite.id = ctx.get_sprite_atlas_id(name);
|
|
||||||
|
|
||||||
// if the bounds are null the element is outside the div view,
|
|
||||||
// no interaction should occur so just return
|
|
||||||
if (elem.bounds.is_null()) return;
|
|
||||||
|
|
||||||
Id tex_id = ctx.sprite_atlas.id;
|
|
||||||
|
|
||||||
return ctx.push_sprite(elem.bounds, uv, tex_id, parent.div.z_index)!;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn void? Ctx.draw_sprite_raw(&ctx, String name, Rect bounds, bool center = false)
|
|
||||||
{
|
|
||||||
Elem *parent = ctx.get_parent()!;
|
|
||||||
Sprite* sprite = ctx.sprite_atlas.get(name)!;
|
|
||||||
Id tex_id = ctx.sprite_atlas.id;
|
|
||||||
|
|
||||||
if (center) {
|
|
||||||
Point off = {.x = (bounds.w - sprite.w) / 2, .y = (bounds.h - sprite.h) / 2};
|
|
||||||
bounds = bounds.off(off);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ctx.push_sprite(bounds, sprite.uv(), tex_id, parent.div.z_index, type: sprite.type)!;
|
|
||||||
}
|
|
||||||
*/
|
|
@ -18,9 +18,6 @@ fn ElemEvents? Ctx.button_id(&ctx, Id id, String label, String icon)
|
|||||||
Style* style = ctx.styles.get_style(@str_hash("button"));
|
Style* style = ctx.styles.get_style(@str_hash("button"));
|
||||||
|
|
||||||
Sprite* sprite = icon != "" ? ctx.sprite_atlas.get(icon)! : &&(Sprite){};
|
Sprite* sprite = icon != "" ? ctx.sprite_atlas.get(icon)! : &&(Sprite){};
|
||||||
|
|
||||||
// TODO: get min size by style
|
|
||||||
TextSize text_size = ctx.measure_string(label)!;
|
|
||||||
Rect icon_size = sprite.rect();
|
Rect icon_size = sprite.rect();
|
||||||
|
|
||||||
ushort min_size = style.size;
|
ushort min_size = style.size;
|
||||||
@ -44,7 +41,7 @@ fn ElemEvents? Ctx.button_id(&ctx, Id id, String label, String icon)
|
|||||||
elem.layout.h = @fit(min_size);
|
elem.layout.h = @fit(min_size);
|
||||||
elem.layout.children.w = @exact(content_size.x);
|
elem.layout.children.w = @exact(content_size.x);
|
||||||
elem.layout.children.h = @exact(content_size.y);
|
elem.layout.children.h = @exact(content_size.y);
|
||||||
elem.layout.text = text_size;
|
elem.layout.text = ctx.measure_string(label)!;
|
||||||
elem.layout.content_offset = style.margin + style.border + style.padding;
|
elem.layout.content_offset = style.margin + style.border + style.padding;
|
||||||
|
|
||||||
update_parent_grow(elem, parent);
|
update_parent_grow(elem, parent);
|
||||||
@ -86,47 +83,82 @@ fn ElemEvents? Ctx.button_id(&ctx, Id id, String label, String icon)
|
|||||||
return elem.events;
|
return elem.events;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
// FIXME: this should be inside the style
|
macro Ctx.checkbox(&ctx, String desc, bool* active, String tick_sprite = "", ...)
|
||||||
macro Ctx.checkbox(&ctx, String desc, Point off, bool* active, String tick_sprite = {}, ...)
|
=> ctx.checkbox_id(@compute_id($vasplat), desc, active, tick_sprite);
|
||||||
=> ctx.checkbox_id(@compute_id($vasplat), desc, off, active, tick_sprite);
|
fn void? Ctx.checkbox_id(&ctx, Id id, String description, bool* active, String tick_sprite)
|
||||||
fn void? Ctx.checkbox_id(&ctx, Id id, String description, Point off, bool* active, String tick_sprite)
|
|
||||||
{
|
{
|
||||||
id = ctx.gen_id(id)!;
|
id = ctx.gen_id(id)!;
|
||||||
|
|
||||||
Elem *parent = ctx.get_parent()!;
|
Elem *parent = ctx.get_parent()!;
|
||||||
Elem *elem = ctx.get_elem(id, ETYPE_BUTTON)!;
|
Elem *elem = ctx.get_elem(id, ETYPE_BUTTON)!;
|
||||||
Style* style = ctx.styles.get_style(@str_hash("checkbox"));
|
Style* style = ctx.styles.get_style(@str_hash("checkbox"));
|
||||||
|
|
||||||
Rect size = {off.x, off.y, style.size, style.size};
|
short inner_pad = description != "" ? style.size/2 : 0;
|
||||||
elem.bounds = ctx.layout_element(parent, size, style);
|
/*
|
||||||
|
* |< >| style.size/2
|
||||||
|
* +---------------------|---|-----------+
|
||||||
|
* | | .-----. ---|--
|
||||||
|
* | +-----------------+ ' ### ' | ^
|
||||||
|
* | | description | | ##### | | style.size
|
||||||
|
* | +-----------------+ . ### . | v
|
||||||
|
* | '-----' ---|--
|
||||||
|
* +-------------------------|-------|---+
|
||||||
|
* |<----->| style.size
|
||||||
|
*/
|
||||||
|
|
||||||
// if the bounds are null the element is outside the div view,
|
elem.layout.w = @fit(style.size);
|
||||||
// no interaction should occur so just return
|
elem.layout.h = @fit(style.size);
|
||||||
if (elem.bounds.is_null()) return;
|
elem.layout.children.w = @exact(style.size + inner_pad);
|
||||||
|
elem.layout.children.h = @exact(style.size);
|
||||||
|
elem.layout.text = ctx.measure_string(description)!;
|
||||||
|
elem.layout.content_offset = style.margin + style.border + style.padding;
|
||||||
|
|
||||||
|
update_parent_grow(elem, parent);
|
||||||
|
update_parent_size(elem, parent);
|
||||||
|
|
||||||
elem.events = ctx.get_elem_events(elem);
|
elem.events = ctx.get_elem_events(elem);
|
||||||
if (elem.events.mouse_hover && elem.events.mouse_release) *active = !(*active);
|
if (elem.events.mouse_hover && elem.events.mouse_release) *active = !(*active);
|
||||||
|
|
||||||
if (tick_sprite != {}) {
|
|
||||||
ctx.push_rect(elem.bounds, parent.div.z_index, style)!;
|
Rect content_bounds = elem.bounds.pad(elem.layout.content_offset);
|
||||||
|
Rect text_bounds = {
|
||||||
|
.x = content_bounds.x,
|
||||||
|
.y = content_bounds.y,
|
||||||
|
.w = content_bounds.w - inner_pad - style.size,
|
||||||
|
.h = content_bounds.h
|
||||||
|
};
|
||||||
|
Rect check_bounds = {
|
||||||
|
.x = content_bounds.x + text_bounds.w + inner_pad,
|
||||||
|
.y = content_bounds.y + (content_bounds.h - style.size)/2,
|
||||||
|
.w = style.size,
|
||||||
|
.h = style.size,
|
||||||
|
};
|
||||||
|
|
||||||
|
Style s;
|
||||||
|
s.bg = style.bg;
|
||||||
|
s.secondary = style.secondary;
|
||||||
|
s.border = style.border;
|
||||||
|
s.radius = style.radius;
|
||||||
|
|
||||||
|
ctx.layout_string(description, text_bounds, CENTER, parent.div.z_index, style.fg)!;
|
||||||
|
if (tick_sprite != "") {
|
||||||
|
ctx.push_rect(check_bounds, parent.div.z_index, &s)!;
|
||||||
if (*active) {
|
if (*active) {
|
||||||
ctx.draw_sprite_raw(tick_sprite, elem.bounds, center: true)!;
|
Sprite* sprite = ctx.sprite_atlas.get(tick_sprite)!;
|
||||||
|
Id tex_id = ctx.sprite_atlas.id;
|
||||||
|
ctx.push_sprite(sprite.rect().center_to(check_bounds), sprite.uv(), tex_id, parent.div.z_index, type: sprite.type)!;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ctx.push_rect(elem.bounds, parent.div.z_index, style)!;
|
|
||||||
if (*active) {
|
if (*active) {
|
||||||
ushort x = style.size / 4;
|
s.bg = style.primary;
|
||||||
Rect check = elem.bounds.add({x, x, -x*2, -x*2});
|
ctx.push_rect(check_bounds, parent.div.z_index, &s)!;
|
||||||
Style s = *style;
|
} else {
|
||||||
s.bg = s.primary;
|
ctx.push_rect(check_bounds, parent.div.z_index, &s)!;
|
||||||
s.margin = s.border = s.padding = {};
|
|
||||||
ctx.push_rect(check, parent.div.z_index, &s)!;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// FIXME: this should be inside the style
|
// FIXME: this should be inside the style
|
||||||
macro Ctx.toggle(&ctx, String desc, Point off, bool* active)
|
macro Ctx.toggle(&ctx, String desc, Point off, bool* active)
|
||||||
=> ctx.toggle_id(@compute_id($vasplat), desc, off, active);
|
=> ctx.toggle_id(@compute_id($vasplat), desc, off, active);
|
||||||
@ -157,4 +189,3 @@ fn void? Ctx.toggle_id(&ctx, Id id, String description, Point off, bool* active)
|
|||||||
s.margin = s.border = s.padding = {};
|
s.margin = s.border = s.padding = {};
|
||||||
ctx.push_rect(t, parent.div.z_index, &s)!;
|
ctx.push_rect(t, parent.div.z_index, &s)!;
|
||||||
}
|
}
|
||||||
*/
|
|
@ -161,7 +161,7 @@ fn void? Ctx.div_end(&ctx)
|
|||||||
ctx.active_div = ctx.tree.parentof(ctx.active_div)!;
|
ctx.active_div = ctx.tree.parentof(ctx.active_div)!;
|
||||||
Elem* parent = ctx.get_parent()!;
|
Elem* parent = ctx.get_parent()!;
|
||||||
ctx.div_scissor = parent.bounds;
|
ctx.div_scissor = parent.bounds;
|
||||||
ctx.push_scissor(parent.bounds, elem.div.z_index)!;
|
ctx.reset_scissor(elem.div.z_index)!;
|
||||||
|
|
||||||
update_parent_size(elem, parent);
|
update_parent_size(elem, parent);
|
||||||
}
|
}
|
27
lib/ugui.c3l/src/widgets/ugui_sprite.c3
Normal file
27
lib/ugui.c3l/src/widgets/ugui_sprite.c3
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
module ugui;
|
||||||
|
|
||||||
|
struct ElemSprite {
|
||||||
|
Id id;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro Ctx.sprite(&ctx, String name, ...)
|
||||||
|
=> ctx.sprite_id(@compute_id($vasplat), name);
|
||||||
|
fn void? Ctx.sprite_id(&ctx, Id id, String name)
|
||||||
|
{
|
||||||
|
id = ctx.gen_id(id)!;
|
||||||
|
Elem *parent = ctx.get_parent()!;
|
||||||
|
Elem *elem = ctx.get_elem(id, ETYPE_SPRITE)!;
|
||||||
|
|
||||||
|
Style* style = ctx.styles.get_style(@str_hash("sprite"));
|
||||||
|
Sprite* sprite = ctx.sprite_atlas.get(name)!;
|
||||||
|
elem.sprite.id = ctx.get_sprite_atlas_id(name);
|
||||||
|
|
||||||
|
elem.layout.w = elem.layout.children.w = @exact(sprite.w);
|
||||||
|
elem.layout.h = elem.layout.children.h = @exact(sprite.h);
|
||||||
|
|
||||||
|
update_parent_grow(elem, parent);
|
||||||
|
update_parent_size(elem, parent);
|
||||||
|
|
||||||
|
Id tex_id = ctx.sprite_atlas.id;
|
||||||
|
return ctx.push_sprite(elem.bounds, sprite.uv(), tex_id, parent.div.z_index, type: sprite.type)!;
|
||||||
|
}
|
@ -28,7 +28,7 @@ checkbox {
|
|||||||
border: 2;
|
border: 2;
|
||||||
padding: 1;
|
padding: 1;
|
||||||
radius: 10;
|
radius: 10;
|
||||||
size: 16;
|
size: 20;
|
||||||
bg: #3c3836ff;
|
bg: #3c3836ff;
|
||||||
fg: #fbf1c7ff;
|
fg: #fbf1c7ff;
|
||||||
primary: #cc241dff;
|
primary: #cc241dff;
|
||||||
|
13
src/main.c3
13
src/main.c3
@ -360,7 +360,7 @@ fn void calculator(ugui::Ctx* ui)
|
|||||||
case "c":
|
case "c":
|
||||||
len = 0;
|
len = 0;
|
||||||
case "d":
|
case "d":
|
||||||
len--;
|
if (len > 0) len--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ui input/output
|
// ui input/output
|
||||||
@ -389,9 +389,7 @@ fn void calculator(ugui::Ctx* ui)
|
|||||||
ui.button("3")!!.mouse_press ? buffer[len++] = '3' : 0;
|
ui.button("3")!!.mouse_press ? buffer[len++] = '3' : 0;
|
||||||
ui.button("(")!!.mouse_press ? buffer[len++] = '(' : 0;
|
ui.button("(")!!.mouse_press ? buffer[len++] = '(' : 0;
|
||||||
}!!;
|
}!!;
|
||||||
|
|
||||||
ui.@div(ugui::@exact(10), ugui::@exact(10)) {}!!;
|
ui.@div(ugui::@exact(10), ugui::@exact(10)) {}!!;
|
||||||
|
|
||||||
ui.@div(ugui::@fit(), ugui::@fit(), COLUMN) {
|
ui.@div(ugui::@fit(), ugui::@fit(), COLUMN) {
|
||||||
ui.button("x")!!.mouse_press ? buffer[len++] = '*' : 0;
|
ui.button("x")!!.mouse_press ? buffer[len++] = '*' : 0;
|
||||||
ui.button("/")!!.mouse_press ? buffer[len++] = '/' : 0;
|
ui.button("/")!!.mouse_press ? buffer[len++] = '/' : 0;
|
||||||
@ -400,7 +398,7 @@ fn void calculator(ugui::Ctx* ui)
|
|||||||
}!!;
|
}!!;
|
||||||
ui.@div(ugui::@fit(), ugui::@fit(), COLUMN) {
|
ui.@div(ugui::@fit(), ugui::@fit(), COLUMN) {
|
||||||
ui.button("C")!!.mouse_press ? len = 0 : 0;
|
ui.button("C")!!.mouse_press ? len = 0 : 0;
|
||||||
ui.button("D")!!.mouse_press ? len-- : 0;
|
ui.button("D")!!.mouse_press ? len > 0 ? len-- : 0 : 0;
|
||||||
ui.button("-")!!.mouse_press ? buffer[len++] = '-' : 0;
|
ui.button("-")!!.mouse_press ? buffer[len++] = '-' : 0;
|
||||||
|
|
||||||
// eval the expression with 'bc'
|
// eval the expression with 'bc'
|
||||||
@ -413,5 +411,12 @@ fn void calculator(ugui::Ctx* ui)
|
|||||||
}
|
}
|
||||||
}!!;
|
}!!;
|
||||||
}!!;
|
}!!;
|
||||||
|
|
||||||
|
ui.@div(ugui::@grow(), ugui::@grow(), anchor: CENTER) {
|
||||||
|
static bool state;
|
||||||
|
ui.checkbox("boolean", &state, "tick")!!;
|
||||||
|
ui.sprite("tux")!!;
|
||||||
|
}!!;
|
||||||
|
|
||||||
}!!; }!!;
|
}!!; }!!;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user