Skip to content

Commit 4ba6aef

Browse files
[wip] Take border size into account when doing layout. Border now takes space in the layout flow of the parent, and extends _around_ box's content (as defined by OC_UI_WIDTH/OC_UI_HEIGHT attributes)
1 parent 0f01366 commit 4ba6aef

File tree

5 files changed

+77
-44
lines changed

5 files changed

+77
-44
lines changed

samples/ui/src/main.c

+1
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ ORCA_EXPORT void oc_on_frame_refresh(void)
267267
oc_ui_style_set_i32(OC_UI_AXIS, OC_UI_AXIS_X);
268268
oc_ui_style_set_i32(OC_UI_ALIGN_Y, OC_UI_ALIGN_CENTER);
269269
oc_ui_style_set_f32(OC_UI_SPACING, 8);
270+
oc_ui_style_set_f32(OC_UI_MARGIN_X, 2);
270271

271272
//-------------------------------------------------------------------------
272273
// Checkbox

sketches/ui-bench/main.c

+18
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,24 @@ i32 ui_runloop(void* user)
116116
oc_ui_style_set_color(OC_UI_BG_COLOR, (oc_color){ 1, 0, 0, 1 });
117117
}
118118

119+
oc_ui_box("outer-box")
120+
{
121+
oc_ui_style_set_size(OC_UI_WIDTH, (oc_ui_size){ OC_UI_SIZE_PIXELS, 200 });
122+
oc_ui_style_set_size(OC_UI_HEIGHT, (oc_ui_size){ OC_UI_SIZE_PIXELS, 200 });
123+
oc_ui_style_set_color(OC_UI_BG_COLOR, (oc_color){ 1, 0, 0, 1 });
124+
125+
// oc_ui_style_set_i32(OC_UI_ALIGN_Y, OC_UI_ALIGN_CENTER);
126+
127+
oc_ui_box("inner-box")
128+
{
129+
oc_ui_style_set_size(OC_UI_WIDTH, (oc_ui_size){ OC_UI_SIZE_PIXELS, 100 });
130+
oc_ui_style_set_size(OC_UI_HEIGHT, (oc_ui_size){ OC_UI_SIZE_PIXELS, 100 });
131+
132+
oc_ui_style_set_color(OC_UI_BG_COLOR, (oc_color){ 0, 1, 0, 1 });
133+
oc_ui_style_set_color(OC_UI_BORDER_COLOR, (oc_color){ 0, 0, 1, 0.5 });
134+
oc_ui_style_set_f32(OC_UI_BORDER_SIZE, 50);
135+
}
136+
}
119137
oc_ui_box("container")
120138
{
121139
oc_ui_style_set_size(OC_UI_WIDTH, (oc_ui_size){ OC_UI_SIZE_CHILDREN });

src/graphics/graphics_common.c

+10-2
Original file line numberDiff line numberDiff line change
@@ -1743,8 +1743,16 @@ void oc_rectangle_fill(f32 x, f32 y, f32 w, f32 h)
17431743

17441744
void oc_rectangle_stroke(f32 x, f32 y, f32 w, f32 h)
17451745
{
1746-
oc_rectangle_path(x, y, w, h);
1747-
oc_stroke();
1746+
oc_canvas_context_data* context = oc_currentCanvasContext;
1747+
if(context)
1748+
{
1749+
f32 oldExcursion = context->attributes.maxJointExcursion;
1750+
context->attributes.maxJointExcursion = 2 * context->attributes.width;
1751+
oc_rectangle_path(x, y, w, h);
1752+
oc_stroke();
1753+
1754+
context->attributes.maxJointExcursion = oldExcursion;
1755+
}
17481756
}
17491757

17501758
void oc_rounded_rectangle_path(f32 x, f32 y, f32 w, f32 h, f32 r)

src/ui/ui.c

+38-24
Original file line numberDiff line numberDiff line change
@@ -2435,11 +2435,11 @@ void oc_ui_layout_downward_dependent_size(oc_ui_context* ui, oc_ui_box* box, int
24352435
if(box->style.layout.axis == axis)
24362436
{
24372437
count++;
2438-
minSum += child->minSize[axis];
2438+
minSum += child->minSize[axis] + 2 * child->style.borderSize;
24392439
}
24402440
else
24412441
{
2442-
minSum = oc_max(minSum, child->minSize[axis]);
2442+
minSum = oc_max(minSum, child->minSize[axis] + 2 * child->style.borderSize);
24432443
}
24442444
}
24452445
}
@@ -2480,7 +2480,7 @@ void oc_ui_layout_downward_dependent_size(oc_ui_context* ui, oc_ui_box* box, int
24802480
{
24812481
if(oc_ui_layout_downward_dependency(child, axis))
24822482
{
2483-
sum += child->rect.c[2 + axis];
2483+
sum += child->rect.c[2 + axis] + 2 * child->style.borderSize;
24842484
}
24852485
}
24862486
}
@@ -2490,12 +2490,11 @@ void oc_ui_layout_downward_dependent_size(oc_ui_context* ui, oc_ui_box* box, int
24902490
{
24912491
if(oc_ui_layout_downward_dependency(child, axis))
24922492
{
2493-
sum = oc_max(sum, child->rect.c[2 + axis]);
2493+
sum = oc_max(sum, child->rect.c[2 + axis] + 2 * child->style.borderSize);
24942494
}
24952495
}
24962496
}
2497-
f32 margin = box->style.layout.margin.c[axis];
2498-
box->rect.c[2 + axis] = sum + box->spacing[axis] + 2 * margin;
2497+
box->rect.c[2 + axis] = sum + box->spacing[axis] + 2 * box->style.layout.margin.c[axis];
24992498
}
25002499
}
25012500

@@ -2511,11 +2510,11 @@ void oc_ui_layout_upward_dependent_size(oc_ui_context* ui, oc_ui_box* box, int a
25112510
oc_ui_size* size = &child->style.size.c[axis];
25122511
if(size->kind == OC_UI_SIZE_PARENT)
25132512
{
2514-
child->rect.c[2 + axis] = oc_max(child->minSize[axis], availableSize * size->value);
2513+
child->rect.c[2 + axis] = oc_max(child->minSize[axis], availableSize * size->value) - 2 * child->style.borderSize;
25152514
}
25162515
else if(size->kind == OC_UI_SIZE_PARENT_MINUS_PIXELS)
25172516
{
2518-
child->rect.c[2 + axis] = oc_max(child->minSize[axis], oc_max(0, availableSize - size->value));
2517+
child->rect.c[2 + axis] = oc_max(child->minSize[axis], oc_max(0, availableSize - size->value)) - 2 * child->style.borderSize;
25192518
}
25202519
}
25212520

@@ -2552,7 +2551,7 @@ void oc_ui_layout_upward_dependent_size(oc_ui_context* ui, oc_ui_box* box, int a
25522551
if(!oc_ui_box_hidden(child)
25532552
&& !child->style.floating.c[axis])
25542553
{
2555-
sum += child->rect.c[2 + axis];
2554+
sum += child->rect.c[2 + axis] + 2 * child->style.borderSize;
25562555
slack += oc_min(child->rect.c[2 + axis] * child->style.size.c[axis].relax,
25572556
child->rect.c[2 + axis] - child->minSize[axis]);
25582557
}
@@ -2615,11 +2614,11 @@ void oc_ui_layout_upward_dependent_size(oc_ui_context* ui, oc_ui_box* box, int a
26152614
{
26162615
if(box->style.layout.axis == axis)
26172616
{
2618-
sum += child->rect.c[2 + axis];
2617+
sum += child->rect.c[2 + axis] + 2 * child->style.borderSize;
26192618
}
26202619
else
26212620
{
2622-
sum = oc_max(sum, child->rect.c[2 + axis]);
2621+
sum = oc_max(sum, child->rect.c[2 + axis] + 2 * child->style.borderSize);
26232622
}
26242623
}
26252624
}
@@ -2634,6 +2633,7 @@ void oc_ui_layout_upward_dependent_size(oc_ui_context* ui, oc_ui_box* box, int a
26342633
box->minSize[axis]);
26352634
}
26362635

2636+
/*
26372637
void oc_ui_layout_upward_dependent_fixup(oc_ui_context* ui, oc_ui_box* box, int axis)
26382638
{
26392639
f32 margin = box->style.layout.margin.c[axis];
@@ -2710,6 +2710,7 @@ void oc_ui_layout_upward_dependent_fixup(oc_ui_context* ui, oc_ui_box* box, int
27102710
oc_ui_layout_upward_dependent_fixup(ui, child, axis);
27112711
}
27122712
}
2713+
*/
27132714

27142715
void oc_ui_layout_compute_rect(oc_ui_context* ui, oc_ui_box* box, oc_vec2 pos)
27152716
{
@@ -2718,8 +2719,8 @@ void oc_ui_layout_compute_rect(oc_ui_context* ui, oc_ui_box* box, oc_vec2 pos)
27182719
return;
27192720
}
27202721

2721-
box->rect.x = pos.x;
2722-
box->rect.y = pos.y;
2722+
box->rect.x = pos.x + box->style.borderSize;
2723+
box->rect.y = pos.y + box->style.borderSize;
27232724
box->z = ui->z;
27242725
ui->z++;
27252726

@@ -2729,12 +2730,16 @@ void oc_ui_layout_compute_rect(oc_ui_context* ui, oc_ui_box* box, oc_vec2 pos)
27292730

27302731
oc_ui_align* align = box->style.layout.align.c;
27312732

2732-
oc_vec2 origin = { box->rect.x,
2733-
box->rect.y };
2733+
oc_vec2 origin = {
2734+
box->rect.x,
2735+
box->rect.y,
2736+
};
27342737
oc_vec2 currentPos = origin;
27352738

2736-
oc_vec2 margin = { box->style.layout.margin.x,
2737-
box->style.layout.margin.y };
2739+
oc_vec2 margin = {
2740+
box->style.layout.margin.x,
2741+
box->style.layout.margin.y,
2742+
};
27382743

27392744
currentPos.x += margin.x;
27402745
currentPos.y += margin.y;
@@ -2759,7 +2764,7 @@ void oc_ui_layout_compute_rect(oc_ui_context* ui, oc_ui_box* box, oc_vec2 pos)
27592764
{
27602765
if(align[secondAxis] == OC_UI_ALIGN_CENTER)
27612766
{
2762-
currentPos.c[secondAxis] = origin.c[secondAxis] + 0.5 * (box->rect.c[2 + secondAxis] - child->rect.c[2 + secondAxis]);
2767+
currentPos.c[secondAxis] = origin.c[secondAxis] + 0.5 * (box->rect.c[2 + secondAxis] - child->rect.c[2 + secondAxis] - 2 * child->style.borderSize);
27632768
}
27642769

27652770
oc_vec2 childPos = currentPos;
@@ -2785,7 +2790,7 @@ void oc_ui_layout_compute_rect(oc_ui_context* ui, oc_ui_box* box, oc_vec2 pos)
27852790

27862791
if(!child->style.floating.c[layoutAxis])
27872792
{
2788-
currentPos.c[layoutAxis] += child->rect.c[2 + layoutAxis] + spacing;
2793+
currentPos.c[layoutAxis] += child->rect.c[2 + layoutAxis] + 2 * child->style.borderSize + spacing;
27892794
}
27902795
}
27912796
if(isnan(box->rect.w) || isnan(box->rect.h))
@@ -2895,10 +2900,10 @@ void oc_ui_draw_box(oc_ui_box* box)
28952900
{
28962901
oc_rect clipRect = oc_clip_top();
28972902
oc_rect expRect = {
2898-
box->rect.x - 0.5 * style->borderSize,
2899-
box->rect.y - 0.5 * style->borderSize,
2900-
box->rect.w + style->borderSize,
2901-
box->rect.h + style->borderSize
2903+
box->rect.x - style->borderSize,
2904+
box->rect.y - style->borderSize,
2905+
box->rect.w + 2 * style->borderSize,
2906+
box->rect.h + 2 * style->borderSize
29022907
};
29032908

29042909
if((expRect.x + expRect.w < clipRect.x)
@@ -3009,7 +3014,16 @@ void oc_ui_draw_box(oc_ui_box* box)
30093014
{
30103015
oc_set_width(style->borderSize);
30113016
oc_set_color(style->borderColor);
3012-
oc_ui_rectangle_stroke(box->rect, style->roundness);
3017+
3018+
oc_rect rect = {
3019+
box->rect.x - 0.5 * style->borderSize,
3020+
box->rect.y - 0.5 * style->borderSize,
3021+
box->rect.w + style->borderSize,
3022+
box->rect.h + style->borderSize,
3023+
};
3024+
f32 roundness = style->roundness ? style->roundness + style->borderSize : 0;
3025+
3026+
oc_ui_rectangle_stroke(rect, roundness);
30133027
}
30143028
}
30153029

src/ui/widgets.c

+10-18
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ oc_ui_sig oc_ui_checkbox_str8(oc_str8 name, bool* checked)
142142
oc_ui_style_set_size(OC_UI_WIDTH, (oc_ui_size){ OC_UI_SIZE_PIXELS, 16 });
143143
oc_ui_style_set_size(OC_UI_HEIGHT, (oc_ui_size){ OC_UI_SIZE_PIXELS, 16 });
144144
oc_ui_style_set_var_str8(OC_UI_ROUNDNESS, OC_UI_THEME_ROUNDNESS_SMALL);
145+
oc_ui_style_set_f32(OC_UI_BORDER_SIZE, 1.);
145146

146147
if(*checked)
147148
{
@@ -160,7 +161,6 @@ oc_ui_sig oc_ui_checkbox_str8(oc_str8 name, bool* checked)
160161
else
161162
{
162163
oc_ui_style_set_var_str8(OC_UI_BORDER_COLOR, OC_UI_THEME_TEXT_3);
163-
oc_ui_style_set_f32(OC_UI_BORDER_SIZE, 1.);
164164

165165
oc_ui_style_rule(".hover")
166166
{
@@ -204,14 +204,16 @@ oc_ui_box* oc_ui_slider_str8(oc_str8 name, f32* value)
204204
oc_ui_style_set_size(OC_UI_WIDTH, (oc_ui_size){ OC_UI_SIZE_PIXELS, 100 });
205205
oc_ui_style_set_size(OC_UI_HEIGHT, (oc_ui_size){ OC_UI_SIZE_PIXELS, 24 });
206206

207-
//NOTE: don't clip thumb's borders
208-
oc_ui_style_set_i32(OC_UI_OVERFLOW_X, OC_UI_OVERFLOW_ALLOW);
209-
oc_ui_style_set_i32(OC_UI_OVERFLOW_Y, OC_UI_OVERFLOW_ALLOW);
210-
211207
oc_rect frameRect = frame->rect;
212208
oc_ui_axis trackAxis = (frameRect.w > frameRect.h) ? OC_UI_AXIS_X : OC_UI_AXIS_Y;
213209
oc_ui_axis secondAxis = (trackAxis == OC_UI_AXIS_Y) ? OC_UI_AXIS_X : OC_UI_AXIS_Y;
214210

211+
oc_ui_style_set_i32(OC_UI_ALIGN_X + secondAxis, OC_UI_ALIGN_CENTER);
212+
213+
//NOTE: don't clip thumb border
214+
oc_ui_style_set_i32(OC_UI_OVERFLOW_X, OC_UI_OVERFLOW_ALLOW);
215+
oc_ui_style_set_i32(OC_UI_OVERFLOW_Y, OC_UI_OVERFLOW_ALLOW);
216+
215217
f32 trackThickness = 4;
216218
f32 thumbSize = 24;
217219

@@ -377,10 +379,6 @@ oc_ui_radio_group_info oc_ui_radio_group_str8(oc_str8 name, oc_ui_radio_group_in
377379
oc_ui_style_set_i32(OC_UI_AXIS, OC_UI_AXIS_Y);
378380
oc_ui_style_set_var_str8(OC_UI_SPACING, OC_UI_THEME_SPACING_REGULAR_TIGHT);
379381

380-
//NOTE: don't clip children borders
381-
oc_ui_style_set_i32(OC_UI_OVERFLOW_X, OC_UI_OVERFLOW_ALLOW);
382-
oc_ui_style_set_i32(OC_UI_OVERFLOW_Y, OC_UI_OVERFLOW_ALLOW);
383-
384382
for(int i = 0; i < info->optionCount; i++)
385383
{
386384
oc_ui_box* row = oc_ui_box_str8(info->options[i])
@@ -392,21 +390,16 @@ oc_ui_radio_group_info oc_ui_radio_group_str8(oc_str8 name, oc_ui_radio_group_in
392390

393391
oc_ui_style_set_i32(OC_UI_AXIS, OC_UI_AXIS_X);
394392
oc_ui_style_set_var_str8(OC_UI_SPACING, OC_UI_THEME_SPACING_TIGHT);
395-
oc_ui_style_set_f32(OC_UI_MARGIN_X, 1);
396-
oc_ui_style_set_f32(OC_UI_MARGIN_Y, 1);
397393
oc_ui_style_set_i32(OC_UI_ALIGN_Y, OC_UI_ALIGN_CENTER);
398394

399-
//NOTE: don't clip children borders
400-
oc_ui_style_set_i32(OC_UI_OVERFLOW_X, OC_UI_OVERFLOW_ALLOW);
401-
oc_ui_style_set_i32(OC_UI_OVERFLOW_Y, OC_UI_OVERFLOW_ALLOW);
402-
403395
oc_ui_box* radio = oc_ui_box("radio")
404396
{
405397
oc_ui_box_set_draw_proc(radio, oc_ui_radio_indicator_draw, 0);
406398

407399
oc_ui_style_set_size(OC_UI_WIDTH, (oc_ui_size){ OC_UI_SIZE_PIXELS, 16 });
408400
oc_ui_style_set_size(OC_UI_HEIGHT, (oc_ui_size){ OC_UI_SIZE_PIXELS, 16 });
409401
oc_ui_style_set_f32(OC_UI_ROUNDNESS, 8);
402+
oc_ui_style_set_f32(OC_UI_BORDER_SIZE, 1);
410403

411404
oc_ui_style_set_i32(OC_UI_CLICK_THROUGH, 1);
412405

@@ -436,7 +429,6 @@ oc_ui_radio_group_info oc_ui_radio_group_str8(oc_str8 name, oc_ui_radio_group_in
436429
else
437430
{
438431
oc_ui_style_set_var_str8(OC_UI_BORDER_COLOR, OC_UI_THEME_TEXT_3);
439-
oc_ui_style_set_f32(OC_UI_BORDER_SIZE, 1);
440432

441433
if(oc_ui_box_hot(radio))
442434
{
@@ -810,6 +802,7 @@ oc_ui_select_popup_info oc_ui_select_popup_str8(oc_str8 key, oc_ui_select_popup_
810802
oc_ui_style_set_f32(OC_UI_MARGIN_Y, 6);
811803
oc_ui_style_set_var_str8(OC_UI_BG_COLOR, OC_UI_THEME_FILL_0);
812804
oc_ui_style_set_var_str8(OC_UI_ROUNDNESS, OC_UI_THEME_ROUNDNESS_SMALL);
805+
oc_ui_style_set_f32(OC_UI_BORDER_SIZE, 1);
813806

814807
oc_ui_style_rule("button.hover")
815808
{
@@ -818,7 +811,6 @@ oc_ui_select_popup_info oc_ui_select_popup_str8(oc_str8 key, oc_ui_select_popup_
818811
oc_ui_style_rule("button.active")
819812
{
820813
oc_ui_style_set_var_str8(OC_UI_BORDER_COLOR, OC_UI_THEME_PRIMARY);
821-
oc_ui_style_set_f32(OC_UI_BORDER_SIZE, 1);
822814
}
823815
oc_ui_style_rule("button.hover.active")
824816
{
@@ -1812,6 +1804,7 @@ oc_ui_text_box_result oc_ui_text_box_str8(oc_str8 key, oc_arena* arena, oc_ui_te
18121804
oc_ui_style_set_f32(OC_UI_MARGIN_Y, 6);
18131805
oc_ui_style_set_var_str8(OC_UI_BG_COLOR, OC_UI_THEME_FILL_0);
18141806
oc_ui_style_set_var_str8(OC_UI_ROUNDNESS, OC_UI_THEME_ROUNDNESS_SMALL);
1807+
oc_ui_style_set_f32(OC_UI_BORDER_SIZE, 1);
18151808

18161809
oc_ui_style_set_var_str8(OC_UI_COLOR, OC_UI_THEME_TEXT_0);
18171810
oc_ui_style_set_var_str8(OC_UI_TEXT_SIZE, OC_UI_THEME_TEXT_SIZE_REGULAR);
@@ -1825,7 +1818,6 @@ oc_ui_text_box_result oc_ui_text_box_str8(oc_str8 key, oc_arena* arena, oc_ui_te
18251818
oc_ui_style_rule(".text-box.active")
18261819
{
18271820
oc_ui_style_set_var_str8(OC_UI_BORDER_COLOR, OC_UI_THEME_PRIMARY);
1828-
oc_ui_style_set_f32(OC_UI_BORDER_SIZE, 1);
18291821
}
18301822
oc_ui_style_rule(".text-box.dragging")
18311823
{

0 commit comments

Comments
 (0)