diff --git a/include/justui/jwidget.h b/include/justui/jwidget.h index 5aa0b61..d784d03 100644 --- a/include/justui/jwidget.h +++ b/include/justui/jwidget.h @@ -87,8 +87,10 @@ typedef struct jwidget { uint update :1; /* Whether widget is visible inside its parent */ uint visible :1; + /* Widget is floating outside the layout (and positioned manually) */ + uint floating :1; - uint :24; + uint :23; } jwidget; @@ -329,6 +331,14 @@ int jwidget_content_height(void *w); int jwidget_full_width(void *w); int jwidget_full_height(void *w); +/* jwidget_floating(): Whether widget is floating + A floating widget is not laid out by its parent's layout, and can be + positioned manually. Floating children are rendered after other children. */ +bool jwidget_floating(void *w); + +/* jwidget_set_floating(): Make a widget floating or non-floating */ +void jwidget_set_floating(void *w, bool floating); + //--- // Rendering //--- diff --git a/src/jlayout_box.c b/src/jlayout_box.c index 539961e..1315e2e 100644 --- a/src/jlayout_box.c +++ b/src/jlayout_box.c @@ -280,7 +280,7 @@ void jlayout_box_apply(void *w0) /* Determine natural length along the container, and stretch child along the perpendicular direction if possible */ - if(!child->visible) { + if(!child->visible || child->floating) { elements[i].stretch = 0; elements[i].max = 0; continue; @@ -320,7 +320,7 @@ void jlayout_box_apply(void *w0) for(size_t i = 0; i < n; i++) { exp_t *e = &elements[i]; jwidget *child = w->children[e->id]; - if(!child->visible) continue; + if(!child->visible || child->floating) continue; if(horiz) child->w += e->allocated; @@ -333,7 +333,7 @@ void jlayout_box_apply(void *w0) for(size_t i = 0; i < n; i++) { jwidget *child = w->children[i]; - if(!child->visible) continue; + if(!child->visible || child->floating) continue; if(horiz) { child->x = position; diff --git a/src/jlayout_stack.c b/src/jlayout_stack.c index 6e1d893..5dafc0a 100644 --- a/src/jlayout_stack.c +++ b/src/jlayout_stack.c @@ -45,6 +45,7 @@ void jlayout_stack_apply(void *w0) for(int k = 0; k < w->child_count; k++) { jwidget *child = w->children[k]; + if(!child->visible || child->floating) continue; /* Maximum size to enforce: this is the acceptable size closest to our content size (that space we have to distribute) */ diff --git a/src/jwidget.c b/src/jwidget.c index 5b5a6fc..a6dc23c 100644 --- a/src/jwidget.c +++ b/src/jwidget.c @@ -48,14 +48,21 @@ static void jwidget_poly_render(void *w0, int x, int y) /* If there is a stack layout, render active child */ if((l = jlayout_get_stack(w)) && l->active >= 0) { jwidget *child = w->children[l->active]; - if(child->visible) jwidget_render(child, x+child->x, y+child->y); + if(child->visible && !child->floating) + jwidget_render(child, x+child->x, y+child->y); } - /* Otherwise, simply render all children */ - else { - for(int k = 0; k < w->child_count; k++) { - jwidget *child = w->children[k]; - if(child->visible) jwidget_render(child, x+child->x, y+child->y); - } + /* Otherwise, simply render all non-floating children */ + else for(int k = 0; k < w->child_count; k++) { + jwidget *child = w->children[k]; + if(child->visible)// && !child->floating) + jwidget_render(child, x+child->x, y+child->y); + } + + /* Render floating widgets over the layout */ + for(int k = 0; k < w->child_count; k++) { + jwidget *child = w->children[k]; + if(child->visible && child->floating) + jwidget_render(child, x+child->x, y+child->y); } } @@ -447,7 +454,7 @@ void jwidget_set_visible(void *w0, bool visible) J_CAST(w) if(w->visible == visible) return; - w->visible = visible; + w->visible = (visible != 0); if(w->parent) w->parent->dirty = 1; } @@ -476,7 +483,7 @@ static void jwidget_layout_apply(void *w0) if(!w->visible) return; int t = w->layout; - if(t == J_LAYOUT_NONE) { + if(t == J_LAYOUT_NONE || w->floating) { jwidget_poly const *poly = widget_types[w->type]; if(poly->layout) poly->layout(w); } @@ -549,6 +556,21 @@ int jwidget_full_height(void *w0) return w->h; } +bool jwidget_floating(void *w0) +{ + J_CAST(w) + return w->floating; +} + +void jwidget_set_floating(void *w0, bool floating) +{ + J_CAST(w) + if(w->floating == floating) return; + + w->floating = (floating != 0); + if(w->parent) w->parent->dirty = 1; +} + //--- // Rendering //---