UI: Area Maintenance Post Op Transitions
While performance area maintenance operations (split, join, docking) some areas get highlighted and some are shown darkened to indicate they will be removed. This PR just adds transitions AFTER completion that eases out this highlighting. Make it less jarring and a little easier to follow what happens. Pull Request: https://projects.blender.org/blender/blender/pulls/140628
This commit is contained in:
committed by
Harley Acheson
parent
fe0fe0a5ed
commit
c793bfda23
@@ -22,6 +22,7 @@
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_rect.h"
|
||||
#include "BLI_time.h"
|
||||
|
||||
#include "BLT_translation.hh"
|
||||
|
||||
@@ -667,3 +668,81 @@ void screen_draw_split_preview(ScrArea *area, const eScreenAxis dir_axis, const
|
||||
}
|
||||
UI_draw_roundbox_4fv(&rect, true, 0.0f, border);
|
||||
}
|
||||
|
||||
struct AreaAnimateHighlightData {
|
||||
wmWindow *win;
|
||||
bScreen *screen;
|
||||
rctf rect;
|
||||
float inner[4];
|
||||
float outline[4];
|
||||
double start_time;
|
||||
double end_time;
|
||||
void *draw_callback;
|
||||
};
|
||||
|
||||
static void area_animate_highlight_cb(const wmWindow * /*win*/, void *userdata)
|
||||
{
|
||||
const AreaAnimateHighlightData *data = static_cast<const AreaAnimateHighlightData *>(userdata);
|
||||
|
||||
double now = BLI_time_now_seconds();
|
||||
if (now > data->end_time) {
|
||||
WM_draw_cb_exit(data->win, data->draw_callback);
|
||||
MEM_freeN(const_cast<AreaAnimateHighlightData *>(data));
|
||||
data = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
const float factor = pow((now - data->start_time) / (data->end_time - data->start_time), 2);
|
||||
const bool do_inner = data->inner[3] > 0.0f;
|
||||
const bool do_outline = data->outline[3] > 0.0f;
|
||||
|
||||
float inner_color[4];
|
||||
if (do_inner) {
|
||||
inner_color[0] = data->inner[0];
|
||||
inner_color[1] = data->inner[1];
|
||||
inner_color[2] = data->inner[2];
|
||||
inner_color[3] = (1.0f - factor) * data->inner[3];
|
||||
}
|
||||
|
||||
float outline_color[4];
|
||||
if (do_outline) {
|
||||
outline_color[0] = data->outline[0];
|
||||
outline_color[1] = data->outline[1];
|
||||
outline_color[2] = data->outline[2];
|
||||
outline_color[3] = (1.0f - factor) * data->outline[3];
|
||||
}
|
||||
|
||||
UI_draw_roundbox_corner_set(UI_CNR_ALL);
|
||||
UI_draw_roundbox_4fv_ex(&data->rect,
|
||||
do_inner ? inner_color : nullptr,
|
||||
nullptr,
|
||||
1.0f,
|
||||
do_outline ? outline_color : nullptr,
|
||||
U.pixelsize,
|
||||
EDITORRADIUS);
|
||||
|
||||
data->screen->do_refresh = true;
|
||||
}
|
||||
|
||||
void screen_animate_area_highlight(wmWindow *win,
|
||||
bScreen *screen,
|
||||
const rcti *rect,
|
||||
float inner[4],
|
||||
float outline[4],
|
||||
float seconds)
|
||||
{
|
||||
AreaAnimateHighlightData *data = MEM_callocN<AreaAnimateHighlightData>(
|
||||
"screen_animate_area_highlight");
|
||||
data->win = win;
|
||||
data->screen = screen;
|
||||
BLI_rctf_rcti_copy(&data->rect, rect);
|
||||
if (inner) {
|
||||
copy_v4_v4(data->inner, inner);
|
||||
}
|
||||
if (outline) {
|
||||
copy_v4_v4(data->outline, outline);
|
||||
}
|
||||
data->start_time = BLI_time_now_seconds();
|
||||
data->end_time = data->start_time + seconds;
|
||||
data->draw_callback = WM_draw_cb_activate(win, area_animate_highlight_cb, data);
|
||||
}
|
||||
|
||||
@@ -564,7 +564,18 @@ static bool screen_area_join_ex(bContext *C,
|
||||
|
||||
if (close_all_remainders || offset1 < 0 || offset2 > 0) {
|
||||
/* Close both if trimming `sa1`. */
|
||||
float inner[4] = {0.0f, 0.0f, 0.0f, 0.7f};
|
||||
if (side1) {
|
||||
rcti rect = {side1->v1->vec.x, side1->v3->vec.x, side1->v1->vec.y, side1->v3->vec.y};
|
||||
screen_animate_area_highlight(
|
||||
CTX_wm_window(C), CTX_wm_screen(C), &rect, inner, nullptr, AREA_CLOSE_FADEOUT);
|
||||
}
|
||||
screen_area_close(C, reports, screen, side1);
|
||||
if (side2) {
|
||||
rcti rect = {side2->v1->vec.x, side2->v3->vec.x, side2->v1->vec.y, side2->v3->vec.y};
|
||||
screen_animate_area_highlight(
|
||||
CTX_wm_window(C), CTX_wm_screen(C), &rect, inner, nullptr, AREA_CLOSE_FADEOUT);
|
||||
}
|
||||
screen_area_close(C, reports, screen, side2);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -80,6 +80,11 @@ enum class AreaDockTarget {
|
||||
/* Less expansion needed for global edges. */
|
||||
#define BORDERPADDING_GLOBAL (3.0f * UI_SCALE_FAC)
|
||||
|
||||
#define AREA_CLOSE_FADEOUT 0.22f /* seconds */
|
||||
#define AREA_DOCK_FADEOUT 0.20f /* seconds */
|
||||
#define AREA_JOIN_FADEOUT 0.15f /* seconds */
|
||||
#define AREA_SPLIT_FADEOUT 0.15f /* seconds */
|
||||
|
||||
/* `area.cc` */
|
||||
|
||||
/**
|
||||
@@ -112,6 +117,13 @@ void screen_draw_move_highlight(const wmWindow *win, bScreen *screen, eScreenAxi
|
||||
|
||||
void screen_draw_region_scale_highlight(ARegion *region);
|
||||
|
||||
void screen_animate_area_highlight(wmWindow *win,
|
||||
bScreen *screen,
|
||||
const rcti *rect,
|
||||
float inner[4],
|
||||
float outline[4],
|
||||
float seconds);
|
||||
|
||||
/* `screen_edit.cc` */
|
||||
|
||||
/**
|
||||
|
||||
@@ -1583,6 +1583,10 @@ static wmOperatorStatus area_close_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
float inner[4] = {0.0f, 0.0f, 0.0f, 0.7f};
|
||||
screen_animate_area_highlight(
|
||||
CTX_wm_window(C), CTX_wm_screen(C), &area->totrct, inner, nullptr, AREA_CLOSE_FADEOUT);
|
||||
|
||||
if (!screen_area_close(C, op->reports, screen, area)) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Unable to close area");
|
||||
return OPERATOR_CANCELLED;
|
||||
@@ -2597,6 +2601,14 @@ static wmOperatorStatus area_split_modal(bContext *C, wmOperator *op, const wmEv
|
||||
|
||||
case LEFTMOUSE:
|
||||
if (sd->previewmode) {
|
||||
float inner[4] = {1.0f, 1.0f, 1.0f, 0.1f};
|
||||
float outline[4] = {1.0f, 1.0f, 1.0f, 0.3f};
|
||||
screen_animate_area_highlight(CTX_wm_window(C),
|
||||
CTX_wm_screen(C),
|
||||
&sd->sarea->totrct,
|
||||
inner,
|
||||
outline,
|
||||
AREA_SPLIT_FADEOUT);
|
||||
area_split_apply(C, op);
|
||||
area_split_exit(C, op);
|
||||
return OPERATOR_FINISHED;
|
||||
@@ -3819,6 +3831,22 @@ static bool area_join_apply(bContext *C, wmOperator *op)
|
||||
|
||||
bScreen *screen = CTX_wm_screen(C);
|
||||
|
||||
/* Rect of the combined areas. */
|
||||
const bool vertical = SCREEN_DIR_IS_VERTICAL(jd->dir);
|
||||
rcti combined{};
|
||||
combined.xmin = vertical ? std::max(jd->sa1->totrct.xmin, jd->sa2->totrct.xmin) :
|
||||
std::min(jd->sa1->totrct.xmin, jd->sa2->totrct.xmin);
|
||||
combined.xmax = vertical ? std::min(jd->sa1->totrct.xmax, jd->sa2->totrct.xmax) :
|
||||
std::max(jd->sa1->totrct.xmax, jd->sa2->totrct.xmax);
|
||||
combined.ymin = vertical ? std::min(jd->sa1->totrct.ymin, jd->sa2->totrct.ymin) :
|
||||
std::max(jd->sa1->totrct.ymin, jd->sa2->totrct.ymin);
|
||||
combined.ymax = vertical ? std::max(jd->sa1->totrct.ymax, jd->sa2->totrct.ymax) :
|
||||
std::min(jd->sa1->totrct.ymax, jd->sa2->totrct.ymax);
|
||||
float inner[4] = {1.0f, 1.0f, 1.0f, 0.1f};
|
||||
float outline[4] = {1.0f, 1.0f, 1.0f, 0.3f};
|
||||
screen_animate_area_highlight(
|
||||
CTX_wm_window(C), screen, &combined, inner, outline, AREA_JOIN_FADEOUT);
|
||||
|
||||
if (!screen_area_join(C, op->reports, screen, jd->sa1, jd->sa2)) {
|
||||
return false;
|
||||
}
|
||||
@@ -3971,6 +3999,13 @@ void static area_docking_apply(bContext *C, wmOperator *op)
|
||||
return;
|
||||
}
|
||||
|
||||
float inner[4] = {1.0f, 1.0f, 1.0f, 0.15f};
|
||||
float outline[4] = {1.0f, 1.0f, 1.0f, 0.4f};
|
||||
jd->sa2->flag |= AREA_FLAG_REGION_SIZE_UPDATE;
|
||||
ED_area_update_region_sizes(CTX_wm_manager(C), jd->win2, jd->sa2);
|
||||
screen_animate_area_highlight(
|
||||
jd->win2, CTX_wm_screen(C), &jd->sa2->totrct, inner, outline, AREA_DOCK_FADEOUT);
|
||||
|
||||
if (!aligned_neighbors || !screen_area_join(C, op->reports, CTX_wm_screen(C), jd->sa1, jd->sa2))
|
||||
{
|
||||
ED_area_swapspace(C, jd->sa2, jd->sa1);
|
||||
@@ -3984,6 +4019,9 @@ void static area_docking_apply(bContext *C, wmOperator *op)
|
||||
WM_window_get_active_screen(jd->win2)->active_region = nullptr;
|
||||
}
|
||||
else {
|
||||
float inner[4] = {0.0f, 0.0f, 0.0f, 0.7f};
|
||||
screen_animate_area_highlight(
|
||||
jd->win1, CTX_wm_screen(C), &jd->sa1->totrct, inner, nullptr, AREA_CLOSE_FADEOUT);
|
||||
screen_area_close(C, op->reports, CTX_wm_screen(C), jd->sa1);
|
||||
}
|
||||
}
|
||||
@@ -4416,6 +4454,10 @@ static wmOperatorStatus area_join_modal(bContext *C, wmOperator *op, const wmEve
|
||||
else if (jd->sa1 && jd->sa1 == jd->sa2) {
|
||||
/* Same area so split. */
|
||||
if (area_split_allowed(jd->sa1, jd->split_dir) && jd->split_fac > 0.0001) {
|
||||
float inner[4] = {1.0f, 1.0f, 1.0f, 0.1f};
|
||||
float outline[4] = {1.0f, 1.0f, 1.0f, 0.3f};
|
||||
screen_animate_area_highlight(
|
||||
jd->win1, CTX_wm_screen(C), &jd->sa1->totrct, inner, outline, AREA_SPLIT_FADEOUT);
|
||||
jd->sa2 = area_split(jd->win2,
|
||||
WM_window_get_active_screen(jd->win1),
|
||||
jd->sa1,
|
||||
|
||||
@@ -632,7 +632,8 @@ void WM_draw_cb_exit(wmWindow *win, void *handle)
|
||||
|
||||
static void wm_draw_callbacks(wmWindow *win)
|
||||
{
|
||||
LISTBASE_FOREACH (WindowDrawCB *, wdc, &win->drawcalls) {
|
||||
/* Allow callbacks to remove themselves. */
|
||||
LISTBASE_FOREACH_MUTABLE (WindowDrawCB *, wdc, &win->drawcalls) {
|
||||
wdc->draw(win, wdc->customdata);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user