diff options
Diffstat (limited to 'source/blender/editors/screen')
-rw-r--r-- | source/blender/editors/screen/SConscript | 28 | ||||
-rw-r--r-- | source/blender/editors/screen/area.c | 287 | ||||
-rw-r--r-- | source/blender/editors/screen/glutil.c | 7 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_edit.c | 80 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_intern.h | 13 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 201 |
6 files changed, 451 insertions, 165 deletions
diff --git a/source/blender/editors/screen/SConscript b/source/blender/editors/screen/SConscript index 0e894a13d28..c0a14ce5377 100644 --- a/source/blender/editors/screen/SConscript +++ b/source/blender/editors/screen/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index f30e0abb4f3..cde94ec46ee 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -235,8 +235,8 @@ static void region_draw_azone_icon(AZone *az) static void draw_azone_plus(float x1, float y1, float x2, float y2) { - float width = 2.0f; - float pad = 4.0f; + float width = 0.1f * U.widget_unit; + float pad = 0.2f * U.widget_unit; glRectf((x1 + x2 - width) * 0.5f, y1 + pad, (x1 + x2 + width) * 0.5f, y2 - pad); glRectf(x1 + pad, (y1 + y2 - width) * 0.5f, (x1 + x2 - width) * 0.5f, (y1 + y2 + width) * 0.5f); @@ -395,47 +395,14 @@ void ED_area_overdraw(bContext *C) } -/* get scissor rect, checking overlapping regions */ -void region_scissor_winrct(ARegion *ar, rcti *winrct) -{ - *winrct = ar->winrct; - - if (ELEM(ar->alignment, RGN_OVERLAP_LEFT, RGN_OVERLAP_RIGHT)) - return; - - while (ar->prev) { - ar = ar->prev; - - if (BLI_rcti_isect(winrct, &ar->winrct, NULL)) { - if (ar->flag & RGN_FLAG_HIDDEN) { - /* pass */ - } - else if (ar->alignment & RGN_SPLIT_PREV) { - /* pass */ - } - else if (ar->alignment == RGN_OVERLAP_LEFT) { - winrct->xmin = ar->winrct.xmax + 1; - } - else if (ar->alignment == RGN_OVERLAP_RIGHT) { - winrct->xmax = ar->winrct.xmin - 1; - } - else break; - } - } -} - /* only exported for WM */ /* makes region ready for drawing, sets pixelspace */ void ED_region_set(const bContext *C, ARegion *ar) { wmWindow *win = CTX_wm_window(C); ScrArea *sa = CTX_wm_area(C); - rcti winrct; - /* checks other overlapping regions */ - region_scissor_winrct(ar, &winrct); - - ar->drawrct = winrct; + ar->drawrct = ar->winrct; /* note; this sets state, so we can use wmOrtho and friends */ wmSubWindowScissorSet(win, ar->swinid, &ar->drawrct); @@ -452,24 +419,20 @@ void ED_region_do_draw(bContext *C, ARegion *ar) wmWindow *win = CTX_wm_window(C); ScrArea *sa = CTX_wm_area(C); ARegionType *at = ar->type; - rcti winrct; /* see BKE_spacedata_draw_locks() */ if (at->do_lock) return; - /* checks other overlapping regions */ - region_scissor_winrct(ar, &winrct); - /* if no partial draw rect set, full rect */ if (ar->drawrct.xmin == ar->drawrct.xmax) - ar->drawrct = winrct; + ar->drawrct = ar->winrct; else { /* extra clip for safety (intersect the rects, could use API func) */ - ar->drawrct.xmin = max_ii(winrct.xmin, ar->drawrct.xmin); - ar->drawrct.ymin = max_ii(winrct.ymin, ar->drawrct.ymin); - ar->drawrct.xmax = min_ii(winrct.xmax, ar->drawrct.xmax); - ar->drawrct.ymax = min_ii(winrct.ymax, ar->drawrct.ymax); + ar->drawrct.xmin = max_ii(ar->winrct.xmin, ar->drawrct.xmin); + ar->drawrct.ymin = max_ii(ar->winrct.ymin, ar->drawrct.ymin); + ar->drawrct.xmax = min_ii(ar->winrct.xmax, ar->drawrct.xmax); + ar->drawrct.ymax = min_ii(ar->winrct.ymax, ar->drawrct.ymax); } /* note; this sets state, so we can use wmOrtho and friends */ @@ -500,7 +463,7 @@ void ED_region_do_draw(bContext *C, ARegion *ar) uiFreeInactiveBlocks(C, &ar->uiblocks); if (sa) - region_draw_emboss(ar, &winrct); + region_draw_emboss(ar, &ar->winrct); } /* ********************************** @@ -627,8 +590,8 @@ static void area_azone_initialize(bScreen *screen, ScrArea *sa) BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); } -#define AZONEPAD_EDGE 4 -#define AZONEPAD_ICON 9 +#define AZONEPAD_EDGE (0.2f * U.widget_unit) +#define AZONEPAD_ICON (0.45f * U.widget_unit) static void region_azone_edge(AZone *az, ARegion *ar) { switch (az->edge) { @@ -720,8 +683,8 @@ static void region_azone_icon(ScrArea *sa, AZone *az, ARegion *ar) } } -#define AZONEPAD_TAB_PLUSW 14 -#define AZONEPAD_TAB_PLUSH 14 +#define AZONEPAD_TAB_PLUSW (0.7f * U.widget_unit) +#define AZONEPAD_TAB_PLUSH (0.7f * U.widget_unit) /* region already made zero sized, in shape of edge */ static void region_azone_tab_plus(ScrArea *sa, AZone *az, ARegion *ar) @@ -736,28 +699,28 @@ static void region_azone_tab_plus(ScrArea *sa, AZone *az, ARegion *ar) switch (az->edge) { case AE_TOP_TO_BOTTOMRIGHT: if (ar->winrct.ymax == sa->totrct.ymin) add = 1; else add = 0; - az->x1 = ar->winrct.xmax - 2.5 * AZONEPAD_TAB_PLUSW; + az->x1 = ar->winrct.xmax - 2.5f * AZONEPAD_TAB_PLUSW; az->y1 = ar->winrct.ymax - add; - az->x2 = ar->winrct.xmax - 1.5 * AZONEPAD_TAB_PLUSW; + az->x2 = ar->winrct.xmax - 1.5f * AZONEPAD_TAB_PLUSW; az->y2 = ar->winrct.ymax - add + AZONEPAD_TAB_PLUSH; break; case AE_BOTTOM_TO_TOPLEFT: - az->x1 = ar->winrct.xmax - 2.5 * AZONEPAD_TAB_PLUSW; + az->x1 = ar->winrct.xmax - 2.5f * AZONEPAD_TAB_PLUSW; az->y1 = ar->winrct.ymin - AZONEPAD_TAB_PLUSH; - az->x2 = ar->winrct.xmax - 1.5 * AZONEPAD_TAB_PLUSW; + az->x2 = ar->winrct.xmax - 1.5f * AZONEPAD_TAB_PLUSW; az->y2 = ar->winrct.ymin; break; case AE_LEFT_TO_TOPRIGHT: az->x1 = ar->winrct.xmin - AZONEPAD_TAB_PLUSH; - az->y1 = ar->winrct.ymax - 2.5 * AZONEPAD_TAB_PLUSW; + az->y1 = ar->winrct.ymax - 2.5f * AZONEPAD_TAB_PLUSW; az->x2 = ar->winrct.xmin; - az->y2 = ar->winrct.ymax - 1.5 * AZONEPAD_TAB_PLUSW; + az->y2 = ar->winrct.ymax - 1.5f * AZONEPAD_TAB_PLUSW; break; case AE_RIGHT_TO_TOPLEFT: az->x1 = ar->winrct.xmax - 1; - az->y1 = ar->winrct.ymax - 2.5 * AZONEPAD_TAB_PLUSW; + az->y1 = ar->winrct.ymax - 2.5f * AZONEPAD_TAB_PLUSW; az->x2 = ar->winrct.xmax - 1 + AZONEPAD_TAB_PLUSH; - az->y2 = ar->winrct.ymax - 1.5 * AZONEPAD_TAB_PLUSW; + az->y2 = ar->winrct.ymax - 1.5f * AZONEPAD_TAB_PLUSW; break; } /* rect needed for mouse pointer test */ @@ -765,8 +728,8 @@ static void region_azone_tab_plus(ScrArea *sa, AZone *az, ARegion *ar) } -#define AZONEPAD_TABW 18 -#define AZONEPAD_TABH 7 +#define AZONEPAD_TABW (0.9f * U.widget_unit) +#define AZONEPAD_TABH (0.35f * U.widget_unit) /* region already made zero sized, in shape of edge */ static void region_azone_tab(ScrArea *sa, AZone *az, ARegion *ar) @@ -809,8 +772,8 @@ static void region_azone_tab(ScrArea *sa, AZone *az, ARegion *ar) BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); } -#define AZONEPAD_TRIAW 16 -#define AZONEPAD_TRIAH 9 +#define AZONEPAD_TRIAW (0.8f * U.widget_unit) +#define AZONEPAD_TRIAH (0.45f * U.widget_unit) /* region already made zero sized, in shape of edge */ @@ -892,9 +855,9 @@ static void region_azone_add(ScrArea *sa, ARegion *ar, int alignment) region_azone_initialize(sa, ar, AE_BOTTOM_TO_TOPLEFT); else if (alignment == RGN_ALIGN_BOTTOM) region_azone_initialize(sa, ar, AE_TOP_TO_BOTTOMRIGHT); - else if (ELEM(alignment, RGN_ALIGN_RIGHT, RGN_OVERLAP_RIGHT)) + else if (alignment == RGN_ALIGN_RIGHT) region_azone_initialize(sa, ar, AE_LEFT_TO_TOPRIGHT); - else if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_OVERLAP_LEFT)) + else if (alignment == RGN_ALIGN_LEFT) region_azone_initialize(sa, ar, AE_RIGHT_TO_TOPLEFT); } @@ -909,7 +872,50 @@ static int rct_fits(rcti *rect, char dir, int size) } } -static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int quad) +/* *************************************************************** */ + +/* ar should be overlapping */ +/* function checks if some overlapping region was defined before - on same place */ +static void region_overlap_fix(ARegion *ar) +{ + ARegion *ar1 = ar->prev; + + /* find overlapping previous region on same place */ + while (ar1) { + if (ar1->overlap) { + if ((ar1->alignment & RGN_SPLIT_PREV) == 0) + if (BLI_rcti_isect(&ar1->winrct, &ar->winrct, NULL)) + break; + } + ar1 = ar1->prev; + } + + /* translate */ + if (ar1) { + int align1 = ar1->alignment & ~RGN_SPLIT_PREV; + + if (align1 == RGN_ALIGN_LEFT) { + BLI_rcti_translate(&ar->winrct, ar1->winx, 0); + } + else if (align1 == RGN_ALIGN_RIGHT) { + BLI_rcti_translate(&ar->winrct, -ar1->winx, 0); + } + } + +} + +/* overlapping regions only in the following restricted cases */ +static int region_is_overlap(wmWindow *win, ScrArea *sa, ARegion *ar) +{ + if (U.uiflag2 & USER_REGION_OVERLAP) + if (WM_is_draw_triple(win)) + if (ELEM5(sa->spacetype, SPACE_VIEW3D, SPACE_IMAGE, SPACE_SEQ, SPACE_CLIP, SPACE_NODE)) + if (ELEM3(ar->regiontype, RGN_TYPE_TOOLS, RGN_TYPE_UI, RGN_TYPE_TOOL_PROPS)) + return 1; + return 0; +} + +static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti *remainder, int quad) { rcti *remainder_prev = remainder; int prefsizex, prefsizey; @@ -928,6 +934,9 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int alignment = ar->alignment & ~RGN_SPLIT_PREV; + /* set here, assuming userpref switching forces to call this again */ + ar->overlap = region_is_overlap(win, sa, ar); + /* clear state flags first */ ar->flag &= ~RGN_FLAG_TOO_SMALL; /* user errors */ @@ -935,15 +944,15 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int alignment = RGN_ALIGN_NONE; /* prefsize, for header we stick to exception */ - prefsizex = ar->sizex ? ar->sizex : ar->type->prefsizex; + prefsizex = ar->sizex > 1 ? ar->sizex : UI_DPI_FAC * ar->type->prefsizex; if (ar->regiontype == RGN_TYPE_HEADER) { - prefsizey = ar->type->prefsizey; + prefsizey = ED_area_headersize(); } else if (ar->regiontype == RGN_TYPE_UI && sa->spacetype == SPACE_FILE) { prefsizey = UI_UNIT_Y * 2 + (UI_UNIT_Y / 2); } else { - prefsizey = ar->sizey ? ar->sizey : ar->type->prefsizey; + prefsizey = ar->sizey > 1 ? ar->sizey : UI_DPI_FAC * ar->type->prefsizey; } @@ -985,7 +994,7 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int } } } - else if (ELEM4(alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT, RGN_OVERLAP_LEFT, RGN_OVERLAP_RIGHT)) { + else if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) { if (rct_fits(remainder, 'h', prefsizex) < 0) { ar->flag |= RGN_FLAG_TOO_SMALL; @@ -998,14 +1007,14 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int ar->winrct = *remainder; - if (ELEM(alignment, RGN_ALIGN_RIGHT, RGN_OVERLAP_RIGHT)) { + if (alignment == RGN_ALIGN_RIGHT) { ar->winrct.xmin = ar->winrct.xmax - prefsizex + 1; - if (alignment == RGN_ALIGN_RIGHT) + if (ar->overlap == 0) remainder->xmax = ar->winrct.xmin - 1; } else { ar->winrct.xmax = ar->winrct.xmin + prefsizex - 1; - if (alignment == RGN_ALIGN_LEFT) + if (ar->overlap == 0) remainder->xmin = ar->winrct.xmax + 1; } } @@ -1082,6 +1091,14 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int ar->winx = BLI_rcti_size_x(&ar->winrct) + 1; ar->winy = BLI_rcti_size_y(&ar->winrct) + 1; + /* if region opened normally, we store this for hide/reveal usage */ + if (ar->winx > 1) ar->sizex = ar->winx; + if (ar->winy > 1) ar->sizey = ar->winy; + + /* exception for multiple aligned overlapping regions on same spot */ + if (ar->overlap) + region_overlap_fix(ar); + /* set winrect for azones */ if (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) { ar->winrct = *remainder; @@ -1090,9 +1107,9 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int ar->winrct.ymin = ar->winrct.ymax; else if (alignment == RGN_ALIGN_BOTTOM) ar->winrct.ymax = ar->winrct.ymin; - else if (ELEM(alignment, RGN_ALIGN_RIGHT, RGN_OVERLAP_RIGHT)) + else if (alignment == RGN_ALIGN_RIGHT) ar->winrct.xmin = ar->winrct.xmax; - else if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_OVERLAP_LEFT)) + else if (alignment == RGN_ALIGN_LEFT) ar->winrct.xmax = ar->winrct.xmin; else /* prevent winrct to be valid */ ar->winrct.xmax = ar->winrct.xmin; @@ -1121,12 +1138,12 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int region_azone_add(sa, ar, alignment); } - region_rect_recursive(sa, ar->next, remainder, quad); + region_rect_recursive(win, sa, ar->next, remainder, quad); } static void area_calc_totrct(ScrArea *sa, int sizex, int sizey) { - short rt = 0; // CLAMPIS(G.debug_value, 0, 16); + short rt = U.pixelsize > 1.0f ? 1 : 0; if (sa->v1->vec.x > 0) sa->totrct.xmin = sa->v1->vec.x + 1 + rt; else sa->totrct.xmin = sa->v1->vec.x; @@ -1229,14 +1246,14 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa) ar->type = BKE_regiontype_from_id(sa->type, ar->regiontype); /* area sizes */ - area_calc_totrct(sa, win->sizex, win->sizey); + area_calc_totrct(sa, WM_window_pixels_x(win), WM_window_pixels_y(win)); /* clear all azones, add the area triange widgets */ area_azone_initialize(win->screen, sa); /* region rect sizes */ rect = sa->totrct; - region_rect_recursive(sa, sa->regionbase.first, &rect, 0); + region_rect_recursive(win, sa, sa->regionbase.first, &rect, 0); /* default area handlers */ ed_default_handlers(wm, sa, &sa->handlers, sa->type->keymapflag); @@ -1278,17 +1295,30 @@ void ED_region_init(bContext *C, ARegion *ar) glLoadIdentity(); } -void ED_region_toggle_hidden(bContext *C, ARegion *ar) +/* for quick toggle, can skip fades */ +void region_toggle_hidden(bContext *C, ARegion *ar, int do_fade) { ScrArea *sa = CTX_wm_area(C); - + ar->flag ^= RGN_FLAG_HIDDEN; + + if (do_fade && ar->overlap) { + /* starts a timer, and in end calls the stuff below itself (region_sblend_invoke()) */ + region_blend_start(C, sa, ar); + } + else { + if (ar->flag & RGN_FLAG_HIDDEN) + WM_event_remove_handlers(C, &ar->handlers); + + ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa); + ED_area_tag_redraw(sa); + } +} - if (ar->flag & RGN_FLAG_HIDDEN) - WM_event_remove_handlers(C, &ar->handlers); - - ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa); - ED_area_tag_redraw(sa); +/* exported to all editors, uses fading default */ +void ED_region_toggle_hidden(bContext *C, ARegion *ar) +{ + region_toggle_hidden(C, ar, 1); } /* sa2 to sa1, we swap spaces for fullscreen to keep all allocated data */ @@ -1441,7 +1471,7 @@ void ED_area_prevspace(bContext *C, ScrArea *sa) { SpaceLink *sl = (sa) ? sa->spacedata.first : CTX_wm_space_data(C); - if (sl->next) { + if (sl && sl->next) { /* workaround for case of double prevspace, render window * with a file browser on top of it */ if (sl->next->spacetype == SPACE_FILE && sl->next->next) @@ -1515,22 +1545,22 @@ int ED_area_header_switchbutton(const bContext *C, uiBlock *block, int yco) { ScrArea *sa = CTX_wm_area(C); uiBut *but; - int xco = 8; + int xco = 0.4 * U.widget_unit; but = uiDefIconTextButC(block, ICONTEXTROW, 0, ICON_VIEW3D, - editortype_pup(), xco, yco, UI_UNIT_X + 10, UI_UNIT_Y, + editortype_pup(), xco, yco, 1.5 * U.widget_unit, U.widget_unit, &(sa->butspacetype), 1.0, SPACEICONMAX, 0, 0, TIP_("Display current editor type (click for a menu of available types)")); uiButSetFunc(but, spacefunc, NULL, NULL); uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ - return xco + UI_UNIT_X + 14; + return xco + 1.7 * U.widget_unit; } int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco) { ScrArea *sa = CTX_wm_area(C); - int xco = 8; + int xco = 0.4 * U.widget_unit; uiBut *but; if (!sa->full) @@ -1541,14 +1571,14 @@ int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco) if (sa->flag & HEADER_NO_PULLDOWN) { but = uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, 0, ICON_DISCLOSURE_TRI_RIGHT, - xco, yco, UI_UNIT_X, UI_UNIT_Y - 2, + xco, yco, U.widget_unit, U.widget_unit*0.9, &(sa->flag), 0, 0, 0, 0, "Show pulldown menus"); } else { but = uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, 0, ICON_DISCLOSURE_TRI_DOWN, - xco, yco, UI_UNIT_X, UI_UNIT_Y - 2, + xco, yco, U.widget_unit, U.widget_unit*0.9, &(sa->flag), 0, 0, 0, 0, "Hide pulldown menus"); } @@ -1557,7 +1587,7 @@ int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco) uiBlockSetEmboss(block, UI_EMBOSS); - return xco + UI_UNIT_X; + return xco + U.widget_unit; } /************************ standard UI regions ************************/ @@ -1565,14 +1595,14 @@ int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco) void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *context, int contextnr) { ScrArea *sa = CTX_wm_area(C); - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_GetStyleDraw(); uiBlock *block; PanelType *pt; Panel *panel; View2D *v2d = &ar->v2d; View2DScrollers *scrollers; int x, y, xco, yco, w, em, triangle, open, newcontext = 0; - + if (contextnr >= 0) newcontext = UI_view2d_tab_set(v2d, contextnr); @@ -1608,7 +1638,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * if (pt->draw_header && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) { /* for enabled buttons */ panel->layout = uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, - triangle, UI_UNIT_Y + style->panelspace + 2, UI_UNIT_Y, 1, style); + triangle, (UI_UNIT_Y * 1.1f) + style->panelspace, UI_UNIT_Y, 1, style); pt->draw_header(C, panel); @@ -1653,8 +1683,18 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * uiEndPanels(C, ar, &x, &y); /* clear */ - UI_ThemeClearColor((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK); - glClear(GL_COLOR_BUFFER_BIT); + if (ar->overlap) { + /* view should be in pixelspace */ + UI_view2d_view_restore(C); + glEnable(GL_BLEND); + UI_ThemeColor4((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK); + glRecti(0, 0, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct)); + glDisable(GL_BLEND); + } + else { + UI_ThemeClearColor((ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK); + glClear(GL_COLOR_BUFFER_BIT); + } /* before setting the view */ if (vertical) { @@ -1663,7 +1703,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * v2d->keepofs &= ~(V2D_LOCKOFS_Y | V2D_KEEPOFS_X); v2d->scroll |= V2D_SCROLL_HORIZONTAL_HIDE; v2d->scroll &= ~V2D_SCROLL_VERTICAL_HIDE; - + /* ensure tot is set correctly, to keep views on bottons, with sliders */ y = min_ii(y, v2d->cur.ymin); y = -y; @@ -1684,8 +1724,8 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * y = -y; } - /* +V2D_SCROLL_HEIGHT is workaround to set the actual height */ - UI_view2d_totRect_set(v2d, x + V2D_SCROLL_WIDTH, y + V2D_SCROLL_HEIGHT); + /* +V2D_SCROLL_HEIGHT is workaround to set the actual height (needs to be int) */ + UI_view2d_totRect_set(v2d, x + (int)V2D_SCROLL_WIDTH, y + (int)V2D_SCROLL_HEIGHT); /* set the view */ UI_view2d_view_ortho(v2d); @@ -1725,7 +1765,7 @@ void ED_region_panels_init(wmWindowManager *wm, ARegion *ar) void ED_region_header(const bContext *C, ARegion *ar) { - uiStyle *style = UI_GetStyle(); + uiStyle *style = UI_GetStyleDraw(); uiBlock *block; uiLayout *layout; HeaderType *ht; @@ -1740,8 +1780,8 @@ void ED_region_header(const bContext *C, ARegion *ar) /* set view2d view matrix for scrolling (without scrollers) */ UI_view2d_view_ortho(&ar->v2d); - xco = maxco = 8; - yco = headery - 4; + xco = maxco = 0.4f * UI_UNIT_X; + yco = headery - floor(0.2f * UI_UNIT_Y); /* draw all headers types */ for (ht = ar->type->headertypes.first; ht; ht = ht->next) { @@ -1784,20 +1824,18 @@ void ED_region_header_init(ARegion *ar) /* UI_UNIT_Y is defined as U variable now, depending dpi */ int ED_area_headersize(void) { - return UI_UNIT_Y + 6; + return (int)(1.3f * UI_UNIT_Y); } void ED_region_info_draw(ARegion *ar, const char *text, int block, float alpha) { - const int header_height = 18; - uiStyle *style = UI_GetStyle(); + const int header_height = UI_UNIT_Y; + uiStyle *style = UI_GetStyleDraw(); int fontid = style->widget.uifont_id; rcti rect; - BLF_size(fontid, 11.0f, 72); - /* background box */ - rect = ar->winrct; + ED_region_visible_rect(ar, &rect); rect.xmin = 0; rect.ymin = BLI_rcti_size_y(&ar->winrct) - header_height; @@ -1881,3 +1919,32 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy) } glEnd(); } + +/* If the area has overlapping regions, it returns visible rect for Region *ar */ +/* rect gets returned in local region coordinates */ +void ED_region_visible_rect(ARegion *ar, rcti *rect) +{ + ARegion *arn = ar; + + /* allow function to be called without area */ + while (arn->prev) + arn = arn->prev; + + *rect = ar->winrct; + + /* check if a region overlaps with the current one */ + for (; arn; arn = arn->next) { + if (ar != arn && arn->overlap) { + if (BLI_rcti_isect(rect, &arn->winrct, NULL)) { + /* overlap left */ + if (rect->xmin == arn->winrct.xmin) + rect->xmin = arn->winrct.xmax; + /* overlap right */ + if (rect->xmax == arn->winrct.xmax) + rect->xmax = arn->winrct.xmin; + } + } + } + BLI_rcti_translate(rect, -ar->winrct.xmin, -ar->winrct.ymin); +} + diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index ce2d045dc80..d3947432004 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -33,11 +33,13 @@ #include "MEM_guardedalloc.h" +#include "DNA_userdef_types.h" #include "DNA_vec_types.h" #include "BLI_rect.h" #include "BLI_utildefines.h" +#include "BKE_blender.h" #include "BKE_colortools.h" #include "BLI_math.h" @@ -292,7 +294,10 @@ void setlinestyle(int nr) else { glEnable(GL_LINE_STIPPLE); - glLineStipple(nr, 0xAAAA); + if (U.pixelsize > 1.0f) + glLineStipple(nr, 0xCCCC); + else + glLineStipple(nr, 0xAAAA); } } diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 60aad14efcf..f71d63e5fef 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -263,6 +263,9 @@ int scredge_is_horizontal(ScrEdge *se) ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my) { ScrEdge *se; + int safety = U.widget_unit / 10; + + if (safety < 2) safety = 2; for (se = sc->edgebase.first; se; se = se->next) { if (scredge_is_horizontal(se)) { @@ -270,7 +273,7 @@ ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my) min = MIN2(se->v1->vec.x, se->v2->vec.x); max = MAX2(se->v1->vec.x, se->v2->vec.x); - if (abs(my - se->v1->vec.y) <= 2 && mx >= min && mx <= max) + if (abs(my - se->v1->vec.y) <= safety && mx >= min && mx <= max) return se; } else { @@ -278,7 +281,7 @@ ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my) min = MIN2(se->v1->vec.y, se->v2->vec.y); max = MAX2(se->v1->vec.y, se->v2->vec.y); - if (abs(mx - se->v1->vec.x) <= 2 && my >= min && my <= max) + if (abs(mx - se->v1->vec.x) <= safety && my >= min && my <= max) return se; } } @@ -428,9 +431,9 @@ bScreen *ED_screen_add(wmWindow *win, Scene *scene, const char *name) sc->winid = win->winid; sv1 = screen_addvert(sc, 0, 0); - sv2 = screen_addvert(sc, 0, win->sizey - 1); - sv3 = screen_addvert(sc, win->sizex - 1, win->sizey - 1); - sv4 = screen_addvert(sc, win->sizex - 1, 0); + sv2 = screen_addvert(sc, 0, WM_window_pixels_y(win) - 1); + sv3 = screen_addvert(sc, WM_window_pixels_x(win) - 1, WM_window_pixels_y(win) - 1); + sv4 = screen_addvert(sc, WM_window_pixels_x(win) - 1, 0); screen_addedge(sc, sv1, sv2); screen_addedge(sc, sv2, sv3); @@ -628,7 +631,7 @@ static void screen_test_scale(bScreen *sc, int winsizex, int winsizey) float facx, facy, tempf, min[2], max[2]; /* calculate size */ - min[0] = min[1] = 10000.0f; + min[0] = min[1] = 20000.0f; max[0] = max[1] = 0.0f; for (sv = sc->vertbase.first; sv; sv = sv->next) { @@ -669,6 +672,29 @@ static void screen_test_scale(bScreen *sc, int winsizex, int winsizey) CLAMP(sv->vec.y, 0, winsizey); } + + /* scale prefsizes of regions */ + for (sa = sc->areabase.first; sa; sa = sa->next) { + ARegion *ar; + + for (ar = sa->regionbase.first; ar; ar = ar->next) { + ar->sizex = (int)((float)ar->sizex * facx); + ar->sizey = (int)((float)ar->sizey * facy); + ar->winx = (int)((float)ar->winx * facx); + ar->winy = (int)((float)ar->winy * facy); + } + if (sa->spacedata.first) { + SpaceLink *sl = sa->spacedata.first; + for (sl = sl->next; sl; sl = sl->next) { + for (ar = sl->regionbase.first; ar; ar = ar->next) { + ar->sizex = (int)((float)ar->sizex * facx); + ar->sizey = (int)((float)ar->sizey * facy); + ar->winx = (int)((float)ar->winx * facx); + ar->winy = (int)((float)ar->winy * facy); + } + } + } + } } /* test for collapsed areas. This could happen in some blender version... */ @@ -676,7 +702,7 @@ static void screen_test_scale(bScreen *sc, int winsizex, int winsizey) /* make each window at least ED_area_headersize() high */ for (sa = sc->areabase.first; sa; sa = sa->next) { - int headery = ED_area_headersize() + 1; + int headery = ED_area_headersize() + U.pixelsize; if (sa->v1->vec.y + headery > sa->v2->vec.y) { /* lower edge */ @@ -907,18 +933,18 @@ static void drawscredge_area(ScrArea *sa, int sizex, int sizey, int center) short y1 = sa->v1->vec.y; short x2 = sa->v3->vec.x; short y2 = sa->v3->vec.y; - short a, rt; - - rt = 0; // CLAMPIS(G.debug_value, 0, 16); if (center == 0) { - cpack(0x505050); - for (a = -rt; a <= rt; a++) - if (a != 0) - drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, a); + if (U.pixelsize > 1.0f) { + + glColor3ub(0x50, 0x50, 0x50); + glLineWidth(1.5f * U.pixelsize); + drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, 0); + glLineWidth(1.0f); + } } else { - cpack(0x0); + glColor3ub(0, 0, 0); drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, 0); } } @@ -1002,10 +1028,10 @@ void ED_screen_draw(wmWindow *win) if (sa->flag & AREA_FLAG_DRAWJOINFROM) sa1 = sa; if (sa->flag & AREA_FLAG_DRAWJOINTO) sa2 = sa; if (sa->flag & (AREA_FLAG_DRAWSPLIT_H | AREA_FLAG_DRAWSPLIT_V)) sa3 = sa; - drawscredge_area(sa, win->sizex, win->sizey, 0); + drawscredge_area(sa, WM_window_pixels_x(win), WM_window_pixels_y(win), 0); } for (sa = win->screen->areabase.first; sa; sa = sa->next) - drawscredge_area(sa, win->sizex, win->sizey, 1); + drawscredge_area(sa, WM_window_pixels_x(win), WM_window_pixels_y(win), 1); /* blended join arrow */ if (sa1 && sa2) { @@ -1078,20 +1104,20 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win) rcti winrct; winrct.xmin = 0; - winrct.xmax = win->sizex - 1; + winrct.xmax = WM_window_pixels_x(win) - 1; winrct.ymin = 0; - winrct.ymax = win->sizey - 1; + winrct.ymax = WM_window_pixels_y(win) - 1; + + /* header size depends on DPI, let's verify */ + screen_refresh_headersizes(); - screen_test_scale(win->screen, win->sizex, win->sizey); + screen_test_scale(win->screen, WM_window_pixels_x(win), WM_window_pixels_y(win)); if (win->screen->mainwin == 0) win->screen->mainwin = wm_subwindow_open(win, &winrct); else wm_subwindow_position(win, win->screen->mainwin, &winrct); - /* header size depends on DPI, let's verify */ - screen_refresh_headersizes(); - for (sa = win->screen->areabase.first; sa; sa = sa->next) { /* set spacetype and region callbacks, calls init() */ /* sets subwindows for regions, adds handlers */ @@ -1142,6 +1168,9 @@ void ED_region_exit(bContext *C, ARegion *ar) MEM_freeN(ar->headerstr); ar->headerstr = NULL; + if (ar->regiontimer) + WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), ar->regiontimer); + CTX_wm_region_set(C, prevar); } @@ -1262,9 +1291,12 @@ void ED_screen_set_subwinactive(bContext *C, wmEvent *event) break; } if (sa) { + /* make overlap active when mouse over */ for (ar = sa->regionbase.first; ar; ar = ar->next) { - if (BLI_rcti_isect_pt_v(&ar->winrct, &event->x)) + if (BLI_rcti_isect_pt_v(&ar->winrct, &event->x)) { scr->subwinactive = ar->swinid; + break; + } } } else diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h index 86d99777e98..b811fc46188 100644 --- a/source/blender/editors/screen/screen_intern.h +++ b/source/blender/editors/screen/screen_intern.h @@ -35,10 +35,11 @@ struct wmWindow; struct Scene; -#define AZONESPOT 12 +#define AZONESPOT (0.6f * U.widget_unit) /* area.c */ void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space); +void region_toggle_hidden(bContext *C, ARegion *ar, int do_fade); /* screen_edit.c */ ScrEdge *screen_findedge(bScreen *sc, ScrVert *v1, ScrVert *v2); @@ -57,12 +58,16 @@ ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my); struct AZone *is_in_area_actionzone(ScrArea *sa, const int xy[2]); /* screen_context.c */ -int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result); +int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result); extern const char *screen_context_dir[]; /* doc access */ /* screendump.c */ -void SCREEN_OT_screenshot(struct wmOperatorType *ot); -void SCREEN_OT_screencast(struct wmOperatorType *ot); +void SCREEN_OT_screenshot(struct wmOperatorType *ot); +void SCREEN_OT_screencast(struct wmOperatorType *ot); + +/* screen_ops.c */ +void region_blend_start(struct bContext *C, struct ScrArea *sa, struct ARegion *ar); + #endif /* __SCREEN_INTERN_H__ */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 67d4af916aa..a26f5e87090 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -140,9 +140,11 @@ static int screen_active_editable(bContext *C) /* when mouse is over area-edge */ int ED_operator_screen_mainwinactive(bContext *C) { + bScreen *screen; if (CTX_wm_window(C) == NULL) return 0; - if (CTX_wm_screen(C) == NULL) return 0; - if (CTX_wm_screen(C)->subwinactive != CTX_wm_screen(C)->mainwin) return 0; + screen = CTX_wm_screen(C); + if (screen == NULL) return 0; + if (screen->subwinactive != screen->mainwin) return 0; return 1; } @@ -965,7 +967,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; @@ -975,18 +977,18 @@ static void area_move_set_limits(bScreen *sc, int dir, int *bigger, int *smaller int y1 = sa->v2->vec.y - sa->v1->vec.y - areaminy; /* if top or down edge selected, test height */ - if (sa->v1->flag && sa->v4->flag) + if (sa->v1->editflag && sa->v4->editflag) *bigger = min_ii(*bigger, y1); - else if (sa->v2->flag && sa->v3->flag) + else if (sa->v2->editflag && sa->v3->editflag) *smaller = min_ii(*smaller, y1); } else { int x1 = sa->v4->vec.x - sa->v1->vec.x - AREAMINX; /* if left or right edge selected, test width */ - if (sa->v1->flag && sa->v2->flag) + if (sa->v1->editflag && sa->v2->editflag) *bigger = min_ii(*bigger, x1); - else if (sa->v3->flag && sa->v4->flag) + else if (sa->v3->editflag && sa->v4->editflag) *smaller = min_ii(*smaller, x1); } } @@ -999,6 +1001,7 @@ static int area_move_init(bContext *C, wmOperator *op) bScreen *sc = CTX_wm_screen(C); ScrEdge *actedge; sAreaMoveData *md; + ScrVert *v1; int x, y; /* required properties */ @@ -1017,7 +1020,9 @@ static int area_move_init(bContext *C, wmOperator *op) else md->origval = actedge->v1->vec.x; select_connected_scredge(sc, actedge); - /* now all vertices with 'flag==1' are the ones that can be moved. */ + /* now all vertices with 'flag==1' are the ones that can be moved. Move this to editflag */ + for (v1 = sc->vertbase.first; v1; v1 = v1->next) + v1->editflag = v1->flag; area_move_set_limits(sc, md->dir, &md->bigger, &md->smaller); @@ -1036,27 +1041,27 @@ static void area_move_apply_do(bContext *C, int origval, int delta, int dir, int delta = CLAMPIS(delta, -smaller, bigger); for (v1 = sc->vertbase.first; v1; v1 = v1->next) { - if (v1->flag) { + if (v1->editflag) { /* 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; } } } for (sa = sc->areabase.first; sa; sa = sa->next) { - if (sa->v1->flag || sa->v2->flag || sa->v3->flag || sa->v4->flag) + if (sa->v1->editflag || sa->v2->editflag || sa->v3->editflag || sa->v4->editflag) ED_area_tag_redraw(sa); } @@ -1334,10 +1339,10 @@ static int area_split_apply(bContext *C, wmOperator *op) /* select newly created edge, prepare for moving edge */ for (sv = sc->vertbase.first; sv; sv = sv->next) - sv->flag = 0; + sv->editflag = 0; - sd->nedge->v1->flag = 1; - sd->nedge->v2->flag = 1; + sd->nedge->v1->editflag = 1; + sd->nedge->v2->editflag = 1; if (dir == 'h') sd->origval = sd->nedge->v1->vec.y; else sd->origval = sd->nedge->v1->vec.x; @@ -1720,9 +1725,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 +1739,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; @@ -1786,7 +1791,7 @@ static void region_scale_validate_size(RegionMoveData *rmd) static void region_scale_toggle_hidden(bContext *C, RegionMoveData *rmd) { - ED_region_toggle_hidden(C, rmd->ar); + region_toggle_hidden(C, rmd->ar, 0); region_scale_validate_size(rmd); } @@ -2797,7 +2802,6 @@ static void SCREEN_OT_region_quadview(wmOperatorType *ot) } - /* ************** region flip operator ***************************** */ /* flip a region alignment */ @@ -3413,6 +3417,7 @@ static void SCREEN_OT_back_to_previous(struct wmOperatorType *ot) static int userpref_show_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) { + wmWindow *win = CTX_wm_window(C); rcti rect; int sizex, sizey; @@ -3420,8 +3425,9 @@ static int userpref_show_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *ev sizey = 480; /* some magic to calculate postition */ - rect.xmin = event->x + CTX_wm_window(C)->posx - sizex / 2; - rect.ymin = event->y + CTX_wm_window(C)->posy - sizey / 2; + /* pixelsize: mouse coords are in U.pixelsize units :/ */ + rect.xmin = (event->x / U.pixelsize) + win->posx - sizex / 2; + rect.ymin = (event->y / U.pixelsize) + win->posy - sizey / 2; rect.xmax = rect.xmin + sizex; rect.ymax = rect.ymin + sizey; @@ -3506,7 +3512,7 @@ static int scene_new_exec(bContext *C, wmOperator *op) int type = RNA_enum_get(op->ptr, "type"); if (type == SCE_COPY_NEW) { - newscene = BKE_scene_add("Scene"); + newscene = BKE_scene_add(bmain, "Scene"); } else { /* different kinds of copying */ newscene = BKE_scene_copy(scene, type); @@ -3583,6 +3589,149 @@ 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.2f +#define TIMESTEP 0.04f + +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.9f - 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 > (double)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 +3764,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 +3867,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); |