Compare commits
4 Commits
c3
...
correct-pa
Author | SHA1 | Date | |
---|---|---|---|
f409a67130 | |||
d0a8e8a1ff | |||
fa334ed154 | |||
b35bb427a7 |
2
TODO
2
TODO
@ -47,6 +47,8 @@ to maintain focus until mouse release (fix scroll bars)
|
||||
## Layout
|
||||
|
||||
[x] Flexbox
|
||||
[ ] For some reason padding is not correct, look at the sliders, they have 2px per side when the
|
||||
theme specifies 4px per side
|
||||
[ ] Center elements to the row/column
|
||||
[ ] Text wrapping / reflow
|
||||
[ ] Consider a multi-pass recursive approach to layout (like https://github.com/nicbarker/clay)
|
||||
|
@ -147,7 +147,8 @@ fn void? Ctx.checkbox_id(&ctx, Id id, String description, Point off, bool* activ
|
||||
Rect check = elem.bounds.add({x, x, -x*2, -x*2});
|
||||
Style s = *style;
|
||||
s.bg = s.primary;
|
||||
s.margin = s.border = s.padding = {};
|
||||
s.margin = s.padding = {};
|
||||
s.border = 0;
|
||||
ctx.push_rect(check, parent.div.z_index, &s)!;
|
||||
}
|
||||
}
|
||||
@ -180,6 +181,7 @@ fn void? Ctx.toggle_id(&ctx, Id id, String description, Point off, bool* active)
|
||||
Rect t = elem.bounds.add({*active ? (style.size+3) : +3, +3, -style.size-6, -6});
|
||||
Style s = *style;
|
||||
s.bg = s.primary;
|
||||
s.margin = s.border = s.padding = {};
|
||||
s.margin = s.padding = {};
|
||||
s.border = 0;
|
||||
ctx.push_rect(t, parent.div.z_index, &s)!;
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ enum CmdType {
|
||||
// command to draw a rect
|
||||
struct CmdRect {
|
||||
Rect rect;
|
||||
ushort thickness;
|
||||
ushort radius;
|
||||
Color color;
|
||||
}
|
||||
@ -92,18 +93,19 @@ fn void? Ctx.push_scissor(&ctx, Rect rect, int z_index)
|
||||
|
||||
fn void? Ctx.push_rect(&ctx, Rect rect, int z_index, Style* style)
|
||||
{
|
||||
Rect border = style.border;
|
||||
Rect padding = style.padding;
|
||||
ushort border = style.border;
|
||||
ushort radius = style.radius;
|
||||
Color bg = style.bg;
|
||||
Color border_color = style.secondary;
|
||||
|
||||
if (!border.is_null()) {
|
||||
if (border != 0) {
|
||||
Cmd cmd = {
|
||||
.type = CMD_RECT,
|
||||
.rect.rect = rect,
|
||||
.rect.color = border_color,
|
||||
.rect.radius = radius,
|
||||
.rect.radius = radius+border,
|
||||
.rect.thickness = border,
|
||||
};
|
||||
ctx.push_cmd(&cmd, z_index)!;
|
||||
}
|
||||
@ -111,13 +113,14 @@ fn void? Ctx.push_rect(&ctx, Rect rect, int z_index, Style* style)
|
||||
Cmd cmd = {
|
||||
.type = CMD_RECT,
|
||||
.rect.rect = {
|
||||
.x = rect.x + border.x + padding.x,
|
||||
.y = rect.y + border.y + padding.y,
|
||||
.w = rect.w - (border.x+border.w) - (padding.x+padding.w),
|
||||
.h = rect.h - (border.y+border.h) - (padding.y+padding.h),
|
||||
.x = rect.x + border + padding.x,
|
||||
.y = rect.y + border + padding.y,
|
||||
.h = rect.h - (border*2) - (padding.y+padding.h),
|
||||
.w = rect.w - (border*2) - (padding.x+padding.w),
|
||||
},
|
||||
.rect.color = bg,
|
||||
.rect.radius = radius,
|
||||
.rect.thickness = max(rect.w, rect.h)/2+1,
|
||||
};
|
||||
if (cull_rect(cmd.rect.rect, ctx.div_scissor)) return;
|
||||
ctx.push_cmd(&cmd, z_index)!;
|
||||
|
@ -144,22 +144,22 @@ fn Rect Ctx.position_element(&ctx, Elem *parent, Rect rect, Style* style)
|
||||
child_occupied = child_occupied.off(origin.add(rect.position()));
|
||||
|
||||
Rect margin = style.margin;
|
||||
Rect border = style.border;
|
||||
Rect padding = style.padding;
|
||||
ushort border = style.border;
|
||||
|
||||
// padding, grows both the placement and occupied area
|
||||
child_placement = child_placement.grow(padding.position().add(padding.size()));
|
||||
child_occupied = child_occupied.grow(padding.position().add(padding.size()));
|
||||
// border, grows both the placement and occupied area
|
||||
child_placement = child_placement.grow(border.position().add(border.size()));
|
||||
child_occupied = child_occupied.grow(border.position().add(border.size()));
|
||||
child_placement = child_placement.grow({border*2, border*2});
|
||||
child_occupied = child_occupied.grow({border*2, border*2});
|
||||
// margin, offsets the placement and grows the occupied area
|
||||
child_placement = child_placement.off(margin.position());
|
||||
child_occupied = child_occupied.grow(margin.position().add(margin.size()));
|
||||
|
||||
// oh yeah also adjust the rect if i was to grow
|
||||
if (adapt_x) rect.w -= padding.x+padding.w + border.x+border.w + margin.x+margin.w;
|
||||
if (adapt_y) rect.h -= padding.y+padding.h + border.y+border.h + margin.y+margin.h;
|
||||
if (adapt_x) rect.w -= padding.x+padding.w + border*2 + margin.x+margin.w;
|
||||
if (adapt_y) rect.h -= padding.y+padding.h + border*2 + margin.y+margin.h;
|
||||
|
||||
// set the size
|
||||
child_placement = child_placement.grow(rect.size());
|
||||
|
@ -7,8 +7,10 @@ import std::io;
|
||||
// global style, similar to the css box model
|
||||
struct Style { // css box model
|
||||
Rect padding;
|
||||
Rect border;
|
||||
Rect margin;
|
||||
ushort border;
|
||||
ushort radius;
|
||||
ushort size;
|
||||
|
||||
Color bg; // background color
|
||||
Color fg; // foreground color
|
||||
@ -16,14 +18,12 @@ struct Style { // css box model
|
||||
Color secondary; // secondary color
|
||||
Color accent; // accent color
|
||||
|
||||
ushort radius;
|
||||
short size;
|
||||
}
|
||||
|
||||
const Style DEFAULT_STYLE = {
|
||||
.margin = {2, 2, 2, 2},
|
||||
.border = {2, 2, 2, 2},
|
||||
.padding = {1, 1, 1, 1},
|
||||
.padding = {},
|
||||
.border = 2,
|
||||
.radius = 12,
|
||||
.size = 16,
|
||||
|
||||
@ -89,8 +89,8 @@ fn int Ctx.import_style_from_file(&ctx, String path)
|
||||
* Style can be serialized and deserialized with a subset of CSS
|
||||
* <style name> {
|
||||
* padding: left right top bottom;
|
||||
* border: left right top bottom;
|
||||
* margin: left right top bottoms;
|
||||
* border: uint;
|
||||
* radius: uint;
|
||||
* size: uint;
|
||||
* Color: #RRGGBBAA;
|
||||
@ -331,11 +331,6 @@ fn bool Parser.parse_property(&p)
|
||||
if (p.parse_size(&padding) == false) return false;
|
||||
p.style.padding = padding;
|
||||
|
||||
case "border":
|
||||
Rect border;
|
||||
if (p.parse_size(&border) == false) return false;
|
||||
p.style.border = border;
|
||||
|
||||
case "margin":
|
||||
Rect margin;
|
||||
if (p.parse_size(&margin) == false) return false;
|
||||
@ -366,23 +361,32 @@ fn bool Parser.parse_property(&p)
|
||||
if (p.parse_color(&accent) == false) return false;
|
||||
p.style.accent = accent;
|
||||
|
||||
case "radius":
|
||||
short r;
|
||||
if (p.parse_number(&r) == false) return false;
|
||||
if (r < 0) {
|
||||
io::eprintfn("CSS parsing error at %d:%d: 'radius' must be a positive number, got %d", t.line, t.col, r);
|
||||
case "border":
|
||||
short border;
|
||||
if (p.parse_number(&border) == false) return false;
|
||||
if (border < 0) {
|
||||
io::eprintfn("CSS parsing error at %d:%d: 'border' must be a positive number, got %d", t.line, t.col, border);
|
||||
return false;
|
||||
}
|
||||
p.style.radius = (ushort)r;
|
||||
p.style.border = (ushort)border;
|
||||
|
||||
case "radius":
|
||||
short radius;
|
||||
if (p.parse_number(&radius) == false) return false;
|
||||
if (radius < 0) {
|
||||
io::eprintfn("CSS parsing error at %d:%d: 'radius' must be a positive number, got %d", t.line, t.col, radius);
|
||||
return false;
|
||||
}
|
||||
p.style.radius = (ushort)radius;
|
||||
|
||||
case "size":
|
||||
short s;
|
||||
if (p.parse_number(&s) == false) return false;
|
||||
if (s < 0) {
|
||||
io::eprintfn("CSS parsing error at %d:%d: 'size' must be a positive number, got %d", t.line, t.col, s);
|
||||
short size;
|
||||
if (p.parse_number(&size) == false) return false;
|
||||
if (size < 0) {
|
||||
io::eprintfn("CSS parsing error at %d:%d: 'size' must be a positive number, got %d", t.line, t.col, size);
|
||||
return false;
|
||||
}
|
||||
p.style.size = (ushort)s;
|
||||
p.style.size = (ushort)size;
|
||||
|
||||
|
||||
default:
|
||||
|
@ -7,6 +7,7 @@ layout(set = 3, binding = 0) uniform Viewport {
|
||||
layout(location = 0) in vec4 in_color;
|
||||
layout(location = 1) in vec4 in_quad_size; // x,y, w,h
|
||||
layout(location = 2) in float in_radius;
|
||||
layout(location = 3) in float thickness;
|
||||
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
|
||||
@ -16,12 +17,16 @@ float sdf_rr(vec2 p, vec2 half_size, float radius) {
|
||||
return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - radius;
|
||||
}
|
||||
|
||||
const float smoothness = 0.9;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 centerpoint = in_quad_size.xy + in_quad_size.zw * 0.5;
|
||||
vec2 half_size = in_quad_size.zw * 0.5;
|
||||
float distance = sdf_rr(vec2(gl_FragCoord) - centerpoint, half_size, in_radius);
|
||||
float alpha = 1.0 - smoothstep(0.0, 1.5, distance);
|
||||
float distance = -sdf_rr(vec2(gl_FragCoord) - centerpoint, half_size, in_radius);
|
||||
|
||||
fragColor = vec4(in_color.rgb, in_color.a * alpha);
|
||||
float alpha_out = smoothstep(0.0-smoothness, 0.0, distance);
|
||||
float alpha_in = 1.0 - smoothstep(thickness-smoothness, thickness, distance);
|
||||
|
||||
fragColor = vec4(in_color.rgb, in_color.a * alpha_out * alpha_in);
|
||||
}
|
@ -12,6 +12,7 @@ layout(location = 3) in uvec4 color;
|
||||
layout(location = 0) out vec4 out_color;
|
||||
layout(location = 1) out vec4 out_quad_size;
|
||||
layout(location = 2) out float out_radius;
|
||||
layout(location = 3) out float out_thickness;
|
||||
|
||||
void main()
|
||||
{
|
||||
@ -26,4 +27,5 @@ void main()
|
||||
out_color = vec4(color) / 255.0;
|
||||
out_quad_size = vec4(attr);
|
||||
out_radius = float(abs(uv.x));
|
||||
out_thickness = float(uv.y - uv.x);
|
||||
}
|
||||
|
@ -8,8 +8,7 @@ default {
|
||||
|
||||
button {
|
||||
margin: 2 2 2 2;
|
||||
border: 2 2 2 2;
|
||||
padding: 1 1 1 1;
|
||||
border: 2;
|
||||
radius: 10;
|
||||
|
||||
bg: #3c3836ff;
|
||||
@ -21,8 +20,7 @@ button {
|
||||
|
||||
button-active {
|
||||
margin: 2 2 2 2;
|
||||
border: 2 2 2 2;
|
||||
padding: 1 1 1 1;
|
||||
border: 2;
|
||||
radius: 10;
|
||||
|
||||
bg: #504945ff;
|
||||
@ -34,8 +32,7 @@ button-active {
|
||||
|
||||
checkbox {
|
||||
margin: 2 2 2 2;
|
||||
border: 2 2 2 2;
|
||||
padding: 1 1 1 1;
|
||||
border: 2;
|
||||
radius: 10;
|
||||
size: 16;
|
||||
bg: #3c3836ff;
|
||||
@ -47,9 +44,8 @@ checkbox {
|
||||
|
||||
toggle {
|
||||
margin: 2 2 2 2;
|
||||
border: 2 2 2 2;
|
||||
padding: 1 1 1 1;
|
||||
radius: 10;
|
||||
border: 2;
|
||||
radius: 0;
|
||||
size: 16;
|
||||
bg: #3c3836ff;
|
||||
fg: #fbf1c7ff;
|
||||
@ -60,8 +56,8 @@ toggle {
|
||||
|
||||
slider {
|
||||
margin: 2 2 2 2;
|
||||
padding: 2 2 2 2;
|
||||
border: 1 1 1 1;
|
||||
padding: 4 4 4 4;
|
||||
border: 1;
|
||||
radius: 4;
|
||||
size: 8;
|
||||
bg: #3c3836ff;
|
||||
|
@ -13,6 +13,7 @@ alias Times = ringbuffer::RingBuffer{time::NanoDuration[128]};
|
||||
|
||||
fn void Times.print_stats(×)
|
||||
{
|
||||
if (times.written == 0);
|
||||
time::NanoDuration min, max, avg, x;
|
||||
min = times.get(0);
|
||||
for (usz i = 0; i < times.written; i++) {
|
||||
@ -21,7 +22,7 @@ fn void Times.print_stats(×)
|
||||
if (x > max) { max = x; }
|
||||
avg += x;
|
||||
}
|
||||
avg = (NanoDuration)((ulong)avg/128.0);
|
||||
avg = (NanoDuration)((ulong)avg/times.written);
|
||||
|
||||
io::printfn("min=%s, max=%s, avg=%s", min, max, avg);
|
||||
}
|
||||
@ -32,6 +33,7 @@ struct TimeStats {
|
||||
|
||||
fn TimeStats Times.get_stats(×)
|
||||
{
|
||||
if (times.written == 0) return {};
|
||||
time::NanoDuration min, max, avg, x;
|
||||
min = times.get(0);
|
||||
for (usz i = 0; i < times.written; i++) {
|
||||
@ -40,7 +42,7 @@ fn TimeStats Times.get_stats(×)
|
||||
if (x > max) { max = x; }
|
||||
avg += x;
|
||||
}
|
||||
avg = (NanoDuration)((ulong)avg/128.0);
|
||||
avg = (NanoDuration)((ulong)avg/times.written);
|
||||
|
||||
return {.min = min, .max = max, .avg = avg};
|
||||
}
|
||||
|
@ -651,11 +651,11 @@ fn bool Renderer.push_sprite(&self, short x, short y, short w, short h, short u,
|
||||
return self.map_quad(qa);
|
||||
}
|
||||
|
||||
fn bool Renderer.push_quad(&self, short x, short y, short w, short h, uint color, ushort radius = 0)
|
||||
fn bool Renderer.push_quad(&self, short x, short y, short w, short h, uint color, ushort radius = 0, ushort thickness = 0)
|
||||
{
|
||||
QuadAttributes qa = {
|
||||
.pos = {.x = x, .y = y, .w = w, .h = h},
|
||||
.uv = {.u = radius, .v = radius},
|
||||
.uv = {.u = radius, .v = radius+thickness},
|
||||
.color = color
|
||||
};
|
||||
|
||||
@ -866,7 +866,7 @@ fn void Renderer.render_ugui(&self, CmdQueue* queue)
|
||||
foreach (&c : queue) {
|
||||
if (c.type == CMD_RECT) {
|
||||
CmdRect r = c.rect;
|
||||
self.push_quad(r.rect.x, r.rect.y, r.rect.w, r.rect.h, r.color.to_uint(), r.radius);
|
||||
self.push_quad(r.rect.x, r.rect.y, r.rect.w, r.rect.h, r.color.to_uint(), r.radius, r.thickness);
|
||||
} else if (c.type == CMD_SPRITE) {
|
||||
CmdSprite s = c.sprite;
|
||||
self.push_sprite(s.rect.x, s.rect.y, s.texture_rect.w, s.texture_rect.h, s.texture_rect.x, s.texture_rect.y, s.hue.to_uint());
|
||||
|
Loading…
Reference in New Issue
Block a user