diff options
Diffstat (limited to 'source/blender/editors/screen/screen_ops.c')
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 159 |
1 files changed, 150 insertions, 9 deletions
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 67d4af916aa..269cc672e34 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -965,7 +965,7 @@ typedef struct sAreaMoveData { static void area_move_set_limits(bScreen *sc, int dir, int *bigger, int *smaller) { ScrArea *sa; - int areaminy = ED_area_headersize() + 1; + int areaminy = ED_area_headersize() + U.pixelsize; // pixelsize is used as area divider /* we check all areas and test for free space with MINSIZE */ *bigger = *smaller = 100000; @@ -1038,19 +1038,19 @@ static void area_move_apply_do(bContext *C, int origval, int delta, int dir, int for (v1 = sc->vertbase.first; v1; v1 = v1->next) { if (v1->flag) { /* that way a nice AREAGRID */ - if ((dir == 'v') && v1->vec.x > 0 && v1->vec.x < win->sizex - 1) { + if ((dir == 'v') && v1->vec.x > 0 && v1->vec.x < WM_window_pixels_x(win) - 1) { v1->vec.x = origval + delta; if (delta != bigger && delta != -smaller) v1->vec.x -= (v1->vec.x % AREAGRID); } - if ((dir == 'h') && v1->vec.y > 0 && v1->vec.y < win->sizey - 1) { + if ((dir == 'h') && v1->vec.y > 0 && v1->vec.y < WM_window_pixels_y(win) - 1) { v1->vec.y = origval + delta; v1->vec.y += AREAGRID - 1; v1->vec.y -= (v1->vec.y % AREAGRID); /* prevent too small top header */ - if (v1->vec.y > win->sizey - areaminy) - v1->vec.y = win->sizey - areaminy; + if (v1->vec.y > WM_window_pixels_y(win) - areaminy) + v1->vec.y = WM_window_pixels_y(win) - areaminy; } } } @@ -1720,9 +1720,9 @@ static int region_scale_invoke(bContext *C, wmOperator *op, wmEvent *event) /* if not set we do now, otherwise it uses type */ if (rmd->ar->sizex == 0) - rmd->ar->sizex = rmd->ar->type->prefsizex; + rmd->ar->sizex = rmd->ar->winx; if (rmd->ar->sizey == 0) - rmd->ar->sizey = rmd->ar->type->prefsizey; + rmd->ar->sizey = rmd->ar->winy; /* now copy to regionmovedata */ if (rmd->edge == AE_LEFT_TO_TOPRIGHT || rmd->edge == AE_RIGHT_TO_TOPLEFT) { @@ -1734,7 +1734,7 @@ static int region_scale_invoke(bContext *C, wmOperator *op, wmEvent *event) /* limit headers to standard height for now */ if (rmd->ar->regiontype == RGN_TYPE_HEADER) - maxsize = rmd->ar->type->prefsizey; + maxsize = ED_area_headersize(); else maxsize = 1000; @@ -2797,7 +2797,6 @@ static void SCREEN_OT_region_quadview(wmOperatorType *ot) } - /* ************** region flip operator ***************************** */ /* flip a region alignment */ @@ -3583,6 +3582,146 @@ static void SCENE_OT_delete(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +/* ***************** region alpha blending ***************** */ + +/* implementation note: a disapplearing region needs at least 1 last draw with 100% backbuffer + texture over it- then triple buffer will clear it entirely. + This because flag RGN_HIDDEN is set in end - region doesnt draw at all then */ + +typedef struct RegionAlphaInfo { + ScrArea *sa; + ARegion *ar, *child_ar; /* other region */ + int hidden; +} RegionAlphaInfo; + +#define TIMEOUT 0.3f +#define TIMESTEP 0.04 + +float ED_region_blend_factor(ARegion *ar) +{ + /* check parent too */ + if(ar->regiontimer == NULL && (ar->alignment & RGN_SPLIT_PREV) && ar->prev) + ar = ar->prev; + + if (ar->regiontimer) { + RegionAlphaInfo *rgi = ar->regiontimer->customdata; + float alpha; + + alpha = (float)ar->regiontimer->duration / TIMEOUT; + /* makes sure the blend out works 100% - without area redraws */ + if (rgi->hidden) alpha = 0.9 - TIMESTEP - alpha; + + CLAMP(alpha, 0.0f, 1.0f); + return alpha; + } + return 1.0f; +} + +/* assumes region has running region-blend timer */ +static void region_blend_end(bContext *C, ARegion *ar, int is_running) +{ + RegionAlphaInfo *rgi = ar->regiontimer->customdata; + + /* always send redraw */ + ED_region_tag_redraw(ar); + if (rgi->child_ar) + ED_region_tag_redraw(rgi->child_ar); + + /* if running timer was hiding, the flag toggle went wrong */ + if (is_running) { + if (rgi->hidden) + rgi->ar->flag &= ~RGN_FLAG_HIDDEN; + } + else { + if (rgi->hidden) { + rgi->ar->flag |= rgi->hidden; + ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), rgi->sa); + } + /* area decoration needs redraw in end */ + ED_area_tag_redraw(rgi->sa); + } + WM_event_remove_timer(CTX_wm_manager(C), NULL, ar->regiontimer); /* frees rgi */ + ar->regiontimer = NULL; + +} +/* assumes that *ar itself is not a splitted version from previous region */ +void region_blend_start(bContext *C, ScrArea *sa, ARegion *ar) +{ + wmWindowManager *wm = CTX_wm_manager(C); + wmWindow *win = CTX_wm_window(C); + RegionAlphaInfo *rgi; + + /* end running timer */ + if (ar->regiontimer) { + + region_blend_end(C, ar, 1); + } + rgi = MEM_callocN(sizeof(RegionAlphaInfo), "RegionAlphaInfo"); + + rgi->hidden = ar->flag & RGN_FLAG_HIDDEN; + rgi->sa = sa; + rgi->ar = ar; + ar->flag &= ~RGN_FLAG_HIDDEN; + + /* blend in, reinitialize regions because it got unhidden */ + if (rgi->hidden == 0) + ED_area_initialize(wm, win, sa); + else + WM_event_remove_handlers(C, &ar->handlers); + + if(ar->next) + if (ar->next->alignment & RGN_SPLIT_PREV) + rgi->child_ar = ar->next; + + /* new timer */ + ar->regiontimer = WM_event_add_timer(wm, win, TIMERREGION, TIMESTEP); + ar->regiontimer->customdata = rgi; + +} + +/* timer runs in win->handlers, so it cannot use context to find area/region */ +static int region_blend_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) +{ + RegionAlphaInfo *rgi; + wmTimer *timer = event->customdata; + + /* event type is TIMERREGION, but we better check */ + if (event->type != TIMERREGION || timer == NULL) + return OPERATOR_PASS_THROUGH; + + rgi = timer->customdata; + + /* always send redraws */ + ED_region_tag_redraw(rgi->ar); + if (rgi->child_ar) + ED_region_tag_redraw(rgi->child_ar); + + /* end timer? */ + if (rgi->ar->regiontimer->duration > TIMEOUT) { + region_blend_end(C, rgi->ar, 0); + return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH); + } + + return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH); +} + +static void SCREEN_OT_region_blend(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Region Alpha"; + ot->idname = "SCREEN_OT_region_blend"; + ot->description = "Blend in and out overlapping region"; + + /* api callbacks */ + ot->invoke = region_blend_invoke; + + /* flags */ + ot->flag = 0; + + /* properties */ +} + + /* **************** Assigning operatortypes to global list, adding handlers **************** */ @@ -3615,6 +3754,7 @@ void ED_operatortypes_screen(void) WM_operatortype_append(SCREEN_OT_screenshot); WM_operatortype_append(SCREEN_OT_screencast); WM_operatortype_append(SCREEN_OT_userpref_show); + WM_operatortype_append(SCREEN_OT_region_blend); /*frame changes*/ WM_operatortype_append(SCREEN_OT_frame_offset); @@ -3717,6 +3857,7 @@ void ED_keymap_screen(wmKeyConfig *keyconf) /* standard timers */ WM_keymap_add_item(keymap, "SCREEN_OT_animation_step", TIMER0, KM_ANY, KM_ANY, 0); + WM_keymap_add_item(keymap, "SCREEN_OT_region_blend", TIMERREGION, KM_ANY, KM_ANY, 0); RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_screen_set", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", 1); |