allow widgets to float over their parent's layout

This commit is contained in:
Lephenixnoir 2021-05-13 11:16:16 +02:00
parent d6951295b0
commit 87d6d4eea4
No known key found for this signature in database
GPG key ID: 1BBA026E13FC0495
4 changed files with 46 additions and 13 deletions

View file

@ -87,8 +87,10 @@ typedef struct jwidget {
uint update :1; uint update :1;
/* Whether widget is visible inside its parent */ /* Whether widget is visible inside its parent */
uint visible :1; uint visible :1;
/* Widget is floating outside the layout (and positioned manually) */
uint floating :1;
uint :24; uint :23;
} jwidget; } jwidget;
@ -329,6 +331,14 @@ int jwidget_content_height(void *w);
int jwidget_full_width(void *w); int jwidget_full_width(void *w);
int jwidget_full_height(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 // Rendering
//--- //---

View file

@ -280,7 +280,7 @@ void jlayout_box_apply(void *w0)
/* Determine natural length along the container, and stretch child /* Determine natural length along the container, and stretch child
along the perpendicular direction if possible */ along the perpendicular direction if possible */
if(!child->visible) { if(!child->visible || child->floating) {
elements[i].stretch = 0; elements[i].stretch = 0;
elements[i].max = 0; elements[i].max = 0;
continue; continue;
@ -320,7 +320,7 @@ void jlayout_box_apply(void *w0)
for(size_t i = 0; i < n; i++) { for(size_t i = 0; i < n; i++) {
exp_t *e = &elements[i]; exp_t *e = &elements[i];
jwidget *child = w->children[e->id]; jwidget *child = w->children[e->id];
if(!child->visible) continue; if(!child->visible || child->floating) continue;
if(horiz) if(horiz)
child->w += e->allocated; child->w += e->allocated;
@ -333,7 +333,7 @@ void jlayout_box_apply(void *w0)
for(size_t i = 0; i < n; i++) { for(size_t i = 0; i < n; i++) {
jwidget *child = w->children[i]; jwidget *child = w->children[i];
if(!child->visible) continue; if(!child->visible || child->floating) continue;
if(horiz) { if(horiz) {
child->x = position; child->x = position;

View file

@ -45,6 +45,7 @@ void jlayout_stack_apply(void *w0)
for(int k = 0; k < w->child_count; k++) { for(int k = 0; k < w->child_count; k++) {
jwidget *child = w->children[k]; jwidget *child = w->children[k];
if(!child->visible || child->floating) continue;
/* Maximum size to enforce: this is the acceptable size closest to our /* Maximum size to enforce: this is the acceptable size closest to our
content size (that space we have to distribute) */ content size (that space we have to distribute) */

View file

@ -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 there is a stack layout, render active child */
if((l = jlayout_get_stack(w)) && l->active >= 0) { if((l = jlayout_get_stack(w)) && l->active >= 0) {
jwidget *child = w->children[l->active]; 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 */ /* Otherwise, simply render all non-floating children */
else { else for(int k = 0; k < w->child_count; k++) {
for(int k = 0; k < w->child_count; k++) { jwidget *child = w->children[k];
jwidget *child = w->children[k]; if(child->visible)// && !child->floating)
if(child->visible) jwidget_render(child, x+child->x, y+child->y); 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) J_CAST(w)
if(w->visible == visible) return; if(w->visible == visible) return;
w->visible = visible; w->visible = (visible != 0);
if(w->parent) w->parent->dirty = 1; if(w->parent) w->parent->dirty = 1;
} }
@ -476,7 +483,7 @@ static void jwidget_layout_apply(void *w0)
if(!w->visible) return; if(!w->visible) return;
int t = w->layout; int t = w->layout;
if(t == J_LAYOUT_NONE) { if(t == J_LAYOUT_NONE || w->floating) {
jwidget_poly const *poly = widget_types[w->type]; jwidget_poly const *poly = widget_types[w->type];
if(poly->layout) poly->layout(w); if(poly->layout) poly->layout(w);
} }
@ -549,6 +556,21 @@ int jwidget_full_height(void *w0)
return w->h; 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 // Rendering
//--- //---