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;
/* 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
//---

View file

@ -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;

View file

@ -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) */

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((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
//---