diff --git a/src/ui.c b/src/ui.c index ad0bd93..675ac9f 100644 --- a/src/ui.c +++ b/src/ui.c @@ -36,6 +36,7 @@ typedef struct ui_style_attr mg_color color; mg_font font; f32 value; + u32 flags; }; } ui_style_attr; @@ -84,6 +85,7 @@ typedef struct ui_context ui_stack_elt* borderSizeStack; ui_stack_elt* roundnessStack; ui_stack_elt* animationTimeStack; + ui_stack_elt* animationFlagsStack; u32 z; ui_box* hovered; @@ -256,6 +258,7 @@ UI_STYLE_STACK_OP_DEF(font_size, fontSizeStack, f32, value) UI_STYLE_STACK_OP_DEF(border_size, borderSizeStack, f32, value) UI_STYLE_STACK_OP_DEF(roundness, roundnessStack, f32, value) UI_STYLE_STACK_OP_DEF(animation_time, animationTimeStack, f32, value) +UI_STYLE_STACK_OP_DEF(animation_flags, animationFlagsStack, u32, flags) ui_style_attr* ui_style_attr_query(ui_stack_elt* stack, ui_style_tag tag, ui_style_selector selector) { @@ -317,6 +320,20 @@ f32 ui_style_float_query(ui_stack_elt* stack, ui_style_tag tag, ui_style_selecto } } +u32 ui_style_flags_query(ui_stack_elt* stack, ui_style_tag tag, ui_style_selector selector) +{ + ui_style_attr* attr = ui_style_attr_query(stack, tag, selector); + if(attr) + { + return(attr->flags); + } + else + { + return(0); + } +} + + ui_size ui_style_size_query(ui_stack_elt* stack, ui_style_tag tag, ui_style_selector selector) { ui_style_attr* attr = ui_style_attr_query(stack, tag, selector); @@ -345,6 +362,7 @@ ui_style* ui_collate_style(ui_context* context, ui_style_tag tag, ui_style_selec style->borderSize = ui_style_float_query(context->borderSizeStack, tag, selector); style->roundness = ui_style_float_query(context->roundnessStack, tag, selector); style->animationTime = ui_style_float_query(context->animationTimeStack, tag, selector); + style->animationFlags = ui_style_flags_query(context->animationFlagsStack, tag, selector); return(style); } @@ -589,7 +607,7 @@ void ui_box_set_size(ui_box* box, ui_axis axis, ui_size_kind kind, f32 value, f3 void ui_box_set_floating(ui_box* box, ui_axis axis, f32 pos) { box->floating[axis] = true; - box->targetRect.c[axis] = pos; + box->floatTarget.c[axis] = pos; } void ui_box_set_closed(ui_box* box, bool closed) @@ -689,15 +707,71 @@ void ui_box_compute_styling(ui_context* ui, ui_box* box) box->computedStyle.size[UI_AXIS_Y] = targetStyle->size[UI_AXIS_Y]; //TODO: interpolate based on transition values - ui_animate_color(ui, &box->computedStyle.bgColor, targetStyle->bgColor, animationTime); - ui_animate_color(ui, &box->computedStyle.fgColor, targetStyle->fgColor, animationTime); - ui_animate_color(ui, &box->computedStyle.borderColor, targetStyle->borderColor, animationTime); - ui_animate_color(ui, &box->computedStyle.fontColor, targetStyle->fontColor, animationTime); + u32 flags = box->computedStyle.animationFlags; + if(flags & UI_STYLE_ANIMATE_BG_COLOR) + { + ui_animate_color(ui, &box->computedStyle.bgColor, targetStyle->bgColor, animationTime); + } + else + { + box->computedStyle.bgColor = targetStyle->bgColor; + } + + if(flags & UI_STYLE_ANIMATE_FG_COLOR) + { + ui_animate_color(ui, &box->computedStyle.fgColor, targetStyle->fgColor, animationTime); + } + else + { + box->computedStyle.fgColor = targetStyle->fgColor; + } + + if(flags & UI_STYLE_ANIMATE_BORDER_COLOR) + { + ui_animate_color(ui, &box->computedStyle.borderColor, targetStyle->borderColor, animationTime); + } + else + { + box->computedStyle.borderColor = targetStyle->borderColor; + } + + if(flags & UI_STYLE_ANIMATE_FONT_COLOR) + { + ui_animate_color(ui, &box->computedStyle.fontColor, targetStyle->fontColor, animationTime); + } + else + { + box->computedStyle.fontColor = targetStyle->fontColor; + } + + if(flags & UI_STYLE_ANIMATE_FONT_SIZE) + { + ui_animate_f32(ui, &box->computedStyle.fontSize, targetStyle->fontSize, animationTime); + } + else + { + box->computedStyle.fontSize = targetStyle->fontSize; + } + + if(flags & UI_STYLE_ANIMATE_BORDER_SIZE) + { + ui_animate_f32(ui, &box->computedStyle.borderSize, targetStyle->borderSize, animationTime); + } + else + { + box->computedStyle.borderSize = targetStyle->borderSize; + } + + if(flags & UI_STYLE_ANIMATE_ROUNDNESS) + { + ui_animate_f32(ui, &box->computedStyle.roundness, targetStyle->roundness, animationTime); + } + else + { + box->computedStyle.roundness = targetStyle->roundness; + } box->computedStyle.font = targetStyle->font; - ui_animate_f32(ui, &box->computedStyle.fontSize, targetStyle->fontSize, animationTime); - ui_animate_f32(ui, &box->computedStyle.borderSize, targetStyle->borderSize, animationTime); - ui_animate_f32(ui, &box->computedStyle.roundness, targetStyle->roundness, animationTime); } void ui_layout_prepass(ui_context* ui, ui_box* box) @@ -728,11 +802,11 @@ void ui_layout_prepass(ui_context* ui, ui_box* box) if(size.kind == UI_SIZE_TEXT) { - box->targetRect.c[2+i] = textBox.c[2+i] + desiredSize[i].value*2; + box->rect.c[2+i] = textBox.c[2+i] + desiredSize[i].value*2; } else if(size.kind == UI_SIZE_PIXELS) { - box->targetRect.c[2+i] = size.value; + box->rect.c[2+i] = size.value; } } @@ -757,7 +831,7 @@ void ui_layout_upward_dependent_size(ui_context* ui, ui_box* box, int axis) if( parent && parent->computedStyle.size[axis].kind != UI_SIZE_CHILDREN) { - box->targetRect.c[2+axis] = parent->targetRect.c[2+axis] * size->value; + box->rect.c[2+axis] = parent->rect.c[2+axis] * size->value; } //TODO else? } @@ -780,7 +854,7 @@ void ui_layout_downward_dependent_size(ui_context* ui, ui_box* box, int axis) ui_layout_downward_dependent_size(ui, child, axis); if(!child->floating[axis]) { - sum += child->targetRect.c[2+axis]; + sum += child->rect.c[2+axis]; } } } @@ -794,7 +868,7 @@ void ui_layout_downward_dependent_size(ui_context* ui, ui_box* box, int axis) ui_layout_downward_dependent_size(ui, child, axis); if(!child->floating[axis]) { - sum = maximum(sum, child->targetRect.c[2+axis]); + sum = maximum(sum, child->rect.c[2+axis]); } } } @@ -805,7 +879,7 @@ void ui_layout_downward_dependent_size(ui_context* ui, ui_box* box, int axis) ui_size* size = &box->computedStyle.size[axis]; if(size->kind == UI_SIZE_CHILDREN) { - box->targetRect.c[2+axis] = sum + size->value*2; + box->rect.c[2+axis] = sum + size->value*2; } } @@ -821,8 +895,8 @@ void ui_layout_compute_rect(ui_context* ui, ui_box* box, vec2 pos) return; } - box->targetRect.x = pos.x; - box->targetRect.y = pos.y; + box->rect.x = pos.x; + box->rect.y = pos.y; box->z = ui->z; ui->z++; @@ -830,12 +904,12 @@ void ui_layout_compute_rect(ui_context* ui, ui_box* box, vec2 pos) ui_axis secondAxis = (layoutAxis == UI_AXIS_X) ? UI_AXIS_Y : UI_AXIS_X; ui_align* align = box->layout.align; - vec2 origin = {box->targetRect.x - box->scroll.x, - box->targetRect.y - box->scroll.y}; + vec2 origin = {box->rect.x - box->scroll.x, + box->rect.y - box->scroll.y}; vec2 currentPos = origin; - vec2 contentsSize = {maximum(box->targetRect.w, box->childrenSum[UI_AXIS_X]), - maximum(box->targetRect.h, box->childrenSum[UI_AXIS_Y])}; + vec2 contentsSize = {maximum(box->rect.w, box->childrenSum[UI_AXIS_X]), + maximum(box->rect.h, box->childrenSum[UI_AXIS_Y])}; for(int i=0; itargetRect.c[2+secondAxis]); + currentPos.c[secondAxis] = origin.c[secondAxis] + 0.5*(contentsSize.c[secondAxis] - child->rect.c[2+secondAxis]); } vec2 childPos = currentPos; @@ -861,7 +935,16 @@ void ui_layout_compute_rect(ui_context* ui, ui_box* box, vec2 pos) { if(child->floating[i]) { - childPos.c[i] = origin.c[i] + child->targetRect.c[i]; + ui_style* style = child->targetStyle; + if(child->targetStyle->animationFlags & UI_STYLE_ANIMATE_POS) + { + ui_animate_f32(ui, &child->floatPos.c[i], child->floatTarget.c[i], style->animationTime); + } + else + { + child->floatPos.c[i] = child->floatTarget.c[i]; + } + childPos.c[i] = origin.c[i] + child->floatPos.c[i]; } } @@ -869,23 +952,9 @@ void ui_layout_compute_rect(ui_context* ui, ui_box* box, vec2 pos) if(!child->floating[layoutAxis]) { - currentPos.c[layoutAxis] += child->targetRect.c[2+layoutAxis]; + currentPos.c[layoutAxis] += child->rect.c[2+layoutAxis]; } } - - if(box->targetStyle->animationTime) - { - ui_animate_f32(ui, &box->rect.x, box->targetRect.x, box->targetStyle->animationTime); - ui_animate_f32(ui, &box->rect.y, box->targetRect.y, box->targetStyle->animationTime); - - //NOTE: size is already animated by the size property - box->rect.w = box->targetRect.w; - box->rect.h = box->targetRect.h; - } - else - { - box->rect = box->targetRect; - } } void ui_layout_find_next_hovered_recursive(ui_context* ui, ui_box* box, vec2 p) diff --git a/src/ui.h b/src/ui.h index 988e772..a605a4b 100644 --- a/src/ui.h +++ b/src/ui.h @@ -84,6 +84,17 @@ typedef enum { UI_STYLE_SEL_NORMAL = 1<<0, typedef u32 ui_style_tag; #define UI_STYLE_TAG_ANY (ui_style_tag)0 +typedef enum { UI_STYLE_ANIMATE_SIZE = 1<<1, + UI_STYLE_ANIMATE_BG_COLOR = 1<<2, + UI_STYLE_ANIMATE_FG_COLOR = 1<<3, + UI_STYLE_ANIMATE_BORDER_COLOR = 1<<4, + UI_STYLE_ANIMATE_FONT_COLOR = 1<<5, + UI_STYLE_ANIMATE_FONT_SIZE = 1<<6, + UI_STYLE_ANIMATE_BORDER_SIZE = 1<<7, + UI_STYLE_ANIMATE_ROUNDNESS = 1<<8, + UI_STYLE_ANIMATE_POS = 1<<9, + } ui_style_animation_flags; + typedef struct ui_style { ui_size size[UI_AXIS_COUNT]; @@ -96,6 +107,7 @@ typedef struct ui_style f32 borderSize; f32 roundness; f32 animationTime; + ui_style_animation_flags animationFlags; } ui_style; typedef struct ui_box ui_box; @@ -146,9 +158,10 @@ struct ui_box ui_style computedStyle; u32 z; bool floating[UI_AXIS_COUNT]; + vec2 floatPos; + vec2 floatTarget; ui_layout layout; f32 childrenSum[2]; - mp_rect targetRect; mp_rect rect; // signals @@ -211,6 +224,7 @@ void ui_push_border_size(f32 size); void ui_push_border_color(mg_color color); void ui_push_roundness(f32 roundness); void ui_push_animation_time(f32 time); +void ui_push_animation_flags(u32 flags); void ui_push_bg_color_ext(ui_style_tag tag, ui_style_selector selector, mg_color color); void ui_push_fg_color_ext(ui_style_tag tag, ui_style_selector selector, mg_color color); @@ -221,6 +235,7 @@ void ui_push_border_size_ext(ui_style_tag tag, ui_style_selector selector, f32 s void ui_push_border_color_ext(ui_style_tag tag, ui_style_selector selector, mg_color color); void ui_push_roundness_ext(ui_style_tag tag, ui_style_selector selector, f32 roundness); void ui_push_animation_time_ext(ui_style_tag tag, ui_style_selector selector, f32 time); +void ui_push_animation_flags_ext(ui_style_tag tag, ui_style_selector selector, u32 flags); void ui_pop_bg_color(); void ui_pop_fg_color(); @@ -231,6 +246,7 @@ void ui_pop_border_size(); void ui_pop_border_color(); void ui_pop_roundness(); void ui_pop_animation_time(); +void ui_pop_animation_flags(); // Basic helpers enum {