diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:17:24 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:21:24 +0300 |
commit | e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch) | |
tree | 8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/editors/screen | |
parent | b3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff) |
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211.
For details on usage and instructions for migrating branches
without conflicts, see:
https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/editors/screen')
-rw-r--r-- | source/blender/editors/screen/CMakeLists.txt | 64 | ||||
-rw-r--r-- | source/blender/editors/screen/area.c | 5138 | ||||
-rw-r--r-- | source/blender/editors/screen/area_utils.c | 58 | ||||
-rw-r--r-- | source/blender/editors/screen/glutil.c | 1017 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_context.c | 1302 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_draw.c | 829 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_edit.c | 2422 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_geometry.c | 678 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_intern.h | 83 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 6827 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_user_menu.c | 351 | ||||
-rw-r--r-- | source/blender/editors/screen/screendump.c | 343 | ||||
-rw-r--r-- | source/blender/editors/screen/workspace_edit.c | 714 | ||||
-rw-r--r-- | source/blender/editors/screen/workspace_layout_edit.c | 225 |
14 files changed, 10234 insertions, 9817 deletions
diff --git a/source/blender/editors/screen/CMakeLists.txt b/source/blender/editors/screen/CMakeLists.txt index 11516a73d1e..daa72ac194c 100644 --- a/source/blender/editors/screen/CMakeLists.txt +++ b/source/blender/editors/screen/CMakeLists.txt @@ -16,51 +16,51 @@ # ***** END GPL LICENSE BLOCK ***** set(INC - ../include - ../../blenfont - ../../blenkernel - ../../blenlib - ../../blenloader - ../../blentranslation - ../../bmesh - ../../depsgraph - ../../gpu - ../../imbuf - ../../makesdna - ../../makesrna - ../../windowmanager - ../../../../intern/guardedalloc - ../../../../intern/glew-mx + ../include + ../../blenfont + ../../blenkernel + ../../blenlib + ../../blenloader + ../../blentranslation + ../../bmesh + ../../depsgraph + ../../gpu + ../../imbuf + ../../makesdna + ../../makesrna + ../../windowmanager + ../../../../intern/guardedalloc + ../../../../intern/glew-mx ) set(INC_SYS - ${GLEW_INCLUDE_PATH} + ${GLEW_INCLUDE_PATH} ) set(SRC - area.c - area_utils.c - glutil.c - screen_context.c - screen_draw.c - screen_edit.c - screen_geometry.c - screen_ops.c - screen_user_menu.c - screendump.c - workspace_edit.c - workspace_layout_edit.c + area.c + area_utils.c + glutil.c + screen_context.c + screen_draw.c + screen_edit.c + screen_geometry.c + screen_ops.c + screen_user_menu.c + screendump.c + workspace_edit.c + workspace_layout_edit.c - screen_intern.h + screen_intern.h ) set(LIB - bf_editor_datafiles - bf_editor_space_sequencer + bf_editor_datafiles + bf_editor_space_sequencer ) if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) + add_definitions(-DWITH_INTERNATIONAL) endif() add_definitions(${GL_DEFINITIONS}) diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index e01f6e04086..4ca26d108a2 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -21,7 +21,6 @@ * \ingroup edscr */ - #include <string.h> #include <stdio.h> @@ -73,111 +72,114 @@ #include "screen_intern.h" enum RegionEmbossSide { - REGION_EMBOSS_LEFT = (1 << 0), - REGION_EMBOSS_TOP = (1 << 1), - REGION_EMBOSS_BOTTOM = (1 << 2), - REGION_EMBOSS_RIGHT = (1 << 3), - REGION_EMBOSS_ALL = REGION_EMBOSS_LEFT | REGION_EMBOSS_TOP | REGION_EMBOSS_RIGHT | REGION_EMBOSS_BOTTOM, + REGION_EMBOSS_LEFT = (1 << 0), + REGION_EMBOSS_TOP = (1 << 1), + REGION_EMBOSS_BOTTOM = (1 << 2), + REGION_EMBOSS_RIGHT = (1 << 3), + REGION_EMBOSS_ALL = REGION_EMBOSS_LEFT | REGION_EMBOSS_TOP | REGION_EMBOSS_RIGHT | + REGION_EMBOSS_BOTTOM, }; /* general area and region code */ static void region_draw_emboss(const ARegion *ar, const rcti *scirct, int sides) { - rcti rect; + rcti rect; - /* translate scissor rect to region space */ - rect.xmin = scirct->xmin - ar->winrct.xmin; - rect.ymin = scirct->ymin - ar->winrct.ymin; - rect.xmax = scirct->xmax - ar->winrct.xmin; - rect.ymax = scirct->ymax - ar->winrct.ymin; + /* translate scissor rect to region space */ + rect.xmin = scirct->xmin - ar->winrct.xmin; + rect.ymin = scirct->ymin - ar->winrct.ymin; + rect.xmax = scirct->xmax - ar->winrct.xmin; + rect.ymax = scirct->ymax - ar->winrct.ymin; - /* set transp line */ - GPU_blend(true); - GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + /* set transp line */ + GPU_blend(true); + GPU_blend_set_func_separate( + GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - float color[4] = {0.0f, 0.0f, 0.0f, 0.25f}; - UI_GetThemeColor3fv(TH_EDITOR_OUTLINE, color); + float color[4] = {0.0f, 0.0f, 0.0f, 0.25f}; + UI_GetThemeColor3fv(TH_EDITOR_OUTLINE, color); - GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - immUniformColor4fv(color); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor4fv(color); - immBeginAtMost(GPU_PRIM_LINES, 8); + immBeginAtMost(GPU_PRIM_LINES, 8); - /* right */ - if (sides & REGION_EMBOSS_RIGHT) { - immVertex2f(pos, rect.xmax, rect.ymax); - immVertex2f(pos, rect.xmax, rect.ymin); - } + /* right */ + if (sides & REGION_EMBOSS_RIGHT) { + immVertex2f(pos, rect.xmax, rect.ymax); + immVertex2f(pos, rect.xmax, rect.ymin); + } - /* bottom */ - if (sides & REGION_EMBOSS_BOTTOM) { - immVertex2f(pos, rect.xmax, rect.ymin); - immVertex2f(pos, rect.xmin, rect.ymin); - } + /* bottom */ + if (sides & REGION_EMBOSS_BOTTOM) { + immVertex2f(pos, rect.xmax, rect.ymin); + immVertex2f(pos, rect.xmin, rect.ymin); + } - /* left */ - if (sides & REGION_EMBOSS_LEFT) { - immVertex2f(pos, rect.xmin, rect.ymin); - immVertex2f(pos, rect.xmin, rect.ymax); - } + /* left */ + if (sides & REGION_EMBOSS_LEFT) { + immVertex2f(pos, rect.xmin, rect.ymin); + immVertex2f(pos, rect.xmin, rect.ymax); + } - /* top */ - if (sides & REGION_EMBOSS_TOP) { - immVertex2f(pos, rect.xmin, rect.ymax); - immVertex2f(pos, rect.xmax, rect.ymax); - } + /* top */ + if (sides & REGION_EMBOSS_TOP) { + immVertex2f(pos, rect.xmin, rect.ymax); + immVertex2f(pos, rect.xmax, rect.ymax); + } - immEnd(); - immUnbindProgram(); + immEnd(); + immUnbindProgram(); - GPU_blend(false); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + GPU_blend(false); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } void ED_region_pixelspace(ARegion *ar) { - wmOrtho2_region_pixelspace(ar); - GPU_matrix_identity_set(); + wmOrtho2_region_pixelspace(ar); + GPU_matrix_identity_set(); } /* only exported for WM */ -void ED_region_do_listen(wmWindow *win, ScrArea *sa, ARegion *ar, wmNotifier *note, const Scene *scene) +void ED_region_do_listen( + wmWindow *win, ScrArea *sa, ARegion *ar, wmNotifier *note, const Scene *scene) { - /* generic notes first */ - switch (note->category) { - case NC_WM: - if (note->data == ND_FILEREAD) - ED_region_tag_redraw(ar); - break; - case NC_WINDOW: - ED_region_tag_redraw(ar); - break; - } + /* generic notes first */ + switch (note->category) { + case NC_WM: + if (note->data == ND_FILEREAD) + ED_region_tag_redraw(ar); + break; + case NC_WINDOW: + ED_region_tag_redraw(ar); + break; + } - if (ar->type && ar->type->listener) - ar->type->listener(win, sa, ar, note, scene); + if (ar->type && ar->type->listener) + ar->type->listener(win, sa, ar, note, scene); } /* only exported for WM */ void ED_area_do_listen(wmWindow *win, ScrArea *sa, wmNotifier *note, Scene *scene) { - /* no generic notes? */ - if (sa->type && sa->type->listener) { - sa->type->listener(win, sa, note, scene); - } + /* no generic notes? */ + if (sa->type && sa->type->listener) { + sa->type->listener(win, sa, note, scene); + } } /* only exported for WM */ void ED_area_do_refresh(bContext *C, ScrArea *sa) { - /* no generic notes? */ - if (sa->type && sa->type->refresh) { - sa->type->refresh(C, sa); - } - sa->do_refresh = false; + /* no generic notes? */ + if (sa->type && sa->type->refresh) { + sa->type->refresh(C, sa); + } + sa->do_refresh = false; } /** @@ -185,49 +187,49 @@ void ED_area_do_refresh(bContext *C, ScrArea *sa) */ static void area_draw_azone_fullscreen(short x1, short y1, short x2, short y2, float alpha) { - int x = x2 - ((float) x2 - x1) * 0.5f / UI_DPI_FAC; - int y = y2 - ((float) y2 - y1) * 0.5f / UI_DPI_FAC; + int x = x2 - ((float)x2 - x1) * 0.5f / UI_DPI_FAC; + int y = y2 - ((float)y2 - y1) * 0.5f / UI_DPI_FAC; - /* adjust the icon distance from the corner */ - x += 36.0f / UI_DPI_FAC; - y += 36.0f / UI_DPI_FAC; + /* adjust the icon distance from the corner */ + x += 36.0f / UI_DPI_FAC; + y += 36.0f / UI_DPI_FAC; - /* draws from the left bottom corner of the icon */ - x -= UI_DPI_ICON_SIZE; - y -= UI_DPI_ICON_SIZE; + /* draws from the left bottom corner of the icon */ + x -= UI_DPI_ICON_SIZE; + y -= UI_DPI_ICON_SIZE; - alpha = min_ff(alpha, 0.75f); + alpha = min_ff(alpha, 0.75f); - UI_icon_draw_aspect(x, y, ICON_FULLSCREEN_EXIT, 0.7f / UI_DPI_FAC, alpha, NULL); + UI_icon_draw_aspect(x, y, ICON_FULLSCREEN_EXIT, 0.7f / UI_DPI_FAC, alpha, NULL); - /* debug drawing : - * The click_rect is the same as defined in fullscreen_click_rcti_init - * Keep them both in sync */ + /* debug drawing : + * The click_rect is the same as defined in fullscreen_click_rcti_init + * Keep them both in sync */ - if (G.debug_value == 101) { - rcti click_rect; - float icon_size = UI_DPI_ICON_SIZE + 7 * UI_DPI_FAC; + if (G.debug_value == 101) { + rcti click_rect; + float icon_size = UI_DPI_ICON_SIZE + 7 * UI_DPI_FAC; - BLI_rcti_init(&click_rect, x, x + icon_size, y, y + icon_size); + BLI_rcti_init(&click_rect, x, x + icon_size, y, y + icon_size); - GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - immUniformColor4f(1.0f, 0.0f, 0.0f, alpha); - imm_draw_box_wire_2d(pos, click_rect.xmin, click_rect.ymin, click_rect.xmax, click_rect.ymax); + immUniformColor4f(1.0f, 0.0f, 0.0f, alpha); + imm_draw_box_wire_2d(pos, click_rect.xmin, click_rect.ymin, click_rect.xmax, click_rect.ymax); - immUniformColor4f(0.0f, 1.0f, 1.0f, alpha); - immBegin(GPU_PRIM_LINES, 4); - immVertex2f(pos, click_rect.xmin, click_rect.ymin); - immVertex2f(pos, click_rect.xmax, click_rect.ymax); - immVertex2f(pos, click_rect.xmin, click_rect.ymax); - immVertex2f(pos, click_rect.xmax, click_rect.ymin); - immEnd(); + immUniformColor4f(0.0f, 1.0f, 1.0f, alpha); + immBegin(GPU_PRIM_LINES, 4); + immVertex2f(pos, click_rect.xmin, click_rect.ymin); + immVertex2f(pos, click_rect.xmax, click_rect.ymax); + immVertex2f(pos, click_rect.xmin, click_rect.ymax); + immVertex2f(pos, click_rect.xmax, click_rect.ymin); + immEnd(); - immUnbindProgram(); - } + immUnbindProgram(); + } } /** @@ -235,7 +237,7 @@ static void area_draw_azone_fullscreen(short x1, short y1, short x2, short y2, f */ static void area_draw_azone(short UNUSED(x1), short UNUSED(y1), short UNUSED(x2), short UNUSED(y2)) { - /* No drawing needed since all corners are action zone, and visually distinguishable. */ + /* No drawing needed since all corners are action zone, and visually distinguishable. */ } /** @@ -243,204 +245,210 @@ static void area_draw_azone(short UNUSED(x1), short UNUSED(y1), short UNUSED(x2) */ static void draw_azone_arrow(float x1, float y1, float x2, float y2, AZEdge edge) { - const float size = 0.2f * U.widget_unit; - const float l = 1.0f; /* arrow length */ - const float s = 0.25f; /* arrow thickness */ - const float hl = l / 2.0f; - const float points[6][2] = {{0, -hl}, {l, hl}, {l - s, hl + s}, {0, s + s - hl}, {s - l, hl + s}, {-l, hl}}; - const float center[2] = {(x1 + x2) / 2, (y1 + y2) / 2}; - - int axis; - int sign; - switch (edge) { - case AE_BOTTOM_TO_TOPLEFT: - axis = 0; - sign = 1; - break; - case AE_TOP_TO_BOTTOMRIGHT: - axis = 0; - sign = -1; - break; - case AE_LEFT_TO_TOPRIGHT: - axis = 1; - sign = 1; - break; - case AE_RIGHT_TO_TOPLEFT: - axis = 1; - sign = -1; - break; - default: - BLI_assert(0); - return; - } - - GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - - GPU_blend(true); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - immUniformColor4f(0.8f, 0.8f, 0.8f, 0.4f); - - immBegin(GPU_PRIM_TRI_FAN, 6); - for (int i = 0; i < 6; i++) { - if (axis == 0) { - immVertex2f(pos, center[0] + points[i][0] * size, center[1] + points[i][1] * sign * size); - } - else { - immVertex2f(pos, center[0] + points[i][1] * sign * size, center[1] + points[i][0] * size); - } - } - immEnd(); - - immUnbindProgram(); - GPU_blend(false); + const float size = 0.2f * U.widget_unit; + const float l = 1.0f; /* arrow length */ + const float s = 0.25f; /* arrow thickness */ + const float hl = l / 2.0f; + const float points[6][2] = { + {0, -hl}, {l, hl}, {l - s, hl + s}, {0, s + s - hl}, {s - l, hl + s}, {-l, hl}}; + const float center[2] = {(x1 + x2) / 2, (y1 + y2) / 2}; + + int axis; + int sign; + switch (edge) { + case AE_BOTTOM_TO_TOPLEFT: + axis = 0; + sign = 1; + break; + case AE_TOP_TO_BOTTOMRIGHT: + axis = 0; + sign = -1; + break; + case AE_LEFT_TO_TOPRIGHT: + axis = 1; + sign = 1; + break; + case AE_RIGHT_TO_TOPLEFT: + axis = 1; + sign = -1; + break; + default: + BLI_assert(0); + return; + } + + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + + GPU_blend(true); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor4f(0.8f, 0.8f, 0.8f, 0.4f); + + immBegin(GPU_PRIM_TRI_FAN, 6); + for (int i = 0; i < 6; i++) { + if (axis == 0) { + immVertex2f(pos, center[0] + points[i][0] * size, center[1] + points[i][1] * sign * size); + } + else { + immVertex2f(pos, center[0] + points[i][1] * sign * size, center[1] + points[i][0] * size); + } + } + immEnd(); + + immUnbindProgram(); + GPU_blend(false); } static void region_draw_azone_tab_arrow(AZone *az) { - GPU_blend(true); + GPU_blend(true); - /* add code to draw region hidden as 'too small' */ - switch (az->edge) { - case AE_TOP_TO_BOTTOMRIGHT: - UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT); - break; - case AE_BOTTOM_TO_TOPLEFT: - UI_draw_roundbox_corner_set(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT); - break; - case AE_LEFT_TO_TOPRIGHT: - UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT); - break; - case AE_RIGHT_TO_TOPLEFT: - UI_draw_roundbox_corner_set(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT); - break; - } + /* add code to draw region hidden as 'too small' */ + switch (az->edge) { + case AE_TOP_TO_BOTTOMRIGHT: + UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT); + break; + case AE_BOTTOM_TO_TOPLEFT: + UI_draw_roundbox_corner_set(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT); + break; + case AE_LEFT_TO_TOPRIGHT: + UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT); + break; + case AE_RIGHT_TO_TOPLEFT: + UI_draw_roundbox_corner_set(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT); + break; + } - float color[4] = {0.05f, 0.05f, 0.05f, 0.4f}; - UI_draw_roundbox_aa(true, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, color); + float color[4] = {0.05f, 0.05f, 0.05f, 0.4f}; + UI_draw_roundbox_aa( + true, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, color); - draw_azone_arrow((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, az->edge); + draw_azone_arrow((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, az->edge); } static void area_azone_tag_update(ScrArea *sa) { - sa->flag |= AREA_FLAG_ACTIONZONES_UPDATE; + sa->flag |= AREA_FLAG_ACTIONZONES_UPDATE; } static void region_draw_azones(ScrArea *sa, ARegion *ar) { - AZone *az; - - if (!sa) - return; - - GPU_line_width(1.0f); - GPU_blend(true); - GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - - GPU_matrix_push(); - GPU_matrix_translate_2f(-ar->winrct.xmin, -ar->winrct.ymin); - - for (az = sa->actionzones.first; az; az = az->next) { - /* test if action zone is over this region */ - rcti azrct; - BLI_rcti_init(&azrct, az->x1, az->x2, az->y1, az->y2); - - if (BLI_rcti_isect(&ar->drawrct, &azrct, NULL)) { - if (az->type == AZONE_AREA) { - area_draw_azone(az->x1, az->y1, az->x2, az->y2); - } - else if (az->type == AZONE_REGION) { - if (az->ar) { - /* only display tab or icons when the region is hidden */ - if (az->ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) { - region_draw_azone_tab_arrow(az); - } - } - } - else if (az->type == AZONE_FULLSCREEN) { - area_draw_azone_fullscreen(az->x1, az->y1, az->x2, az->y2, az->alpha); - } - } - if (!IS_EQF(az->alpha, 0.0f) && ELEM(az->type, AZONE_FULLSCREEN, AZONE_REGION_SCROLL)) { - area_azone_tag_update(sa); - } - } - - GPU_matrix_pop(); - - GPU_blend(false); + AZone *az; + + if (!sa) + return; + + GPU_line_width(1.0f); + GPU_blend(true); + GPU_blend_set_func_separate( + GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + + GPU_matrix_push(); + GPU_matrix_translate_2f(-ar->winrct.xmin, -ar->winrct.ymin); + + for (az = sa->actionzones.first; az; az = az->next) { + /* test if action zone is over this region */ + rcti azrct; + BLI_rcti_init(&azrct, az->x1, az->x2, az->y1, az->y2); + + if (BLI_rcti_isect(&ar->drawrct, &azrct, NULL)) { + if (az->type == AZONE_AREA) { + area_draw_azone(az->x1, az->y1, az->x2, az->y2); + } + else if (az->type == AZONE_REGION) { + if (az->ar) { + /* only display tab or icons when the region is hidden */ + if (az->ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) { + region_draw_azone_tab_arrow(az); + } + } + } + else if (az->type == AZONE_FULLSCREEN) { + area_draw_azone_fullscreen(az->x1, az->y1, az->x2, az->y2, az->alpha); + } + } + if (!IS_EQF(az->alpha, 0.0f) && ELEM(az->type, AZONE_FULLSCREEN, AZONE_REGION_SCROLL)) { + area_azone_tag_update(sa); + } + } + + GPU_matrix_pop(); + + GPU_blend(false); } static void region_draw_status_text(ScrArea *sa, ARegion *ar) { - bool overlap = ED_region_is_overlap(sa->spacetype, ar->regiontype); + bool overlap = ED_region_is_overlap(sa->spacetype, ar->regiontype); - if (overlap) { - GPU_clear_color(0.0, 0.0, 0.0, 0.0); - glClear(GL_COLOR_BUFFER_BIT); - } - else { - UI_ThemeClearColor(TH_HEADER); - glClear(GL_COLOR_BUFFER_BIT); - } + if (overlap) { + GPU_clear_color(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + } + else { + UI_ThemeClearColor(TH_HEADER); + glClear(GL_COLOR_BUFFER_BIT); + } - int fontid = BLF_set_default(); + int fontid = BLF_set_default(); - const float width = BLF_width(fontid, ar->headerstr, BLF_DRAW_STR_DUMMY_MAX); - const float x = UI_UNIT_X; - const float y = 0.4f * UI_UNIT_Y; + const float width = BLF_width(fontid, ar->headerstr, BLF_DRAW_STR_DUMMY_MAX); + const float x = UI_UNIT_X; + const float y = 0.4f * UI_UNIT_Y; - if (overlap) { - const float pad = 2.0f * UI_DPI_FAC; - const float x1 = x - (UI_UNIT_X - pad); - const float x2 = x + width + (UI_UNIT_X - pad); - const float y1 = pad; - const float y2 = ar->winy - pad; + if (overlap) { + const float pad = 2.0f * UI_DPI_FAC; + const float x1 = x - (UI_UNIT_X - pad); + const float x2 = x + width + (UI_UNIT_X - pad); + const float y1 = pad; + const float y2 = ar->winy - pad; - GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend_set_func_separate( + GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - float color[4] = {0.0f, 0.0f, 0.0f, 0.5f}; - UI_GetThemeColor3fv(TH_BACK, color); - UI_draw_roundbox_corner_set(UI_CNR_ALL); - UI_draw_roundbox_aa(true, x1, y1, x2, y2, 4.0f, color); + float color[4] = {0.0f, 0.0f, 0.0f, 0.5f}; + UI_GetThemeColor3fv(TH_BACK, color); + UI_draw_roundbox_corner_set(UI_CNR_ALL); + UI_draw_roundbox_aa(true, x1, y1, x2, y2, 4.0f, color); - UI_FontThemeColor(fontid, TH_TEXT); - } - else { - UI_FontThemeColor(fontid, TH_TEXT); - } + UI_FontThemeColor(fontid, TH_TEXT); + } + else { + UI_FontThemeColor(fontid, TH_TEXT); + } - BLF_position(fontid, x, y, 0.0f); - BLF_draw(fontid, ar->headerstr, BLF_DRAW_STR_DUMMY_MAX); + BLF_position(fontid, x, y, 0.0f); + BLF_draw(fontid, ar->headerstr, BLF_DRAW_STR_DUMMY_MAX); } /* Follow wmMsgNotifyFn spec */ -void ED_region_do_msg_notify_tag_redraw( - bContext *UNUSED(C), wmMsgSubscribeKey *UNUSED(msg_key), wmMsgSubscribeValue *msg_val) -{ - ARegion *ar = msg_val->owner; - ED_region_tag_redraw(ar); - - /* This avoids _many_ situations where header/properties control display settings. - * the common case is space properties in the header */ - if (ELEM(ar->regiontype, RGN_TYPE_HEADER, RGN_TYPE_UI)) { - while (ar && ar->prev) { - ar = ar->prev; - } - for (; ar; ar = ar->next) { - if (ELEM(ar->regiontype, RGN_TYPE_WINDOW, RGN_TYPE_CHANNELS)) { - ED_region_tag_redraw(ar); - } - } - } +void ED_region_do_msg_notify_tag_redraw(bContext *UNUSED(C), + wmMsgSubscribeKey *UNUSED(msg_key), + wmMsgSubscribeValue *msg_val) +{ + ARegion *ar = msg_val->owner; + ED_region_tag_redraw(ar); + + /* This avoids _many_ situations where header/properties control display settings. + * the common case is space properties in the header */ + if (ELEM(ar->regiontype, RGN_TYPE_HEADER, RGN_TYPE_UI)) { + while (ar && ar->prev) { + ar = ar->prev; + } + for (; ar; ar = ar->next) { + if (ELEM(ar->regiontype, RGN_TYPE_WINDOW, RGN_TYPE_CHANNELS)) { + ED_region_tag_redraw(ar); + } + } + } } /* Follow wmMsgNotifyFn spec */ -void ED_area_do_msg_notify_tag_refresh( - bContext *UNUSED(C), wmMsgSubscribeKey *UNUSED(msg_key), wmMsgSubscribeValue *msg_val) +void ED_area_do_msg_notify_tag_refresh(bContext *UNUSED(C), + wmMsgSubscribeKey *UNUSED(msg_key), + wmMsgSubscribeValue *msg_val) { - ScrArea *sa = msg_val->user_data; - ED_area_tag_refresh(sa); + ScrArea *sa = msg_val->user_data; + ED_area_tag_refresh(sa); } /** @@ -451,140 +459,141 @@ void ED_area_do_msg_notify_tag_refresh( */ static bool area_is_pseudo_minimized(const ScrArea *area) { - return (area->winx < 3) || (area->winy < 3); + return (area->winx < 3) || (area->winy < 3); } /* only exported for WM */ void ED_region_do_layout(bContext *C, ARegion *ar) { - /* This is optional, only needed for dynamically sized regions. */ - ScrArea *sa = CTX_wm_area(C); - ARegionType *at = ar->type; + /* This is optional, only needed for dynamically sized regions. */ + ScrArea *sa = CTX_wm_area(C); + ARegionType *at = ar->type; - if (!at->layout) { - return; - } + if (!at->layout) { + return; + } - if (at->do_lock || (sa && area_is_pseudo_minimized(sa))) { - return; - } + if (at->do_lock || (sa && area_is_pseudo_minimized(sa))) { + return; + } - ar->do_draw |= RGN_DRAWING; + ar->do_draw |= RGN_DRAWING; - UI_SetTheme(sa ? sa->spacetype : 0, at->regionid); - at->layout(C, ar); + UI_SetTheme(sa ? sa->spacetype : 0, at->regionid); + at->layout(C, ar); } /* only exported for WM */ 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; + wmWindow *win = CTX_wm_window(C); + ScrArea *sa = CTX_wm_area(C); + ARegionType *at = ar->type; - /* see BKE_spacedata_draw_locks() */ - if (at->do_lock) - return; + /* see BKE_spacedata_draw_locks() */ + if (at->do_lock) + return; - ar->do_draw |= RGN_DRAWING; + ar->do_draw |= RGN_DRAWING; - /* Set viewport, scissor, ortho and ar->drawrct. */ - wmPartialViewport(&ar->drawrct, &ar->winrct, &ar->drawrct); + /* Set viewport, scissor, ortho and ar->drawrct. */ + wmPartialViewport(&ar->drawrct, &ar->winrct, &ar->drawrct); - wmOrtho2_region_pixelspace(ar); + wmOrtho2_region_pixelspace(ar); - UI_SetTheme(sa ? sa->spacetype : 0, at->regionid); + UI_SetTheme(sa ? sa->spacetype : 0, at->regionid); - if (sa && area_is_pseudo_minimized(sa)) { - UI_ThemeClearColor(TH_EDITOR_OUTLINE); - glClear(GL_COLOR_BUFFER_BIT); - return; - } - /* optional header info instead? */ - else if (ar->headerstr) { - region_draw_status_text(sa, ar); - } - else if (at->draw) { - at->draw(C, ar); - } + if (sa && area_is_pseudo_minimized(sa)) { + UI_ThemeClearColor(TH_EDITOR_OUTLINE); + glClear(GL_COLOR_BUFFER_BIT); + return; + } + /* optional header info instead? */ + else if (ar->headerstr) { + region_draw_status_text(sa, ar); + } + else if (at->draw) { + at->draw(C, ar); + } - /* XXX test: add convention to end regions always in pixel space, for drawing of borders/gestures etc */ - ED_region_pixelspace(ar); + /* XXX test: add convention to end regions always in pixel space, for drawing of borders/gestures etc */ + ED_region_pixelspace(ar); - ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_PIXEL); + ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_PIXEL); - region_draw_azones(sa, ar); + region_draw_azones(sa, ar); - /* for debugging unneeded area redraws and partial redraw */ + /* for debugging unneeded area redraws and partial redraw */ #if 0 - GPU_blend(true); - GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - immUniformColor4f(drand48(), drand48(), drand48(), 0.1f); - immRectf(pos, ar->drawrct.xmin - ar->winrct.xmin, ar->drawrct.ymin - ar->winrct.ymin, - ar->drawrct.xmax - ar->winrct.xmin, ar->drawrct.ymax - ar->winrct.ymin); - immUnbindProgram(); - GPU_blend(false); + GPU_blend(true); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor4f(drand48(), drand48(), drand48(), 0.1f); + immRectf(pos, ar->drawrct.xmin - ar->winrct.xmin, ar->drawrct.ymin - ar->winrct.ymin, + ar->drawrct.xmax - ar->winrct.xmin, ar->drawrct.ymax - ar->winrct.ymin); + immUnbindProgram(); + GPU_blend(false); #endif - memset(&ar->drawrct, 0, sizeof(ar->drawrct)); - - UI_blocklist_free_inactive(C, &ar->uiblocks); - - if (sa) { - const bScreen *screen = WM_window_get_active_screen(win); - - /* Only region emboss for top-bar */ - if ((screen->state != SCREENFULL) && ED_area_is_global(sa)) { - region_draw_emboss(ar, &ar->winrct, (REGION_EMBOSS_LEFT | REGION_EMBOSS_RIGHT)); - } - else if ((ar->regiontype == RGN_TYPE_WINDOW) && (ar->alignment == RGN_ALIGN_QSPLIT)) { - - /* draw separating lines between the quad views */ - - float color[4] = { 0.0f, 0.0f, 0.0f, 0.8f }; - UI_GetThemeColor3fv(TH_EDITOR_OUTLINE, color); - GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - immUniformColor4fv(color); - GPU_line_width(1.0f); - imm_draw_box_wire_2d(pos, 0, 0, ar->winrct.xmax - ar->winrct.xmin + 1, ar->winrct.ymax - ar->winrct.ymin + 1); - immUnbindProgram(); - } - } - - /* We may want to detach message-subscriptions from drawing. */ - { - WorkSpace *workspace = CTX_wm_workspace(C); - wmWindowManager *wm = CTX_wm_manager(C); - bScreen *screen = WM_window_get_active_screen(win); - Scene *scene = CTX_data_scene(C); - struct wmMsgBus *mbus = wm->message_bus; - WM_msgbus_clear_by_owner(mbus, ar); - - /* Cheat, always subscribe to this space type properties. - * - * This covers most cases and avoids copy-paste similar code for each space type. - */ - if (ELEM(ar->regiontype, RGN_TYPE_WINDOW, RGN_TYPE_CHANNELS, RGN_TYPE_UI, RGN_TYPE_TOOLS)) { - SpaceLink *sl = sa->spacedata.first; - - PointerRNA ptr; - RNA_pointer_create(&screen->id, &RNA_Space, sl, &ptr); - - wmMsgSubscribeValue msg_sub_value_region_tag_redraw = { - .owner = ar, - .user_data = ar, - .notify = ED_region_do_msg_notify_tag_redraw, - }; - /* All properties for this space type. */ - WM_msg_subscribe_rna(mbus, &ptr, NULL, &msg_sub_value_region_tag_redraw, __func__); - } - - ED_region_message_subscribe(C, workspace, scene, screen, sa, ar, mbus); - } + memset(&ar->drawrct, 0, sizeof(ar->drawrct)); + + UI_blocklist_free_inactive(C, &ar->uiblocks); + + if (sa) { + const bScreen *screen = WM_window_get_active_screen(win); + + /* Only region emboss for top-bar */ + if ((screen->state != SCREENFULL) && ED_area_is_global(sa)) { + region_draw_emboss(ar, &ar->winrct, (REGION_EMBOSS_LEFT | REGION_EMBOSS_RIGHT)); + } + else if ((ar->regiontype == RGN_TYPE_WINDOW) && (ar->alignment == RGN_ALIGN_QSPLIT)) { + + /* draw separating lines between the quad views */ + + float color[4] = {0.0f, 0.0f, 0.0f, 0.8f}; + UI_GetThemeColor3fv(TH_EDITOR_OUTLINE, color); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor4fv(color); + GPU_line_width(1.0f); + imm_draw_box_wire_2d( + pos, 0, 0, ar->winrct.xmax - ar->winrct.xmin + 1, ar->winrct.ymax - ar->winrct.ymin + 1); + immUnbindProgram(); + } + } + + /* We may want to detach message-subscriptions from drawing. */ + { + WorkSpace *workspace = CTX_wm_workspace(C); + wmWindowManager *wm = CTX_wm_manager(C); + bScreen *screen = WM_window_get_active_screen(win); + Scene *scene = CTX_data_scene(C); + struct wmMsgBus *mbus = wm->message_bus; + WM_msgbus_clear_by_owner(mbus, ar); + + /* Cheat, always subscribe to this space type properties. + * + * This covers most cases and avoids copy-paste similar code for each space type. + */ + if (ELEM(ar->regiontype, RGN_TYPE_WINDOW, RGN_TYPE_CHANNELS, RGN_TYPE_UI, RGN_TYPE_TOOLS)) { + SpaceLink *sl = sa->spacedata.first; + + PointerRNA ptr; + RNA_pointer_create(&screen->id, &RNA_Space, sl, &ptr); + + wmMsgSubscribeValue msg_sub_value_region_tag_redraw = { + .owner = ar, + .user_data = ar, + .notify = ED_region_do_msg_notify_tag_redraw, + }; + /* All properties for this space type. */ + WM_msg_subscribe_rna(mbus, &ptr, NULL, &msg_sub_value_region_tag_redraw, __func__); + } + + ED_region_message_subscribe(C, workspace, scene, screen, sa, ar, mbus); + } } /* ********************************** @@ -594,93 +603,93 @@ void ED_region_do_draw(bContext *C, ARegion *ar) void ED_region_tag_redraw(ARegion *ar) { - /* don't tag redraw while drawing, it shouldn't happen normally - * but python scripts can cause this to happen indirectly */ - if (ar && !(ar->do_draw & RGN_DRAWING)) { - /* zero region means full region redraw */ - ar->do_draw &= ~(RGN_DRAW_PARTIAL | RGN_DRAW_NO_REBUILD); - ar->do_draw |= RGN_DRAW; - memset(&ar->drawrct, 0, sizeof(ar->drawrct)); - } + /* don't tag redraw while drawing, it shouldn't happen normally + * but python scripts can cause this to happen indirectly */ + if (ar && !(ar->do_draw & RGN_DRAWING)) { + /* zero region means full region redraw */ + ar->do_draw &= ~(RGN_DRAW_PARTIAL | RGN_DRAW_NO_REBUILD); + ar->do_draw |= RGN_DRAW; + memset(&ar->drawrct, 0, sizeof(ar->drawrct)); + } } void ED_region_tag_redraw_overlay(ARegion *ar) { - if (ar) - ar->do_draw_overlay = RGN_DRAW; + if (ar) + ar->do_draw_overlay = RGN_DRAW; } void ED_region_tag_redraw_no_rebuild(ARegion *ar) { - if (ar && !(ar->do_draw & (RGN_DRAWING | RGN_DRAW))) { - ar->do_draw &= ~RGN_DRAW_PARTIAL; - ar->do_draw |= RGN_DRAW_NO_REBUILD; - memset(&ar->drawrct, 0, sizeof(ar->drawrct)); - } + if (ar && !(ar->do_draw & (RGN_DRAWING | RGN_DRAW))) { + ar->do_draw &= ~RGN_DRAW_PARTIAL; + ar->do_draw |= RGN_DRAW_NO_REBUILD; + memset(&ar->drawrct, 0, sizeof(ar->drawrct)); + } } void ED_region_tag_refresh_ui(ARegion *ar) { - if (ar) { - ar->do_draw |= RGN_DRAW_REFRESH_UI; - } + if (ar) { + ar->do_draw |= RGN_DRAW_REFRESH_UI; + } } void ED_region_tag_redraw_partial(ARegion *ar, const rcti *rct) { - if (ar && !(ar->do_draw & RGN_DRAWING)) { - if (!(ar->do_draw & (RGN_DRAW | RGN_DRAW_NO_REBUILD | RGN_DRAW_PARTIAL))) { - /* no redraw set yet, set partial region */ - ar->do_draw |= RGN_DRAW_PARTIAL; - ar->drawrct = *rct; - } - else if (ar->drawrct.xmin != ar->drawrct.xmax) { - BLI_assert((ar->do_draw & RGN_DRAW_PARTIAL) != 0); - /* partial redraw already set, expand region */ - BLI_rcti_union(&ar->drawrct, rct); - } - else { - BLI_assert((ar->do_draw & (RGN_DRAW | RGN_DRAW_NO_REBUILD)) != 0); - /* Else, full redraw is already requested, nothing to do here. */ - } - } + if (ar && !(ar->do_draw & RGN_DRAWING)) { + if (!(ar->do_draw & (RGN_DRAW | RGN_DRAW_NO_REBUILD | RGN_DRAW_PARTIAL))) { + /* no redraw set yet, set partial region */ + ar->do_draw |= RGN_DRAW_PARTIAL; + ar->drawrct = *rct; + } + else if (ar->drawrct.xmin != ar->drawrct.xmax) { + BLI_assert((ar->do_draw & RGN_DRAW_PARTIAL) != 0); + /* partial redraw already set, expand region */ + BLI_rcti_union(&ar->drawrct, rct); + } + else { + BLI_assert((ar->do_draw & (RGN_DRAW | RGN_DRAW_NO_REBUILD)) != 0); + /* Else, full redraw is already requested, nothing to do here. */ + } + } } void ED_area_tag_redraw(ScrArea *sa) { - ARegion *ar; + ARegion *ar; - if (sa) - for (ar = sa->regionbase.first; ar; ar = ar->next) - ED_region_tag_redraw(ar); + if (sa) + for (ar = sa->regionbase.first; ar; ar = ar->next) + ED_region_tag_redraw(ar); } void ED_area_tag_redraw_no_rebuild(ScrArea *sa) { - ARegion *ar; + ARegion *ar; - if (sa) - for (ar = sa->regionbase.first; ar; ar = ar->next) - ED_region_tag_redraw_no_rebuild(ar); + if (sa) + for (ar = sa->regionbase.first; ar; ar = ar->next) + ED_region_tag_redraw_no_rebuild(ar); } void ED_area_tag_redraw_regiontype(ScrArea *sa, int regiontype) { - ARegion *ar; + ARegion *ar; - if (sa) { - for (ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->regiontype == regiontype) { - ED_region_tag_redraw(ar); - } - } - } + if (sa) { + for (ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->regiontype == regiontype) { + ED_region_tag_redraw(ar); + } + } + } } void ED_area_tag_refresh(ScrArea *sa) { - if (sa) - sa->do_refresh = true; + if (sa) + sa->do_refresh = true; } /* *************************************************************** */ @@ -688,339 +697,341 @@ void ED_area_tag_refresh(ScrArea *sa) /* use NULL to disable it */ void ED_area_status_text(ScrArea *sa, const char *str) { - ARegion *ar; - - /* happens when running transform operators in background mode */ - if (sa == NULL) - return; - - for (ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->regiontype == RGN_TYPE_HEADER) { - if (str) { - if (ar->headerstr == NULL) - ar->headerstr = MEM_mallocN(UI_MAX_DRAW_STR, "headerprint"); - BLI_strncpy(ar->headerstr, str, UI_MAX_DRAW_STR); - BLI_str_rstrip(ar->headerstr); - } - else if (ar->headerstr) { - MEM_freeN(ar->headerstr); - ar->headerstr = NULL; - } - ED_region_tag_redraw(ar); - } - } + ARegion *ar; + + /* happens when running transform operators in background mode */ + if (sa == NULL) + return; + + for (ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->regiontype == RGN_TYPE_HEADER) { + if (str) { + if (ar->headerstr == NULL) + ar->headerstr = MEM_mallocN(UI_MAX_DRAW_STR, "headerprint"); + BLI_strncpy(ar->headerstr, str, UI_MAX_DRAW_STR); + BLI_str_rstrip(ar->headerstr); + } + else if (ar->headerstr) { + MEM_freeN(ar->headerstr); + ar->headerstr = NULL; + } + ED_region_tag_redraw(ar); + } + } } void ED_workspace_status_text(bContext *C, const char *str) { - wmWindow *win = CTX_wm_window(C); - WorkSpace *workspace = CTX_wm_workspace(C); + wmWindow *win = CTX_wm_window(C); + WorkSpace *workspace = CTX_wm_workspace(C); - /* Can be NULL when running operators in background mode. */ - if (workspace == NULL) - return; + /* Can be NULL when running operators in background mode. */ + if (workspace == NULL) + return; - if (str) { - if (workspace->status_text == NULL) - workspace->status_text = MEM_mallocN(UI_MAX_DRAW_STR, "headerprint"); - BLI_strncpy(workspace->status_text, str, UI_MAX_DRAW_STR); - } - else if (workspace->status_text) { - MEM_freeN(workspace->status_text); - workspace->status_text = NULL; - } + if (str) { + if (workspace->status_text == NULL) + workspace->status_text = MEM_mallocN(UI_MAX_DRAW_STR, "headerprint"); + BLI_strncpy(workspace->status_text, str, UI_MAX_DRAW_STR); + } + else if (workspace->status_text) { + MEM_freeN(workspace->status_text); + workspace->status_text = NULL; + } - /* Redraw status bar. */ - for (ScrArea *sa = win->global_areas.areabase.first; sa; sa = sa->next) { - if (sa->spacetype == SPACE_STATUSBAR) { - ED_area_tag_redraw(sa); - break; - } - } + /* Redraw status bar. */ + for (ScrArea *sa = win->global_areas.areabase.first; sa; sa = sa->next) { + if (sa->spacetype == SPACE_STATUSBAR) { + ED_area_tag_redraw(sa); + break; + } + } } /* ************************************************************ */ - static void area_azone_initialize(wmWindow *win, const bScreen *screen, ScrArea *sa) { - AZone *az; - - /* reinitialize entirely, regions and fullscreen add azones too */ - BLI_freelistN(&sa->actionzones); - - if (screen->state != SCREENNORMAL) { - return; - } - - if (U.app_flag & USER_APP_LOCK_UI_LAYOUT) { - return; - } - - if (ED_area_is_global(sa)) { - return; - } - - if (screen->temp) { - return; - } - - float coords[4][4] = { - /* Bottom-left. */ - {sa->totrct.xmin - U.pixelsize, - sa->totrct.ymin - U.pixelsize, - sa->totrct.xmin + AZONESPOTW, - sa->totrct.ymin + AZONESPOTH}, - /* Bottom-right. */ - {sa->totrct.xmax - AZONESPOTW, - sa->totrct.ymin - U.pixelsize, - sa->totrct.xmax + U.pixelsize, - sa->totrct.ymin + AZONESPOTH}, - /* Top-left. */ - {sa->totrct.xmin - U.pixelsize, - sa->totrct.ymax - AZONESPOTH, - sa->totrct.xmin + AZONESPOTW, - sa->totrct.ymax + U.pixelsize}, - /* Top-right. */ - {sa->totrct.xmax - AZONESPOTW, - sa->totrct.ymax - AZONESPOTH, - sa->totrct.xmax + U.pixelsize, - sa->totrct.ymax + U.pixelsize}}; - - for (int i = 0; i < 4; i++) { - /* can't click on bottom corners on OS X, already used for resizing */ + AZone *az; + + /* reinitialize entirely, regions and fullscreen add azones too */ + BLI_freelistN(&sa->actionzones); + + if (screen->state != SCREENNORMAL) { + return; + } + + if (U.app_flag & USER_APP_LOCK_UI_LAYOUT) { + return; + } + + if (ED_area_is_global(sa)) { + return; + } + + if (screen->temp) { + return; + } + + float coords[4][4] = {/* Bottom-left. */ + {sa->totrct.xmin - U.pixelsize, + sa->totrct.ymin - U.pixelsize, + sa->totrct.xmin + AZONESPOTW, + sa->totrct.ymin + AZONESPOTH}, + /* Bottom-right. */ + {sa->totrct.xmax - AZONESPOTW, + sa->totrct.ymin - U.pixelsize, + sa->totrct.xmax + U.pixelsize, + sa->totrct.ymin + AZONESPOTH}, + /* Top-left. */ + {sa->totrct.xmin - U.pixelsize, + sa->totrct.ymax - AZONESPOTH, + sa->totrct.xmin + AZONESPOTW, + sa->totrct.ymax + U.pixelsize}, + /* Top-right. */ + {sa->totrct.xmax - AZONESPOTW, + sa->totrct.ymax - AZONESPOTH, + sa->totrct.xmax + U.pixelsize, + sa->totrct.ymax + U.pixelsize}}; + + for (int i = 0; i < 4; i++) { + /* can't click on bottom corners on OS X, already used for resizing */ #ifdef __APPLE__ - if (!WM_window_is_fullscreen(win) && - ((coords[i][0] == 0 && coords[i][1] == 0) || - (coords[i][0] == WM_window_pixels_x(win) && coords[i][1] == 0))) - { - continue; - } + if (!WM_window_is_fullscreen(win) && + ((coords[i][0] == 0 && coords[i][1] == 0) || + (coords[i][0] == WM_window_pixels_x(win) && coords[i][1] == 0))) { + continue; + } #else - (void)win; + (void)win; #endif - /* set area action zones */ - az = (AZone *)MEM_callocN(sizeof(AZone), "actionzone"); - BLI_addtail(&(sa->actionzones), az); - az->type = AZONE_AREA; - az->x1 = coords[i][0]; - az->y1 = coords[i][1]; - az->x2 = coords[i][2]; - az->y2 = coords[i][3]; - BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); - } + /* set area action zones */ + az = (AZone *)MEM_callocN(sizeof(AZone), "actionzone"); + BLI_addtail(&(sa->actionzones), az); + az->type = AZONE_AREA; + az->x1 = coords[i][0]; + az->y1 = coords[i][1]; + az->x2 = coords[i][2]; + az->y2 = coords[i][3]; + BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); + } } static void fullscreen_azone_initialize(ScrArea *sa, ARegion *ar) { - AZone *az; + AZone *az; - if (ED_area_is_global(sa) || (ar->regiontype != RGN_TYPE_WINDOW)) - return; + if (ED_area_is_global(sa) || (ar->regiontype != RGN_TYPE_WINDOW)) + return; - az = (AZone *)MEM_callocN(sizeof(AZone), "fullscreen action zone"); - BLI_addtail(&(sa->actionzones), az); - az->type = AZONE_FULLSCREEN; - az->ar = ar; - az->alpha = 0.0f; + az = (AZone *)MEM_callocN(sizeof(AZone), "fullscreen action zone"); + BLI_addtail(&(sa->actionzones), az); + az->type = AZONE_FULLSCREEN; + az->ar = ar; + az->alpha = 0.0f; - az->x1 = ar->winrct.xmax - (AZONEFADEOUT - 1); - az->y1 = ar->winrct.ymax - (AZONEFADEOUT - 1); - az->x2 = ar->winrct.xmax; - az->y2 = ar->winrct.ymax; - BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); + az->x1 = ar->winrct.xmax - (AZONEFADEOUT - 1); + az->y1 = ar->winrct.ymax - (AZONEFADEOUT - 1); + az->x2 = ar->winrct.xmax; + az->y2 = ar->winrct.ymax; + BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); } -#define AZONEPAD_EDGE (0.1f * U.widget_unit) -#define AZONEPAD_ICON (0.45f * U.widget_unit) +#define AZONEPAD_EDGE (0.1f * U.widget_unit) +#define AZONEPAD_ICON (0.45f * U.widget_unit) static void region_azone_edge(AZone *az, ARegion *ar) { - switch (az->edge) { - case AE_TOP_TO_BOTTOMRIGHT: - az->x1 = ar->winrct.xmin; - az->y1 = ar->winrct.ymax - AZONEPAD_EDGE; - az->x2 = ar->winrct.xmax; - az->y2 = ar->winrct.ymax + AZONEPAD_EDGE; - break; - case AE_BOTTOM_TO_TOPLEFT: - az->x1 = ar->winrct.xmin; - az->y1 = ar->winrct.ymin + AZONEPAD_EDGE; - az->x2 = ar->winrct.xmax; - az->y2 = ar->winrct.ymin - AZONEPAD_EDGE; - break; - case AE_LEFT_TO_TOPRIGHT: - az->x1 = ar->winrct.xmin - AZONEPAD_EDGE; - az->y1 = ar->winrct.ymin; - az->x2 = ar->winrct.xmin + AZONEPAD_EDGE; - az->y2 = ar->winrct.ymax; - break; - case AE_RIGHT_TO_TOPLEFT: - az->x1 = ar->winrct.xmax + AZONEPAD_EDGE; - az->y1 = ar->winrct.ymin; - az->x2 = ar->winrct.xmax - AZONEPAD_EDGE; - az->y2 = ar->winrct.ymax; - break; - } - - BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); + switch (az->edge) { + case AE_TOP_TO_BOTTOMRIGHT: + az->x1 = ar->winrct.xmin; + az->y1 = ar->winrct.ymax - AZONEPAD_EDGE; + az->x2 = ar->winrct.xmax; + az->y2 = ar->winrct.ymax + AZONEPAD_EDGE; + break; + case AE_BOTTOM_TO_TOPLEFT: + az->x1 = ar->winrct.xmin; + az->y1 = ar->winrct.ymin + AZONEPAD_EDGE; + az->x2 = ar->winrct.xmax; + az->y2 = ar->winrct.ymin - AZONEPAD_EDGE; + break; + case AE_LEFT_TO_TOPRIGHT: + az->x1 = ar->winrct.xmin - AZONEPAD_EDGE; + az->y1 = ar->winrct.ymin; + az->x2 = ar->winrct.xmin + AZONEPAD_EDGE; + az->y2 = ar->winrct.ymax; + break; + case AE_RIGHT_TO_TOPLEFT: + az->x1 = ar->winrct.xmax + AZONEPAD_EDGE; + az->y1 = ar->winrct.ymin; + az->x2 = ar->winrct.xmax - AZONEPAD_EDGE; + az->y2 = ar->winrct.ymax; + break; + } + + BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); } /* region already made zero sized, in shape of edge */ static void region_azone_tab_plus(ScrArea *sa, AZone *az, ARegion *ar) { - AZone *azt; - int tot = 0, add; - /* Edge offset multiplied by the */ - - float edge_offset = 1.0f; - const float tab_size_x = 0.7f * U.widget_unit; - const float tab_size_y = 0.4f * U.widget_unit; - - - for (azt = sa->actionzones.first; azt; azt = azt->next) { - if (azt->edge == az->edge) tot++; - } - - switch (az->edge) { - case AE_TOP_TO_BOTTOMRIGHT: - add = (ar->winrct.ymax == sa->totrct.ymin) ? 1 : 0; - az->x1 = ar->winrct.xmax - ((edge_offset + 1.0f) * tab_size_x); - az->y1 = ar->winrct.ymax - add; - az->x2 = ar->winrct.xmax - (edge_offset * tab_size_x); - az->y2 = ar->winrct.ymax - add + tab_size_y; - break; - case AE_BOTTOM_TO_TOPLEFT: - az->x1 = ar->winrct.xmax - ((edge_offset + 1.0f) * tab_size_x); - az->y1 = ar->winrct.ymin - tab_size_y; - az->x2 = ar->winrct.xmax - (edge_offset * tab_size_x); - az->y2 = ar->winrct.ymin; - break; - case AE_LEFT_TO_TOPRIGHT: - az->x1 = ar->winrct.xmin - tab_size_y; - az->y1 = ar->winrct.ymax - ((edge_offset + 1.0f) * tab_size_x); - az->x2 = ar->winrct.xmin; - az->y2 = ar->winrct.ymax - (edge_offset * tab_size_x); - break; - case AE_RIGHT_TO_TOPLEFT: - az->x1 = ar->winrct.xmax; - az->y1 = ar->winrct.ymax - ((edge_offset + 1.0f) * tab_size_x); - az->x2 = ar->winrct.xmax + tab_size_y; - az->y2 = ar->winrct.ymax - (edge_offset * tab_size_x); - break; - } - /* rect needed for mouse pointer test */ - BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); + AZone *azt; + int tot = 0, add; + /* Edge offset multiplied by the */ + + float edge_offset = 1.0f; + const float tab_size_x = 0.7f * U.widget_unit; + const float tab_size_y = 0.4f * U.widget_unit; + + for (azt = sa->actionzones.first; azt; azt = azt->next) { + if (azt->edge == az->edge) + tot++; + } + + switch (az->edge) { + case AE_TOP_TO_BOTTOMRIGHT: + add = (ar->winrct.ymax == sa->totrct.ymin) ? 1 : 0; + az->x1 = ar->winrct.xmax - ((edge_offset + 1.0f) * tab_size_x); + az->y1 = ar->winrct.ymax - add; + az->x2 = ar->winrct.xmax - (edge_offset * tab_size_x); + az->y2 = ar->winrct.ymax - add + tab_size_y; + break; + case AE_BOTTOM_TO_TOPLEFT: + az->x1 = ar->winrct.xmax - ((edge_offset + 1.0f) * tab_size_x); + az->y1 = ar->winrct.ymin - tab_size_y; + az->x2 = ar->winrct.xmax - (edge_offset * tab_size_x); + az->y2 = ar->winrct.ymin; + break; + case AE_LEFT_TO_TOPRIGHT: + az->x1 = ar->winrct.xmin - tab_size_y; + az->y1 = ar->winrct.ymax - ((edge_offset + 1.0f) * tab_size_x); + az->x2 = ar->winrct.xmin; + az->y2 = ar->winrct.ymax - (edge_offset * tab_size_x); + break; + case AE_RIGHT_TO_TOPLEFT: + az->x1 = ar->winrct.xmax; + az->y1 = ar->winrct.ymax - ((edge_offset + 1.0f) * tab_size_x); + az->x2 = ar->winrct.xmax + tab_size_y; + az->y2 = ar->winrct.ymax - (edge_offset * tab_size_x); + break; + } + /* rect needed for mouse pointer test */ + BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); } static bool region_azone_edge_poll(const ARegion *ar, const bool is_fullscreen) { - const bool is_hidden = (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)); + const bool is_hidden = (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)); - if (is_hidden && is_fullscreen) { - return false; - } - if (!is_hidden && ar->regiontype == RGN_TYPE_HEADER) { - return false; - } + if (is_hidden && is_fullscreen) { + return false; + } + if (!is_hidden && ar->regiontype == RGN_TYPE_HEADER) { + return false; + } - return true; + return true; } -static void region_azone_edge_initialize(ScrArea *sa, ARegion *ar, AZEdge edge, const bool is_fullscreen) +static void region_azone_edge_initialize(ScrArea *sa, + ARegion *ar, + AZEdge edge, + const bool is_fullscreen) { - AZone *az = NULL; - const bool is_hidden = (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)); + AZone *az = NULL; + const bool is_hidden = (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)); - if (!region_azone_edge_poll(ar, is_fullscreen)) { - return; - } + if (!region_azone_edge_poll(ar, is_fullscreen)) { + return; + } - az = (AZone *)MEM_callocN(sizeof(AZone), "actionzone"); - BLI_addtail(&(sa->actionzones), az); - az->type = AZONE_REGION; - az->ar = ar; - az->edge = edge; + az = (AZone *)MEM_callocN(sizeof(AZone), "actionzone"); + BLI_addtail(&(sa->actionzones), az); + az->type = AZONE_REGION; + az->ar = ar; + az->edge = edge; - if (is_hidden) { - region_azone_tab_plus(sa, az, ar); - } - else { - region_azone_edge(az, ar); - } + if (is_hidden) { + region_azone_tab_plus(sa, az, ar); + } + else { + region_azone_edge(az, ar); + } } -static void region_azone_scrollbar_initialize(ScrArea *sa, ARegion *ar, AZScrollDirection direction) +static void region_azone_scrollbar_initialize(ScrArea *sa, + ARegion *ar, + AZScrollDirection direction) { - rcti scroller_vert = (direction == AZ_SCROLL_VERT) ? ar->v2d.vert : ar->v2d.hor; - AZone *az = MEM_callocN(sizeof(*az), __func__); + rcti scroller_vert = (direction == AZ_SCROLL_VERT) ? ar->v2d.vert : ar->v2d.hor; + AZone *az = MEM_callocN(sizeof(*az), __func__); - BLI_addtail(&sa->actionzones, az); - az->type = AZONE_REGION_SCROLL; - az->ar = ar; - az->direction = direction; + BLI_addtail(&sa->actionzones, az); + az->type = AZONE_REGION_SCROLL; + az->ar = ar; + az->direction = direction; - if (direction == AZ_SCROLL_VERT) { - az->ar->v2d.alpha_vert = 0; - } - else if (direction == AZ_SCROLL_HOR) { - az->ar->v2d.alpha_hor = 0; - } + if (direction == AZ_SCROLL_VERT) { + az->ar->v2d.alpha_vert = 0; + } + else if (direction == AZ_SCROLL_HOR) { + az->ar->v2d.alpha_hor = 0; + } - BLI_rcti_translate(&scroller_vert, ar->winrct.xmin, ar->winrct.ymin); - az->x1 = scroller_vert.xmin - AZONEFADEIN; - az->y1 = scroller_vert.ymin - AZONEFADEIN; - az->x2 = scroller_vert.xmax + AZONEFADEIN; - az->y2 = scroller_vert.ymax + AZONEFADEIN; + BLI_rcti_translate(&scroller_vert, ar->winrct.xmin, ar->winrct.ymin); + az->x1 = scroller_vert.xmin - AZONEFADEIN; + az->y1 = scroller_vert.ymin - AZONEFADEIN; + az->x2 = scroller_vert.xmax + AZONEFADEIN; + az->y2 = scroller_vert.ymax + AZONEFADEIN; - BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); + BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); } static void region_azones_scrollbars_initialize(ScrArea *sa, ARegion *ar) { - const View2D *v2d = &ar->v2d; + const View2D *v2d = &ar->v2d; - if ((v2d->scroll & V2D_SCROLL_VERTICAL) && ((v2d->scroll & V2D_SCROLL_SCALE_VERTICAL) == 0)) { - region_azone_scrollbar_initialize(sa, ar, AZ_SCROLL_VERT); - } - if ((v2d->scroll & V2D_SCROLL_HORIZONTAL) && ((v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL) == 0)) { - region_azone_scrollbar_initialize(sa, ar, AZ_SCROLL_HOR); - } + if ((v2d->scroll & V2D_SCROLL_VERTICAL) && ((v2d->scroll & V2D_SCROLL_SCALE_VERTICAL) == 0)) { + region_azone_scrollbar_initialize(sa, ar, AZ_SCROLL_VERT); + } + if ((v2d->scroll & V2D_SCROLL_HORIZONTAL) && + ((v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL) == 0)) { + region_azone_scrollbar_initialize(sa, ar, AZ_SCROLL_HOR); + } } - /* *************************************************************** */ static void region_azones_add(const bScreen *screen, ScrArea *sa, ARegion *ar, const int alignment) { - const bool is_fullscreen = screen->state == SCREENFULL; + const bool is_fullscreen = screen->state == SCREENFULL; - /* edge code (t b l r) is along which area edge azone will be drawn */ - if (alignment == RGN_ALIGN_TOP) - region_azone_edge_initialize(sa, ar, AE_BOTTOM_TO_TOPLEFT, is_fullscreen); - else if (alignment == RGN_ALIGN_BOTTOM) - region_azone_edge_initialize(sa, ar, AE_TOP_TO_BOTTOMRIGHT, is_fullscreen); - else if (alignment == RGN_ALIGN_RIGHT) - region_azone_edge_initialize(sa, ar, AE_LEFT_TO_TOPRIGHT, is_fullscreen); - else if (alignment == RGN_ALIGN_LEFT) - region_azone_edge_initialize(sa, ar, AE_RIGHT_TO_TOPLEFT, is_fullscreen); + /* edge code (t b l r) is along which area edge azone will be drawn */ + if (alignment == RGN_ALIGN_TOP) + region_azone_edge_initialize(sa, ar, AE_BOTTOM_TO_TOPLEFT, is_fullscreen); + else if (alignment == RGN_ALIGN_BOTTOM) + region_azone_edge_initialize(sa, ar, AE_TOP_TO_BOTTOMRIGHT, is_fullscreen); + else if (alignment == RGN_ALIGN_RIGHT) + region_azone_edge_initialize(sa, ar, AE_LEFT_TO_TOPRIGHT, is_fullscreen); + else if (alignment == RGN_ALIGN_LEFT) + region_azone_edge_initialize(sa, ar, AE_RIGHT_TO_TOPLEFT, is_fullscreen); - if (is_fullscreen) { - fullscreen_azone_initialize(sa, ar); - } + if (is_fullscreen) { + fullscreen_azone_initialize(sa, ar); + } - region_azones_scrollbars_initialize(sa, ar); + region_azones_scrollbars_initialize(sa, ar); } /* dir is direction to check, not the splitting edge direction! */ static int rct_fits(const rcti *rect, char dir, int size) { - if (dir == 'h') { - return BLI_rcti_size_x(rect) + 1 - size; - } - else { /* 'v' */ - return BLI_rcti_size_y(rect) + 1 - size; - } + if (dir == 'h') { + return BLI_rcti_size_x(rect) + 1 - size; + } + else { /* 'v' */ + return BLI_rcti_size_y(rect) + 1 - size; + } } /* *************************************************************** */ @@ -1029,655 +1040,665 @@ static int rct_fits(const rcti *rect, char dir, int size) /* function checks if some overlapping region was defined before - on same place */ static void region_overlap_fix(ScrArea *sa, ARegion *ar) { - ARegion *ar1; - const int align = ar->alignment & ~RGN_SPLIT_PREV; - int align1 = 0; - - /* find overlapping previous region on same place */ - for (ar1 = ar->prev; ar1; ar1 = ar1->prev) { - if (ar1->flag & (RGN_FLAG_HIDDEN)) { - continue; - } - - if (ar1->overlap && ((ar1->alignment & RGN_SPLIT_PREV) == 0)) { - if (ELEM(ar1->alignment, RGN_ALIGN_FLOAT)) { - continue; - } - align1 = ar1->alignment; - if (BLI_rcti_isect(&ar1->winrct, &ar->winrct, NULL)) { - if (align1 != align) { - /* Left overlapping right or vice-versa, forbid this! */ - ar->flag |= RGN_FLAG_TOO_SMALL; - return; - } - /* Else, we have our previous region on same side. */ - break; - } - } - } - - /* translate or close */ - if (ar1) { - if (align1 == RGN_ALIGN_LEFT) { - if (ar->winrct.xmax + ar1->winx > sa->winx - U.widget_unit) { - ar->flag |= RGN_FLAG_TOO_SMALL; - return; - } - else { - BLI_rcti_translate(&ar->winrct, ar1->winx, 0); - } - } - else if (align1 == RGN_ALIGN_RIGHT) { - if (ar->winrct.xmin - ar1->winx < U.widget_unit) { - ar->flag |= RGN_FLAG_TOO_SMALL; - return; - } - else { - BLI_rcti_translate(&ar->winrct, -ar1->winx, 0); - } - } - } - - /* At this point, 'ar' is in its final position and still open. - * Make a final check it does not overlap any previous 'other side' region. */ - for (ar1 = ar->prev; ar1; ar1 = ar1->prev) { - if (ar1->flag & (RGN_FLAG_HIDDEN)) { - continue; - } - if (ELEM(ar1->alignment, RGN_ALIGN_FLOAT)) { - continue; - } - - if (ar1->overlap && (ar1->alignment & RGN_SPLIT_PREV) == 0) { - if ((ar1->alignment != align) && BLI_rcti_isect(&ar1->winrct, &ar->winrct, NULL)) { - /* Left overlapping right or vice-versa, forbid this! */ - ar->flag |= RGN_FLAG_TOO_SMALL; - return; - } - } - } + ARegion *ar1; + const int align = ar->alignment & ~RGN_SPLIT_PREV; + int align1 = 0; + + /* find overlapping previous region on same place */ + for (ar1 = ar->prev; ar1; ar1 = ar1->prev) { + if (ar1->flag & (RGN_FLAG_HIDDEN)) { + continue; + } + + if (ar1->overlap && ((ar1->alignment & RGN_SPLIT_PREV) == 0)) { + if (ELEM(ar1->alignment, RGN_ALIGN_FLOAT)) { + continue; + } + align1 = ar1->alignment; + if (BLI_rcti_isect(&ar1->winrct, &ar->winrct, NULL)) { + if (align1 != align) { + /* Left overlapping right or vice-versa, forbid this! */ + ar->flag |= RGN_FLAG_TOO_SMALL; + return; + } + /* Else, we have our previous region on same side. */ + break; + } + } + } + + /* translate or close */ + if (ar1) { + if (align1 == RGN_ALIGN_LEFT) { + if (ar->winrct.xmax + ar1->winx > sa->winx - U.widget_unit) { + ar->flag |= RGN_FLAG_TOO_SMALL; + return; + } + else { + BLI_rcti_translate(&ar->winrct, ar1->winx, 0); + } + } + else if (align1 == RGN_ALIGN_RIGHT) { + if (ar->winrct.xmin - ar1->winx < U.widget_unit) { + ar->flag |= RGN_FLAG_TOO_SMALL; + return; + } + else { + BLI_rcti_translate(&ar->winrct, -ar1->winx, 0); + } + } + } + + /* At this point, 'ar' is in its final position and still open. + * Make a final check it does not overlap any previous 'other side' region. */ + for (ar1 = ar->prev; ar1; ar1 = ar1->prev) { + if (ar1->flag & (RGN_FLAG_HIDDEN)) { + continue; + } + if (ELEM(ar1->alignment, RGN_ALIGN_FLOAT)) { + continue; + } + + if (ar1->overlap && (ar1->alignment & RGN_SPLIT_PREV) == 0) { + if ((ar1->alignment != align) && BLI_rcti_isect(&ar1->winrct, &ar->winrct, NULL)) { + /* Left overlapping right or vice-versa, forbid this! */ + ar->flag |= RGN_FLAG_TOO_SMALL; + return; + } + } + } } /* overlapping regions only in the following restricted cases */ bool ED_region_is_overlap(int spacetype, int regiontype) { - if (regiontype == RGN_TYPE_HUD) { - return true; - } - if (U.uiflag2 & USER_REGION_OVERLAP) { - if (spacetype == SPACE_NODE) { - if (regiontype == RGN_TYPE_TOOLS) { - return true; - } - } - else if (ELEM(spacetype, SPACE_VIEW3D, SPACE_IMAGE)) { - if (ELEM(regiontype, RGN_TYPE_TOOLS, RGN_TYPE_UI, RGN_TYPE_TOOL_PROPS, RGN_TYPE_HEADER, RGN_TYPE_FOOTER)) { - return true; - } - } - } - - return false; -} - -static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, rcti *overlap_remainder, int quad) -{ - rcti *remainder_prev = remainder; - - if (ar == NULL) - return; - - int prev_winx = ar->winx; - int prev_winy = ar->winy; - - /* no returns in function, winrct gets set in the end again */ - BLI_rcti_init(&ar->winrct, 0, 0, 0, 0); - - /* for test; allow split of previously defined region */ - if (ar->alignment & RGN_SPLIT_PREV) - if (ar->prev) - remainder = &ar->prev->winrct; - - int alignment = ar->alignment & ~RGN_SPLIT_PREV; - - /* set here, assuming userpref switching forces to call this again */ - ar->overlap = ED_region_is_overlap(sa->spacetype, ar->regiontype); - - /* clear state flags first */ - ar->flag &= ~(RGN_FLAG_TOO_SMALL | RGN_FLAG_SIZE_CLAMP_X | RGN_FLAG_SIZE_CLAMP_Y); - /* user errors */ - if ((ar->next == NULL) && !ELEM(alignment, RGN_ALIGN_QSPLIT, RGN_ALIGN_FLOAT)) { - alignment = RGN_ALIGN_NONE; - } - - /* prefsize, taking into account DPI */ - int prefsizex = UI_DPI_FAC * ((ar->sizex > 1) ? ar->sizex + 0.5f : ar->type->prefsizex); - int prefsizey; - - if (ar->flag & RGN_FLAG_PREFSIZE_OR_HIDDEN) { - prefsizex = UI_DPI_FAC * ar->type->prefsizex; - prefsizey = UI_DPI_FAC * ar->type->prefsizey; - } - else if (ar->regiontype == RGN_TYPE_HEADER) { - prefsizey = ED_area_headersize(); - } - else if (ar->regiontype == RGN_TYPE_FOOTER) { - prefsizey = ED_area_footersize(); - } - else if (ED_area_is_global(sa)) { - prefsizey = ED_region_global_size_y(); - } - else if (ar->regiontype == RGN_TYPE_UI && sa->spacetype == SPACE_FILE) { - prefsizey = UI_UNIT_Y * 2 + (UI_UNIT_Y / 2); - } - else { - prefsizey = UI_DPI_FAC * (ar->sizey > 1 ? ar->sizey + 0.5f : ar->type->prefsizey); - } - - - if (ar->flag & RGN_FLAG_HIDDEN) { - /* hidden is user flag */ - } - else if (alignment == RGN_ALIGN_FLOAT) { - /** - * \note Currently this window type is only used for #RGN_TYPE_HUD, - * We expect the panel to resize it's self to be larger. - * - * This aligns to the lower left of the area. - */ - const int size_min[2] = {UI_UNIT_X, UI_UNIT_Y}; - rcti overlap_remainder_margin = *overlap_remainder; - BLI_rcti_resize( - &overlap_remainder_margin, - max_ii(0, BLI_rcti_size_x(overlap_remainder) - UI_UNIT_X / 2), - max_ii(0, BLI_rcti_size_y(overlap_remainder) - UI_UNIT_Y / 2)); - ar->winrct.xmin = overlap_remainder_margin.xmin; - ar->winrct.ymin = overlap_remainder_margin.ymin; - ar->winrct.xmax = ar->winrct.xmin + prefsizex - 1; - ar->winrct.ymax = ar->winrct.ymin + prefsizey - 1; - - BLI_rcti_isect(&ar->winrct, &overlap_remainder_margin, &ar->winrct); - - if (BLI_rcti_size_x(&ar->winrct) != prefsizex - 1) { - ar->flag |= RGN_FLAG_SIZE_CLAMP_X; - } - if (BLI_rcti_size_y(&ar->winrct) != prefsizey - 1) { - ar->flag |= RGN_FLAG_SIZE_CLAMP_Y; - } - - /* We need to use a test that wont have been previously clamped. */ - rcti winrct_test = { - .xmin = ar->winrct.xmin, - .ymin = ar->winrct.ymin, - .xmax = ar->winrct.xmin + size_min[0], - .ymax = ar->winrct.ymin + size_min[1], - }; - BLI_rcti_isect(&winrct_test, &overlap_remainder_margin, &winrct_test); - if (BLI_rcti_size_x(&winrct_test) < size_min[0] || - BLI_rcti_size_y(&winrct_test) < size_min[1]) - { - ar->flag |= RGN_FLAG_TOO_SMALL; - } - } - else if (rct_fits(remainder, 'v', 1) < 0 || rct_fits(remainder, 'h', 1) < 0) { - /* remainder is too small for any usage */ - ar->flag |= RGN_FLAG_TOO_SMALL; - } - else if (alignment == RGN_ALIGN_NONE) { - /* typically last region */ - ar->winrct = *remainder; - BLI_rcti_init(remainder, 0, 0, 0, 0); - } - else if (alignment == RGN_ALIGN_TOP || alignment == RGN_ALIGN_BOTTOM) { - rcti *winrct = (ar->overlap) ? overlap_remainder : remainder; - - if (rct_fits(winrct, 'v', prefsizey) < 0) { - ar->flag |= RGN_FLAG_TOO_SMALL; - } - else { - int fac = rct_fits(winrct, 'v', prefsizey); - - if (fac < 0) - prefsizey += fac; - - ar->winrct = *winrct; - - if (alignment == RGN_ALIGN_TOP) { - ar->winrct.ymin = ar->winrct.ymax - prefsizey + 1; - winrct->ymax = ar->winrct.ymin - 1; - } - else { - ar->winrct.ymax = ar->winrct.ymin + prefsizey - 1; - winrct->ymin = ar->winrct.ymax + 1; - } - } - } - else if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) { - rcti *winrct = (ar->overlap) ? overlap_remainder : remainder; - - if (rct_fits(winrct, 'h', prefsizex) < 0) { - ar->flag |= RGN_FLAG_TOO_SMALL; - } - else { - int fac = rct_fits(winrct, 'h', prefsizex); - - if (fac < 0) - prefsizex += fac; - - ar->winrct = *winrct; - - if (alignment == RGN_ALIGN_RIGHT) { - ar->winrct.xmin = ar->winrct.xmax - prefsizex + 1; - winrct->xmax = ar->winrct.xmin - 1; - } - else { - ar->winrct.xmax = ar->winrct.xmin + prefsizex - 1; - winrct->xmin = ar->winrct.xmax + 1; - } - } - } - else if (alignment == RGN_ALIGN_VSPLIT || alignment == RGN_ALIGN_HSPLIT) { - /* percentage subdiv*/ - ar->winrct = *remainder; - - if (alignment == RGN_ALIGN_HSPLIT) { - if (rct_fits(remainder, 'h', prefsizex) > 4) { - ar->winrct.xmax = BLI_rcti_cent_x(remainder); - remainder->xmin = ar->winrct.xmax + 1; - } - else { - BLI_rcti_init(remainder, 0, 0, 0, 0); - } - } - else { - if (rct_fits(remainder, 'v', prefsizey) > 4) { - ar->winrct.ymax = BLI_rcti_cent_y(remainder); - remainder->ymin = ar->winrct.ymax + 1; - } - else { - BLI_rcti_init(remainder, 0, 0, 0, 0); - } - } - } - else if (alignment == RGN_ALIGN_QSPLIT) { - ar->winrct = *remainder; - - /* test if there's still 4 regions left */ - if (quad == 0) { - ARegion *artest = ar->next; - int count = 1; - - while (artest) { - artest->alignment = RGN_ALIGN_QSPLIT; - artest = artest->next; - count++; - } - - if (count != 4) { - /* let's stop adding regions */ - BLI_rcti_init(remainder, 0, 0, 0, 0); - if (G.debug & G_DEBUG) - printf("region quadsplit failed\n"); - } - else { - quad = 1; - } - } - if (quad) { - if (quad == 1) { /* left bottom */ - ar->winrct.xmax = BLI_rcti_cent_x(remainder); - ar->winrct.ymax = BLI_rcti_cent_y(remainder); - } - else if (quad == 2) { /* left top */ - ar->winrct.xmax = BLI_rcti_cent_x(remainder); - ar->winrct.ymin = BLI_rcti_cent_y(remainder) + 1; - } - else if (quad == 3) { /* right bottom */ - ar->winrct.xmin = BLI_rcti_cent_x(remainder) + 1; - ar->winrct.ymax = BLI_rcti_cent_y(remainder); - } - else { /* right top */ - ar->winrct.xmin = BLI_rcti_cent_x(remainder) + 1; - ar->winrct.ymin = BLI_rcti_cent_y(remainder) + 1; - BLI_rcti_init(remainder, 0, 0, 0, 0); - } - - quad++; - } - } - - /* for speedup */ - 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 */ - /* prevent rounding errors for UI_DPI_FAC mult and divide */ - if (ar->winx > 1) ar->sizex = (ar->winx + 0.5f) / UI_DPI_FAC; - if (ar->winy > 1) ar->sizey = (ar->winy + 0.5f) / UI_DPI_FAC; - - /* exception for multiple overlapping regions on same spot */ - if (ar->overlap && (alignment != RGN_ALIGN_FLOAT)) { - region_overlap_fix(sa, ar); - } - - /* set winrect for azones */ - if (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) { - ar->winrct = (ar->overlap) ? *overlap_remainder : *remainder; - - switch (alignment) { - case RGN_ALIGN_TOP: - ar->winrct.ymin = ar->winrct.ymax; - break; - case RGN_ALIGN_BOTTOM: - ar->winrct.ymax = ar->winrct.ymin; - break; - case RGN_ALIGN_RIGHT: - ar->winrct.xmin = ar->winrct.xmax; - break; - case RGN_ALIGN_LEFT: - default: - /* prevent winrct to be valid */ - ar->winrct.xmax = ar->winrct.xmin; - break; - } - } - - /* restore prev-split exception */ - if (ar->alignment & RGN_SPLIT_PREV) { - if (ar->prev) { - remainder = remainder_prev; - ar->prev->winx = BLI_rcti_size_x(&ar->prev->winrct) + 1; - ar->prev->winy = BLI_rcti_size_y(&ar->prev->winrct) + 1; - } - } - - /* After non-overlapping region, all following overlapping regions - * fit within the remaining space again. */ - if (!ar->overlap) { - *overlap_remainder = *remainder; - } - - region_rect_recursive(sa, ar->next, remainder, overlap_remainder, quad); - - /* Tag for redraw if size changes. */ - if (ar->winx != prev_winx || ar->winy != prev_winy) { - ED_region_tag_redraw(ar); - } + if (regiontype == RGN_TYPE_HUD) { + return true; + } + if (U.uiflag2 & USER_REGION_OVERLAP) { + if (spacetype == SPACE_NODE) { + if (regiontype == RGN_TYPE_TOOLS) { + return true; + } + } + else if (ELEM(spacetype, SPACE_VIEW3D, SPACE_IMAGE)) { + if (ELEM(regiontype, + RGN_TYPE_TOOLS, + RGN_TYPE_UI, + RGN_TYPE_TOOL_PROPS, + RGN_TYPE_HEADER, + RGN_TYPE_FOOTER)) { + return true; + } + } + } + + return false; +} + +static void region_rect_recursive( + ScrArea *sa, ARegion *ar, rcti *remainder, rcti *overlap_remainder, int quad) +{ + rcti *remainder_prev = remainder; + + if (ar == NULL) + return; + + int prev_winx = ar->winx; + int prev_winy = ar->winy; + + /* no returns in function, winrct gets set in the end again */ + BLI_rcti_init(&ar->winrct, 0, 0, 0, 0); + + /* for test; allow split of previously defined region */ + if (ar->alignment & RGN_SPLIT_PREV) + if (ar->prev) + remainder = &ar->prev->winrct; + + int alignment = ar->alignment & ~RGN_SPLIT_PREV; + + /* set here, assuming userpref switching forces to call this again */ + ar->overlap = ED_region_is_overlap(sa->spacetype, ar->regiontype); + + /* clear state flags first */ + ar->flag &= ~(RGN_FLAG_TOO_SMALL | RGN_FLAG_SIZE_CLAMP_X | RGN_FLAG_SIZE_CLAMP_Y); + /* user errors */ + if ((ar->next == NULL) && !ELEM(alignment, RGN_ALIGN_QSPLIT, RGN_ALIGN_FLOAT)) { + alignment = RGN_ALIGN_NONE; + } + + /* prefsize, taking into account DPI */ + int prefsizex = UI_DPI_FAC * ((ar->sizex > 1) ? ar->sizex + 0.5f : ar->type->prefsizex); + int prefsizey; + + if (ar->flag & RGN_FLAG_PREFSIZE_OR_HIDDEN) { + prefsizex = UI_DPI_FAC * ar->type->prefsizex; + prefsizey = UI_DPI_FAC * ar->type->prefsizey; + } + else if (ar->regiontype == RGN_TYPE_HEADER) { + prefsizey = ED_area_headersize(); + } + else if (ar->regiontype == RGN_TYPE_FOOTER) { + prefsizey = ED_area_footersize(); + } + else if (ED_area_is_global(sa)) { + prefsizey = ED_region_global_size_y(); + } + else if (ar->regiontype == RGN_TYPE_UI && sa->spacetype == SPACE_FILE) { + prefsizey = UI_UNIT_Y * 2 + (UI_UNIT_Y / 2); + } + else { + prefsizey = UI_DPI_FAC * (ar->sizey > 1 ? ar->sizey + 0.5f : ar->type->prefsizey); + } + + if (ar->flag & RGN_FLAG_HIDDEN) { + /* hidden is user flag */ + } + else if (alignment == RGN_ALIGN_FLOAT) { + /** + * \note Currently this window type is only used for #RGN_TYPE_HUD, + * We expect the panel to resize it's self to be larger. + * + * This aligns to the lower left of the area. + */ + const int size_min[2] = {UI_UNIT_X, UI_UNIT_Y}; + rcti overlap_remainder_margin = *overlap_remainder; + BLI_rcti_resize(&overlap_remainder_margin, + max_ii(0, BLI_rcti_size_x(overlap_remainder) - UI_UNIT_X / 2), + max_ii(0, BLI_rcti_size_y(overlap_remainder) - UI_UNIT_Y / 2)); + ar->winrct.xmin = overlap_remainder_margin.xmin; + ar->winrct.ymin = overlap_remainder_margin.ymin; + ar->winrct.xmax = ar->winrct.xmin + prefsizex - 1; + ar->winrct.ymax = ar->winrct.ymin + prefsizey - 1; + + BLI_rcti_isect(&ar->winrct, &overlap_remainder_margin, &ar->winrct); + + if (BLI_rcti_size_x(&ar->winrct) != prefsizex - 1) { + ar->flag |= RGN_FLAG_SIZE_CLAMP_X; + } + if (BLI_rcti_size_y(&ar->winrct) != prefsizey - 1) { + ar->flag |= RGN_FLAG_SIZE_CLAMP_Y; + } + + /* We need to use a test that wont have been previously clamped. */ + rcti winrct_test = { + .xmin = ar->winrct.xmin, + .ymin = ar->winrct.ymin, + .xmax = ar->winrct.xmin + size_min[0], + .ymax = ar->winrct.ymin + size_min[1], + }; + BLI_rcti_isect(&winrct_test, &overlap_remainder_margin, &winrct_test); + if (BLI_rcti_size_x(&winrct_test) < size_min[0] || + BLI_rcti_size_y(&winrct_test) < size_min[1]) { + ar->flag |= RGN_FLAG_TOO_SMALL; + } + } + else if (rct_fits(remainder, 'v', 1) < 0 || rct_fits(remainder, 'h', 1) < 0) { + /* remainder is too small for any usage */ + ar->flag |= RGN_FLAG_TOO_SMALL; + } + else if (alignment == RGN_ALIGN_NONE) { + /* typically last region */ + ar->winrct = *remainder; + BLI_rcti_init(remainder, 0, 0, 0, 0); + } + else if (alignment == RGN_ALIGN_TOP || alignment == RGN_ALIGN_BOTTOM) { + rcti *winrct = (ar->overlap) ? overlap_remainder : remainder; + + if (rct_fits(winrct, 'v', prefsizey) < 0) { + ar->flag |= RGN_FLAG_TOO_SMALL; + } + else { + int fac = rct_fits(winrct, 'v', prefsizey); + + if (fac < 0) + prefsizey += fac; + + ar->winrct = *winrct; + + if (alignment == RGN_ALIGN_TOP) { + ar->winrct.ymin = ar->winrct.ymax - prefsizey + 1; + winrct->ymax = ar->winrct.ymin - 1; + } + else { + ar->winrct.ymax = ar->winrct.ymin + prefsizey - 1; + winrct->ymin = ar->winrct.ymax + 1; + } + } + } + else if (ELEM(alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) { + rcti *winrct = (ar->overlap) ? overlap_remainder : remainder; + + if (rct_fits(winrct, 'h', prefsizex) < 0) { + ar->flag |= RGN_FLAG_TOO_SMALL; + } + else { + int fac = rct_fits(winrct, 'h', prefsizex); + + if (fac < 0) + prefsizex += fac; + + ar->winrct = *winrct; + + if (alignment == RGN_ALIGN_RIGHT) { + ar->winrct.xmin = ar->winrct.xmax - prefsizex + 1; + winrct->xmax = ar->winrct.xmin - 1; + } + else { + ar->winrct.xmax = ar->winrct.xmin + prefsizex - 1; + winrct->xmin = ar->winrct.xmax + 1; + } + } + } + else if (alignment == RGN_ALIGN_VSPLIT || alignment == RGN_ALIGN_HSPLIT) { + /* percentage subdiv*/ + ar->winrct = *remainder; + + if (alignment == RGN_ALIGN_HSPLIT) { + if (rct_fits(remainder, 'h', prefsizex) > 4) { + ar->winrct.xmax = BLI_rcti_cent_x(remainder); + remainder->xmin = ar->winrct.xmax + 1; + } + else { + BLI_rcti_init(remainder, 0, 0, 0, 0); + } + } + else { + if (rct_fits(remainder, 'v', prefsizey) > 4) { + ar->winrct.ymax = BLI_rcti_cent_y(remainder); + remainder->ymin = ar->winrct.ymax + 1; + } + else { + BLI_rcti_init(remainder, 0, 0, 0, 0); + } + } + } + else if (alignment == RGN_ALIGN_QSPLIT) { + ar->winrct = *remainder; + + /* test if there's still 4 regions left */ + if (quad == 0) { + ARegion *artest = ar->next; + int count = 1; + + while (artest) { + artest->alignment = RGN_ALIGN_QSPLIT; + artest = artest->next; + count++; + } + + if (count != 4) { + /* let's stop adding regions */ + BLI_rcti_init(remainder, 0, 0, 0, 0); + if (G.debug & G_DEBUG) + printf("region quadsplit failed\n"); + } + else { + quad = 1; + } + } + if (quad) { + if (quad == 1) { /* left bottom */ + ar->winrct.xmax = BLI_rcti_cent_x(remainder); + ar->winrct.ymax = BLI_rcti_cent_y(remainder); + } + else if (quad == 2) { /* left top */ + ar->winrct.xmax = BLI_rcti_cent_x(remainder); + ar->winrct.ymin = BLI_rcti_cent_y(remainder) + 1; + } + else if (quad == 3) { /* right bottom */ + ar->winrct.xmin = BLI_rcti_cent_x(remainder) + 1; + ar->winrct.ymax = BLI_rcti_cent_y(remainder); + } + else { /* right top */ + ar->winrct.xmin = BLI_rcti_cent_x(remainder) + 1; + ar->winrct.ymin = BLI_rcti_cent_y(remainder) + 1; + BLI_rcti_init(remainder, 0, 0, 0, 0); + } + + quad++; + } + } + + /* for speedup */ + 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 */ + /* prevent rounding errors for UI_DPI_FAC mult and divide */ + if (ar->winx > 1) + ar->sizex = (ar->winx + 0.5f) / UI_DPI_FAC; + if (ar->winy > 1) + ar->sizey = (ar->winy + 0.5f) / UI_DPI_FAC; + + /* exception for multiple overlapping regions on same spot */ + if (ar->overlap && (alignment != RGN_ALIGN_FLOAT)) { + region_overlap_fix(sa, ar); + } + + /* set winrect for azones */ + if (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) { + ar->winrct = (ar->overlap) ? *overlap_remainder : *remainder; + + switch (alignment) { + case RGN_ALIGN_TOP: + ar->winrct.ymin = ar->winrct.ymax; + break; + case RGN_ALIGN_BOTTOM: + ar->winrct.ymax = ar->winrct.ymin; + break; + case RGN_ALIGN_RIGHT: + ar->winrct.xmin = ar->winrct.xmax; + break; + case RGN_ALIGN_LEFT: + default: + /* prevent winrct to be valid */ + ar->winrct.xmax = ar->winrct.xmin; + break; + } + } + + /* restore prev-split exception */ + if (ar->alignment & RGN_SPLIT_PREV) { + if (ar->prev) { + remainder = remainder_prev; + ar->prev->winx = BLI_rcti_size_x(&ar->prev->winrct) + 1; + ar->prev->winy = BLI_rcti_size_y(&ar->prev->winrct) + 1; + } + } + + /* After non-overlapping region, all following overlapping regions + * fit within the remaining space again. */ + if (!ar->overlap) { + *overlap_remainder = *remainder; + } + + region_rect_recursive(sa, ar->next, remainder, overlap_remainder, quad); + + /* Tag for redraw if size changes. */ + if (ar->winx != prev_winx || ar->winy != prev_winy) { + ED_region_tag_redraw(ar); + } } static void area_calc_totrct(ScrArea *sa, const rcti *window_rect) { - short px = (short)U.pixelsize; - - sa->totrct.xmin = sa->v1->vec.x; - sa->totrct.xmax = sa->v4->vec.x; - sa->totrct.ymin = sa->v1->vec.y; - sa->totrct.ymax = sa->v2->vec.y; - - /* scale down totrct by 1 pixel on all sides not matching window borders */ - if (sa->totrct.xmin > window_rect->xmin) { - sa->totrct.xmin += px; - } - if (sa->totrct.xmax < (window_rect->xmax - 1)) { - sa->totrct.xmax -= px; - } - if (sa->totrct.ymin > window_rect->ymin) { - sa->totrct.ymin += px; - } - if (sa->totrct.ymax < (window_rect->ymax - 1)) { - sa->totrct.ymax -= px; - } - /* Although the following asserts are correct they lead to a very unstable Blender. - * And the asserts would fail even in 2.7x (they were added in 2.8x as part of the top-bar commit). - * For more details see T54864. */ + short px = (short)U.pixelsize; + + sa->totrct.xmin = sa->v1->vec.x; + sa->totrct.xmax = sa->v4->vec.x; + sa->totrct.ymin = sa->v1->vec.y; + sa->totrct.ymax = sa->v2->vec.y; + + /* scale down totrct by 1 pixel on all sides not matching window borders */ + if (sa->totrct.xmin > window_rect->xmin) { + sa->totrct.xmin += px; + } + if (sa->totrct.xmax < (window_rect->xmax - 1)) { + sa->totrct.xmax -= px; + } + if (sa->totrct.ymin > window_rect->ymin) { + sa->totrct.ymin += px; + } + if (sa->totrct.ymax < (window_rect->ymax - 1)) { + sa->totrct.ymax -= px; + } + /* Although the following asserts are correct they lead to a very unstable Blender. + * And the asserts would fail even in 2.7x (they were added in 2.8x as part of the top-bar commit). + * For more details see T54864. */ #if 0 - BLI_assert(sa->totrct.xmin >= 0); - BLI_assert(sa->totrct.xmax >= 0); - BLI_assert(sa->totrct.ymin >= 0); - BLI_assert(sa->totrct.ymax >= 0); + BLI_assert(sa->totrct.xmin >= 0); + BLI_assert(sa->totrct.xmax >= 0); + BLI_assert(sa->totrct.ymin >= 0); + BLI_assert(sa->totrct.ymax >= 0); #endif - /* for speedup */ - sa->winx = BLI_rcti_size_x(&sa->totrct) + 1; - sa->winy = BLI_rcti_size_y(&sa->totrct) + 1; + /* for speedup */ + sa->winx = BLI_rcti_size_x(&sa->totrct) + 1; + sa->winy = BLI_rcti_size_y(&sa->totrct) + 1; } - /* used for area initialize below */ static void region_subwindow(ARegion *ar) { - bool hidden = (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) != 0; + bool hidden = (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) != 0; - if ((ar->alignment & RGN_SPLIT_PREV) && ar->prev) - hidden = hidden || (ar->prev->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)); + if ((ar->alignment & RGN_SPLIT_PREV) && ar->prev) + hidden = hidden || (ar->prev->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)); - ar->visible = !hidden; + ar->visible = !hidden; } /** * \param ar: Region, may be NULL when adding handlers for \a sa. */ -static void ed_default_handlers(wmWindowManager *wm, ScrArea *sa, ARegion *ar, ListBase *handlers, int flag) -{ - BLI_assert(ar ? (&ar->handlers == handlers) : (&sa->handlers == handlers)); - - /* note, add-handler checks if it already exists */ - - /* XXX it would be good to have boundbox checks for some of these... */ - if (flag & ED_KEYMAP_UI) { - wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "User Interface", 0, 0); - WM_event_add_keymap_handler(handlers, keymap); - - /* user interface widgets */ - UI_region_handlers_add(handlers); - } - if (flag & ED_KEYMAP_GIZMO) { - BLI_assert(ar && ar->type->regionid == RGN_TYPE_WINDOW); - if (ar) { - /* Anything else is confusing, only allow this. */ - BLI_assert(&ar->handlers == handlers); - if (ar->gizmo_map == NULL) { - ar->gizmo_map = WM_gizmomap_new_from_type( - &(const struct wmGizmoMapType_Params){sa->spacetype, ar->type->regionid}); - } - WM_gizmomap_add_handlers(ar, ar->gizmo_map); - } - } - if (flag & ED_KEYMAP_TOOL) { - WM_event_add_keymap_handler_dynamic(&ar->handlers, WM_event_get_keymap_from_toolsystem, sa); - } - if (flag & ED_KEYMAP_VIEW2D) { - /* 2d-viewport handling+manipulation */ - wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "View2D", 0, 0); - WM_event_add_keymap_handler(handlers, keymap); - } - if (flag & ED_KEYMAP_MARKERS) { - /* time-markers */ - wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Markers", 0, 0); - - /* use a boundbox restricted map */ - /* same local check for all areas */ - static rcti rect = {0, 10000, 0, -1}; - rect.ymax = UI_MARKER_MARGIN_Y; - BLI_assert(ar->type->regionid == RGN_TYPE_WINDOW); - WM_event_add_keymap_handler_bb(handlers, keymap, &rect, &ar->winrct); - } - if (flag & ED_KEYMAP_ANIMATION) { - /* frame changing and timeline operators (for time spaces) */ - wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Animation", 0, 0); - WM_event_add_keymap_handler(handlers, keymap); - } - if (flag & ED_KEYMAP_FRAMES) { - /* frame changing/jumping (for all spaces) */ - wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Frames", 0, 0); - WM_event_add_keymap_handler(handlers, keymap); - } - if (flag & ED_KEYMAP_HEADER) { - /* standard keymap for headers regions */ - wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Header", 0, 0); - WM_event_add_keymap_handler(handlers, keymap); - } - if (flag & ED_KEYMAP_FOOTER) { - /* standard keymap for footer regions */ - wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Footer", 0, 0); - WM_event_add_keymap_handler(handlers, keymap); - } - - /* Keep last because of LMB/RMB handling, see: T57527. */ - if (flag & ED_KEYMAP_GPENCIL) { - /* grease pencil */ - /* NOTE: This is now 4 keymaps - One for basic functionality, - * and others for special stroke modes (edit, paint and sculpt). - * - * For now, it's easier to just include all, - * since you hardly want one without the others. - */ - wmKeyMap *keymap_general = WM_keymap_ensure(wm->defaultconf, "Grease Pencil", 0, 0); - WM_event_add_keymap_handler(handlers, keymap_general); - - wmKeyMap *keymap_edit = WM_keymap_ensure(wm->defaultconf, "Grease Pencil Stroke Edit Mode", 0, 0); - WM_event_add_keymap_handler(handlers, keymap_edit); - - wmKeyMap *keymap_paint = WM_keymap_ensure(wm->defaultconf, "Grease Pencil Stroke Paint Mode", 0, 0); - WM_event_add_keymap_handler(handlers, keymap_paint); - - wmKeyMap *keymap_paint_draw = WM_keymap_ensure(wm->defaultconf, "Grease Pencil Stroke Paint (Draw brush)", 0, 0); - WM_event_add_keymap_handler(handlers, keymap_paint_draw); - - wmKeyMap *keymap_paint_erase = WM_keymap_ensure(wm->defaultconf, "Grease Pencil Stroke Paint (Erase)", 0, 0); - WM_event_add_keymap_handler(handlers, keymap_paint_erase); - - wmKeyMap *keymap_paint_fill = WM_keymap_ensure(wm->defaultconf, "Grease Pencil Stroke Paint (Fill)", 0, 0); - WM_event_add_keymap_handler(handlers, keymap_paint_fill); - - wmKeyMap *keymap_sculpt = WM_keymap_ensure(wm->defaultconf, "Grease Pencil Stroke Sculpt Mode", 0, 0); - WM_event_add_keymap_handler(handlers, keymap_sculpt); - } +static void ed_default_handlers( + wmWindowManager *wm, ScrArea *sa, ARegion *ar, ListBase *handlers, int flag) +{ + BLI_assert(ar ? (&ar->handlers == handlers) : (&sa->handlers == handlers)); + + /* note, add-handler checks if it already exists */ + + /* XXX it would be good to have boundbox checks for some of these... */ + if (flag & ED_KEYMAP_UI) { + wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "User Interface", 0, 0); + WM_event_add_keymap_handler(handlers, keymap); + + /* user interface widgets */ + UI_region_handlers_add(handlers); + } + if (flag & ED_KEYMAP_GIZMO) { + BLI_assert(ar && ar->type->regionid == RGN_TYPE_WINDOW); + if (ar) { + /* Anything else is confusing, only allow this. */ + BLI_assert(&ar->handlers == handlers); + if (ar->gizmo_map == NULL) { + ar->gizmo_map = WM_gizmomap_new_from_type( + &(const struct wmGizmoMapType_Params){sa->spacetype, ar->type->regionid}); + } + WM_gizmomap_add_handlers(ar, ar->gizmo_map); + } + } + if (flag & ED_KEYMAP_TOOL) { + WM_event_add_keymap_handler_dynamic(&ar->handlers, WM_event_get_keymap_from_toolsystem, sa); + } + if (flag & ED_KEYMAP_VIEW2D) { + /* 2d-viewport handling+manipulation */ + wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "View2D", 0, 0); + WM_event_add_keymap_handler(handlers, keymap); + } + if (flag & ED_KEYMAP_MARKERS) { + /* time-markers */ + wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Markers", 0, 0); + + /* use a boundbox restricted map */ + /* same local check for all areas */ + static rcti rect = {0, 10000, 0, -1}; + rect.ymax = UI_MARKER_MARGIN_Y; + BLI_assert(ar->type->regionid == RGN_TYPE_WINDOW); + WM_event_add_keymap_handler_bb(handlers, keymap, &rect, &ar->winrct); + } + if (flag & ED_KEYMAP_ANIMATION) { + /* frame changing and timeline operators (for time spaces) */ + wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Animation", 0, 0); + WM_event_add_keymap_handler(handlers, keymap); + } + if (flag & ED_KEYMAP_FRAMES) { + /* frame changing/jumping (for all spaces) */ + wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Frames", 0, 0); + WM_event_add_keymap_handler(handlers, keymap); + } + if (flag & ED_KEYMAP_HEADER) { + /* standard keymap for headers regions */ + wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Header", 0, 0); + WM_event_add_keymap_handler(handlers, keymap); + } + if (flag & ED_KEYMAP_FOOTER) { + /* standard keymap for footer regions */ + wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Footer", 0, 0); + WM_event_add_keymap_handler(handlers, keymap); + } + + /* Keep last because of LMB/RMB handling, see: T57527. */ + if (flag & ED_KEYMAP_GPENCIL) { + /* grease pencil */ + /* NOTE: This is now 4 keymaps - One for basic functionality, + * and others for special stroke modes (edit, paint and sculpt). + * + * For now, it's easier to just include all, + * since you hardly want one without the others. + */ + wmKeyMap *keymap_general = WM_keymap_ensure(wm->defaultconf, "Grease Pencil", 0, 0); + WM_event_add_keymap_handler(handlers, keymap_general); + + wmKeyMap *keymap_edit = WM_keymap_ensure( + wm->defaultconf, "Grease Pencil Stroke Edit Mode", 0, 0); + WM_event_add_keymap_handler(handlers, keymap_edit); + + wmKeyMap *keymap_paint = WM_keymap_ensure( + wm->defaultconf, "Grease Pencil Stroke Paint Mode", 0, 0); + WM_event_add_keymap_handler(handlers, keymap_paint); + + wmKeyMap *keymap_paint_draw = WM_keymap_ensure( + wm->defaultconf, "Grease Pencil Stroke Paint (Draw brush)", 0, 0); + WM_event_add_keymap_handler(handlers, keymap_paint_draw); + + wmKeyMap *keymap_paint_erase = WM_keymap_ensure( + wm->defaultconf, "Grease Pencil Stroke Paint (Erase)", 0, 0); + WM_event_add_keymap_handler(handlers, keymap_paint_erase); + + wmKeyMap *keymap_paint_fill = WM_keymap_ensure( + wm->defaultconf, "Grease Pencil Stroke Paint (Fill)", 0, 0); + WM_event_add_keymap_handler(handlers, keymap_paint_fill); + + wmKeyMap *keymap_sculpt = WM_keymap_ensure( + wm->defaultconf, "Grease Pencil Stroke Sculpt Mode", 0, 0); + WM_event_add_keymap_handler(handlers, keymap_sculpt); + } } void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *area) { - rcti rect, overlap_rect; - rcti window_rect; + rcti rect, overlap_rect; + rcti window_rect; - if (!(area->flag & AREA_FLAG_REGION_SIZE_UPDATE)) { - return; - } - const bScreen *screen = WM_window_get_active_screen(win); + if (!(area->flag & AREA_FLAG_REGION_SIZE_UPDATE)) { + return; + } + const bScreen *screen = WM_window_get_active_screen(win); - WM_window_rect_calc(win, &window_rect); - area_calc_totrct(area, &window_rect); + WM_window_rect_calc(win, &window_rect); + area_calc_totrct(area, &window_rect); - /* region rect sizes */ - rect = area->totrct; - overlap_rect = rect; - region_rect_recursive(area, area->regionbase.first, &rect, &overlap_rect, 0); + /* region rect sizes */ + rect = area->totrct; + overlap_rect = rect; + region_rect_recursive(area, area->regionbase.first, &rect, &overlap_rect, 0); - /* Dynamically sized regions may have changed region sizes, so we have to force azone update. */ - area_azone_initialize(win, screen, area); + /* Dynamically sized regions may have changed region sizes, so we have to force azone update. */ + area_azone_initialize(win, screen, area); - for (ARegion *ar = area->regionbase.first; ar; ar = ar->next) { - region_subwindow(ar); + for (ARegion *ar = area->regionbase.first; ar; ar = ar->next) { + region_subwindow(ar); - /* region size may have changed, init does necessary adjustments */ - if (ar->type->init) { - ar->type->init(wm, ar); - } + /* region size may have changed, init does necessary adjustments */ + if (ar->type->init) { + ar->type->init(wm, ar); + } - /* Some AZones use View2D data which is only updated in region init, so call that first! */ - region_azones_add(screen, area, ar, ar->alignment & ~RGN_SPLIT_PREV); - } - ED_area_azones_update(area, &win->eventstate->x); + /* Some AZones use View2D data which is only updated in region init, so call that first! */ + region_azones_add(screen, area, ar, ar->alignment & ~RGN_SPLIT_PREV); + } + ED_area_azones_update(area, &win->eventstate->x); - area->flag &= ~AREA_FLAG_REGION_SIZE_UPDATE; + area->flag &= ~AREA_FLAG_REGION_SIZE_UPDATE; } /* called in screen_refresh, or screens_init, also area size changes */ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa) { - WorkSpace *workspace = WM_window_get_active_workspace(win); - const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook); - ViewLayer *view_layer = WM_window_get_active_view_layer(win); - ARegion *ar; - rcti rect, overlap_rect; - rcti window_rect; - - if (ED_area_is_global(sa) && (sa->global->flag & GLOBAL_AREA_IS_HIDDEN)) { - return; - } - WM_window_rect_calc(win, &window_rect); - - /* set typedefinitions */ - sa->type = BKE_spacetype_from_id(sa->spacetype); - - if (sa->type == NULL) { - sa->spacetype = SPACE_VIEW3D; - sa->type = BKE_spacetype_from_id(sa->spacetype); - } - - for (ar = sa->regionbase.first; ar; ar = ar->next) - ar->type = BKE_regiontype_from_id_or_first(sa->type, ar->regiontype); - - /* area sizes */ - area_calc_totrct(sa, &window_rect); - - /* region rect sizes */ - rect = sa->totrct; - overlap_rect = rect; - region_rect_recursive(sa, sa->regionbase.first, &rect, &overlap_rect, 0); - sa->flag &= ~AREA_FLAG_REGION_SIZE_UPDATE; - - /* default area handlers */ - ed_default_handlers(wm, sa, NULL, &sa->handlers, sa->type->keymapflag); - /* checks spacedata, adds own handlers */ - if (sa->type->init) - sa->type->init(wm, sa); - - /* clear all azones, add the area triangle widgets */ - area_azone_initialize(win, screen, sa); - - /* region windows, default and own handlers */ - for (ar = sa->regionbase.first; ar; ar = ar->next) { - region_subwindow(ar); - - if (ar->visible) { - /* default region handlers */ - ed_default_handlers(wm, sa, ar, &ar->handlers, ar->type->keymapflag); - /* own handlers */ - if (ar->type->init) { - ar->type->init(wm, ar); - } - } - else { - /* prevent uiblocks to run */ - UI_blocklist_free(NULL, &ar->uiblocks); - } - - /* Some AZones use View2D data which is only updated in region init, so call that first! */ - region_azones_add(screen, sa, ar, ar->alignment & ~RGN_SPLIT_PREV); - } - - - /* Avoid re-initializing tools while resizing the window. */ - if ((G.moving & G_TRANSFORM_WM) == 0) { - if ((1 << sa->spacetype) & WM_TOOLSYSTEM_SPACE_MASK) { - WM_toolsystem_refresh_screen_area(workspace, view_layer, sa); - sa->flag |= AREA_FLAG_ACTIVE_TOOL_UPDATE; - } - else { - sa->runtime.tool = NULL; - sa->runtime.is_tool_set = true; - } - } + WorkSpace *workspace = WM_window_get_active_workspace(win); + const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); + ARegion *ar; + rcti rect, overlap_rect; + rcti window_rect; + + if (ED_area_is_global(sa) && (sa->global->flag & GLOBAL_AREA_IS_HIDDEN)) { + return; + } + WM_window_rect_calc(win, &window_rect); + + /* set typedefinitions */ + sa->type = BKE_spacetype_from_id(sa->spacetype); + + if (sa->type == NULL) { + sa->spacetype = SPACE_VIEW3D; + sa->type = BKE_spacetype_from_id(sa->spacetype); + } + + for (ar = sa->regionbase.first; ar; ar = ar->next) + ar->type = BKE_regiontype_from_id_or_first(sa->type, ar->regiontype); + + /* area sizes */ + area_calc_totrct(sa, &window_rect); + + /* region rect sizes */ + rect = sa->totrct; + overlap_rect = rect; + region_rect_recursive(sa, sa->regionbase.first, &rect, &overlap_rect, 0); + sa->flag &= ~AREA_FLAG_REGION_SIZE_UPDATE; + + /* default area handlers */ + ed_default_handlers(wm, sa, NULL, &sa->handlers, sa->type->keymapflag); + /* checks spacedata, adds own handlers */ + if (sa->type->init) + sa->type->init(wm, sa); + + /* clear all azones, add the area triangle widgets */ + area_azone_initialize(win, screen, sa); + + /* region windows, default and own handlers */ + for (ar = sa->regionbase.first; ar; ar = ar->next) { + region_subwindow(ar); + + if (ar->visible) { + /* default region handlers */ + ed_default_handlers(wm, sa, ar, &ar->handlers, ar->type->keymapflag); + /* own handlers */ + if (ar->type->init) { + ar->type->init(wm, ar); + } + } + else { + /* prevent uiblocks to run */ + UI_blocklist_free(NULL, &ar->uiblocks); + } + + /* Some AZones use View2D data which is only updated in region init, so call that first! */ + region_azones_add(screen, sa, ar, ar->alignment & ~RGN_SPLIT_PREV); + } + + /* Avoid re-initializing tools while resizing the window. */ + if ((G.moving & G_TRANSFORM_WM) == 0) { + if ((1 << sa->spacetype) & WM_TOOLSYSTEM_SPACE_MASK) { + WM_toolsystem_refresh_screen_area(workspace, view_layer, sa); + sa->flag |= AREA_FLAG_ACTIVE_TOOL_UPDATE; + } + else { + sa->runtime.tool = NULL; + sa->runtime.is_tool_set = true; + } + } } static void region_update_rect(ARegion *ar) { - ar->winx = BLI_rcti_size_x(&ar->winrct) + 1; - ar->winy = BLI_rcti_size_y(&ar->winrct) + 1; + ar->winx = BLI_rcti_size_x(&ar->winrct) + 1; + ar->winy = BLI_rcti_size_y(&ar->winrct) + 1; - /* v2d mask is used to subtract scrollbars from a 2d view. Needs initialize here. */ - BLI_rcti_init(&ar->v2d.mask, 0, ar->winx - 1, 0, ar->winy -1); + /* v2d mask is used to subtract scrollbars from a 2d view. Needs initialize here. */ + BLI_rcti_init(&ar->v2d.mask, 0, ar->winx - 1, 0, ar->winy - 1); } /** @@ -1685,63 +1706,63 @@ static void region_update_rect(ARegion *ar) */ void ED_region_update_rect(ARegion *ar) { - region_update_rect(ar); + region_update_rect(ar); } /* externally called for floating regions like menus */ void ED_region_init(ARegion *ar) { - /* refresh can be called before window opened */ - region_subwindow(ar); + /* refresh can be called before window opened */ + region_subwindow(ar); - region_update_rect(ar); + region_update_rect(ar); } void ED_region_cursor_set(wmWindow *win, ScrArea *sa, ARegion *ar) { - if (ar && sa && ar->type && ar->type->cursor) { - ar->type->cursor(win, sa, ar); - } - else { - if (WM_cursor_set_from_tool(win, sa, ar)) { - return; - } - WM_cursor_set(win, CURSOR_STD); - } + if (ar && sa && ar->type && ar->type->cursor) { + ar->type->cursor(win, sa, ar); + } + else { + if (WM_cursor_set_from_tool(win, sa, ar)) { + return; + } + WM_cursor_set(win, CURSOR_STD); + } } /* for use after changing visibility of regions */ void ED_region_visibility_change_update(bContext *C, ARegion *ar) { - ScrArea *sa = CTX_wm_area(C); + ScrArea *sa = CTX_wm_area(C); - if (ar->flag & RGN_FLAG_HIDDEN) - WM_event_remove_handlers(C, &ar->handlers); + 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); + ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa); + ED_area_tag_redraw(sa); } /* for quick toggle, can skip fades */ void region_toggle_hidden(bContext *C, ARegion *ar, const bool do_fade) { - ScrArea *sa = CTX_wm_area(C); + ScrArea *sa = CTX_wm_area(C); - ar->flag ^= RGN_FLAG_HIDDEN; + 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 { - ED_region_visibility_change_update(C, ar); - } + 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 { + ED_region_visibility_change_update(C, ar); + } } /* exported to all editors, uses fading default */ void ED_region_toggle_hidden(bContext *C, ARegion *ar) { - region_toggle_hidden(C, ar, true); + region_toggle_hidden(C, ar, true); } /** @@ -1749,73 +1770,72 @@ void ED_region_toggle_hidden(bContext *C, ARegion *ar) */ void ED_area_data_copy(ScrArea *sa_dst, ScrArea *sa_src, const bool do_free) { - SpaceType *st; - ARegion *ar; - const char spacetype = sa_dst->spacetype; - const short flag_copy = HEADER_NO_PULLDOWN; + SpaceType *st; + ARegion *ar; + const char spacetype = sa_dst->spacetype; + const short flag_copy = HEADER_NO_PULLDOWN; - sa_dst->spacetype = sa_src->spacetype; - sa_dst->type = sa_src->type; + sa_dst->spacetype = sa_src->spacetype; + sa_dst->type = sa_src->type; - sa_dst->flag = (sa_dst->flag & ~flag_copy) | (sa_src->flag & flag_copy); + sa_dst->flag = (sa_dst->flag & ~flag_copy) | (sa_src->flag & flag_copy); - /* area */ - if (do_free) { - BKE_spacedata_freelist(&sa_dst->spacedata); - } - BKE_spacedata_copylist(&sa_dst->spacedata, &sa_src->spacedata); + /* area */ + if (do_free) { + BKE_spacedata_freelist(&sa_dst->spacedata); + } + BKE_spacedata_copylist(&sa_dst->spacedata, &sa_src->spacedata); - /* Note; SPACE_EMPTY is possible on new screens */ + /* Note; SPACE_EMPTY is possible on new screens */ - /* regions */ - if (do_free) { - st = BKE_spacetype_from_id(spacetype); - for (ar = sa_dst->regionbase.first; ar; ar = ar->next) - BKE_area_region_free(st, ar); - BLI_freelistN(&sa_dst->regionbase); - } - st = BKE_spacetype_from_id(sa_src->spacetype); - for (ar = sa_src->regionbase.first; ar; ar = ar->next) { - ARegion *newar = BKE_area_region_copy(st, ar); - BLI_addtail(&sa_dst->regionbase, newar); - } + /* regions */ + if (do_free) { + st = BKE_spacetype_from_id(spacetype); + for (ar = sa_dst->regionbase.first; ar; ar = ar->next) + BKE_area_region_free(st, ar); + BLI_freelistN(&sa_dst->regionbase); + } + st = BKE_spacetype_from_id(sa_src->spacetype); + for (ar = sa_src->regionbase.first; ar; ar = ar->next) { + ARegion *newar = BKE_area_region_copy(st, ar); + BLI_addtail(&sa_dst->regionbase, newar); + } } void ED_area_data_swap(ScrArea *sa_dst, ScrArea *sa_src) { - SWAP(char, sa_dst->spacetype, sa_src->spacetype); - SWAP(SpaceType *, sa_dst->type, sa_src->type); - + SWAP(char, sa_dst->spacetype, sa_src->spacetype); + SWAP(SpaceType *, sa_dst->type, sa_src->type); - SWAP(ListBase, sa_dst->spacedata, sa_src->spacedata); - SWAP(ListBase, sa_dst->regionbase, sa_src->regionbase); + SWAP(ListBase, sa_dst->spacedata, sa_src->spacedata); + SWAP(ListBase, sa_dst->regionbase, sa_src->regionbase); } /* *********** Space switching code *********** */ void ED_area_swapspace(bContext *C, ScrArea *sa1, ScrArea *sa2) { - ScrArea *tmp = MEM_callocN(sizeof(ScrArea), "addscrarea"); + ScrArea *tmp = MEM_callocN(sizeof(ScrArea), "addscrarea"); - ED_area_exit(C, sa1); - ED_area_exit(C, sa2); + ED_area_exit(C, sa1); + ED_area_exit(C, sa2); - ED_area_data_copy(tmp, sa1, false); - ED_area_data_copy(sa1, sa2, true); - ED_area_data_copy(sa2, tmp, true); - ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa1); - ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa2); + ED_area_data_copy(tmp, sa1, false); + ED_area_data_copy(sa1, sa2, true); + ED_area_data_copy(sa2, tmp, true); + ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa1); + ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa2); - BKE_screen_area_free(tmp); - MEM_freeN(tmp); + BKE_screen_area_free(tmp); + MEM_freeN(tmp); - /* tell WM to refresh, cursor types etc */ - WM_event_add_mousemove(C); + /* tell WM to refresh, cursor types etc */ + WM_event_add_mousemove(C); - ED_area_tag_redraw(sa1); - ED_area_tag_refresh(sa1); - ED_area_tag_redraw(sa2); - ED_area_tag_refresh(sa2); + ED_area_tag_redraw(sa1); + ED_area_tag_refresh(sa1); + ED_area_tag_redraw(sa2); + ED_area_tag_refresh(sa2); } /** @@ -1823,325 +1843,348 @@ void ED_area_swapspace(bContext *C, ScrArea *sa1, ScrArea *sa2) */ void ED_area_newspace(bContext *C, ScrArea *sa, int type, const bool skip_ar_exit) { - wmWindow *win = CTX_wm_window(C); - - if (sa->spacetype != type) { - SpaceType *st; - SpaceLink *slold; - SpaceLink *sl; - /* store sa->type->exit callback */ - void *sa_exit = sa->type ? sa->type->exit : NULL; - /* When the user switches between space-types from the type-selector, - * changing the header-type is jarring (especially when using Ctrl-MouseWheel). - * - * However, add-on install for example, forces the header to the top which shouldn't - * be applied back to the previous space type when closing - see: T57724 - * - * Newly created windows wont have any space data, use the alignment - * the space type defaults to in this case instead - * (needed for preferences to have space-type on bottom). - */ - int header_alignment = ED_area_header_alignment_or_fallback(sa, -1); - const bool sync_header_alignment = ( - (header_alignment != -1) && - (sa->flag & AREA_FLAG_TEMP_TYPE) == 0); - - /* in some cases (opening temp space) we don't want to - * call area exit callback, so we temporarily unset it */ - if (skip_ar_exit && sa->type) { - sa->type->exit = NULL; - } - - ED_area_exit(C, sa); - - /* restore old area exit callback */ - if (skip_ar_exit && sa->type) { - sa->type->exit = sa_exit; - } - - st = BKE_spacetype_from_id(type); - slold = sa->spacedata.first; - - sa->spacetype = type; - sa->type = st; - - /* If st->new may be called, don't use context until then. The - * sa->type->context() callback has changed but data may be invalid - * (e.g. with properties editor) until space-data is properly created */ - - /* check previously stored space */ - for (sl = sa->spacedata.first; sl; sl = sl->next) - if (sl->spacetype == type) - break; - - /* old spacedata... happened during work on 2.50, remove */ - if (sl && BLI_listbase_is_empty(&sl->regionbase)) { - st->free(sl); - BLI_freelinkN(&sa->spacedata, sl); - if (slold == sl) { - slold = NULL; - } - sl = NULL; - } - - if (sl) { - /* swap regions */ - slold->regionbase = sa->regionbase; - sa->regionbase = sl->regionbase; - BLI_listbase_clear(&sl->regionbase); - - /* put in front of list */ - BLI_remlink(&sa->spacedata, sl); - BLI_addhead(&sa->spacedata, sl); - } - else { - /* new space */ - if (st) { - /* Don't get scene from context here which may depend on space-data. */ - Scene *scene = WM_window_get_active_scene(win); - sl = st->new(sa, scene); - BLI_addhead(&sa->spacedata, sl); - - /* swap regions */ - if (slold) - slold->regionbase = sa->regionbase; - sa->regionbase = sl->regionbase; - BLI_listbase_clear(&sl->regionbase); - } - } - - /* Sync header alignment. */ - if (sync_header_alignment) { - /* Spaces with footer. */ - if (st->spaceid == SPACE_TEXT) { - for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->regiontype == RGN_TYPE_HEADER) { - ar->alignment = header_alignment; - } - if (ar->regiontype == RGN_TYPE_FOOTER) { - int footer_alignment = (header_alignment == RGN_ALIGN_BOTTOM) ? RGN_ALIGN_TOP : RGN_ALIGN_BOTTOM; - ar->alignment = footer_alignment; - break; - } - } - } - else { - for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->regiontype == RGN_TYPE_HEADER) { - ar->alignment = header_alignment; - break; - } - } - } - } - - ED_area_initialize(CTX_wm_manager(C), win, sa); - - /* tell WM to refresh, cursor types etc */ - WM_event_add_mousemove(C); - - /* send space change notifier */ - WM_event_add_notifier(C, NC_SPACE | ND_SPACE_CHANGED, sa); - - ED_area_tag_refresh(sa); - } - - /* also redraw when re-used */ - ED_area_tag_redraw(sa); + wmWindow *win = CTX_wm_window(C); + + if (sa->spacetype != type) { + SpaceType *st; + SpaceLink *slold; + SpaceLink *sl; + /* store sa->type->exit callback */ + void *sa_exit = sa->type ? sa->type->exit : NULL; + /* When the user switches between space-types from the type-selector, + * changing the header-type is jarring (especially when using Ctrl-MouseWheel). + * + * However, add-on install for example, forces the header to the top which shouldn't + * be applied back to the previous space type when closing - see: T57724 + * + * Newly created windows wont have any space data, use the alignment + * the space type defaults to in this case instead + * (needed for preferences to have space-type on bottom). + */ + int header_alignment = ED_area_header_alignment_or_fallback(sa, -1); + const bool sync_header_alignment = ((header_alignment != -1) && + (sa->flag & AREA_FLAG_TEMP_TYPE) == 0); + + /* in some cases (opening temp space) we don't want to + * call area exit callback, so we temporarily unset it */ + if (skip_ar_exit && sa->type) { + sa->type->exit = NULL; + } + + ED_area_exit(C, sa); + + /* restore old area exit callback */ + if (skip_ar_exit && sa->type) { + sa->type->exit = sa_exit; + } + + st = BKE_spacetype_from_id(type); + slold = sa->spacedata.first; + + sa->spacetype = type; + sa->type = st; + + /* If st->new may be called, don't use context until then. The + * sa->type->context() callback has changed but data may be invalid + * (e.g. with properties editor) until space-data is properly created */ + + /* check previously stored space */ + for (sl = sa->spacedata.first; sl; sl = sl->next) + if (sl->spacetype == type) + break; + + /* old spacedata... happened during work on 2.50, remove */ + if (sl && BLI_listbase_is_empty(&sl->regionbase)) { + st->free(sl); + BLI_freelinkN(&sa->spacedata, sl); + if (slold == sl) { + slold = NULL; + } + sl = NULL; + } + + if (sl) { + /* swap regions */ + slold->regionbase = sa->regionbase; + sa->regionbase = sl->regionbase; + BLI_listbase_clear(&sl->regionbase); + + /* put in front of list */ + BLI_remlink(&sa->spacedata, sl); + BLI_addhead(&sa->spacedata, sl); + } + else { + /* new space */ + if (st) { + /* Don't get scene from context here which may depend on space-data. */ + Scene *scene = WM_window_get_active_scene(win); + sl = st->new (sa, scene); + BLI_addhead(&sa->spacedata, sl); + + /* swap regions */ + if (slold) + slold->regionbase = sa->regionbase; + sa->regionbase = sl->regionbase; + BLI_listbase_clear(&sl->regionbase); + } + } + + /* Sync header alignment. */ + if (sync_header_alignment) { + /* Spaces with footer. */ + if (st->spaceid == SPACE_TEXT) { + for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->regiontype == RGN_TYPE_HEADER) { + ar->alignment = header_alignment; + } + if (ar->regiontype == RGN_TYPE_FOOTER) { + int footer_alignment = (header_alignment == RGN_ALIGN_BOTTOM) ? RGN_ALIGN_TOP : + RGN_ALIGN_BOTTOM; + ar->alignment = footer_alignment; + break; + } + } + } + else { + for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->regiontype == RGN_TYPE_HEADER) { + ar->alignment = header_alignment; + break; + } + } + } + } + + ED_area_initialize(CTX_wm_manager(C), win, sa); + + /* tell WM to refresh, cursor types etc */ + WM_event_add_mousemove(C); + + /* send space change notifier */ + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_CHANGED, sa); + + ED_area_tag_refresh(sa); + } + + /* also redraw when re-used */ + ED_area_tag_redraw(sa); } void ED_area_prevspace(bContext *C, ScrArea *sa) { - SpaceLink *sl = sa->spacedata.first; + SpaceLink *sl = sa->spacedata.first; - if (sl && sl->next) { - ED_area_newspace(C, sa, sl->next->spacetype, false); + if (sl && sl->next) { + ED_area_newspace(C, sa, sl->next->spacetype, false); - /* keep old spacedata but move it to end, so calling - * ED_area_prevspace once more won't open it again */ - BLI_remlink(&sa->spacedata, sl); - BLI_addtail(&sa->spacedata, sl); - } - else { - /* no change */ - return; - } - sa->flag &= ~(AREA_FLAG_STACKED_FULLSCREEN | AREA_FLAG_TEMP_TYPE); + /* keep old spacedata but move it to end, so calling + * ED_area_prevspace once more won't open it again */ + BLI_remlink(&sa->spacedata, sl); + BLI_addtail(&sa->spacedata, sl); + } + else { + /* no change */ + return; + } + sa->flag &= ~(AREA_FLAG_STACKED_FULLSCREEN | AREA_FLAG_TEMP_TYPE); - ED_area_tag_redraw(sa); + ED_area_tag_redraw(sa); - /* send space change notifier */ - WM_event_add_notifier(C, NC_SPACE | ND_SPACE_CHANGED, sa); + /* send space change notifier */ + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_CHANGED, sa); } /* returns offset for next button in header */ int ED_area_header_switchbutton(const bContext *C, uiBlock *block, int yco) { - ScrArea *sa = CTX_wm_area(C); - bScreen *scr = CTX_wm_screen(C); - PointerRNA areaptr; - int xco = 0.4 * U.widget_unit; - - RNA_pointer_create(&(scr->id), &RNA_Area, sa, &areaptr); - - uiDefButR(block, UI_BTYPE_MENU, 0, "", xco, yco, 1.6 * U.widget_unit, U.widget_unit, - &areaptr, "ui_type", 0, 0.0f, 0.0f, 0.0f, 0.0f, ""); - - return xco + 1.7 * U.widget_unit; + ScrArea *sa = CTX_wm_area(C); + bScreen *scr = CTX_wm_screen(C); + PointerRNA areaptr; + int xco = 0.4 * U.widget_unit; + + RNA_pointer_create(&(scr->id), &RNA_Area, sa, &areaptr); + + uiDefButR(block, + UI_BTYPE_MENU, + 0, + "", + xco, + yco, + 1.6 * U.widget_unit, + U.widget_unit, + &areaptr, + "ui_type", + 0, + 0.0f, + 0.0f, + 0.0f, + 0.0f, + ""); + + return xco + 1.7 * U.widget_unit; } /************************ standard UI regions ************************/ static ThemeColorID region_background_color_id(const bContext *C, const ARegion *region) { - ScrArea *area = CTX_wm_area(C); + ScrArea *area = CTX_wm_area(C); - switch (region->regiontype) { - case RGN_TYPE_HEADER: - if (ED_screen_area_active(C) || ED_area_is_global(area)) { - return TH_HEADER; - } - else { - return TH_HEADERDESEL; - } - case RGN_TYPE_PREVIEW: - return TH_PREVIEW_BACK; - default: - return TH_BACK; - } + switch (region->regiontype) { + case RGN_TYPE_HEADER: + if (ED_screen_area_active(C) || ED_area_is_global(area)) { + return TH_HEADER; + } + else { + return TH_HEADERDESEL; + } + case RGN_TYPE_PREVIEW: + return TH_PREVIEW_BACK; + default: + return TH_BACK; + } } static void region_clear_color(const bContext *C, const ARegion *ar, ThemeColorID colorid) { - if (ar->alignment == RGN_ALIGN_FLOAT) { - /* handle our own drawing. */ - } - else if (ar->overlap) { - /* view should be in pixelspace */ - UI_view2d_view_restore(C); + if (ar->alignment == RGN_ALIGN_FLOAT) { + /* handle our own drawing. */ + } + else if (ar->overlap) { + /* view should be in pixelspace */ + UI_view2d_view_restore(C); - float back[4]; - UI_GetThemeColor4fv(colorid, back); - GPU_clear_color(back[3] * back[0], back[3] * back[1], back[3] * back[2], back[3]); - GPU_clear(GPU_COLOR_BIT); - } - else { - UI_ThemeClearColor(colorid); - GPU_clear(GPU_COLOR_BIT); - } + float back[4]; + UI_GetThemeColor4fv(colorid, back); + GPU_clear_color(back[3] * back[0], back[3] * back[1], back[3] * back[2], back[3]); + GPU_clear(GPU_COLOR_BIT); + } + else { + UI_ThemeClearColor(colorid); + GPU_clear(GPU_COLOR_BIT); + } } BLI_INLINE bool streq_array_any(const char *s, const char *arr[]) { - for (uint i = 0; arr[i]; i++) { - if (STREQ(arr[i], s)) { - return true; - } - } - return false; -} - -static void ed_panel_draw( - const bContext *C, - ScrArea *sa, - ARegion *ar, - ListBase *lb, - PanelType *pt, - Panel *panel, - int w, - int em, - bool vertical) -{ - uiStyle *style = UI_style_get_dpi(); - - /* draw panel */ - uiBlock *block = UI_block_begin(C, ar, pt->idname, UI_EMBOSS); - - bool open; - panel = UI_panel_begin(sa, ar, lb, block, pt, panel, &open); - - /* bad fixed values */ - int xco, yco, h = 0; - - if (pt->draw_header_preset && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) { - /* for preset menu */ - panel->layout = UI_block_layout( - block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, - 0, (UI_UNIT_Y * 1.1f) + style->panelspace, UI_UNIT_Y, 1, 0, style); - - pt->draw_header_preset(C, panel); - - int headerend = w - UI_UNIT_X; - - UI_block_layout_resolve(block, &xco, &yco); - UI_block_translate(block, headerend - xco, 0); - panel->layout = NULL; - } - - if (pt->draw_header && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) { - int labelx, labely; - UI_panel_label_offset(block, &labelx, &labely); - - /* for enabled buttons */ - panel->layout = UI_block_layout( - block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, - labelx, labely, UI_UNIT_Y, 1, 0, style); - - pt->draw_header(C, panel); - - UI_block_layout_resolve(block, &xco, &yco); - panel->labelofs = xco - labelx; - panel->layout = NULL; - } - else { - panel->labelofs = 0; - } - - if (open) { - short panelContext; - - /* panel context can either be toolbar region or normal panels region */ - if (pt->flag & PNL_LAYOUT_VERT_BAR) { - panelContext = UI_LAYOUT_VERT_BAR; - } - else if (ar->regiontype == RGN_TYPE_TOOLS) { - panelContext = UI_LAYOUT_TOOLBAR; - } - else { - panelContext = UI_LAYOUT_PANEL; - } - - panel->layout = UI_block_layout( - block, UI_LAYOUT_VERTICAL, panelContext, - (pt->flag & PNL_LAYOUT_VERT_BAR) ? 0 : style->panelspace, 0, - (pt->flag & PNL_LAYOUT_VERT_BAR) ? 0 : w - 2 * style->panelspace, - em, 0, style); - - pt->draw(C, panel); - - UI_block_layout_resolve(block, &xco, &yco); - panel->layout = NULL; - - if (yco != 0) { - h = -yco + 2 * style->panelspace; - } - } - - UI_block_end(C, block); - - /* Draw child panels. */ - if (open) { - for (LinkData *link = pt->children.first; link; link = link->next) { - PanelType *child_pt = link->data; - Panel *child_panel = UI_panel_find_by_type(&panel->children, child_pt); - - if (child_pt->draw && (!child_pt->poll || child_pt->poll(C, child_pt))) { - ed_panel_draw(C, sa, ar, &panel->children, child_pt, child_panel, w, em, vertical); - } - } - } - - UI_panel_end(block, w, h); + for (uint i = 0; arr[i]; i++) { + if (STREQ(arr[i], s)) { + return true; + } + } + return false; +} + +static void ed_panel_draw(const bContext *C, + ScrArea *sa, + ARegion *ar, + ListBase *lb, + PanelType *pt, + Panel *panel, + int w, + int em, + bool vertical) +{ + uiStyle *style = UI_style_get_dpi(); + + /* draw panel */ + uiBlock *block = UI_block_begin(C, ar, pt->idname, UI_EMBOSS); + + bool open; + panel = UI_panel_begin(sa, ar, lb, block, pt, panel, &open); + + /* bad fixed values */ + int xco, yco, h = 0; + + if (pt->draw_header_preset && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) { + /* for preset menu */ + panel->layout = UI_block_layout(block, + UI_LAYOUT_HORIZONTAL, + UI_LAYOUT_HEADER, + 0, + (UI_UNIT_Y * 1.1f) + style->panelspace, + UI_UNIT_Y, + 1, + 0, + style); + + pt->draw_header_preset(C, panel); + + int headerend = w - UI_UNIT_X; + + UI_block_layout_resolve(block, &xco, &yco); + UI_block_translate(block, headerend - xco, 0); + panel->layout = NULL; + } + + if (pt->draw_header && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) { + int labelx, labely; + UI_panel_label_offset(block, &labelx, &labely); + + /* for enabled buttons */ + panel->layout = UI_block_layout( + block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, labelx, labely, UI_UNIT_Y, 1, 0, style); + + pt->draw_header(C, panel); + + UI_block_layout_resolve(block, &xco, &yco); + panel->labelofs = xco - labelx; + panel->layout = NULL; + } + else { + panel->labelofs = 0; + } + + if (open) { + short panelContext; + + /* panel context can either be toolbar region or normal panels region */ + if (pt->flag & PNL_LAYOUT_VERT_BAR) { + panelContext = UI_LAYOUT_VERT_BAR; + } + else if (ar->regiontype == RGN_TYPE_TOOLS) { + panelContext = UI_LAYOUT_TOOLBAR; + } + else { + panelContext = UI_LAYOUT_PANEL; + } + + panel->layout = UI_block_layout(block, + UI_LAYOUT_VERTICAL, + panelContext, + (pt->flag & PNL_LAYOUT_VERT_BAR) ? 0 : style->panelspace, + 0, + (pt->flag & PNL_LAYOUT_VERT_BAR) ? 0 : + w - 2 * style->panelspace, + em, + 0, + style); + + pt->draw(C, panel); + + UI_block_layout_resolve(block, &xco, &yco); + panel->layout = NULL; + + if (yco != 0) { + h = -yco + 2 * style->panelspace; + } + } + + UI_block_end(C, block); + + /* Draw child panels. */ + if (open) { + for (LinkData *link = pt->children.first; link; link = link->next) { + PanelType *child_pt = link->data; + Panel *child_panel = UI_panel_find_by_type(&panel->children, child_pt); + + if (child_pt->draw && (!child_pt->poll || child_pt->poll(C, child_pt))) { + ed_panel_draw(C, sa, ar, &panel->children, child_pt, child_panel, w, em, vertical); + } + } + } + + UI_panel_end(block, w, h); } /** @@ -2150,430 +2193,423 @@ static void ed_panel_draw( * Can be NULL to skip context checks. */ void ED_region_panels_layout_ex( - const bContext *C, ARegion *ar, - const char *contexts[], int contextnr, const bool vertical) -{ - ar->runtime.category = NULL; - - const WorkSpace *workspace = CTX_wm_workspace(C); - ScrArea *sa = CTX_wm_area(C); - PanelType *pt; - View2D *v2d = &ar->v2d; - int x, y, w, em; - bool is_context_new = 0; - int scroll; - - /* XXX, should use some better check? */ - /* For now also has hardcoded check for clip editor until it supports actual toolbar. */ - bool use_category_tabs = ((1 << ar->regiontype) & RGN_TYPE_HAS_CATEGORY_MASK) || - (ar->regiontype == RGN_TYPE_TOOLS && sa->spacetype == SPACE_CLIP); - /* offset panels for small vertical tab area */ - const char *category = NULL; - const int category_tabs_width = UI_PANEL_CATEGORY_MARGIN_WIDTH; - int margin_x = 0; - const bool region_layout_based = ar->flag & RGN_FLAG_DYNAMIC_SIZE; - - BLI_SMALLSTACK_DECLARE(pt_stack, PanelType *); - - if (contextnr != -1) - is_context_new = UI_view2d_tab_set(v2d, contextnr); - - /* before setting the view */ - if (vertical) { - /* only allow scrolling in vertical direction */ - v2d->keepofs |= V2D_LOCKOFS_X | V2D_KEEPOFS_Y; - v2d->keepofs &= ~(V2D_LOCKOFS_Y | V2D_KEEPOFS_X); - v2d->scroll &= ~(V2D_SCROLL_BOTTOM); - v2d->scroll |= (V2D_SCROLL_RIGHT); - } - else { - /* for now, allow scrolling in both directions (since layouts are optimized for vertical, - * they often don't fit in horizontal layout) - */ - v2d->keepofs &= ~(V2D_LOCKOFS_X | V2D_LOCKOFS_Y | V2D_KEEPOFS_X | V2D_KEEPOFS_Y); - v2d->scroll |= (V2D_SCROLL_BOTTOM); - v2d->scroll &= ~(V2D_SCROLL_RIGHT); - } - - scroll = v2d->scroll; - - - /* collect panels to draw */ - for (pt = ar->type->paneltypes.last; pt; pt = pt->prev) { - /* Only draw top level panels. */ - if (pt->parent) { - continue; - } - - /* verify context */ - if (contexts && pt->context[0] && !streq_array_any(pt->context, contexts)) { - continue; - } - - /* If we're tagged, only use compatible. */ - if (pt->owner_id[0] && BKE_workspace_owner_id_check(workspace, pt->owner_id) == false) { - continue; - } - - /* draw panel */ - if (pt->draw && (!pt->poll || pt->poll(C, pt))) { - BLI_SMALLSTACK_PUSH(pt_stack, pt); - } - } - - - /* collect categories */ - if (use_category_tabs) { - UI_panel_category_clear_all(ar); - - /* gather unique categories */ - BLI_SMALLSTACK_ITER_BEGIN(pt_stack, pt) - { - if (pt->category[0]) { - if (!UI_panel_category_find(ar, pt->category)) { - UI_panel_category_add(ar, pt->category); - } - } - } - BLI_SMALLSTACK_ITER_END; - - if (!UI_panel_category_is_visible(ar)) { - use_category_tabs = false; - } - else { - category = UI_panel_category_active_get(ar, true); - margin_x = category_tabs_width; - } - } - - - if (vertical) { - w = BLI_rctf_size_x(&v2d->cur); - em = (ar->type->prefsizex) ? 10 : 20; /* works out to 10*UI_UNIT_X or 20*UI_UNIT_X */ - } - else { - w = UI_PANEL_WIDTH; - em = (ar->type->prefsizex) ? 10 : 20; - } - - w -= margin_x; - - /* create panels */ - UI_panels_begin(C, ar); - - /* set view2d view matrix - UI_block_begin() stores it */ - UI_view2d_view_ortho(v2d); - - BLI_SMALLSTACK_ITER_BEGIN(pt_stack, pt) - { - Panel *panel = UI_panel_find_by_type(&ar->panels, pt); - - if (use_category_tabs && pt->category[0] && !STREQ(category, pt->category)) { - if ((panel == NULL) || ((panel->flag & PNL_PIN) == 0)) { - continue; - } - } - - ed_panel_draw(C, sa, ar, &ar->panels, pt, panel, w, em, vertical); - } - BLI_SMALLSTACK_ITER_END; - - /* align panels and return size */ - UI_panels_end(C, ar, &x, &y); - - /* before setting the view */ - if (region_layout_based) { - /* XXX, only single panel support atm. - * Can't use x/y values calculated above because they're not using the real height of panels, - * instead they calculate offsets for the next panel to start drawing. */ - Panel *panel = ar->panels.last; - if (panel != NULL) { - int size_dyn[2] = { - UI_UNIT_X * ((panel->flag & PNL_CLOSED) ? 8 : 14) / UI_DPI_FAC, - UI_panel_size_y(panel) / UI_DPI_FAC, - }; - /* region size is layout based and needs to be updated */ - if ((ar->sizex != size_dyn[0]) || - (ar->sizey != size_dyn[1])) - { - ar->sizex = size_dyn[0]; - ar->sizey = size_dyn[1]; - sa->flag |= AREA_FLAG_REGION_SIZE_UPDATE; - } - y = ABS(ar->sizey * UI_DPI_FAC - 1); - } - } - else if (vertical) { - /* we always keep the scroll offset - so the total view gets increased with the scrolled away part */ - if (v2d->cur.ymax < -FLT_EPSILON) { - /* Clamp to lower view boundary */ - if (v2d->tot.ymin < -v2d->winy) { - y = min_ii(y, 0); - } - else { - y = min_ii(y, v2d->cur.ymin); - } - } - - y = -y; - } - else { - /* don't jump back when panels close or hide */ - if (!is_context_new) { - if (v2d->tot.xmax > v2d->winx) { - x = max_ii(x, 0); - } - else { - x = max_ii(x, v2d->cur.xmax); - } - } - - y = -y; - } - - /* this also changes the 'cur' */ - UI_view2d_totRect_set(v2d, x, y); - - if (scroll != v2d->scroll) { - /* Note: this code scales fine, but because of rounding differences, positions of elements - * flip +1 or -1 pixel compared to redoing the entire layout again. - * Leaving in commented code for future tests */ + const bContext *C, ARegion *ar, const char *contexts[], int contextnr, const bool vertical) +{ + ar->runtime.category = NULL; + + const WorkSpace *workspace = CTX_wm_workspace(C); + ScrArea *sa = CTX_wm_area(C); + PanelType *pt; + View2D *v2d = &ar->v2d; + int x, y, w, em; + bool is_context_new = 0; + int scroll; + + /* XXX, should use some better check? */ + /* For now also has hardcoded check for clip editor until it supports actual toolbar. */ + bool use_category_tabs = ((1 << ar->regiontype) & RGN_TYPE_HAS_CATEGORY_MASK) || + (ar->regiontype == RGN_TYPE_TOOLS && sa->spacetype == SPACE_CLIP); + /* offset panels for small vertical tab area */ + const char *category = NULL; + const int category_tabs_width = UI_PANEL_CATEGORY_MARGIN_WIDTH; + int margin_x = 0; + const bool region_layout_based = ar->flag & RGN_FLAG_DYNAMIC_SIZE; + + BLI_SMALLSTACK_DECLARE(pt_stack, PanelType *); + + if (contextnr != -1) + is_context_new = UI_view2d_tab_set(v2d, contextnr); + + /* before setting the view */ + if (vertical) { + /* only allow scrolling in vertical direction */ + v2d->keepofs |= V2D_LOCKOFS_X | V2D_KEEPOFS_Y; + v2d->keepofs &= ~(V2D_LOCKOFS_Y | V2D_KEEPOFS_X); + v2d->scroll &= ~(V2D_SCROLL_BOTTOM); + v2d->scroll |= (V2D_SCROLL_RIGHT); + } + else { + /* for now, allow scrolling in both directions (since layouts are optimized for vertical, + * they often don't fit in horizontal layout) + */ + v2d->keepofs &= ~(V2D_LOCKOFS_X | V2D_LOCKOFS_Y | V2D_KEEPOFS_X | V2D_KEEPOFS_Y); + v2d->scroll |= (V2D_SCROLL_BOTTOM); + v2d->scroll &= ~(V2D_SCROLL_RIGHT); + } + + scroll = v2d->scroll; + + /* collect panels to draw */ + for (pt = ar->type->paneltypes.last; pt; pt = pt->prev) { + /* Only draw top level panels. */ + if (pt->parent) { + continue; + } + + /* verify context */ + if (contexts && pt->context[0] && !streq_array_any(pt->context, contexts)) { + continue; + } + + /* If we're tagged, only use compatible. */ + if (pt->owner_id[0] && BKE_workspace_owner_id_check(workspace, pt->owner_id) == false) { + continue; + } + + /* draw panel */ + if (pt->draw && (!pt->poll || pt->poll(C, pt))) { + BLI_SMALLSTACK_PUSH(pt_stack, pt); + } + } + + /* collect categories */ + if (use_category_tabs) { + UI_panel_category_clear_all(ar); + + /* gather unique categories */ + BLI_SMALLSTACK_ITER_BEGIN (pt_stack, pt) { + if (pt->category[0]) { + if (!UI_panel_category_find(ar, pt->category)) { + UI_panel_category_add(ar, pt->category); + } + } + } + BLI_SMALLSTACK_ITER_END; + + if (!UI_panel_category_is_visible(ar)) { + use_category_tabs = false; + } + else { + category = UI_panel_category_active_get(ar, true); + margin_x = category_tabs_width; + } + } + + if (vertical) { + w = BLI_rctf_size_x(&v2d->cur); + em = (ar->type->prefsizex) ? 10 : 20; /* works out to 10*UI_UNIT_X or 20*UI_UNIT_X */ + } + else { + w = UI_PANEL_WIDTH; + em = (ar->type->prefsizex) ? 10 : 20; + } + + w -= margin_x; + + /* create panels */ + UI_panels_begin(C, ar); + + /* set view2d view matrix - UI_block_begin() stores it */ + UI_view2d_view_ortho(v2d); + + BLI_SMALLSTACK_ITER_BEGIN (pt_stack, pt) { + Panel *panel = UI_panel_find_by_type(&ar->panels, pt); + + if (use_category_tabs && pt->category[0] && !STREQ(category, pt->category)) { + if ((panel == NULL) || ((panel->flag & PNL_PIN) == 0)) { + continue; + } + } + + ed_panel_draw(C, sa, ar, &ar->panels, pt, panel, w, em, vertical); + } + BLI_SMALLSTACK_ITER_END; + + /* align panels and return size */ + UI_panels_end(C, ar, &x, &y); + + /* before setting the view */ + if (region_layout_based) { + /* XXX, only single panel support atm. + * Can't use x/y values calculated above because they're not using the real height of panels, + * instead they calculate offsets for the next panel to start drawing. */ + Panel *panel = ar->panels.last; + if (panel != NULL) { + int size_dyn[2] = { + UI_UNIT_X * ((panel->flag & PNL_CLOSED) ? 8 : 14) / UI_DPI_FAC, + UI_panel_size_y(panel) / UI_DPI_FAC, + }; + /* region size is layout based and needs to be updated */ + if ((ar->sizex != size_dyn[0]) || (ar->sizey != size_dyn[1])) { + ar->sizex = size_dyn[0]; + ar->sizey = size_dyn[1]; + sa->flag |= AREA_FLAG_REGION_SIZE_UPDATE; + } + y = ABS(ar->sizey * UI_DPI_FAC - 1); + } + } + else if (vertical) { + /* we always keep the scroll offset - so the total view gets increased with the scrolled away part */ + if (v2d->cur.ymax < -FLT_EPSILON) { + /* Clamp to lower view boundary */ + if (v2d->tot.ymin < -v2d->winy) { + y = min_ii(y, 0); + } + else { + y = min_ii(y, v2d->cur.ymin); + } + } + + y = -y; + } + else { + /* don't jump back when panels close or hide */ + if (!is_context_new) { + if (v2d->tot.xmax > v2d->winx) { + x = max_ii(x, 0); + } + else { + x = max_ii(x, v2d->cur.xmax); + } + } + + y = -y; + } + + /* this also changes the 'cur' */ + UI_view2d_totRect_set(v2d, x, y); + + if (scroll != v2d->scroll) { + /* Note: this code scales fine, but because of rounding differences, positions of elements + * flip +1 or -1 pixel compared to redoing the entire layout again. + * Leaving in commented code for future tests */ #if 0 - UI_panels_scale(ar, BLI_rctf_size_x(&v2d->cur)); - break; + UI_panels_scale(ar, BLI_rctf_size_x(&v2d->cur)); + break; #endif - } + } - if (use_category_tabs) { - ar->runtime.category = category; - } + if (use_category_tabs) { + ar->runtime.category = category; + } } void ED_region_panels_layout(const bContext *C, ARegion *ar) { - ED_region_panels_layout_ex(C, ar, NULL, -1, true); + ED_region_panels_layout_ex(C, ar, NULL, -1, true); } void ED_region_panels_draw(const bContext *C, ARegion *ar) { - View2D *v2d = &ar->v2d; + View2D *v2d = &ar->v2d; - if (ar->alignment != RGN_ALIGN_FLOAT) { - region_clear_color(C, ar, (ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK); - } + if (ar->alignment != RGN_ALIGN_FLOAT) { + region_clear_color( + C, ar, (ar->type->regionid == RGN_TYPE_PREVIEW) ? TH_PREVIEW_BACK : TH_BACK); + } - /* reset line width for drawing tabs */ - GPU_line_width(1.0f); + /* reset line width for drawing tabs */ + GPU_line_width(1.0f); - /* set the view */ - UI_view2d_view_ortho(v2d); + /* set the view */ + UI_view2d_view_ortho(v2d); - /* View2D matrix might have changed due to dynamic sized regions. */ - UI_blocklist_update_window_matrix(C, &ar->uiblocks); + /* View2D matrix might have changed due to dynamic sized regions. */ + UI_blocklist_update_window_matrix(C, &ar->uiblocks); - /* draw panels */ - UI_panels_draw(C, ar); + /* draw panels */ + UI_panels_draw(C, ar); - /* restore view matrix */ - UI_view2d_view_restore(C); + /* restore view matrix */ + UI_view2d_view_restore(C); - /* Set in layout. */ - if (ar->runtime.category) { - UI_panel_category_draw_all(ar, ar->runtime.category); - } + /* Set in layout. */ + if (ar->runtime.category) { + UI_panel_category_draw_all(ar, ar->runtime.category); + } - /* scrollers */ - const rcti *mask = NULL; - rcti mask_buf; - if (ar->runtime.category && (ar->alignment == RGN_ALIGN_RIGHT)) { - UI_view2d_mask_from_win(v2d, &mask_buf); - mask_buf.xmax -= UI_PANEL_CATEGORY_MARGIN_WIDTH; - mask = &mask_buf; - } - View2DScrollers *scrollers = UI_view2d_scrollers_calc( - C, v2d, mask, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY); - UI_view2d_scrollers_draw(C, v2d, scrollers); - UI_view2d_scrollers_free(scrollers); + /* scrollers */ + const rcti *mask = NULL; + rcti mask_buf; + if (ar->runtime.category && (ar->alignment == RGN_ALIGN_RIGHT)) { + UI_view2d_mask_from_win(v2d, &mask_buf); + mask_buf.xmax -= UI_PANEL_CATEGORY_MARGIN_WIDTH; + mask = &mask_buf; + } + View2DScrollers *scrollers = UI_view2d_scrollers_calc( + C, v2d, mask, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY); + UI_view2d_scrollers_draw(C, v2d, scrollers); + UI_view2d_scrollers_free(scrollers); } void ED_region_panels_ex( - const bContext *C, ARegion *ar, - const char *contexts[], int contextnr, const bool vertical) + const bContext *C, ARegion *ar, const char *contexts[], int contextnr, const bool vertical) { - /* TODO: remove? */ - ED_region_panels_layout_ex(C, ar, contexts, contextnr, vertical); - ED_region_panels_draw(C, ar); + /* TODO: remove? */ + ED_region_panels_layout_ex(C, ar, contexts, contextnr, vertical); + ED_region_panels_draw(C, ar); } void ED_region_panels(const bContext *C, ARegion *ar) { - /* TODO: remove? */ - ED_region_panels_layout(C, ar); - ED_region_panels_draw(C, ar); + /* TODO: remove? */ + ED_region_panels_layout(C, ar); + ED_region_panels_draw(C, ar); } void ED_region_panels_init(wmWindowManager *wm, ARegion *ar) { - wmKeyMap *keymap; + wmKeyMap *keymap; - UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_PANELS_UI, ar->winx, ar->winy); + UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_PANELS_UI, ar->winx, ar->winy); - keymap = WM_keymap_ensure(wm->defaultconf, "View2D Buttons List", 0, 0); - WM_event_add_keymap_handler(&ar->handlers, keymap); + keymap = WM_keymap_ensure(wm->defaultconf, "View2D Buttons List", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); } void ED_region_header_layout(const bContext *C, ARegion *ar) { - uiStyle *style = UI_style_get_dpi(); - uiBlock *block; - uiLayout *layout; - HeaderType *ht; - Header header = {NULL}; - bool region_layout_based = ar->flag & RGN_FLAG_DYNAMIC_SIZE; + uiStyle *style = UI_style_get_dpi(); + uiBlock *block; + uiLayout *layout; + HeaderType *ht; + Header header = {NULL}; + bool region_layout_based = ar->flag & RGN_FLAG_DYNAMIC_SIZE; - /* Height of buttons and scaling needed to achieve it. */ - const int buttony = min_ii(UI_UNIT_Y, ar->winy - 2 * UI_DPI_FAC); - const float buttony_scale = buttony / (float)UI_UNIT_Y; + /* Height of buttons and scaling needed to achieve it. */ + const int buttony = min_ii(UI_UNIT_Y, ar->winy - 2 * UI_DPI_FAC); + const float buttony_scale = buttony / (float)UI_UNIT_Y; - /* Vertically center buttons. */ - int xco = UI_HEADER_OFFSET; - int yco = buttony + (ar->winy - buttony) / 2; - int maxco = xco; + /* Vertically center buttons. */ + int xco = UI_HEADER_OFFSET; + int yco = buttony + (ar->winy - buttony) / 2; + int maxco = xco; - /* XXX workaround for 1 px alignment issue. Not sure what causes it... Would prefer a proper fix - Julian */ - if (!ELEM(CTX_wm_area(C)->spacetype, SPACE_TOPBAR, SPACE_STATUSBAR)) { - yco -= 1; - } + /* XXX workaround for 1 px alignment issue. Not sure what causes it... Would prefer a proper fix - Julian */ + if (!ELEM(CTX_wm_area(C)->spacetype, SPACE_TOPBAR, SPACE_STATUSBAR)) { + yco -= 1; + } - /* set view2d view matrix for scrolling (without scrollers) */ - UI_view2d_view_ortho(&ar->v2d); + /* set view2d view matrix for scrolling (without scrollers) */ + UI_view2d_view_ortho(&ar->v2d); - /* draw all headers types */ - for (ht = ar->type->headertypes.first; ht; ht = ht->next) { - if (ht->poll && !ht->poll(C, ht)) { - continue; - } + /* draw all headers types */ + for (ht = ar->type->headertypes.first; ht; ht = ht->next) { + if (ht->poll && !ht->poll(C, ht)) { + continue; + } - block = UI_block_begin(C, ar, ht->idname, UI_EMBOSS); - layout = UI_block_layout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, xco, yco, buttony, 1, 0, style); + block = UI_block_begin(C, ar, ht->idname, UI_EMBOSS); + layout = UI_block_layout( + block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, xco, yco, buttony, 1, 0, style); - if (buttony_scale != 1.0f) { - uiLayoutSetScaleY(layout, buttony_scale); - } + if (buttony_scale != 1.0f) { + uiLayoutSetScaleY(layout, buttony_scale); + } - if (ht->draw) { - header.type = ht; - header.layout = layout; - ht->draw(C, &header); - if (ht->next) { - uiItemS(layout); - } + if (ht->draw) { + header.type = ht; + header.layout = layout; + ht->draw(C, &header); + if (ht->next) { + uiItemS(layout); + } - /* for view2d */ - xco = uiLayoutGetWidth(layout); - if (xco > maxco) - maxco = xco; - } + /* for view2d */ + xco = uiLayoutGetWidth(layout); + if (xco > maxco) + maxco = xco; + } - UI_block_layout_resolve(block, &xco, &yco); + UI_block_layout_resolve(block, &xco, &yco); - /* for view2d */ - if (xco > maxco) - maxco = xco; + /* for view2d */ + if (xco > maxco) + maxco = xco; - int new_sizex = (maxco + UI_HEADER_OFFSET) / UI_DPI_FAC; + int new_sizex = (maxco + UI_HEADER_OFFSET) / UI_DPI_FAC; - if (region_layout_based && (ar->sizex != new_sizex)) { - /* region size is layout based and needs to be updated */ - ScrArea *sa = CTX_wm_area(C); + if (region_layout_based && (ar->sizex != new_sizex)) { + /* region size is layout based and needs to be updated */ + ScrArea *sa = CTX_wm_area(C); - ar->sizex = new_sizex; - sa->flag |= AREA_FLAG_REGION_SIZE_UPDATE; - } + ar->sizex = new_sizex; + sa->flag |= AREA_FLAG_REGION_SIZE_UPDATE; + } - UI_block_end(C, block); - } + UI_block_end(C, block); + } - if (!region_layout_based) { - maxco += UI_HEADER_OFFSET; - } + if (!region_layout_based) { + maxco += UI_HEADER_OFFSET; + } - /* always as last */ - UI_view2d_totRect_set(&ar->v2d, maxco, ar->winy); + /* always as last */ + UI_view2d_totRect_set(&ar->v2d, maxco, ar->winy); - /* restore view matrix */ - UI_view2d_view_restore(C); + /* restore view matrix */ + UI_view2d_view_restore(C); } void ED_region_header_draw(const bContext *C, ARegion *ar) { - /* clear */ - region_clear_color(C, ar, region_background_color_id(C, ar)); + /* clear */ + region_clear_color(C, ar, region_background_color_id(C, ar)); - UI_view2d_view_ortho(&ar->v2d); + UI_view2d_view_ortho(&ar->v2d); - /* View2D matrix might have changed due to dynamic sized regions. */ - UI_blocklist_update_window_matrix(C, &ar->uiblocks); + /* View2D matrix might have changed due to dynamic sized regions. */ + UI_blocklist_update_window_matrix(C, &ar->uiblocks); - /* draw blocks */ - UI_blocklist_draw(C, &ar->uiblocks); + /* draw blocks */ + UI_blocklist_draw(C, &ar->uiblocks); - /* restore view matrix */ - UI_view2d_view_restore(C); + /* restore view matrix */ + UI_view2d_view_restore(C); } void ED_region_header(const bContext *C, ARegion *ar) { - /* TODO: remove? */ - ED_region_header_layout(C, ar); - ED_region_header_draw(C, ar); + /* TODO: remove? */ + ED_region_header_layout(C, ar); + ED_region_header_draw(C, ar); } void ED_region_header_init(ARegion *ar) { - UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy); + UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy); } int ED_area_headersize(void) { - /* Accomodate widget and padding. */ - return U.widget_unit + (int)(UI_DPI_FAC * HEADER_PADDING_Y); + /* Accomodate widget and padding. */ + return U.widget_unit + (int)(UI_DPI_FAC * HEADER_PADDING_Y); } int ED_area_header_alignment_or_fallback(const ScrArea *area, int fallback) { - for (ARegion *ar = area->regionbase.first; ar; ar = ar->next) { - if (ar->regiontype == RGN_TYPE_HEADER) { - return ar->alignment; - } - } - return fallback; + for (ARegion *ar = area->regionbase.first; ar; ar = ar->next) { + if (ar->regiontype == RGN_TYPE_HEADER) { + return ar->alignment; + } + } + return fallback; } int ED_area_header_alignment(const ScrArea *area) { - return ED_area_header_alignment_or_fallback( - area, (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP); + return ED_area_header_alignment_or_fallback( + area, (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP); } int ED_area_footersize(void) { - return ED_area_headersize(); + return ED_area_headersize(); } int ED_area_footer_alignment_or_fallback(const ScrArea *area, int fallback) { - for (ARegion *ar = area->regionbase.first; ar; ar = ar->next) { - if (ar->regiontype == RGN_TYPE_FOOTER) { - return ar->alignment; - } - } - return fallback; + for (ARegion *ar = area->regionbase.first; ar; ar = ar->next) { + if (ar->regiontype == RGN_TYPE_FOOTER) { + return ar->alignment; + } + } + return fallback; } int ED_area_footer_alignment(const ScrArea *area) { - return ED_area_footer_alignment_or_fallback( - area, (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_TOP : RGN_ALIGN_BOTTOM); + return ED_area_footer_alignment_or_fallback( + area, (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_TOP : RGN_ALIGN_BOTTOM); } /** @@ -2581,51 +2617,51 @@ int ED_area_footer_alignment(const ScrArea *area) */ int ED_area_global_size_y(const ScrArea *area) { - BLI_assert(ED_area_is_global(area)); - return round_fl_to_int(area->global->cur_fixed_height * UI_DPI_FAC); + BLI_assert(ED_area_is_global(area)); + return round_fl_to_int(area->global->cur_fixed_height * UI_DPI_FAC); } int ED_area_global_min_size_y(const ScrArea *area) { - BLI_assert(ED_area_is_global(area)); - return round_fl_to_int(area->global->size_min * UI_DPI_FAC); + BLI_assert(ED_area_is_global(area)); + return round_fl_to_int(area->global->size_min * UI_DPI_FAC); } int ED_area_global_max_size_y(const ScrArea *area) { - BLI_assert(ED_area_is_global(area)); - return round_fl_to_int(area->global->size_max * UI_DPI_FAC); + BLI_assert(ED_area_is_global(area)); + return round_fl_to_int(area->global->size_max * UI_DPI_FAC); } bool ED_area_is_global(const ScrArea *area) { - return area->global != NULL; + return area->global != NULL; } ScrArea *ED_screen_areas_iter_first(const wmWindow *win, const bScreen *screen) { - ScrArea *global_area = win->global_areas.areabase.first; + ScrArea *global_area = win->global_areas.areabase.first; - if (!global_area) { - return screen->areabase.first; - } - else if ((global_area->global->flag & GLOBAL_AREA_IS_HIDDEN) == 0) { - return global_area; - } - /* Find next visible area. */ - return ED_screen_areas_iter_next(screen, global_area); + if (!global_area) { + return screen->areabase.first; + } + else if ((global_area->global->flag & GLOBAL_AREA_IS_HIDDEN) == 0) { + return global_area; + } + /* Find next visible area. */ + return ED_screen_areas_iter_next(screen, global_area); } ScrArea *ED_screen_areas_iter_next(const bScreen *screen, const ScrArea *area) { - if (area->global) { - for (ScrArea *area_iter = area->next; area_iter; area_iter = area_iter->next) { - if ((area_iter->global->flag & GLOBAL_AREA_IS_HIDDEN) == 0) { - return area_iter; - } - } - /* No visible next global area found, start iterating over layout areas. */ - return screen->areabase.first; - } + if (area->global) { + for (ScrArea *area_iter = area->next; area_iter; area_iter = area_iter->next) { + if ((area_iter->global->flag & GLOBAL_AREA_IS_HIDDEN) == 0) { + return area_iter; + } + } + /* No visible next global area found, start iterating over layout areas. */ + return screen->areabase.first; + } - return area->next; + return area->next; } /** @@ -2636,646 +2672,654 @@ ScrArea *ED_screen_areas_iter_next(const bScreen *screen, const ScrArea *area) */ int ED_region_global_size_y(void) { - return ED_area_headersize(); /* same size as header */ -} - -void ED_region_info_draw_multiline(ARegion *ar, const char *text_array[], float fill_color[4], const bool full_redraw) -{ - const int header_height = UI_UNIT_Y; - uiStyle *style = UI_style_get_dpi(); - int fontid = style->widget.uifont_id; - int scissor[4]; - rcti rect; - int num_lines = 0; - - /* background box */ - ED_region_visible_rect(ar, &rect); - - /* Box fill entire width or just around text. */ - if (!full_redraw) { - const char **text = &text_array[0]; - while (*text) { - rect.xmax = min_ii(rect.xmax, rect.xmin + BLF_width(fontid, *text, BLF_DRAW_STR_DUMMY_MAX) + 1.2f * U.widget_unit); - text++; - num_lines++; - } - } - /* Just count the line number. */ - else { - const char **text = &text_array[0]; - while (*text) { - text++; - num_lines++; - } - } - - rect.ymin = rect.ymax - header_height * num_lines; - - /* setup scissor */ - GPU_scissor_get_i(scissor); - GPU_scissor(rect.xmin, rect.ymin, - BLI_rcti_size_x(&rect) + 1, BLI_rcti_size_y(&rect) + 1); - - GPU_blend(true); - GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - immUniformColor4fv(fill_color); - immRecti(pos, rect.xmin, rect.ymin, rect.xmax + 1, rect.ymax + 1); - immUnbindProgram(); - GPU_blend(false); - - /* text */ - UI_FontThemeColor(fontid, TH_TEXT_HI); - BLF_clipping(fontid, rect.xmin, rect.ymin, rect.xmax, rect.ymax); - BLF_enable(fontid, BLF_CLIPPING); - int offset = num_lines - 1; - { - const char **text = &text_array[0]; - while (*text) { - BLF_position(fontid, rect.xmin + 0.6f * U.widget_unit, rect.ymin + 0.3f * U.widget_unit + offset * header_height, 0.0f); - BLF_draw(fontid, *text, BLF_DRAW_STR_DUMMY_MAX); - text++; - offset--; - } - } - - BLF_disable(fontid, BLF_CLIPPING); - - /* restore scissor as it was before */ - GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]); -} - -void ED_region_info_draw(ARegion *ar, const char *text, float fill_color[4], const bool full_redraw) -{ - ED_region_info_draw_multiline(ar, (const char *[2]){text, NULL}, fill_color, full_redraw); -} - -#define MAX_METADATA_STR 1024 - -static const char *meta_data_list[] = -{ - "File", - "Strip", - "Date", - "RenderTime", - "Note", - "Marker", - "Time", - "Frame", - "Camera", - "Scene", + return ED_area_headersize(); /* same size as header */ +} + +void ED_region_info_draw_multiline(ARegion *ar, + const char *text_array[], + float fill_color[4], + const bool full_redraw) +{ + const int header_height = UI_UNIT_Y; + uiStyle *style = UI_style_get_dpi(); + int fontid = style->widget.uifont_id; + int scissor[4]; + rcti rect; + int num_lines = 0; + + /* background box */ + ED_region_visible_rect(ar, &rect); + + /* Box fill entire width or just around text. */ + if (!full_redraw) { + const char **text = &text_array[0]; + while (*text) { + rect.xmax = min_ii(rect.xmax, + rect.xmin + BLF_width(fontid, *text, BLF_DRAW_STR_DUMMY_MAX) + + 1.2f * U.widget_unit); + text++; + num_lines++; + } + } + /* Just count the line number. */ + else { + const char **text = &text_array[0]; + while (*text) { + text++; + num_lines++; + } + } + + rect.ymin = rect.ymax - header_height * num_lines; + + /* setup scissor */ + GPU_scissor_get_i(scissor); + GPU_scissor(rect.xmin, rect.ymin, BLI_rcti_size_x(&rect) + 1, BLI_rcti_size_y(&rect) + 1); + + GPU_blend(true); + GPU_blend_set_func_separate( + GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor4fv(fill_color); + immRecti(pos, rect.xmin, rect.ymin, rect.xmax + 1, rect.ymax + 1); + immUnbindProgram(); + GPU_blend(false); + + /* text */ + UI_FontThemeColor(fontid, TH_TEXT_HI); + BLF_clipping(fontid, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + BLF_enable(fontid, BLF_CLIPPING); + int offset = num_lines - 1; + { + const char **text = &text_array[0]; + while (*text) { + BLF_position(fontid, + rect.xmin + 0.6f * U.widget_unit, + rect.ymin + 0.3f * U.widget_unit + offset * header_height, + 0.0f); + BLF_draw(fontid, *text, BLF_DRAW_STR_DUMMY_MAX); + text++; + offset--; + } + } + + BLF_disable(fontid, BLF_CLIPPING); + + /* restore scissor as it was before */ + GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]); +} + +void ED_region_info_draw(ARegion *ar, + const char *text, + float fill_color[4], + const bool full_redraw) +{ + ED_region_info_draw_multiline(ar, (const char * [2]){text, NULL}, fill_color, full_redraw); +} + +#define MAX_METADATA_STR 1024 + +static const char *meta_data_list[] = { + "File", + "Strip", + "Date", + "RenderTime", + "Note", + "Marker", + "Time", + "Frame", + "Camera", + "Scene", }; BLI_INLINE bool metadata_is_valid(ImBuf *ibuf, char *r_str, short index, int offset) { - return (IMB_metadata_get_field(ibuf->metadata, meta_data_list[index], r_str + offset, MAX_METADATA_STR - offset) && r_str[0]); + return (IMB_metadata_get_field( + ibuf->metadata, meta_data_list[index], r_str + offset, MAX_METADATA_STR - offset) && + r_str[0]); } BLI_INLINE bool metadata_is_custom_drawable(const char *field) { - /* Metadata field stored by Blender for multilayer EXR images. Is rather - * useless to be viewed all the time. Can still be seen in the Metadata - * panel. */ - if (STREQ(field, "BlenderMultiChannel")) { - return false; - } - /* Is almost always has value "scanlineimage", also useless to be seen - * all the time. */ - if (STREQ(field, "type")) { - return false; - } - return !BKE_stamp_is_known_field(field); + /* Metadata field stored by Blender for multilayer EXR images. Is rather + * useless to be viewed all the time. Can still be seen in the Metadata + * panel. */ + if (STREQ(field, "BlenderMultiChannel")) { + return false; + } + /* Is almost always has value "scanlineimage", also useless to be seen + * all the time. */ + if (STREQ(field, "type")) { + return false; + } + return !BKE_stamp_is_known_field(field); } typedef struct MetadataCustomDrawContext { - int fontid; - int xmin, ymin; - int vertical_offset; - int current_y; + int fontid; + int xmin, ymin; + int vertical_offset; + int current_y; } MetadataCustomDrawContext; -static void metadata_custom_draw_fields( - const char *field, - const char *value, - void *ctx_v) +static void metadata_custom_draw_fields(const char *field, const char *value, void *ctx_v) { - if (!metadata_is_custom_drawable(field)) { - return; - } - MetadataCustomDrawContext *ctx = (MetadataCustomDrawContext *)ctx_v; - char temp_str[MAX_METADATA_STR]; - BLI_snprintf(temp_str, MAX_METADATA_STR, "%s: %s", field, value); - BLF_position(ctx->fontid, ctx->xmin, ctx->ymin + ctx->current_y, 0.0f); - BLF_draw(ctx->fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); - ctx->current_y += ctx->vertical_offset; + if (!metadata_is_custom_drawable(field)) { + return; + } + MetadataCustomDrawContext *ctx = (MetadataCustomDrawContext *)ctx_v; + char temp_str[MAX_METADATA_STR]; + BLI_snprintf(temp_str, MAX_METADATA_STR, "%s: %s", field, value); + BLF_position(ctx->fontid, ctx->xmin, ctx->ymin + ctx->current_y, 0.0f); + BLF_draw(ctx->fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); + ctx->current_y += ctx->vertical_offset; } static void metadata_draw_imbuf(ImBuf *ibuf, const rctf *rect, int fontid, const bool is_top) { - char temp_str[MAX_METADATA_STR]; - int line_width; - int ofs_y = 0; - short i; - int len; - const float height = BLF_height_max(fontid); - const float margin = height / 8; - const float vertical_offset = (height + margin); - - /* values taking margins into account */ - const float descender = BLF_descender(fontid); - const float xmin = (rect->xmin + margin); - const float xmax = (rect->xmax - margin); - const float ymin = (rect->ymin + margin) - descender; - const float ymax = (rect->ymax - margin) - descender; - - if (is_top) { - for (i = 0; i < 4; i++) { - /* first line */ - if (i == 0) { - bool do_newline = false; - len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[0]); - if (metadata_is_valid(ibuf, temp_str, 0, len)) { - BLF_position(fontid, xmin, ymax - vertical_offset, 0.0f); - BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); - do_newline = true; - } - - len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[1]); - if (metadata_is_valid(ibuf, temp_str, 1, len)) { - line_width = BLF_width(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); - BLF_position(fontid, xmax - line_width, ymax - vertical_offset, 0.0f); - BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); - do_newline = true; - } - - if (do_newline) - ofs_y += vertical_offset; - } /* Strip */ - else if (i == 1 || i == 2) { - len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[i + 1]); - if (metadata_is_valid(ibuf, temp_str, i + 1, len)) { - BLF_position(fontid, xmin, ymax - vertical_offset - ofs_y, 0.0f); - BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); - ofs_y += vertical_offset; - } - } /* Note (wrapped) */ - else if (i == 3) { - len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[i + 1]); - if (metadata_is_valid(ibuf, temp_str, i + 1, len)) { - struct ResultBLF info; - BLF_enable(fontid, BLF_WORD_WRAP); - BLF_wordwrap(fontid, ibuf->x - (margin * 2)); - BLF_position(fontid, xmin, ymax - vertical_offset - ofs_y, 0.0f); - BLF_draw_ex(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX, &info); - BLF_wordwrap(fontid, 0); - BLF_disable(fontid, BLF_WORD_WRAP); - ofs_y += vertical_offset * info.lines; - } - } - else { - len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[i + 1]); - if (metadata_is_valid(ibuf, temp_str, i + 1, len)) { - line_width = BLF_width(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); - BLF_position(fontid, xmax - line_width, ymax - vertical_offset - ofs_y, 0.0f); - BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); - ofs_y += vertical_offset; - } - } - } - } - else { - MetadataCustomDrawContext ctx; - ctx.fontid = fontid; - ctx.xmin = xmin; - ctx.ymin = ymin; - ctx.vertical_offset = vertical_offset; - ctx.current_y = ofs_y; - ctx.vertical_offset = vertical_offset; - IMB_metadata_foreach(ibuf, metadata_custom_draw_fields, &ctx); - int ofs_x = 0; - ofs_y = ctx.current_y; - for (i = 5; i < 10; i++) { - len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[i]); - if (metadata_is_valid(ibuf, temp_str, i, len)) { - BLF_position(fontid, xmin + ofs_x, ymin + ofs_y, 0.0f); - BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); - - ofs_x += BLF_width(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX) + UI_UNIT_X; - } - } - } + char temp_str[MAX_METADATA_STR]; + int line_width; + int ofs_y = 0; + short i; + int len; + const float height = BLF_height_max(fontid); + const float margin = height / 8; + const float vertical_offset = (height + margin); + + /* values taking margins into account */ + const float descender = BLF_descender(fontid); + const float xmin = (rect->xmin + margin); + const float xmax = (rect->xmax - margin); + const float ymin = (rect->ymin + margin) - descender; + const float ymax = (rect->ymax - margin) - descender; + + if (is_top) { + for (i = 0; i < 4; i++) { + /* first line */ + if (i == 0) { + bool do_newline = false; + len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[0]); + if (metadata_is_valid(ibuf, temp_str, 0, len)) { + BLF_position(fontid, xmin, ymax - vertical_offset, 0.0f); + BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); + do_newline = true; + } + + len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[1]); + if (metadata_is_valid(ibuf, temp_str, 1, len)) { + line_width = BLF_width(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); + BLF_position(fontid, xmax - line_width, ymax - vertical_offset, 0.0f); + BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); + do_newline = true; + } + + if (do_newline) + ofs_y += vertical_offset; + } /* Strip */ + else if (i == 1 || i == 2) { + len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[i + 1]); + if (metadata_is_valid(ibuf, temp_str, i + 1, len)) { + BLF_position(fontid, xmin, ymax - vertical_offset - ofs_y, 0.0f); + BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); + ofs_y += vertical_offset; + } + } /* Note (wrapped) */ + else if (i == 3) { + len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[i + 1]); + if (metadata_is_valid(ibuf, temp_str, i + 1, len)) { + struct ResultBLF info; + BLF_enable(fontid, BLF_WORD_WRAP); + BLF_wordwrap(fontid, ibuf->x - (margin * 2)); + BLF_position(fontid, xmin, ymax - vertical_offset - ofs_y, 0.0f); + BLF_draw_ex(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX, &info); + BLF_wordwrap(fontid, 0); + BLF_disable(fontid, BLF_WORD_WRAP); + ofs_y += vertical_offset * info.lines; + } + } + else { + len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[i + 1]); + if (metadata_is_valid(ibuf, temp_str, i + 1, len)) { + line_width = BLF_width(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); + BLF_position(fontid, xmax - line_width, ymax - vertical_offset - ofs_y, 0.0f); + BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); + ofs_y += vertical_offset; + } + } + } + } + else { + MetadataCustomDrawContext ctx; + ctx.fontid = fontid; + ctx.xmin = xmin; + ctx.ymin = ymin; + ctx.vertical_offset = vertical_offset; + ctx.current_y = ofs_y; + ctx.vertical_offset = vertical_offset; + IMB_metadata_foreach(ibuf, metadata_custom_draw_fields, &ctx); + int ofs_x = 0; + ofs_y = ctx.current_y; + for (i = 5; i < 10; i++) { + len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[i]); + if (metadata_is_valid(ibuf, temp_str, i, len)) { + BLF_position(fontid, xmin + ofs_x, ymin + ofs_y, 0.0f); + BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); + + ofs_x += BLF_width(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX) + UI_UNIT_X; + } + } + } } typedef struct MetadataCustomCountContext { - int count; + int count; } MetadataCustomCountContext; -static void metadata_custom_count_fields( - const char *field, - const char *UNUSED(value), - void *ctx_v) +static void metadata_custom_count_fields(const char *field, const char *UNUSED(value), void *ctx_v) { - if (!metadata_is_custom_drawable(field)) { - return; - } - MetadataCustomCountContext *ctx = (MetadataCustomCountContext *)ctx_v; - ctx->count++; + if (!metadata_is_custom_drawable(field)) { + return; + } + MetadataCustomCountContext *ctx = (MetadataCustomCountContext *)ctx_v; + ctx->count++; } - static float metadata_box_height_get(ImBuf *ibuf, int fontid, const bool is_top) { - const float height = BLF_height_max(fontid); - const float margin = (height / 8); - char str[MAX_METADATA_STR] = ""; - short i, count = 0; - - if (is_top) { - if (metadata_is_valid(ibuf, str, 0, 0) || metadata_is_valid(ibuf, str, 1, 0)) { - count++; - } - for (i = 2; i < 5; i++) { - if (metadata_is_valid(ibuf, str, i, 0)) { - if (i == 4) { - struct { - struct ResultBLF info; - rctf rect; - } wrap; - - BLF_enable(fontid, BLF_WORD_WRAP); - BLF_wordwrap(fontid, ibuf->x - (margin * 2)); - BLF_boundbox_ex(fontid, str, sizeof(str), &wrap.rect, &wrap.info); - BLF_wordwrap(fontid, 0); - BLF_disable(fontid, BLF_WORD_WRAP); - - count += wrap.info.lines; - } - else { - count++; - } - } - } - } - else { - for (i = 5; i < 10; i++) { - if (metadata_is_valid(ibuf, str, i, 0)) { - count = 1; - break; - } - } - MetadataCustomCountContext ctx; - ctx.count = 0; - IMB_metadata_foreach(ibuf, metadata_custom_count_fields, &ctx); - count += ctx.count; - } - - if (count) { - return (height + margin) * count; - } - - return 0; + const float height = BLF_height_max(fontid); + const float margin = (height / 8); + char str[MAX_METADATA_STR] = ""; + short i, count = 0; + + if (is_top) { + if (metadata_is_valid(ibuf, str, 0, 0) || metadata_is_valid(ibuf, str, 1, 0)) { + count++; + } + for (i = 2; i < 5; i++) { + if (metadata_is_valid(ibuf, str, i, 0)) { + if (i == 4) { + struct { + struct ResultBLF info; + rctf rect; + } wrap; + + BLF_enable(fontid, BLF_WORD_WRAP); + BLF_wordwrap(fontid, ibuf->x - (margin * 2)); + BLF_boundbox_ex(fontid, str, sizeof(str), &wrap.rect, &wrap.info); + BLF_wordwrap(fontid, 0); + BLF_disable(fontid, BLF_WORD_WRAP); + + count += wrap.info.lines; + } + else { + count++; + } + } + } + } + else { + for (i = 5; i < 10; i++) { + if (metadata_is_valid(ibuf, str, i, 0)) { + count = 1; + break; + } + } + MetadataCustomCountContext ctx; + ctx.count = 0; + IMB_metadata_foreach(ibuf, metadata_custom_count_fields, &ctx); + count += ctx.count; + } + + if (count) { + return (height + margin) * count; + } + + return 0; } #undef MAX_METADATA_STR -void ED_region_image_metadata_draw(int x, int y, ImBuf *ibuf, const rctf *frame, float zoomx, float zoomy) +void ED_region_image_metadata_draw( + int x, int y, ImBuf *ibuf, const rctf *frame, float zoomx, float zoomy) { - float box_y; - rctf rect; - uiStyle *style = UI_style_get_dpi(); - - if (!ibuf->metadata) - return; + float box_y; + rctf rect; + uiStyle *style = UI_style_get_dpi(); - /* find window pixel coordinates of origin */ - GPU_matrix_push(); + if (!ibuf->metadata) + return; - /* offset and zoom using ogl */ - GPU_matrix_translate_2f(x, y); - GPU_matrix_scale_2f(zoomx, zoomy); + /* find window pixel coordinates of origin */ + GPU_matrix_push(); - BLF_size(blf_mono_font, style->widgetlabel.points * 1.5f * U.pixelsize, U.dpi); + /* offset and zoom using ogl */ + GPU_matrix_translate_2f(x, y); + GPU_matrix_scale_2f(zoomx, zoomy); - /* *** upper box*** */ + BLF_size(blf_mono_font, style->widgetlabel.points * 1.5f * U.pixelsize, U.dpi); - /* get needed box height */ - box_y = metadata_box_height_get(ibuf, blf_mono_font, true); + /* *** upper box*** */ - if (box_y) { - /* set up rect */ - BLI_rctf_init(&rect, frame->xmin, frame->xmax, frame->ymax, frame->ymax + box_y); - /* draw top box */ - GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - immUniformThemeColor(TH_METADATA_BG); - immRectf(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax); - immUnbindProgram(); + /* get needed box height */ + box_y = metadata_box_height_get(ibuf, blf_mono_font, true); - BLF_clipping(blf_mono_font, rect.xmin, rect.ymin, rect.xmax, rect.ymax); - BLF_enable(blf_mono_font, BLF_CLIPPING); + if (box_y) { + /* set up rect */ + BLI_rctf_init(&rect, frame->xmin, frame->xmax, frame->ymax, frame->ymax + box_y); + /* draw top box */ + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformThemeColor(TH_METADATA_BG); + immRectf(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + immUnbindProgram(); - UI_FontThemeColor(blf_mono_font, TH_METADATA_TEXT); - metadata_draw_imbuf(ibuf, &rect, blf_mono_font, true); + BLF_clipping(blf_mono_font, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + BLF_enable(blf_mono_font, BLF_CLIPPING); - BLF_disable(blf_mono_font, BLF_CLIPPING); - } + UI_FontThemeColor(blf_mono_font, TH_METADATA_TEXT); + metadata_draw_imbuf(ibuf, &rect, blf_mono_font, true); + BLF_disable(blf_mono_font, BLF_CLIPPING); + } - /* *** lower box*** */ + /* *** lower box*** */ - box_y = metadata_box_height_get(ibuf, blf_mono_font, false); + box_y = metadata_box_height_get(ibuf, blf_mono_font, false); - if (box_y) { - /* set up box rect */ - BLI_rctf_init(&rect, frame->xmin, frame->xmax, frame->ymin - box_y, frame->ymin); - /* draw top box */ - GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - immUniformThemeColor(TH_METADATA_BG); - immRectf(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax); - immUnbindProgram(); + if (box_y) { + /* set up box rect */ + BLI_rctf_init(&rect, frame->xmin, frame->xmax, frame->ymin - box_y, frame->ymin); + /* draw top box */ + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformThemeColor(TH_METADATA_BG); + immRectf(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + immUnbindProgram(); - BLF_clipping(blf_mono_font, rect.xmin, rect.ymin, rect.xmax, rect.ymax); - BLF_enable(blf_mono_font, BLF_CLIPPING); + BLF_clipping(blf_mono_font, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + BLF_enable(blf_mono_font, BLF_CLIPPING); - UI_FontThemeColor(blf_mono_font, TH_METADATA_TEXT); - metadata_draw_imbuf(ibuf, &rect, blf_mono_font, false); + UI_FontThemeColor(blf_mono_font, TH_METADATA_TEXT); + metadata_draw_imbuf(ibuf, &rect, blf_mono_font, false); - BLF_disable(blf_mono_font, BLF_CLIPPING); - } + BLF_disable(blf_mono_font, BLF_CLIPPING); + } - GPU_matrix_pop(); + GPU_matrix_pop(); } typedef struct MetadataPanelDrawContext { - uiLayout *layout; + uiLayout *layout; } MetadataPanelDrawContext; -static void metadata_panel_draw_field( - const char *field, - const char *value, - void *ctx_v) +static void metadata_panel_draw_field(const char *field, const char *value, void *ctx_v) { - MetadataPanelDrawContext *ctx = (MetadataPanelDrawContext *)ctx_v; - uiLayout *row = uiLayoutRow(ctx->layout, false); - uiItemL(row, field, ICON_NONE); - uiItemL(row, value, ICON_NONE); + MetadataPanelDrawContext *ctx = (MetadataPanelDrawContext *)ctx_v; + uiLayout *row = uiLayoutRow(ctx->layout, false); + uiItemL(row, field, ICON_NONE); + uiItemL(row, value, ICON_NONE); } void ED_region_image_metadata_panel_draw(ImBuf *ibuf, uiLayout *layout) { - MetadataPanelDrawContext ctx; - ctx.layout = layout; - IMB_metadata_foreach(ibuf, metadata_panel_draw_field, &ctx); + MetadataPanelDrawContext ctx; + ctx.layout = layout; + IMB_metadata_foreach(ibuf, metadata_panel_draw_field, &ctx); } void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy) { - float gridsize, gridstep = 1.0f / 32.0f; - float fac, blendfac; - int x1, y1, x2, y2; - - /* the image is located inside (0, 0), (1, 1) as set by view2d */ - UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x1, &y1); - UI_view2d_view_to_region(&ar->v2d, 1.0f, 1.0f, &x2, &y2); - - GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - immUniformThemeColorShade(TH_BACK, 20); - immRectf(pos, x1, y1, x2, y2); - immUnbindProgram(); - - /* gridsize adapted to zoom level */ - gridsize = 0.5f * (zoomx + zoomy); - if (gridsize <= 0.0f) - return; - - if (gridsize < 1.0f) { - while (gridsize < 1.0f) { - gridsize *= 4.0f; - gridstep *= 4.0f; - } - } - else { - while (gridsize >= 4.0f) { - gridsize /= 4.0f; - gridstep /= 4.0f; - } - } - - blendfac = 0.25f * gridsize - floorf(0.25f * gridsize); - CLAMP(blendfac, 0.0f, 1.0f); - - int count_fine = 1.0f / gridstep; - int count_large = 1.0f / (4.0f * gridstep); - - if (count_fine > 0) { - GPU_vertformat_clear(format); - pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - unsigned color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); - immBegin(GPU_PRIM_LINES, 4 * count_fine + 4 * count_large); - - float theme_color[3]; - UI_GetThemeColorShade3fv(TH_BACK, (int)(20.0f * (1.0f - blendfac)), theme_color); - fac = 0.0f; - - /* the fine resolution level */ - for (int i = 0; i < count_fine; i++) { - immAttr3fv(color, theme_color); - immVertex2f(pos, x1, y1 * (1.0f - fac) + y2 * fac); - immAttr3fv(color, theme_color); - immVertex2f(pos, x2, y1 * (1.0f - fac) + y2 * fac); - immAttr3fv(color, theme_color); - immVertex2f(pos, x1 * (1.0f - fac) + x2 * fac, y1); - immAttr3fv(color, theme_color); - immVertex2f(pos, x1 * (1.0f - fac) + x2 * fac, y2); - fac += gridstep; - } - - if (count_large > 0) { - UI_GetThemeColor3fv(TH_BACK, theme_color); - fac = 0.0f; - - /* the large resolution level */ - for (int i = 0; i < count_large; i++) { - immAttr3fv(color, theme_color); - immVertex2f(pos, x1, y1 * (1.0f - fac) + y2 * fac); - immAttr3fv(color, theme_color); - immVertex2f(pos, x2, y1 * (1.0f - fac) + y2 * fac); - immAttr3fv(color, theme_color); - immVertex2f(pos, x1 * (1.0f - fac) + x2 * fac, y1); - immAttr3fv(color, theme_color); - immVertex2f(pos, x1 * (1.0f - fac) + x2 * fac, y2); - fac += 4.0f * gridstep; - } - } - - immEnd(); - immUnbindProgram(); - } + float gridsize, gridstep = 1.0f / 32.0f; + float fac, blendfac; + int x1, y1, x2, y2; + + /* the image is located inside (0, 0), (1, 1) as set by view2d */ + UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x1, &y1); + UI_view2d_view_to_region(&ar->v2d, 1.0f, 1.0f, &x2, &y2); + + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformThemeColorShade(TH_BACK, 20); + immRectf(pos, x1, y1, x2, y2); + immUnbindProgram(); + + /* gridsize adapted to zoom level */ + gridsize = 0.5f * (zoomx + zoomy); + if (gridsize <= 0.0f) + return; + + if (gridsize < 1.0f) { + while (gridsize < 1.0f) { + gridsize *= 4.0f; + gridstep *= 4.0f; + } + } + else { + while (gridsize >= 4.0f) { + gridsize /= 4.0f; + gridstep /= 4.0f; + } + } + + blendfac = 0.25f * gridsize - floorf(0.25f * gridsize); + CLAMP(blendfac, 0.0f, 1.0f); + + int count_fine = 1.0f / gridstep; + int count_large = 1.0f / (4.0f * gridstep); + + if (count_fine > 0) { + GPU_vertformat_clear(format); + pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + unsigned color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); + immBegin(GPU_PRIM_LINES, 4 * count_fine + 4 * count_large); + + float theme_color[3]; + UI_GetThemeColorShade3fv(TH_BACK, (int)(20.0f * (1.0f - blendfac)), theme_color); + fac = 0.0f; + + /* the fine resolution level */ + for (int i = 0; i < count_fine; i++) { + immAttr3fv(color, theme_color); + immVertex2f(pos, x1, y1 * (1.0f - fac) + y2 * fac); + immAttr3fv(color, theme_color); + immVertex2f(pos, x2, y1 * (1.0f - fac) + y2 * fac); + immAttr3fv(color, theme_color); + immVertex2f(pos, x1 * (1.0f - fac) + x2 * fac, y1); + immAttr3fv(color, theme_color); + immVertex2f(pos, x1 * (1.0f - fac) + x2 * fac, y2); + fac += gridstep; + } + + if (count_large > 0) { + UI_GetThemeColor3fv(TH_BACK, theme_color); + fac = 0.0f; + + /* the large resolution level */ + for (int i = 0; i < count_large; i++) { + immAttr3fv(color, theme_color); + immVertex2f(pos, x1, y1 * (1.0f - fac) + y2 * fac); + immAttr3fv(color, theme_color); + immVertex2f(pos, x2, y1 * (1.0f - fac) + y2 * fac); + immAttr3fv(color, theme_color); + immVertex2f(pos, x1 * (1.0f - fac) + x2 * fac, y1); + immAttr3fv(color, theme_color); + immVertex2f(pos, x1 * (1.0f - fac) + x2 * fac, y2); + fac += 4.0f * gridstep; + } + } + + immEnd(); + immUnbindProgram(); + } } /* 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)) { - if (ELEM(arn->alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) { - /* Overlap left, also check 1 pixel offset (2 regions on one side). */ - if (ABS(rect->xmin - arn->winrct.xmin) < 2) { - rect->xmin = arn->winrct.xmax; - } - - /* Overlap right. */ - if (ABS(rect->xmax - arn->winrct.xmax) < 2) { - rect->xmax = arn->winrct.xmin; - } - } - else if (ELEM(arn->alignment, RGN_ALIGN_TOP, RGN_ALIGN_BOTTOM)) { - /* Same logic as above for vertical regions. */ - if (ABS(rect->ymin - arn->winrct.ymin) < 2) { - rect->ymin = arn->winrct.ymax; - } - if (ABS(rect->ymax - arn->winrct.ymax) < 2) { - rect->ymax = arn->winrct.ymin; - } - } - else if (arn->alignment == RGN_ALIGN_FLOAT) { - /* Skip floating. */ - } - else { - BLI_assert(!"Region overlap with unknown alignment"); - } - } - } - } - BLI_rcti_translate(rect, -ar->winrct.xmin, -ar->winrct.ymin); + 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)) { + if (ELEM(arn->alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) { + /* Overlap left, also check 1 pixel offset (2 regions on one side). */ + if (ABS(rect->xmin - arn->winrct.xmin) < 2) { + rect->xmin = arn->winrct.xmax; + } + + /* Overlap right. */ + if (ABS(rect->xmax - arn->winrct.xmax) < 2) { + rect->xmax = arn->winrct.xmin; + } + } + else if (ELEM(arn->alignment, RGN_ALIGN_TOP, RGN_ALIGN_BOTTOM)) { + /* Same logic as above for vertical regions. */ + if (ABS(rect->ymin - arn->winrct.ymin) < 2) { + rect->ymin = arn->winrct.ymax; + } + if (ABS(rect->ymax - arn->winrct.ymax) < 2) { + rect->ymax = arn->winrct.ymin; + } + } + else if (arn->alignment == RGN_ALIGN_FLOAT) { + /* Skip floating. */ + } + else { + BLI_assert(!"Region overlap with unknown alignment"); + } + } + } + } + BLI_rcti_translate(rect, -ar->winrct.xmin, -ar->winrct.ymin); } /* Cache display helpers */ void ED_region_cache_draw_background(const ARegion *ar) { - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - immUniformColor4ub(128, 128, 255, 64); - immRecti(pos, 0, 0, ar->winx, 8 * UI_DPI_FAC); - immUnbindProgram(); + uint pos = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor4ub(128, 128, 255, 64); + immRecti(pos, 0, 0, ar->winx, 8 * UI_DPI_FAC); + immUnbindProgram(); } void ED_region_cache_draw_curfra_label(const int framenr, const float x, const float y) { - uiStyle *style = UI_style_get(); - int fontid = style->widget.uifont_id; - char numstr[32]; - float font_dims[2] = {0.0f, 0.0f}; + uiStyle *style = UI_style_get(); + int fontid = style->widget.uifont_id; + char numstr[32]; + float font_dims[2] = {0.0f, 0.0f}; - /* frame number */ - BLF_size(fontid, 11.0f * U.pixelsize, U.dpi); - BLI_snprintf(numstr, sizeof(numstr), "%d", framenr); + /* frame number */ + BLF_size(fontid, 11.0f * U.pixelsize, U.dpi); + BLI_snprintf(numstr, sizeof(numstr), "%d", framenr); - BLF_width_and_height(fontid, numstr, sizeof(numstr), &font_dims[0], &font_dims[1]); + BLF_width_and_height(fontid, numstr, sizeof(numstr), &font_dims[0], &font_dims[1]); - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - immUniformThemeColor(TH_CFRAME); - immRecti(pos, x, y, x + font_dims[0] + 6.0f, y + font_dims[1] + 4.0f); - immUnbindProgram(); + uint pos = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformThemeColor(TH_CFRAME); + immRecti(pos, x, y, x + font_dims[0] + 6.0f, y + font_dims[1] + 4.0f); + immUnbindProgram(); - UI_FontThemeColor(fontid, TH_TEXT); - BLF_position(fontid, x + 2.0f, y + 2.0f, 0.0f); - BLF_draw(fontid, numstr, sizeof(numstr)); + UI_FontThemeColor(fontid, TH_TEXT); + BLF_position(fontid, x + 2.0f, y + 2.0f, 0.0f); + BLF_draw(fontid, numstr, sizeof(numstr)); } -void ED_region_cache_draw_cached_segments(const ARegion *ar, const int num_segments, const int *points, const int sfra, const int efra) +void ED_region_cache_draw_cached_segments( + const ARegion *ar, const int num_segments, const int *points, const int sfra, const int efra) { - if (num_segments) { - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - immUniformColor4ub(128, 128, 255, 128); + if (num_segments) { + uint pos = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor4ub(128, 128, 255, 128); - for (int a = 0; a < num_segments; a++) { - float x1 = (float)(points[a * 2] - sfra) / (efra - sfra + 1) * ar->winx; - float x2 = (float)(points[a * 2 + 1] - sfra + 1) / (efra - sfra + 1) * ar->winx; + for (int a = 0; a < num_segments; a++) { + float x1 = (float)(points[a * 2] - sfra) / (efra - sfra + 1) * ar->winx; + float x2 = (float)(points[a * 2 + 1] - sfra + 1) / (efra - sfra + 1) * ar->winx; - immRecti(pos, x1, 0, x2, 8 * UI_DPI_FAC); - /* TODO(merwin): use primitive restart to draw multiple rects more efficiently */ - } + immRecti(pos, x1, 0, x2, 8 * UI_DPI_FAC); + /* TODO(merwin): use primitive restart to draw multiple rects more efficiently */ + } - immUnbindProgram(); - } + immUnbindProgram(); + } } /** * Generate subscriptions for this region. */ -void ED_region_message_subscribe( - bContext *C, - struct WorkSpace *workspace, struct Scene *scene, - struct bScreen *screen, struct ScrArea *sa, struct ARegion *ar, - struct wmMsgBus *mbus) +void ED_region_message_subscribe(bContext *C, + struct WorkSpace *workspace, + struct Scene *scene, + struct bScreen *screen, + struct ScrArea *sa, + struct ARegion *ar, + struct wmMsgBus *mbus) { - if (ar->gizmo_map != NULL) { - WM_gizmomap_message_subscribe(C, ar->gizmo_map, ar, mbus); - } + if (ar->gizmo_map != NULL) { + WM_gizmomap_message_subscribe(C, ar->gizmo_map, ar, mbus); + } - if (!BLI_listbase_is_empty(&ar->uiblocks)) { - UI_region_message_subscribe(ar, mbus); - } + if (!BLI_listbase_is_empty(&ar->uiblocks)) { + UI_region_message_subscribe(ar, mbus); + } - if (ar->type->message_subscribe != NULL) { - ar->type->message_subscribe(C, workspace, scene, screen, sa, ar, mbus); - } + if (ar->type->message_subscribe != NULL) { + ar->type->message_subscribe(C, workspace, scene, screen, sa, ar, mbus); + } } int ED_region_snap_size_test(const ARegion *ar) { - /* Use a larger value because toggling scrollbars can jump in size. */ - const int snap_match_threshold = 16; - if (ar->type->snap_size != NULL) { - return ((((ar->sizex - ar->type->snap_size(ar, ar->sizex, 0)) <= snap_match_threshold) << 0) | - (((ar->sizey - ar->type->snap_size(ar, ar->sizey, 1)) <= snap_match_threshold) << 1)); - } - return 0; + /* Use a larger value because toggling scrollbars can jump in size. */ + const int snap_match_threshold = 16; + if (ar->type->snap_size != NULL) { + return ((((ar->sizex - ar->type->snap_size(ar, ar->sizex, 0)) <= snap_match_threshold) << 0) | + (((ar->sizey - ar->type->snap_size(ar, ar->sizey, 1)) <= snap_match_threshold) << 1)); + } + return 0; } bool ED_region_snap_size_apply(ARegion *ar, int snap_flag) { - bool changed = false; - if (ar->type->snap_size != NULL) { - if (snap_flag & (1 << 0)) { - short snap_size = ar->type->snap_size(ar, ar->sizex, 0); - if (snap_size != ar->sizex) { - ar->sizex = snap_size; - changed = true; - } - } - if (snap_flag & (1 << 1)) { - short snap_size = ar->type->snap_size(ar, ar->sizey, 1); - if (snap_size != ar->sizey) { - ar->sizey = snap_size; - changed = true; - } - } - } - return changed; + bool changed = false; + if (ar->type->snap_size != NULL) { + if (snap_flag & (1 << 0)) { + short snap_size = ar->type->snap_size(ar, ar->sizex, 0); + if (snap_size != ar->sizex) { + ar->sizex = snap_size; + changed = true; + } + } + if (snap_flag & (1 << 1)) { + short snap_size = ar->type->snap_size(ar, ar->sizey, 1); + if (snap_size != ar->sizey) { + ar->sizey = snap_size; + changed = true; + } + } + } + return changed; } diff --git a/source/blender/editors/screen/area_utils.c b/source/blender/editors/screen/area_utils.c index 2137d98d226..1a99210b73d 100644 --- a/source/blender/editors/screen/area_utils.c +++ b/source/blender/editors/screen/area_utils.c @@ -42,18 +42,20 @@ /** * Callback for #ARegionType.message_subscribe */ -void ED_region_generic_tools_region_message_subscribe( - const struct bContext *UNUSED(C), - struct WorkSpace *UNUSED(workspace), struct Scene *UNUSED(scene), - struct bScreen *UNUSED(screen), struct ScrArea *UNUSED(sa), struct ARegion *ar, - struct wmMsgBus *mbus) +void ED_region_generic_tools_region_message_subscribe(const struct bContext *UNUSED(C), + struct WorkSpace *UNUSED(workspace), + struct Scene *UNUSED(scene), + struct bScreen *UNUSED(screen), + struct ScrArea *UNUSED(sa), + struct ARegion *ar, + struct wmMsgBus *mbus) { - wmMsgSubscribeValue msg_sub_value_region_tag_redraw = { - .owner = ar, - .user_data = ar, - .notify = ED_region_do_msg_notify_tag_redraw, - }; - WM_msg_subscribe_rna_anon_prop(mbus, WorkSpace, tools, &msg_sub_value_region_tag_redraw); + wmMsgSubscribeValue msg_sub_value_region_tag_redraw = { + .owner = ar, + .user_data = ar, + .notify = ED_region_do_msg_notify_tag_redraw, + }; + WM_msg_subscribe_rna_anon_prop(mbus, WorkSpace, tools, &msg_sub_value_region_tag_redraw); } /** @@ -61,23 +63,23 @@ void ED_region_generic_tools_region_message_subscribe( */ int ED_region_generic_tools_region_snap_size(const ARegion *ar, int size, int axis) { - if (axis == 0) { - /* Note, this depends on the icon size: see #ICON_DEFAULT_HEIGHT_TOOLBAR. */ - const float snap_units[] = {2 + 0.8f, 4 + 0.8f}; - const float aspect = BLI_rctf_size_x(&ar->v2d.cur) / (BLI_rcti_size_x(&ar->v2d.mask) + 1); - int best_diff = INT_MAX; - int best_size = size; - for (uint i = 0; i < ARRAY_SIZE(snap_units); i += 1) { - const int test_size = (snap_units[i] * U.widget_unit) / (UI_DPI_FAC * aspect); - const int test_diff = ABS(test_size - size); - if (test_diff < best_diff) { - best_size = test_size; - best_diff = test_diff; - } - } - return best_size; - } - return size; + if (axis == 0) { + /* Note, this depends on the icon size: see #ICON_DEFAULT_HEIGHT_TOOLBAR. */ + const float snap_units[] = {2 + 0.8f, 4 + 0.8f}; + const float aspect = BLI_rctf_size_x(&ar->v2d.cur) / (BLI_rcti_size_x(&ar->v2d.mask) + 1); + int best_diff = INT_MAX; + int best_size = size; + for (uint i = 0; i < ARRAY_SIZE(snap_units); i += 1) { + const int test_size = (snap_units[i] * U.widget_unit) / (UI_DPI_FAC * aspect); + const int test_diff = ABS(test_size - size); + if (test_diff < best_diff) { + best_size = test_size; + best_diff = test_diff; + } + } + return best_size; + } + return size; } /** \} */ diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index 1606a159e38..7fec62157c1 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -21,7 +21,6 @@ * \ingroup edscr */ - #include <stdio.h> #include <string.h> @@ -50,75 +49,76 @@ /* Invert line handling */ -#define GL_TOGGLE(mode, onoff) (((onoff) ? glEnable : glDisable)(mode)) +#define GL_TOGGLE(mode, onoff) (((onoff) ? glEnable : glDisable)(mode)) void set_inverted_drawing(int enable) { - glLogicOp(enable ? GL_INVERT : GL_COPY); - GL_TOGGLE(GL_COLOR_LOGIC_OP, enable); - GL_TOGGLE(GL_DITHER, !enable); + glLogicOp(enable ? GL_INVERT : GL_COPY); + GL_TOGGLE(GL_COLOR_LOGIC_OP, enable); + GL_TOGGLE(GL_DITHER, !enable); } float glaGetOneFloat(int param) { - GLfloat v; - glGetFloatv(param, &v); - return v; + GLfloat v; + glGetFloatv(param, &v); + return v; } int glaGetOneInt(int param) { - GLint v; - glGetIntegerv(param, &v); - return v; + GLint v; + glGetIntegerv(param, &v); + return v; } void glaRasterPosSafe2f(float x, float y, float known_good_x, float known_good_y) { - GLubyte dummy = 0; - - /* As long as known good coordinates are correct - * this is guaranteed to generate an ok raster - * position (ignoring potential (real) overflow - * issues). - */ - glRasterPos2f(known_good_x, known_good_y); - - /* Now shift the raster position to where we wanted - * it in the first place using the glBitmap trick. - */ - glBitmap(0, 0, 0, 0, x - known_good_x, y - known_good_y, &dummy); + GLubyte dummy = 0; + + /* As long as known good coordinates are correct + * this is guaranteed to generate an ok raster + * position (ignoring potential (real) overflow + * issues). + */ + glRasterPos2f(known_good_x, known_good_y); + + /* Now shift the raster position to where we wanted + * it in the first place using the glBitmap trick. + */ + glBitmap(0, 0, 0, 0, x - known_good_x, y - known_good_y, &dummy); } static int get_cached_work_texture(int *r_w, int *r_h) { - static GLint texid = -1; - static int tex_w = 256; - static int tex_h = 256; + static GLint texid = -1; + static int tex_w = 256; + static int tex_h = 256; - if (texid == -1) { - glGenTextures(1, (GLuint *)&texid); + if (texid == -1) { + glGenTextures(1, (GLuint *)&texid); - glBindTexture(GL_TEXTURE_2D, texid); + glBindTexture(GL_TEXTURE_2D, texid); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_w, tex_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_w, tex_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, 0); - } + glBindTexture(GL_TEXTURE_2D, 0); + } - *r_w = tex_w; - *r_h = tex_h; - return texid; + *r_w = tex_w; + *r_h = tex_h; + return texid; } static void immDrawPixelsTexSetupAttributes(IMMDrawPixelsTexState *state) { - GPUVertFormat *vert_format = immVertexFormat(); - state->pos = GPU_vertformat_attr_add(vert_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - state->texco = GPU_vertformat_attr_add(vert_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + GPUVertFormat *vert_format = immVertexFormat(); + state->pos = GPU_vertformat_attr_add(vert_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + state->texco = GPU_vertformat_attr_add( + vert_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); } /* To be used before calling immDrawPixelsTex @@ -128,17 +128,17 @@ static void immDrawPixelsTexSetupAttributes(IMMDrawPixelsTexState *state) * */ IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin) { - IMMDrawPixelsTexState state; - immDrawPixelsTexSetupAttributes(&state); + IMMDrawPixelsTexState state; + immDrawPixelsTexSetupAttributes(&state); - state.shader = GPU_shader_get_builtin_shader(builtin); + state.shader = GPU_shader_get_builtin_shader(builtin); - /* Shader will be unbind by immUnbindProgram in immDrawPixelsTexScaled_clipping */ - immBindBuiltinProgram(builtin); - immUniform1i("image", 0); - state.do_shader_unbind = true; + /* Shader will be unbind by immUnbindProgram in immDrawPixelsTexScaled_clipping */ + immBindBuiltinProgram(builtin); + immUniform1i("image", 0); + state.do_shader_unbind = true; - return state; + return state; } /* Use the currently bound shader. @@ -155,210 +155,381 @@ IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin) * it's finished. * */ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state, - float x, float y, int img_w, int img_h, - int format, int type, int zoomfilter, void *rect, - float scaleX, float scaleY, - float clip_min_x, float clip_min_y, - float clip_max_x, float clip_max_y, - float xzoom, float yzoom, float color[4]) + float x, + float y, + int img_w, + int img_h, + int format, + int type, + int zoomfilter, + void *rect, + float scaleX, + float scaleY, + float clip_min_x, + float clip_min_y, + float clip_max_x, + float clip_max_y, + float xzoom, + float yzoom, + float color[4]) { - unsigned char *uc_rect = (unsigned char *) rect; - const float *f_rect = (float *)rect; - int subpart_x, subpart_y, tex_w, tex_h; - int seamless, offset_x, offset_y, nsubparts_x, nsubparts_y; - int texid = get_cached_work_texture(&tex_w, &tex_h); - int components; - const bool use_clipping = ((clip_min_x < clip_max_x) && (clip_min_y < clip_max_y)); - float white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - - GLint unpack_row_length; - glGetIntegerv(GL_UNPACK_ROW_LENGTH, &unpack_row_length); - - glPixelStorei(GL_UNPACK_ROW_LENGTH, img_w); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texid); - - /* don't want nasty border artifacts */ - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, zoomfilter); - - /* setup seamless 2=on, 0=off */ - seamless = ((tex_w < img_w || tex_h < img_h) && tex_w > 2 && tex_h > 2) ? 2 : 0; - - offset_x = tex_w - seamless; - offset_y = tex_h - seamless; - - nsubparts_x = (img_w + (offset_x - 1)) / (offset_x); - nsubparts_y = (img_h + (offset_y - 1)) / (offset_y); - - if (format == GL_RGBA) - components = 4; - else if (format == GL_RGB) - components = 3; - else if (format == GL_RED) - components = 1; - else { - BLI_assert(!"Incompatible format passed to glaDrawPixelsTexScaled"); - return; - } - - if (type == GL_FLOAT) { - /* need to set internal format to higher range float */ - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, tex_w, tex_h, 0, format, GL_FLOAT, NULL); - } - else { - /* switch to 8bit RGBA for byte buffer */ - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_w, tex_h, 0, format, GL_UNSIGNED_BYTE, NULL); - } - - unsigned int pos = state->pos, texco = state->texco; - - /* optional */ - /* NOTE: Shader could be null for GLSL OCIO drawing, it is fine, since - * it does not need color. - */ - if (state->shader != NULL && GPU_shader_get_uniform_ensure(state->shader, "color") != -1) { - immUniformColor4fv((color) ? color : white); - } - - for (subpart_y = 0; subpart_y < nsubparts_y; subpart_y++) { - for (subpart_x = 0; subpart_x < nsubparts_x; subpart_x++) { - int remainder_x = img_w - subpart_x * offset_x; - int remainder_y = img_h - subpart_y * offset_y; - int subpart_w = (remainder_x < tex_w) ? remainder_x : tex_w; - int subpart_h = (remainder_y < tex_h) ? remainder_y : tex_h; - int offset_left = (seamless && subpart_x != 0) ? 1 : 0; - int offset_bot = (seamless && subpart_y != 0) ? 1 : 0; - int offset_right = (seamless && remainder_x > tex_w) ? 1 : 0; - int offset_top = (seamless && remainder_y > tex_h) ? 1 : 0; - float rast_x = x + subpart_x * offset_x * xzoom; - float rast_y = y + subpart_y * offset_y * yzoom; - /* check if we already got these because we always get 2 more when doing seamless */ - if (subpart_w <= seamless || subpart_h <= seamless) - continue; - - if (use_clipping) { - if (rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX < clip_min_x || - rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY < clip_min_y) - { - continue; - } - if (rast_x + (float)offset_left * xzoom > clip_max_x || - rast_y + (float)offset_bot * yzoom > clip_max_y) - { - continue; - } - } - - if (type == GL_FLOAT) { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, format, GL_FLOAT, &f_rect[((size_t)subpart_y) * offset_y * img_w * components + subpart_x * offset_x * components]); - - /* add an extra border of pixels so linear looks ok at edges of full image */ - if (subpart_w < tex_w) - glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, 0, 1, subpart_h, format, GL_FLOAT, &f_rect[((size_t)subpart_y) * offset_y * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]); - if (subpart_h < tex_h) - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, subpart_h, subpart_w, 1, format, GL_FLOAT, &f_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + subpart_x * offset_x * components]); - if (subpart_w < tex_w && subpart_h < tex_h) - glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, subpart_h, 1, 1, format, GL_FLOAT, &f_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]); - } - else { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, format, GL_UNSIGNED_BYTE, &uc_rect[((size_t)subpart_y) * offset_y * img_w * components + subpart_x * offset_x * components]); - - if (subpart_w < tex_w) - glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, 0, 1, subpart_h, format, GL_UNSIGNED_BYTE, &uc_rect[((size_t)subpart_y) * offset_y * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]); - if (subpart_h < tex_h) - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, subpart_h, subpart_w, 1, format, GL_UNSIGNED_BYTE, &uc_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + subpart_x * offset_x * components]); - if (subpart_w < tex_w && subpart_h < tex_h) - glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, subpart_h, 1, 1, format, GL_UNSIGNED_BYTE, &uc_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]); - } - - immBegin(GPU_PRIM_TRI_FAN, 4); - immAttr2f(texco, (float)(0 + offset_left) / tex_w, (float)(0 + offset_bot) / tex_h); - immVertex2f(pos, rast_x + (float)offset_left * xzoom, rast_y + (float)offset_bot * yzoom); - - immAttr2f(texco, (float)(subpart_w - offset_right) / tex_w, (float)(0 + offset_bot) / tex_h); - immVertex2f(pos, rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX, rast_y + (float)offset_bot * yzoom); - - immAttr2f(texco, (float)(subpart_w - offset_right) / tex_w, (float)(subpart_h - offset_top) / tex_h); - immVertex2f(pos, rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX, rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY); - - immAttr2f(texco, (float)(0 + offset_left) / tex_w, (float)(subpart_h - offset_top) / tex_h); - immVertex2f(pos, rast_x + (float)offset_left * xzoom, rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY); - immEnd(); - - /* NOTE: Weirdly enough this is only required on macOS. Without this there is some sort of - * bleeding of data is happening from tiles which are drawn later on. - * This doesn't seem to be too slow, but still would be nice to have fast and nice solution. */ + unsigned char *uc_rect = (unsigned char *)rect; + const float *f_rect = (float *)rect; + int subpart_x, subpart_y, tex_w, tex_h; + int seamless, offset_x, offset_y, nsubparts_x, nsubparts_y; + int texid = get_cached_work_texture(&tex_w, &tex_h); + int components; + const bool use_clipping = ((clip_min_x < clip_max_x) && (clip_min_y < clip_max_y)); + float white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + + GLint unpack_row_length; + glGetIntegerv(GL_UNPACK_ROW_LENGTH, &unpack_row_length); + + glPixelStorei(GL_UNPACK_ROW_LENGTH, img_w); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texid); + + /* don't want nasty border artifacts */ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, zoomfilter); + + /* setup seamless 2=on, 0=off */ + seamless = ((tex_w < img_w || tex_h < img_h) && tex_w > 2 && tex_h > 2) ? 2 : 0; + + offset_x = tex_w - seamless; + offset_y = tex_h - seamless; + + nsubparts_x = (img_w + (offset_x - 1)) / (offset_x); + nsubparts_y = (img_h + (offset_y - 1)) / (offset_y); + + if (format == GL_RGBA) + components = 4; + else if (format == GL_RGB) + components = 3; + else if (format == GL_RED) + components = 1; + else { + BLI_assert(!"Incompatible format passed to glaDrawPixelsTexScaled"); + return; + } + + if (type == GL_FLOAT) { + /* need to set internal format to higher range float */ + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, tex_w, tex_h, 0, format, GL_FLOAT, NULL); + } + else { + /* switch to 8bit RGBA for byte buffer */ + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_w, tex_h, 0, format, GL_UNSIGNED_BYTE, NULL); + } + + unsigned int pos = state->pos, texco = state->texco; + + /* optional */ + /* NOTE: Shader could be null for GLSL OCIO drawing, it is fine, since + * it does not need color. + */ + if (state->shader != NULL && GPU_shader_get_uniform_ensure(state->shader, "color") != -1) { + immUniformColor4fv((color) ? color : white); + } + + for (subpart_y = 0; subpart_y < nsubparts_y; subpart_y++) { + for (subpart_x = 0; subpart_x < nsubparts_x; subpart_x++) { + int remainder_x = img_w - subpart_x * offset_x; + int remainder_y = img_h - subpart_y * offset_y; + int subpart_w = (remainder_x < tex_w) ? remainder_x : tex_w; + int subpart_h = (remainder_y < tex_h) ? remainder_y : tex_h; + int offset_left = (seamless && subpart_x != 0) ? 1 : 0; + int offset_bot = (seamless && subpart_y != 0) ? 1 : 0; + int offset_right = (seamless && remainder_x > tex_w) ? 1 : 0; + int offset_top = (seamless && remainder_y > tex_h) ? 1 : 0; + float rast_x = x + subpart_x * offset_x * xzoom; + float rast_y = y + subpart_y * offset_y * yzoom; + /* check if we already got these because we always get 2 more when doing seamless */ + if (subpart_w <= seamless || subpart_h <= seamless) + continue; + + if (use_clipping) { + if (rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX < clip_min_x || + rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY < clip_min_y) { + continue; + } + if (rast_x + (float)offset_left * xzoom > clip_max_x || + rast_y + (float)offset_bot * yzoom > clip_max_y) { + continue; + } + } + + if (type == GL_FLOAT) { + glTexSubImage2D(GL_TEXTURE_2D, + 0, + 0, + 0, + subpart_w, + subpart_h, + format, + GL_FLOAT, + &f_rect[((size_t)subpart_y) * offset_y * img_w * components + + subpart_x * offset_x * components]); + + /* add an extra border of pixels so linear looks ok at edges of full image */ + if (subpart_w < tex_w) + glTexSubImage2D(GL_TEXTURE_2D, + 0, + subpart_w, + 0, + 1, + subpart_h, + format, + GL_FLOAT, + &f_rect[((size_t)subpart_y) * offset_y * img_w * components + + (subpart_x * offset_x + subpart_w - 1) * components]); + if (subpart_h < tex_h) + glTexSubImage2D( + GL_TEXTURE_2D, + 0, + 0, + subpart_h, + subpart_w, + 1, + format, + GL_FLOAT, + &f_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + + subpart_x * offset_x * components]); + if (subpart_w < tex_w && subpart_h < tex_h) + glTexSubImage2D( + GL_TEXTURE_2D, + 0, + subpart_w, + subpart_h, + 1, + 1, + format, + GL_FLOAT, + &f_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + + (subpart_x * offset_x + subpart_w - 1) * components]); + } + else { + glTexSubImage2D(GL_TEXTURE_2D, + 0, + 0, + 0, + subpart_w, + subpart_h, + format, + GL_UNSIGNED_BYTE, + &uc_rect[((size_t)subpart_y) * offset_y * img_w * components + + subpart_x * offset_x * components]); + + if (subpart_w < tex_w) + glTexSubImage2D(GL_TEXTURE_2D, + 0, + subpart_w, + 0, + 1, + subpart_h, + format, + GL_UNSIGNED_BYTE, + &uc_rect[((size_t)subpart_y) * offset_y * img_w * components + + (subpart_x * offset_x + subpart_w - 1) * components]); + if (subpart_h < tex_h) + glTexSubImage2D( + GL_TEXTURE_2D, + 0, + 0, + subpart_h, + subpart_w, + 1, + format, + GL_UNSIGNED_BYTE, + &uc_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + + subpart_x * offset_x * components]); + if (subpart_w < tex_w && subpart_h < tex_h) + glTexSubImage2D( + GL_TEXTURE_2D, + 0, + subpart_w, + subpart_h, + 1, + 1, + format, + GL_UNSIGNED_BYTE, + &uc_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + + (subpart_x * offset_x + subpart_w - 1) * components]); + } + + immBegin(GPU_PRIM_TRI_FAN, 4); + immAttr2f(texco, (float)(0 + offset_left) / tex_w, (float)(0 + offset_bot) / tex_h); + immVertex2f(pos, rast_x + (float)offset_left * xzoom, rast_y + (float)offset_bot * yzoom); + + immAttr2f(texco, (float)(subpart_w - offset_right) / tex_w, (float)(0 + offset_bot) / tex_h); + immVertex2f(pos, + rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX, + rast_y + (float)offset_bot * yzoom); + + immAttr2f(texco, + (float)(subpart_w - offset_right) / tex_w, + (float)(subpart_h - offset_top) / tex_h); + immVertex2f(pos, + rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX, + rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY); + + immAttr2f(texco, (float)(0 + offset_left) / tex_w, (float)(subpart_h - offset_top) / tex_h); + immVertex2f(pos, + rast_x + (float)offset_left * xzoom, + rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY); + immEnd(); + + /* NOTE: Weirdly enough this is only required on macOS. Without this there is some sort of + * bleeding of data is happening from tiles which are drawn later on. + * This doesn't seem to be too slow, but still would be nice to have fast and nice solution. */ #ifdef __APPLE__ - GPU_flush(); + GPU_flush(); #endif - } - } + } + } - if (state->do_shader_unbind) { - immUnbindProgram(); - } + if (state->do_shader_unbind) { + immUnbindProgram(); + } - glBindTexture(GL_TEXTURE_2D, 0); - glPixelStorei(GL_UNPACK_ROW_LENGTH, unpack_row_length); + glBindTexture(GL_TEXTURE_2D, 0); + glPixelStorei(GL_UNPACK_ROW_LENGTH, unpack_row_length); } void immDrawPixelsTexScaled(IMMDrawPixelsTexState *state, - float x, float y, int img_w, int img_h, - int format, int type, int zoomfilter, void *rect, - float scaleX, float scaleY, float xzoom, float yzoom, float color[4]) + float x, + float y, + int img_w, + int img_h, + int format, + int type, + int zoomfilter, + void *rect, + float scaleX, + float scaleY, + float xzoom, + float yzoom, + float color[4]) { - immDrawPixelsTexScaled_clipping(state, x, y, img_w, img_h, format, type, zoomfilter, rect, - scaleX, scaleY, 0.0f, 0.0f, 0.0f, 0.0f, xzoom, yzoom, color); + immDrawPixelsTexScaled_clipping(state, + x, + y, + img_w, + img_h, + format, + type, + zoomfilter, + rect, + scaleX, + scaleY, + 0.0f, + 0.0f, + 0.0f, + 0.0f, + xzoom, + yzoom, + color); } void immDrawPixelsTex(IMMDrawPixelsTexState *state, - float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect, - float xzoom, float yzoom, float color[4]) + float x, + float y, + int img_w, + int img_h, + int format, + int type, + int zoomfilter, + void *rect, + float xzoom, + float yzoom, + float color[4]) { - immDrawPixelsTexScaled_clipping(state, x, y, img_w, img_h, format, type, zoomfilter, rect, 1.0f, 1.0f, - 0.0f, 0.0f, 0.0f, 0.0f, xzoom, yzoom, color); + immDrawPixelsTexScaled_clipping(state, + x, + y, + img_w, + img_h, + format, + type, + zoomfilter, + rect, + 1.0f, + 1.0f, + 0.0f, + 0.0f, + 0.0f, + 0.0f, + xzoom, + yzoom, + color); } void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state, - float x, float y, int img_w, int img_h, - int format, int type, int zoomfilter, void *rect, - float clip_min_x, float clip_min_y, float clip_max_x, float clip_max_y, - float xzoom, float yzoom, float color[4]) + float x, + float y, + int img_w, + int img_h, + int format, + int type, + int zoomfilter, + void *rect, + float clip_min_x, + float clip_min_y, + float clip_max_x, + float clip_max_y, + float xzoom, + float yzoom, + float color[4]) { - immDrawPixelsTexScaled_clipping(state, x, y, img_w, img_h, format, type, zoomfilter, rect, 1.0f, 1.0f, - clip_min_x, clip_min_y, clip_max_x, clip_max_y, xzoom, yzoom, color); + immDrawPixelsTexScaled_clipping(state, + x, + y, + img_w, + img_h, + format, + type, + zoomfilter, + rect, + 1.0f, + 1.0f, + clip_min_x, + clip_min_y, + clip_max_x, + clip_max_y, + xzoom, + yzoom, + color); } /* *************** glPolygonOffset hack ************* */ float bglPolygonOffsetCalc(const float winmat[16], float viewdist, float dist) { - if (winmat[15] > 0.5f) { + if (winmat[15] > 0.5f) { #if 1 - return 0.00001f * dist * viewdist; // ortho tweaking + return 0.00001f * dist * viewdist; // ortho tweaking #else - static float depth_fac = 0.0f; - if (depth_fac == 0.0f) { - int depthbits; - glGetIntegerv(GL_DEPTH_BITS, &depthbits); - depth_fac = 1.0f / (float)((1 << depthbits) - 1); - } - offs = (-1.0 / winmat[10]) * dist * depth_fac; - - UNUSED_VARS(viewdist); + static float depth_fac = 0.0f; + if (depth_fac == 0.0f) { + int depthbits; + glGetIntegerv(GL_DEPTH_BITS, &depthbits); + depth_fac = 1.0f / (float)((1 << depthbits) - 1); + } + offs = (-1.0 / winmat[10]) * dist * depth_fac; + + UNUSED_VARS(viewdist); #endif - } - else { - /* This adjustment effectively results in reducing the Z value by 0.25%. - * - * winmat[14] actually evaluates to `-2 * far * near / (far - near)`, - * is very close to -0.2 with default clip range, and is used as the coefficient multiplied by `w / z`, - * thus controlling the z dependent part of the depth value. - */ - return winmat[14] * -0.0025f * dist; - } + } + else { + /* This adjustment effectively results in reducing the Z value by 0.25%. + * + * winmat[14] actually evaluates to `-2 * far * near / (far - near)`, + * is very close to -0.2 with default clip range, and is used as the coefficient multiplied by `w / z`, + * thus controlling the z dependent part of the depth value. + */ + return winmat[14] * -0.0025f * dist; + } } /** @@ -366,201 +537,267 @@ float bglPolygonOffsetCalc(const float winmat[16], float viewdist, float dist) */ void bglPolygonOffset(float viewdist, float dist) { - static float winmat[16], offset = 0.0f; + static float winmat[16], offset = 0.0f; - if (dist != 0.0f) { - // glEnable(GL_POLYGON_OFFSET_FILL); - // glPolygonOffset(-1.0, -1.0); + if (dist != 0.0f) { + // glEnable(GL_POLYGON_OFFSET_FILL); + // glPolygonOffset(-1.0, -1.0); - /* hack below is to mimic polygon offset */ - GPU_matrix_projection_get(winmat); + /* hack below is to mimic polygon offset */ + GPU_matrix_projection_get(winmat); - /* dist is from camera to center point */ + /* dist is from camera to center point */ - float offs = bglPolygonOffsetCalc(winmat, viewdist, dist); + float offs = bglPolygonOffsetCalc(winmat, viewdist, dist); - winmat[14] -= offs; - offset += offs; - } - else { - winmat[14] += offset; - offset = 0.0; - } + winmat[14] -= offs; + offset += offs; + } + else { + winmat[14] += offset; + offset = 0.0; + } - GPU_matrix_projection_set(winmat); + GPU_matrix_projection_set(winmat); } /* **** Color management helper functions for GLSL display/transform ***** */ /* Draw given image buffer on a screen using GLSL for display transform */ -void glaDrawImBuf_glsl_clipping(ImBuf *ibuf, float x, float y, int zoomfilter, +void glaDrawImBuf_glsl_clipping(ImBuf *ibuf, + float x, + float y, + int zoomfilter, ColorManagedViewSettings *view_settings, ColorManagedDisplaySettings *display_settings, - float clip_min_x, float clip_min_y, - float clip_max_x, float clip_max_y, - float zoom_x, float zoom_y) + float clip_min_x, + float clip_min_y, + float clip_max_x, + float clip_max_y, + float zoom_x, + float zoom_y) { - bool force_fallback = false; - bool need_fallback = true; - - /* Early out */ - if (ibuf->rect == NULL && ibuf->rect_float == NULL) - return; - - /* Single channel images could not be transformed using GLSL yet */ - force_fallback |= ibuf->channels == 1; - - /* If user decided not to use GLSL, fallback to glaDrawPixelsAuto */ - force_fallback |= (U.image_draw_method != IMAGE_DRAW_METHOD_GLSL); - - /* Try to draw buffer using GLSL display transform */ - if (force_fallback == false) { - int ok; - - IMMDrawPixelsTexState state = {0}; - /* We want GLSL state to be fully handled by OCIO. */ - state.do_shader_unbind = false; - immDrawPixelsTexSetupAttributes(&state); - - if (ibuf->rect_float) { - if (ibuf->float_colorspace) { - ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings, - ibuf->float_colorspace, - ibuf->dither, true); - } - else { - ok = IMB_colormanagement_setup_glsl_draw(view_settings, display_settings, - ibuf->dither, true); - } - } - else { - ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings, - ibuf->rect_colorspace, - ibuf->dither, false); - } - - if (ok) { - if (ibuf->rect_float) { - int format = 0; - - if (ibuf->channels == 3) - format = GL_RGB; - else if (ibuf->channels == 4) - format = GL_RGBA; - else - BLI_assert(!"Incompatible number of channels for GLSL display"); - - if (format != 0) { - immDrawPixelsTex_clipping(&state, - x, y, ibuf->x, ibuf->y, format, GL_FLOAT, - zoomfilter, ibuf->rect_float, - clip_min_x, clip_min_y, clip_max_x, clip_max_y, - zoom_x, zoom_y, NULL); - } - } - else if (ibuf->rect) { - /* ibuf->rect is always RGBA */ - immDrawPixelsTex_clipping(&state, - x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, - zoomfilter, ibuf->rect, - clip_min_x, clip_min_y, clip_max_x, clip_max_y, - zoom_x, zoom_y, NULL); - } - - IMB_colormanagement_finish_glsl_draw(); - - need_fallback = false; - } - } - - /* In case GLSL failed or not usable, fallback to glaDrawPixelsAuto */ - if (need_fallback) { - unsigned char *display_buffer; - void *cache_handle; - - display_buffer = IMB_display_buffer_acquire(ibuf, view_settings, display_settings, &cache_handle); - - if (display_buffer) { - IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); - immDrawPixelsTex_clipping(&state, - x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, - zoomfilter, display_buffer, - clip_min_x, clip_min_y, clip_max_x, clip_max_y, - zoom_x, zoom_y, NULL); - } - - IMB_display_buffer_release(cache_handle); - } + bool force_fallback = false; + bool need_fallback = true; + + /* Early out */ + if (ibuf->rect == NULL && ibuf->rect_float == NULL) + return; + + /* Single channel images could not be transformed using GLSL yet */ + force_fallback |= ibuf->channels == 1; + + /* If user decided not to use GLSL, fallback to glaDrawPixelsAuto */ + force_fallback |= (U.image_draw_method != IMAGE_DRAW_METHOD_GLSL); + + /* Try to draw buffer using GLSL display transform */ + if (force_fallback == false) { + int ok; + + IMMDrawPixelsTexState state = {0}; + /* We want GLSL state to be fully handled by OCIO. */ + state.do_shader_unbind = false; + immDrawPixelsTexSetupAttributes(&state); + + if (ibuf->rect_float) { + if (ibuf->float_colorspace) { + ok = IMB_colormanagement_setup_glsl_draw_from_space( + view_settings, display_settings, ibuf->float_colorspace, ibuf->dither, true); + } + else { + ok = IMB_colormanagement_setup_glsl_draw( + view_settings, display_settings, ibuf->dither, true); + } + } + else { + ok = IMB_colormanagement_setup_glsl_draw_from_space( + view_settings, display_settings, ibuf->rect_colorspace, ibuf->dither, false); + } + + if (ok) { + if (ibuf->rect_float) { + int format = 0; + + if (ibuf->channels == 3) + format = GL_RGB; + else if (ibuf->channels == 4) + format = GL_RGBA; + else + BLI_assert(!"Incompatible number of channels for GLSL display"); + + if (format != 0) { + immDrawPixelsTex_clipping(&state, + x, + y, + ibuf->x, + ibuf->y, + format, + GL_FLOAT, + zoomfilter, + ibuf->rect_float, + clip_min_x, + clip_min_y, + clip_max_x, + clip_max_y, + zoom_x, + zoom_y, + NULL); + } + } + else if (ibuf->rect) { + /* ibuf->rect is always RGBA */ + immDrawPixelsTex_clipping(&state, + x, + y, + ibuf->x, + ibuf->y, + GL_RGBA, + GL_UNSIGNED_BYTE, + zoomfilter, + ibuf->rect, + clip_min_x, + clip_min_y, + clip_max_x, + clip_max_y, + zoom_x, + zoom_y, + NULL); + } + + IMB_colormanagement_finish_glsl_draw(); + + need_fallback = false; + } + } + + /* In case GLSL failed or not usable, fallback to glaDrawPixelsAuto */ + if (need_fallback) { + unsigned char *display_buffer; + void *cache_handle; + + display_buffer = IMB_display_buffer_acquire( + ibuf, view_settings, display_settings, &cache_handle); + + if (display_buffer) { + IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); + immDrawPixelsTex_clipping(&state, + x, + y, + ibuf->x, + ibuf->y, + GL_RGBA, + GL_UNSIGNED_BYTE, + zoomfilter, + display_buffer, + clip_min_x, + clip_min_y, + clip_max_x, + clip_max_y, + zoom_x, + zoom_y, + NULL); + } + + IMB_display_buffer_release(cache_handle); + } } -void glaDrawImBuf_glsl(ImBuf *ibuf, float x, float y, int zoomfilter, +void glaDrawImBuf_glsl(ImBuf *ibuf, + float x, + float y, + int zoomfilter, ColorManagedViewSettings *view_settings, ColorManagedDisplaySettings *display_settings, - float zoom_x, float zoom_y) + float zoom_x, + float zoom_y) { - glaDrawImBuf_glsl_clipping(ibuf, x, y, zoomfilter, view_settings, display_settings, - 0.0f, 0.0f, 0.0f, 0.0f, zoom_x, zoom_y); + glaDrawImBuf_glsl_clipping(ibuf, + x, + y, + zoomfilter, + view_settings, + display_settings, + 0.0f, + 0.0f, + 0.0f, + 0.0f, + zoom_x, + zoom_y); } void glaDrawImBuf_glsl_ctx_clipping(const bContext *C, ImBuf *ibuf, - float x, float y, + float x, + float y, int zoomfilter, - float clip_min_x, float clip_min_y, - float clip_max_x, float clip_max_y, - float zoom_x, float zoom_y) + float clip_min_x, + float clip_min_y, + float clip_max_x, + float clip_max_y, + float zoom_x, + float zoom_y) { - ColorManagedViewSettings *view_settings; - ColorManagedDisplaySettings *display_settings; - - IMB_colormanagement_display_settings_from_ctx(C, &view_settings, &display_settings); - - glaDrawImBuf_glsl_clipping(ibuf, x, y, zoomfilter, view_settings, display_settings, - clip_min_x, clip_min_y, clip_max_x, clip_max_y, - zoom_x, zoom_y); + ColorManagedViewSettings *view_settings; + ColorManagedDisplaySettings *display_settings; + + IMB_colormanagement_display_settings_from_ctx(C, &view_settings, &display_settings); + + glaDrawImBuf_glsl_clipping(ibuf, + x, + y, + zoomfilter, + view_settings, + display_settings, + clip_min_x, + clip_min_y, + clip_max_x, + clip_max_y, + zoom_x, + zoom_y); } -void glaDrawImBuf_glsl_ctx(const bContext *C, ImBuf *ibuf, float x, float y, int zoomfilter, - float zoom_x, float zoom_y) +void glaDrawImBuf_glsl_ctx( + const bContext *C, ImBuf *ibuf, float x, float y, int zoomfilter, float zoom_x, float zoom_y) { - glaDrawImBuf_glsl_ctx_clipping(C, ibuf, x, y, zoomfilter, 0.0f, 0.0f, 0.0f, 0.0f, zoom_x, zoom_y); + glaDrawImBuf_glsl_ctx_clipping( + C, ibuf, x, y, zoomfilter, 0.0f, 0.0f, 0.0f, 0.0f, zoom_x, zoom_y); } /* don't move to GPU_immediate_util.h because this uses user-prefs * and isn't very low level */ void immDrawBorderCorners(unsigned int pos, const rcti *border, float zoomx, float zoomy) { - float delta_x = 4.0f * UI_DPI_FAC / zoomx; - float delta_y = 4.0f * UI_DPI_FAC / zoomy; - - delta_x = min_ff(delta_x, border->xmax - border->xmin); - delta_y = min_ff(delta_y, border->ymax - border->ymin); - - /* left bottom corner */ - immBegin(GPU_PRIM_LINE_STRIP, 3); - immVertex2f(pos, border->xmin, border->ymin + delta_y); - immVertex2f(pos, border->xmin, border->ymin); - immVertex2f(pos, border->xmin + delta_x, border->ymin); - immEnd(); - - /* left top corner */ - immBegin(GPU_PRIM_LINE_STRIP, 3); - immVertex2f(pos, border->xmin, border->ymax - delta_y); - immVertex2f(pos, border->xmin, border->ymax); - immVertex2f(pos, border->xmin + delta_x, border->ymax); - immEnd(); - - /* right bottom corner */ - immBegin(GPU_PRIM_LINE_STRIP, 3); - immVertex2f(pos, border->xmax - delta_x, border->ymin); - immVertex2f(pos, border->xmax, border->ymin); - immVertex2f(pos, border->xmax, border->ymin + delta_y); - immEnd(); - - /* right top corner */ - immBegin(GPU_PRIM_LINE_STRIP, 3); - immVertex2f(pos, border->xmax - delta_x, border->ymax); - immVertex2f(pos, border->xmax, border->ymax); - immVertex2f(pos, border->xmax, border->ymax - delta_y); - immEnd(); + float delta_x = 4.0f * UI_DPI_FAC / zoomx; + float delta_y = 4.0f * UI_DPI_FAC / zoomy; + + delta_x = min_ff(delta_x, border->xmax - border->xmin); + delta_y = min_ff(delta_y, border->ymax - border->ymin); + + /* left bottom corner */ + immBegin(GPU_PRIM_LINE_STRIP, 3); + immVertex2f(pos, border->xmin, border->ymin + delta_y); + immVertex2f(pos, border->xmin, border->ymin); + immVertex2f(pos, border->xmin + delta_x, border->ymin); + immEnd(); + + /* left top corner */ + immBegin(GPU_PRIM_LINE_STRIP, 3); + immVertex2f(pos, border->xmin, border->ymax - delta_y); + immVertex2f(pos, border->xmin, border->ymax); + immVertex2f(pos, border->xmin + delta_x, border->ymax); + immEnd(); + + /* right bottom corner */ + immBegin(GPU_PRIM_LINE_STRIP, 3); + immVertex2f(pos, border->xmax - delta_x, border->ymin); + immVertex2f(pos, border->xmax, border->ymin); + immVertex2f(pos, border->xmax, border->ymin + delta_y); + immEnd(); + + /* right top corner */ + immBegin(GPU_PRIM_LINE_STRIP, 3); + immVertex2f(pos, border->xmax - delta_x, border->ymax); + immVertex2f(pos, border->xmax, border->ymax); + immVertex2f(pos, border->xmax, border->ymax - delta_y); + immEnd(); } diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index b16d7f68976..719403531ff 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -65,636 +65,680 @@ #include "screen_intern.h" -const char *screen_context_dir[] = { - "scene", "view_layer", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases", - "selected_objects", "selected_bases", - "editable_objects", "editable_bases", - "selected_editable_objects", "selected_editable_bases", - "objects_in_mode", "objects_in_mode_unique_data", - "visible_bones", "editable_bones", "selected_bones", "selected_editable_bones", - "visible_pose_bones", "selected_pose_bones", "selected_pose_bones_from_active_object", - "active_bone", "active_pose_bone", - "active_base", "active_object", "object", "edit_object", - "sculpt_object", "vertex_paint_object", "weight_paint_object", - "image_paint_object", "particle_edit_object", "uv_sculpt_object", "pose_object", - "sequences", "selected_sequences", "selected_editable_sequences", /* sequencer */ - "gpencil_data", "gpencil_data_owner", /* grease pencil data */ - "visible_gpencil_layers", "editable_gpencil_layers", "editable_gpencil_strokes", - "active_gpencil_layer", "active_gpencil_frame", - "active_operator", "selected_editable_fcurves", - NULL}; +const char *screen_context_dir[] = {"scene", + "view_layer", + "visible_objects", + "visible_bases", + "selectable_objects", + "selectable_bases", + "selected_objects", + "selected_bases", + "editable_objects", + "editable_bases", + "selected_editable_objects", + "selected_editable_bases", + "objects_in_mode", + "objects_in_mode_unique_data", + "visible_bones", + "editable_bones", + "selected_bones", + "selected_editable_bones", + "visible_pose_bones", + "selected_pose_bones", + "selected_pose_bones_from_active_object", + "active_bone", + "active_pose_bone", + "active_base", + "active_object", + "object", + "edit_object", + "sculpt_object", + "vertex_paint_object", + "weight_paint_object", + "image_paint_object", + "particle_edit_object", + "uv_sculpt_object", + "pose_object", + "sequences", + "selected_sequences", + "selected_editable_sequences", /* sequencer */ + "gpencil_data", + "gpencil_data_owner", /* grease pencil data */ + "visible_gpencil_layers", + "editable_gpencil_layers", + "editable_gpencil_strokes", + "active_gpencil_layer", + "active_gpencil_frame", + "active_operator", + "selected_editable_fcurves", + NULL}; int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result) { - wmWindow *win = CTX_wm_window(C); - View3D *v3d = CTX_wm_view3d(C); /* This may be NULL in a lot of cases. */ - bScreen *sc = CTX_wm_screen(C); - ScrArea *sa = CTX_wm_area(C); - Scene *scene = WM_window_get_active_scene(win); - ViewLayer *view_layer = WM_window_get_active_view_layer(win); - Object *obact = (view_layer && view_layer->basact) ? view_layer->basact->object : NULL; - Object *obedit = view_layer ? OBEDIT_FROM_VIEW_LAYER(view_layer) : NULL; - - if (CTX_data_dir(member)) { - CTX_data_dir_set(result, screen_context_dir); - return 1; - } - else if (CTX_data_equals(member, "scene")) { - CTX_data_id_pointer_set(result, &scene->id); - return 1; - } - else if (CTX_data_equals(member, "visible_objects")) { - for (Base *base = view_layer->object_bases.first; base; base = base->next) { - if (BASE_VISIBLE(v3d, base)) { - CTX_data_id_list_add(result, &base->object->id); - } - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - else if (CTX_data_equals(member, "selectable_objects")) { - for (Base *base = view_layer->object_bases.first; base; base = base->next) { - if (BASE_SELECTABLE(v3d, base)) { - CTX_data_id_list_add(result, &base->object->id); - } - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - else if (CTX_data_equals(member, "selected_objects")) { - for (Base *base = view_layer->object_bases.first; base; base = base->next) { - if (BASE_SELECTED(v3d, base)) { - CTX_data_id_list_add(result, &base->object->id); - } - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - else if (CTX_data_equals(member, "selected_editable_objects")) { - for (Base *base = view_layer->object_bases.first; base; base = base->next) { - if (BASE_SELECTED_EDITABLE(v3d, base)) { - CTX_data_id_list_add(result, &base->object->id); - } - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - else if (CTX_data_equals(member, "editable_objects")) { - /* Visible + Editable, but not necessarily selected */ - for (Base *base = view_layer->object_bases.first; base; base = base->next) { - if (BASE_EDITABLE(v3d, base)) { - CTX_data_id_list_add(result, &base->object->id); - } - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - else if ( CTX_data_equals(member, "visible_bases")) { - for (Base *base = view_layer->object_bases.first; base; base = base->next) { - if (BASE_VISIBLE(v3d, base)) { - CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); - } - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - else if (CTX_data_equals(member, "selectable_bases")) { - for (Base *base = view_layer->object_bases.first; base; base = base->next) { - if (BASE_SELECTABLE(v3d, base)) { - CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); - } - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - else if (CTX_data_equals(member, "selected_bases")) { - for (Base *base = view_layer->object_bases.first; base; base = base->next) { - if (BASE_SELECTED(v3d, base)) { - CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); - } - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - else if (CTX_data_equals(member, "selected_editable_bases")) { - for (Base *base = view_layer->object_bases.first; base; base = base->next) { - if (BASE_SELECTED_EDITABLE(v3d, base)) { - CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); - } - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - else if (CTX_data_equals(member, "editable_bases")) { - /* Visible + Editable, but not necessarily selected */ - for (Base *base = view_layer->object_bases.first; base; base = base->next) { - if (BASE_EDITABLE(v3d, base)) { - CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); - } - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - else if (CTX_data_equals(member, "objects_in_mode")) { - if (obact && (obact->mode != OB_MODE_OBJECT)) { - FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, obact->type, obact->mode, ob_iter) { - CTX_data_id_list_add(result, &ob_iter->id); - } FOREACH_OBJECT_IN_MODE_END; - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - else if (CTX_data_equals(member, "objects_in_mode_unique_data")) { - if (obact && (obact->mode != OB_MODE_OBJECT)) { - FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, obact->type, obact->mode, ob_iter) { - ob_iter->id.tag |= LIB_TAG_DOIT; - } FOREACH_OBJECT_IN_MODE_END; - FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, obact->type, obact->mode, ob_iter) { - if (ob_iter->id.tag & LIB_TAG_DOIT) { - ob_iter->id.tag &= ~LIB_TAG_DOIT; - CTX_data_id_list_add(result, &ob_iter->id); - } - } FOREACH_OBJECT_IN_MODE_END; - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - else if (CTX_data_equals(member, "visible_bones") || CTX_data_equals(member, "editable_bones")) { - bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL; - EditBone *ebone, *flipbone = NULL; - const bool editable_bones = CTX_data_equals(member, "editable_bones"); - - if (arm && arm->edbo) { - uint objects_len; - Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len); - for (uint i = 0; i < objects_len; i++) { - Object *ob = objects[i]; - arm = ob->data; - - /* Attention: X-Axis Mirroring is also handled here... */ - for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - /* first and foremost, bone must be visible and selected */ - if (EBONE_VISIBLE(arm, ebone)) { - /* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled - * so that most users of this data don't need to explicitly check for it themselves. - * - * We need to make sure that these mirrored copies are not selected, otherwise some - * bones will be operated on twice. - */ - if (arm->flag & ARM_MIRROR_EDIT) - flipbone = ED_armature_ebone_get_mirrored(arm->edbo, ebone); - - /* if we're filtering for editable too, use the check for that instead, - * as it has selection check too */ - if (editable_bones) { - /* only selected + editable */ - if (EBONE_EDITABLE(ebone)) { - CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone); - - if ((flipbone) && !(flipbone->flag & BONE_SELECTED)) - CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone); - } - } - else { - /* only include bones if visible */ - CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone); - - if ((flipbone) && EBONE_VISIBLE(arm, flipbone) == 0) - CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone); - } - } - } - } - MEM_freeN(objects); - - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - } - else if (CTX_data_equals(member, "selected_bones") || CTX_data_equals(member, "selected_editable_bones")) { - bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL; - EditBone *ebone, *flipbone = NULL; - const bool selected_editable_bones = CTX_data_equals(member, "selected_editable_bones"); - - if (arm && arm->edbo) { - uint objects_len; - Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len); - for (uint i = 0; i < objects_len; i++) { - Object *ob = objects[i]; - arm = ob->data; - - /* Attention: X-Axis Mirroring is also handled here... */ - for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - /* first and foremost, bone must be visible and selected */ - if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_SELECTED)) { - /* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled - * so that most users of this data don't need to explicitly check for it themselves. - * - * We need to make sure that these mirrored copies are not selected, otherwise some - * bones will be operated on twice. - */ - if (arm->flag & ARM_MIRROR_EDIT) - flipbone = ED_armature_ebone_get_mirrored(arm->edbo, ebone); - - /* if we're filtering for editable too, use the check for that instead, - * as it has selection check too */ - if (selected_editable_bones) { - /* only selected + editable */ - if (EBONE_EDITABLE(ebone)) { - CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone); - - if ((flipbone) && !(flipbone->flag & BONE_SELECTED)) - CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone); - } - } - else { - /* only include bones if selected */ - CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone); - - if ((flipbone) && !(flipbone->flag & BONE_SELECTED)) - CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone); - } - } - } - } - MEM_freeN(objects); - - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - } - else if (CTX_data_equals(member, "visible_pose_bones")) { - Object *obpose = BKE_object_pose_armature_get(obact); - if (obpose && obpose->pose && obpose->data) { - if (obpose != obact) { - FOREACH_PCHAN_VISIBLE_IN_OBJECT_BEGIN (obpose, pchan) { - CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan); - } FOREACH_PCHAN_SELECTED_IN_OBJECT_END; - } - else if (obact->mode & OB_MODE_POSE) { - FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) { - FOREACH_PCHAN_VISIBLE_IN_OBJECT_BEGIN (ob_iter, pchan) { - CTX_data_list_add(result, &ob_iter->id, &RNA_PoseBone, pchan); - } FOREACH_PCHAN_VISIBLE_IN_OBJECT_END; - } FOREACH_OBJECT_IN_MODE_END; - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - } - else if (CTX_data_equals(member, "selected_pose_bones")) { - Object *obpose = BKE_object_pose_armature_get(obact); - if (obpose && obpose->pose && obpose->data) { - if (obpose != obact) { - FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (obpose, pchan) { - CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan); - } FOREACH_PCHAN_SELECTED_IN_OBJECT_END; - } - else if (obact->mode & OB_MODE_POSE) { - FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) { - FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob_iter, pchan) { - CTX_data_list_add(result, &ob_iter->id, &RNA_PoseBone, pchan); - } FOREACH_PCHAN_SELECTED_IN_OBJECT_END; - } FOREACH_OBJECT_IN_MODE_END; - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - } - else if (CTX_data_equals(member, "selected_pose_bones_from_active_object")) { - Object *obpose = BKE_object_pose_armature_get(obact); - if (obpose && obpose->pose && obpose->data) { - if (obpose != obact) { - FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (obpose, pchan) { - CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan); - } FOREACH_PCHAN_SELECTED_IN_OBJECT_END; - } - else if (obact->mode & OB_MODE_POSE) { - FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (obact, pchan) { - CTX_data_list_add(result, &obact->id, &RNA_PoseBone, pchan); - } FOREACH_PCHAN_SELECTED_IN_OBJECT_END; - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - } - else if (CTX_data_equals(member, "active_bone")) { - if (obact && obact->type == OB_ARMATURE) { - bArmature *arm = obact->data; - if (arm->edbo) { - if (arm->act_edbone) { - CTX_data_pointer_set(result, &arm->id, &RNA_EditBone, arm->act_edbone); - return 1; - } - } - else { - if (arm->act_bone) { - CTX_data_pointer_set(result, &arm->id, &RNA_Bone, arm->act_bone); - return 1; - } - } - } - } - else if (CTX_data_equals(member, "active_pose_bone")) { - bPoseChannel *pchan; - Object *obpose = BKE_object_pose_armature_get(obact); - - pchan = BKE_pose_channel_active(obpose); - if (pchan) { - CTX_data_pointer_set(result, &obpose->id, &RNA_PoseBone, pchan); - return 1; - } - } - else if (CTX_data_equals(member, "active_base")) { - if (view_layer->basact) - CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, view_layer->basact); - - return 1; - } - else if (CTX_data_equals(member, "active_object")) { - if (obact) - CTX_data_id_pointer_set(result, &obact->id); - - return 1; - } - else if (CTX_data_equals(member, "object")) { - if (obact) - CTX_data_id_pointer_set(result, &obact->id); - - return 1; - } - else if (CTX_data_equals(member, "edit_object")) { - /* convenience for now, 1 object per scene in editmode */ - if (obedit) - CTX_data_id_pointer_set(result, &obedit->id); - - return 1; - } - else if (CTX_data_equals(member, "sculpt_object")) { - if (obact && (obact->mode & OB_MODE_SCULPT)) - CTX_data_id_pointer_set(result, &obact->id); - - return 1; - } - else if (CTX_data_equals(member, "vertex_paint_object")) { - if (obact && (obact->mode & OB_MODE_VERTEX_PAINT)) - CTX_data_id_pointer_set(result, &obact->id); - - return 1; - } - else if (CTX_data_equals(member, "weight_paint_object")) { - if (obact && (obact->mode & OB_MODE_WEIGHT_PAINT)) - CTX_data_id_pointer_set(result, &obact->id); - - return 1; - } - else if (CTX_data_equals(member, "image_paint_object")) { - if (obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) - CTX_data_id_pointer_set(result, &obact->id); - - return 1; - } - else if (CTX_data_equals(member, "particle_edit_object")) { - if (obact && (obact->mode & OB_MODE_PARTICLE_EDIT)) - CTX_data_id_pointer_set(result, &obact->id); - - return 1; - } - else if (CTX_data_equals(member, "uv_sculpt_object")) { - /* TODO(campbell): most likely we change rules for uv_sculpt. */ - if (obact && (obact->mode & OB_MODE_EDIT)) { - const ToolSettings *ts = scene->toolsettings; - if (ts->use_uv_sculpt) { - if (ED_uvedit_test(obedit)) { - WorkSpace *workspace = CTX_wm_workspace(C); - if ((workspace->tools_space_type == SPACE_IMAGE) && - (workspace->tools_mode == SI_MODE_UV)) - { - CTX_data_id_pointer_set(result, &obact->id); - } - } - } - } - return 1; - } - else if (CTX_data_equals(member, "pose_object")) { - Object *obpose = BKE_object_pose_armature_get(obact); - if (obpose) { - CTX_data_id_pointer_set(result, &obpose->id); - } - return 1; - } - else if (CTX_data_equals(member, "sequences")) { - Editing *ed = BKE_sequencer_editing_get(scene, false); - if (ed) { - Sequence *seq; - for (seq = ed->seqbasep->first; seq; seq = seq->next) { - CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq); - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - } - else if (CTX_data_equals(member, "selected_sequences")) { - Editing *ed = BKE_sequencer_editing_get(scene, false); - if (ed) { - Sequence *seq; - for (seq = ed->seqbasep->first; seq; seq = seq->next) { - if (seq->flag & SELECT) { - CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq); - } - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - } - else if (CTX_data_equals(member, "selected_editable_sequences")) { - Editing *ed = BKE_sequencer_editing_get(scene, false); - if (ed) { - Sequence *seq; - for (seq = ed->seqbasep->first; seq; seq = seq->next) { - if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) { - CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq); - } - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - } - else if (CTX_data_equals(member, "gpencil_data")) { - /* FIXME: for some reason, CTX_data_active_object(C) returns NULL when called from these situations - * (as outlined above - see Campbell's #ifdefs). That causes the get_active function to fail when - * called from context. For that reason, we end up using an alternative where we pass everything in! - */ - bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact); - - if (gpd) { - CTX_data_id_pointer_set(result, &gpd->id); - return 1; - } - } - else if (CTX_data_equals(member, "gpencil_data_owner")) { - /* pointer to which data/datablock owns the reference to the Grease Pencil data being used (as gpencil_data) - * XXX: see comment for gpencil_data case... - */ - bGPdata **gpd_ptr = NULL; - PointerRNA ptr; - - /* get pointer to Grease Pencil Data */ - gpd_ptr = ED_gpencil_data_get_pointers_direct((ID *)sc, sa, scene, obact, &ptr); - - if (gpd_ptr) { - CTX_data_pointer_set(result, ptr.id.data, ptr.type, ptr.data); - return 1; - } - } - else if (CTX_data_equals(member, "active_gpencil_layer")) { - /* XXX: see comment for gpencil_data case... */ - bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact); - - if (gpd) { - bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd); - - if (gpl) { - CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilLayer, gpl); - return 1; - } - } - } - else if (CTX_data_equals(member, "active_gpencil_frame")) { - /* XXX: see comment for gpencil_data case... */ - bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact); - - if (gpd) { - bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd); - - if (gpl) { - CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilLayer, gpl->actframe); - return 1; - } - } - } - else if (CTX_data_equals(member, "visible_gpencil_layers")) { - /* XXX: see comment for gpencil_data case... */ - bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact); - - if (gpd) { - bGPDlayer *gpl; - - for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { - if ((gpl->flag & GP_LAYER_HIDE) == 0) { - CTX_data_list_add(result, &gpd->id, &RNA_GPencilLayer, gpl); - } - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - } - else if (CTX_data_equals(member, "editable_gpencil_layers")) { - /* XXX: see comment for gpencil_data case... */ - bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact); - - if (gpd) { - bGPDlayer *gpl; - - for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { - if (gpencil_layer_is_editable(gpl)) { - CTX_data_list_add(result, &gpd->id, &RNA_GPencilLayer, gpl); - } - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - } - else if (CTX_data_equals(member, "editable_gpencil_strokes")) { - /* XXX: see comment for gpencil_data case... */ - bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact); - const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); - - if (gpd) { - bGPDlayer *gpl; - - for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { - if (gpencil_layer_is_editable(gpl) && (gpl->actframe)) { - bGPDframe *gpf; - bGPDstroke *gps; - bGPDframe *init_gpf = gpl->actframe; - if (is_multiedit) { - init_gpf = gpl->frames.first; - } - - for (gpf = init_gpf; gpf; gpf = gpf->next) { - if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { - for (gps = gpf->strokes.first; gps; gps = gps->next) { - if (ED_gpencil_stroke_can_use_direct(sa, gps)) { - /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) { - continue; - } - - CTX_data_list_add(result, &gpd->id, &RNA_GPencilStroke, gps); - } - } - } - /* if not multiedit out of loop */ - if (!is_multiedit) { - break; - } - } - } - } - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - } - else if (CTX_data_equals(member, "active_operator")) { - wmOperator *op = NULL; - - SpaceFile *sfile = CTX_wm_space_file(C); - if (sfile) { - op = sfile->op; - } - else if ((op = UI_context_active_operator_get(C))) { - /* do nothing */ - } - else { - /* note, this checks poll, could be a problem, but this also - * happens for the toolbar */ - op = WM_operator_last_redo(C); - } - /* TODO, get the operator from popup's */ - - if (op && op->ptr) { - CTX_data_pointer_set(result, NULL, &RNA_Operator, op); - return 1; - } - } - else if (CTX_data_equals(member, "selected_editable_fcurves")) { - bAnimContext ac; - - if (ANIM_animdata_get_context(C, &ac) && ELEM(ac.spacetype, SPACE_ACTION, SPACE_GRAPH)) { - bAnimListElem *ale; - ListBase anim_data = {NULL, NULL}; - - int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS | ANIMFILTER_SEL) | - (ac.spacetype == SPACE_GRAPH ? ANIMFILTER_CURVE_VISIBLE : ANIMFILTER_LIST_VISIBLE); - - ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); - - for (ale = anim_data.first; ale; ale = ale->next) { - if (ale->type == ANIMTYPE_FCURVE) - CTX_data_list_add(result, ale->id, &RNA_FCurve, ale->data); - } - - ANIM_animdata_freelist(&anim_data); - - CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); - return 1; - } - } - else { - return 0; /* not found */ - } - - return -1; /* found but not available */ + wmWindow *win = CTX_wm_window(C); + View3D *v3d = CTX_wm_view3d(C); /* This may be NULL in a lot of cases. */ + bScreen *sc = CTX_wm_screen(C); + ScrArea *sa = CTX_wm_area(C); + Scene *scene = WM_window_get_active_scene(win); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); + Object *obact = (view_layer && view_layer->basact) ? view_layer->basact->object : NULL; + Object *obedit = view_layer ? OBEDIT_FROM_VIEW_LAYER(view_layer) : NULL; + + if (CTX_data_dir(member)) { + CTX_data_dir_set(result, screen_context_dir); + return 1; + } + else if (CTX_data_equals(member, "scene")) { + CTX_data_id_pointer_set(result, &scene->id); + return 1; + } + else if (CTX_data_equals(member, "visible_objects")) { + for (Base *base = view_layer->object_bases.first; base; base = base->next) { + if (BASE_VISIBLE(v3d, base)) { + CTX_data_id_list_add(result, &base->object->id); + } + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + else if (CTX_data_equals(member, "selectable_objects")) { + for (Base *base = view_layer->object_bases.first; base; base = base->next) { + if (BASE_SELECTABLE(v3d, base)) { + CTX_data_id_list_add(result, &base->object->id); + } + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + else if (CTX_data_equals(member, "selected_objects")) { + for (Base *base = view_layer->object_bases.first; base; base = base->next) { + if (BASE_SELECTED(v3d, base)) { + CTX_data_id_list_add(result, &base->object->id); + } + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + else if (CTX_data_equals(member, "selected_editable_objects")) { + for (Base *base = view_layer->object_bases.first; base; base = base->next) { + if (BASE_SELECTED_EDITABLE(v3d, base)) { + CTX_data_id_list_add(result, &base->object->id); + } + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + else if (CTX_data_equals(member, "editable_objects")) { + /* Visible + Editable, but not necessarily selected */ + for (Base *base = view_layer->object_bases.first; base; base = base->next) { + if (BASE_EDITABLE(v3d, base)) { + CTX_data_id_list_add(result, &base->object->id); + } + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + else if (CTX_data_equals(member, "visible_bases")) { + for (Base *base = view_layer->object_bases.first; base; base = base->next) { + if (BASE_VISIBLE(v3d, base)) { + CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); + } + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + else if (CTX_data_equals(member, "selectable_bases")) { + for (Base *base = view_layer->object_bases.first; base; base = base->next) { + if (BASE_SELECTABLE(v3d, base)) { + CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); + } + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + else if (CTX_data_equals(member, "selected_bases")) { + for (Base *base = view_layer->object_bases.first; base; base = base->next) { + if (BASE_SELECTED(v3d, base)) { + CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); + } + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + else if (CTX_data_equals(member, "selected_editable_bases")) { + for (Base *base = view_layer->object_bases.first; base; base = base->next) { + if (BASE_SELECTED_EDITABLE(v3d, base)) { + CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); + } + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + else if (CTX_data_equals(member, "editable_bases")) { + /* Visible + Editable, but not necessarily selected */ + for (Base *base = view_layer->object_bases.first; base; base = base->next) { + if (BASE_EDITABLE(v3d, base)) { + CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base); + } + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + else if (CTX_data_equals(member, "objects_in_mode")) { + if (obact && (obact->mode != OB_MODE_OBJECT)) { + FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, obact->type, obact->mode, ob_iter) { + CTX_data_id_list_add(result, &ob_iter->id); + } + FOREACH_OBJECT_IN_MODE_END; + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + else if (CTX_data_equals(member, "objects_in_mode_unique_data")) { + if (obact && (obact->mode != OB_MODE_OBJECT)) { + FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, obact->type, obact->mode, ob_iter) { + ob_iter->id.tag |= LIB_TAG_DOIT; + } + FOREACH_OBJECT_IN_MODE_END; + FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, obact->type, obact->mode, ob_iter) { + if (ob_iter->id.tag & LIB_TAG_DOIT) { + ob_iter->id.tag &= ~LIB_TAG_DOIT; + CTX_data_id_list_add(result, &ob_iter->id); + } + } + FOREACH_OBJECT_IN_MODE_END; + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + else if (CTX_data_equals(member, "visible_bones") || CTX_data_equals(member, "editable_bones")) { + bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL; + EditBone *ebone, *flipbone = NULL; + const bool editable_bones = CTX_data_equals(member, "editable_bones"); + + if (arm && arm->edbo) { + uint objects_len; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data( + view_layer, CTX_wm_view3d(C), &objects_len); + for (uint i = 0; i < objects_len; i++) { + Object *ob = objects[i]; + arm = ob->data; + + /* Attention: X-Axis Mirroring is also handled here... */ + for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { + /* first and foremost, bone must be visible and selected */ + if (EBONE_VISIBLE(arm, ebone)) { + /* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled + * so that most users of this data don't need to explicitly check for it themselves. + * + * We need to make sure that these mirrored copies are not selected, otherwise some + * bones will be operated on twice. + */ + if (arm->flag & ARM_MIRROR_EDIT) + flipbone = ED_armature_ebone_get_mirrored(arm->edbo, ebone); + + /* if we're filtering for editable too, use the check for that instead, + * as it has selection check too */ + if (editable_bones) { + /* only selected + editable */ + if (EBONE_EDITABLE(ebone)) { + CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone); + + if ((flipbone) && !(flipbone->flag & BONE_SELECTED)) + CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone); + } + } + else { + /* only include bones if visible */ + CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone); + + if ((flipbone) && EBONE_VISIBLE(arm, flipbone) == 0) + CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone); + } + } + } + } + MEM_freeN(objects); + + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + } + else if (CTX_data_equals(member, "selected_bones") || + CTX_data_equals(member, "selected_editable_bones")) { + bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL; + EditBone *ebone, *flipbone = NULL; + const bool selected_editable_bones = CTX_data_equals(member, "selected_editable_bones"); + + if (arm && arm->edbo) { + uint objects_len; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data( + view_layer, CTX_wm_view3d(C), &objects_len); + for (uint i = 0; i < objects_len; i++) { + Object *ob = objects[i]; + arm = ob->data; + + /* Attention: X-Axis Mirroring is also handled here... */ + for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { + /* first and foremost, bone must be visible and selected */ + if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_SELECTED)) { + /* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled + * so that most users of this data don't need to explicitly check for it themselves. + * + * We need to make sure that these mirrored copies are not selected, otherwise some + * bones will be operated on twice. + */ + if (arm->flag & ARM_MIRROR_EDIT) + flipbone = ED_armature_ebone_get_mirrored(arm->edbo, ebone); + + /* if we're filtering for editable too, use the check for that instead, + * as it has selection check too */ + if (selected_editable_bones) { + /* only selected + editable */ + if (EBONE_EDITABLE(ebone)) { + CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone); + + if ((flipbone) && !(flipbone->flag & BONE_SELECTED)) + CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone); + } + } + else { + /* only include bones if selected */ + CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone); + + if ((flipbone) && !(flipbone->flag & BONE_SELECTED)) + CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone); + } + } + } + } + MEM_freeN(objects); + + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + } + else if (CTX_data_equals(member, "visible_pose_bones")) { + Object *obpose = BKE_object_pose_armature_get(obact); + if (obpose && obpose->pose && obpose->data) { + if (obpose != obact) { + FOREACH_PCHAN_VISIBLE_IN_OBJECT_BEGIN (obpose, pchan) { + CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan); + } + FOREACH_PCHAN_SELECTED_IN_OBJECT_END; + } + else if (obact->mode & OB_MODE_POSE) { + FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) { + FOREACH_PCHAN_VISIBLE_IN_OBJECT_BEGIN (ob_iter, pchan) { + CTX_data_list_add(result, &ob_iter->id, &RNA_PoseBone, pchan); + } + FOREACH_PCHAN_VISIBLE_IN_OBJECT_END; + } + FOREACH_OBJECT_IN_MODE_END; + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + } + else if (CTX_data_equals(member, "selected_pose_bones")) { + Object *obpose = BKE_object_pose_armature_get(obact); + if (obpose && obpose->pose && obpose->data) { + if (obpose != obact) { + FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (obpose, pchan) { + CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan); + } + FOREACH_PCHAN_SELECTED_IN_OBJECT_END; + } + else if (obact->mode & OB_MODE_POSE) { + FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) { + FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob_iter, pchan) { + CTX_data_list_add(result, &ob_iter->id, &RNA_PoseBone, pchan); + } + FOREACH_PCHAN_SELECTED_IN_OBJECT_END; + } + FOREACH_OBJECT_IN_MODE_END; + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + } + else if (CTX_data_equals(member, "selected_pose_bones_from_active_object")) { + Object *obpose = BKE_object_pose_armature_get(obact); + if (obpose && obpose->pose && obpose->data) { + if (obpose != obact) { + FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (obpose, pchan) { + CTX_data_list_add(result, &obpose->id, &RNA_PoseBone, pchan); + } + FOREACH_PCHAN_SELECTED_IN_OBJECT_END; + } + else if (obact->mode & OB_MODE_POSE) { + FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (obact, pchan) { + CTX_data_list_add(result, &obact->id, &RNA_PoseBone, pchan); + } + FOREACH_PCHAN_SELECTED_IN_OBJECT_END; + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + } + else if (CTX_data_equals(member, "active_bone")) { + if (obact && obact->type == OB_ARMATURE) { + bArmature *arm = obact->data; + if (arm->edbo) { + if (arm->act_edbone) { + CTX_data_pointer_set(result, &arm->id, &RNA_EditBone, arm->act_edbone); + return 1; + } + } + else { + if (arm->act_bone) { + CTX_data_pointer_set(result, &arm->id, &RNA_Bone, arm->act_bone); + return 1; + } + } + } + } + else if (CTX_data_equals(member, "active_pose_bone")) { + bPoseChannel *pchan; + Object *obpose = BKE_object_pose_armature_get(obact); + + pchan = BKE_pose_channel_active(obpose); + if (pchan) { + CTX_data_pointer_set(result, &obpose->id, &RNA_PoseBone, pchan); + return 1; + } + } + else if (CTX_data_equals(member, "active_base")) { + if (view_layer->basact) + CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, view_layer->basact); + + return 1; + } + else if (CTX_data_equals(member, "active_object")) { + if (obact) + CTX_data_id_pointer_set(result, &obact->id); + + return 1; + } + else if (CTX_data_equals(member, "object")) { + if (obact) + CTX_data_id_pointer_set(result, &obact->id); + + return 1; + } + else if (CTX_data_equals(member, "edit_object")) { + /* convenience for now, 1 object per scene in editmode */ + if (obedit) + CTX_data_id_pointer_set(result, &obedit->id); + + return 1; + } + else if (CTX_data_equals(member, "sculpt_object")) { + if (obact && (obact->mode & OB_MODE_SCULPT)) + CTX_data_id_pointer_set(result, &obact->id); + + return 1; + } + else if (CTX_data_equals(member, "vertex_paint_object")) { + if (obact && (obact->mode & OB_MODE_VERTEX_PAINT)) + CTX_data_id_pointer_set(result, &obact->id); + + return 1; + } + else if (CTX_data_equals(member, "weight_paint_object")) { + if (obact && (obact->mode & OB_MODE_WEIGHT_PAINT)) + CTX_data_id_pointer_set(result, &obact->id); + + return 1; + } + else if (CTX_data_equals(member, "image_paint_object")) { + if (obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) + CTX_data_id_pointer_set(result, &obact->id); + + return 1; + } + else if (CTX_data_equals(member, "particle_edit_object")) { + if (obact && (obact->mode & OB_MODE_PARTICLE_EDIT)) + CTX_data_id_pointer_set(result, &obact->id); + + return 1; + } + else if (CTX_data_equals(member, "uv_sculpt_object")) { + /* TODO(campbell): most likely we change rules for uv_sculpt. */ + if (obact && (obact->mode & OB_MODE_EDIT)) { + const ToolSettings *ts = scene->toolsettings; + if (ts->use_uv_sculpt) { + if (ED_uvedit_test(obedit)) { + WorkSpace *workspace = CTX_wm_workspace(C); + if ((workspace->tools_space_type == SPACE_IMAGE) && + (workspace->tools_mode == SI_MODE_UV)) { + CTX_data_id_pointer_set(result, &obact->id); + } + } + } + } + return 1; + } + else if (CTX_data_equals(member, "pose_object")) { + Object *obpose = BKE_object_pose_armature_get(obact); + if (obpose) { + CTX_data_id_pointer_set(result, &obpose->id); + } + return 1; + } + else if (CTX_data_equals(member, "sequences")) { + Editing *ed = BKE_sequencer_editing_get(scene, false); + if (ed) { + Sequence *seq; + for (seq = ed->seqbasep->first; seq; seq = seq->next) { + CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq); + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + } + else if (CTX_data_equals(member, "selected_sequences")) { + Editing *ed = BKE_sequencer_editing_get(scene, false); + if (ed) { + Sequence *seq; + for (seq = ed->seqbasep->first; seq; seq = seq->next) { + if (seq->flag & SELECT) { + CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq); + } + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + } + else if (CTX_data_equals(member, "selected_editable_sequences")) { + Editing *ed = BKE_sequencer_editing_get(scene, false); + if (ed) { + Sequence *seq; + for (seq = ed->seqbasep->first; seq; seq = seq->next) { + if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) { + CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq); + } + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + } + else if (CTX_data_equals(member, "gpencil_data")) { + /* FIXME: for some reason, CTX_data_active_object(C) returns NULL when called from these situations + * (as outlined above - see Campbell's #ifdefs). That causes the get_active function to fail when + * called from context. For that reason, we end up using an alternative where we pass everything in! + */ + bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact); + + if (gpd) { + CTX_data_id_pointer_set(result, &gpd->id); + return 1; + } + } + else if (CTX_data_equals(member, "gpencil_data_owner")) { + /* pointer to which data/datablock owns the reference to the Grease Pencil data being used (as gpencil_data) + * XXX: see comment for gpencil_data case... + */ + bGPdata **gpd_ptr = NULL; + PointerRNA ptr; + + /* get pointer to Grease Pencil Data */ + gpd_ptr = ED_gpencil_data_get_pointers_direct((ID *)sc, sa, scene, obact, &ptr); + + if (gpd_ptr) { + CTX_data_pointer_set(result, ptr.id.data, ptr.type, ptr.data); + return 1; + } + } + else if (CTX_data_equals(member, "active_gpencil_layer")) { + /* XXX: see comment for gpencil_data case... */ + bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact); + + if (gpd) { + bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd); + + if (gpl) { + CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilLayer, gpl); + return 1; + } + } + } + else if (CTX_data_equals(member, "active_gpencil_frame")) { + /* XXX: see comment for gpencil_data case... */ + bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact); + + if (gpd) { + bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd); + + if (gpl) { + CTX_data_pointer_set(result, &gpd->id, &RNA_GPencilLayer, gpl->actframe); + return 1; + } + } + } + else if (CTX_data_equals(member, "visible_gpencil_layers")) { + /* XXX: see comment for gpencil_data case... */ + bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact); + + if (gpd) { + bGPDlayer *gpl; + + for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { + if ((gpl->flag & GP_LAYER_HIDE) == 0) { + CTX_data_list_add(result, &gpd->id, &RNA_GPencilLayer, gpl); + } + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + } + else if (CTX_data_equals(member, "editable_gpencil_layers")) { + /* XXX: see comment for gpencil_data case... */ + bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact); + + if (gpd) { + bGPDlayer *gpl; + + for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { + if (gpencil_layer_is_editable(gpl)) { + CTX_data_list_add(result, &gpd->id, &RNA_GPencilLayer, gpl); + } + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + } + else if (CTX_data_equals(member, "editable_gpencil_strokes")) { + /* XXX: see comment for gpencil_data case... */ + bGPdata *gpd = ED_gpencil_data_get_active_direct((ID *)sc, sa, scene, obact); + const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); + + if (gpd) { + bGPDlayer *gpl; + + for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { + if (gpencil_layer_is_editable(gpl) && (gpl->actframe)) { + bGPDframe *gpf; + bGPDstroke *gps; + bGPDframe *init_gpf = gpl->actframe; + if (is_multiedit) { + init_gpf = gpl->frames.first; + } + + for (gpf = init_gpf; gpf; gpf = gpf->next) { + if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { + for (gps = gpf->strokes.first; gps; gps = gps->next) { + if (ED_gpencil_stroke_can_use_direct(sa, gps)) { + /* check if the color is editable */ + if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) { + continue; + } + + CTX_data_list_add(result, &gpd->id, &RNA_GPencilStroke, gps); + } + } + } + /* if not multiedit out of loop */ + if (!is_multiedit) { + break; + } + } + } + } + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + } + else if (CTX_data_equals(member, "active_operator")) { + wmOperator *op = NULL; + + SpaceFile *sfile = CTX_wm_space_file(C); + if (sfile) { + op = sfile->op; + } + else if ((op = UI_context_active_operator_get(C))) { + /* do nothing */ + } + else { + /* note, this checks poll, could be a problem, but this also + * happens for the toolbar */ + op = WM_operator_last_redo(C); + } + /* TODO, get the operator from popup's */ + + if (op && op->ptr) { + CTX_data_pointer_set(result, NULL, &RNA_Operator, op); + return 1; + } + } + else if (CTX_data_equals(member, "selected_editable_fcurves")) { + bAnimContext ac; + + if (ANIM_animdata_get_context(C, &ac) && ELEM(ac.spacetype, SPACE_ACTION, SPACE_GRAPH)) { + bAnimListElem *ale; + ListBase anim_data = {NULL, NULL}; + + int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS | + ANIMFILTER_SEL) | + (ac.spacetype == SPACE_GRAPH ? ANIMFILTER_CURVE_VISIBLE : + ANIMFILTER_LIST_VISIBLE); + + ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + + for (ale = anim_data.first; ale; ale = ale->next) { + if (ale->type == ANIMTYPE_FCURVE) + CTX_data_list_add(result, ale->id, &RNA_FCurve, ale->data); + } + + ANIM_animdata_freelist(&anim_data); + + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return 1; + } + } + else { + return 0; /* not found */ + } + + return -1; /* found but not available */ } diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c index 6a0332731b4..fb738bf40cd 100644 --- a/source/blender/editors/screen/screen_draw.c +++ b/source/blender/editors/screen/screen_draw.c @@ -44,80 +44,80 @@ */ static void draw_horizontal_join_shape(ScrArea *sa, char dir, unsigned int pos) { - const float width = screen_geom_area_width(sa) - 1; - const float height = screen_geom_area_height(sa) - 1; - vec2f points[10]; - short i; - float w, h; + const float width = screen_geom_area_width(sa) - 1; + const float height = screen_geom_area_height(sa) - 1; + vec2f points[10]; + short i; + float w, h; - if (height < width) { - h = height / 8; - w = height / 4; - } - else { - h = width / 8; - w = width / 4; - } + if (height < width) { + h = height / 8; + w = height / 4; + } + else { + h = width / 8; + w = width / 4; + } - points[0].x = sa->v1->vec.x; - points[0].y = sa->v1->vec.y + height / 2; + points[0].x = sa->v1->vec.x; + points[0].y = sa->v1->vec.y + height / 2; - points[1].x = sa->v1->vec.x; - points[1].y = sa->v1->vec.y; + points[1].x = sa->v1->vec.x; + points[1].y = sa->v1->vec.y; - points[2].x = sa->v4->vec.x - w; - points[2].y = sa->v4->vec.y; + points[2].x = sa->v4->vec.x - w; + points[2].y = sa->v4->vec.y; - points[3].x = sa->v4->vec.x - w; - points[3].y = sa->v4->vec.y + height / 2 - 2 * h; + points[3].x = sa->v4->vec.x - w; + points[3].y = sa->v4->vec.y + height / 2 - 2 * h; - points[4].x = sa->v4->vec.x - 2 * w; - points[4].y = sa->v4->vec.y + height / 2; + points[4].x = sa->v4->vec.x - 2 * w; + points[4].y = sa->v4->vec.y + height / 2; - points[5].x = sa->v4->vec.x - w; - points[5].y = sa->v4->vec.y + height / 2 + 2 * h; + points[5].x = sa->v4->vec.x - w; + points[5].y = sa->v4->vec.y + height / 2 + 2 * h; - points[6].x = sa->v3->vec.x - w; - points[6].y = sa->v3->vec.y; + points[6].x = sa->v3->vec.x - w; + points[6].y = sa->v3->vec.y; - points[7].x = sa->v2->vec.x; - points[7].y = sa->v2->vec.y; + points[7].x = sa->v2->vec.x; + points[7].y = sa->v2->vec.y; - points[8].x = sa->v4->vec.x; - points[8].y = sa->v4->vec.y + height / 2 - h; + points[8].x = sa->v4->vec.x; + points[8].y = sa->v4->vec.y + height / 2 - h; - points[9].x = sa->v4->vec.x; - points[9].y = sa->v4->vec.y + height / 2 + h; + points[9].x = sa->v4->vec.x; + points[9].y = sa->v4->vec.y + height / 2 + h; - if (dir == 'l') { - /* when direction is left, then we flip direction of arrow */ - float cx = sa->v1->vec.x + width; - for (i = 0; i < 10; i++) { - points[i].x -= cx; - points[i].x = -points[i].x; - points[i].x += sa->v1->vec.x; - } - } + if (dir == 'l') { + /* when direction is left, then we flip direction of arrow */ + float cx = sa->v1->vec.x + width; + for (i = 0; i < 10; i++) { + points[i].x -= cx; + points[i].x = -points[i].x; + points[i].x += sa->v1->vec.x; + } + } - immBegin(GPU_PRIM_TRI_FAN, 5); + immBegin(GPU_PRIM_TRI_FAN, 5); - for (i = 0; i < 5; i++) { - immVertex2f(pos, points[i].x, points[i].y); - } + for (i = 0; i < 5; i++) { + immVertex2f(pos, points[i].x, points[i].y); + } - immEnd(); + immEnd(); - immBegin(GPU_PRIM_TRI_FAN, 5); + immBegin(GPU_PRIM_TRI_FAN, 5); - for (i = 4; i < 8; i++) { - immVertex2f(pos, points[i].x, points[i].y); - } + for (i = 4; i < 8; i++) { + immVertex2f(pos, points[i].x, points[i].y); + } - immVertex2f(pos, points[0].x, points[0].y); - immEnd(); + immVertex2f(pos, points[0].x, points[0].y); + immEnd(); - immRectf(pos, points[2].x, points[2].y, points[8].x, points[8].y); - immRectf(pos, points[6].x, points[6].y, points[9].x, points[9].y); + immRectf(pos, points[2].x, points[2].y, points[8].x, points[8].y); + immRectf(pos, points[6].x, points[6].y, points[9].x, points[9].y); } /** @@ -125,80 +125,80 @@ static void draw_horizontal_join_shape(ScrArea *sa, char dir, unsigned int pos) */ static void draw_vertical_join_shape(ScrArea *sa, char dir, unsigned int pos) { - const float width = screen_geom_area_width(sa) - 1; - const float height = screen_geom_area_height(sa) - 1; - vec2f points[10]; - short i; - float w, h; + const float width = screen_geom_area_width(sa) - 1; + const float height = screen_geom_area_height(sa) - 1; + vec2f points[10]; + short i; + float w, h; - if (height < width) { - h = height / 4; - w = height / 8; - } - else { - h = width / 4; - w = width / 8; - } + if (height < width) { + h = height / 4; + w = height / 8; + } + else { + h = width / 4; + w = width / 8; + } - points[0].x = sa->v1->vec.x + width / 2; - points[0].y = sa->v3->vec.y; + points[0].x = sa->v1->vec.x + width / 2; + points[0].y = sa->v3->vec.y; - points[1].x = sa->v2->vec.x; - points[1].y = sa->v2->vec.y; + points[1].x = sa->v2->vec.x; + points[1].y = sa->v2->vec.y; - points[2].x = sa->v1->vec.x; - points[2].y = sa->v1->vec.y + h; + points[2].x = sa->v1->vec.x; + points[2].y = sa->v1->vec.y + h; - points[3].x = sa->v1->vec.x + width / 2 - 2 * w; - points[3].y = sa->v1->vec.y + h; + points[3].x = sa->v1->vec.x + width / 2 - 2 * w; + points[3].y = sa->v1->vec.y + h; - points[4].x = sa->v1->vec.x + width / 2; - points[4].y = sa->v1->vec.y + 2 * h; + points[4].x = sa->v1->vec.x + width / 2; + points[4].y = sa->v1->vec.y + 2 * h; - points[5].x = sa->v1->vec.x + width / 2 + 2 * w; - points[5].y = sa->v1->vec.y + h; + points[5].x = sa->v1->vec.x + width / 2 + 2 * w; + points[5].y = sa->v1->vec.y + h; - points[6].x = sa->v4->vec.x; - points[6].y = sa->v4->vec.y + h; + points[6].x = sa->v4->vec.x; + points[6].y = sa->v4->vec.y + h; - points[7].x = sa->v3->vec.x; - points[7].y = sa->v3->vec.y; + points[7].x = sa->v3->vec.x; + points[7].y = sa->v3->vec.y; - points[8].x = sa->v1->vec.x + width / 2 - w; - points[8].y = sa->v1->vec.y; + points[8].x = sa->v1->vec.x + width / 2 - w; + points[8].y = sa->v1->vec.y; - points[9].x = sa->v1->vec.x + width / 2 + w; - points[9].y = sa->v1->vec.y; + points[9].x = sa->v1->vec.x + width / 2 + w; + points[9].y = sa->v1->vec.y; - if (dir == 'u') { - /* when direction is up, then we flip direction of arrow */ - float cy = sa->v1->vec.y + height; - for (i = 0; i < 10; i++) { - points[i].y -= cy; - points[i].y = -points[i].y; - points[i].y += sa->v1->vec.y; - } - } + if (dir == 'u') { + /* when direction is up, then we flip direction of arrow */ + float cy = sa->v1->vec.y + height; + for (i = 0; i < 10; i++) { + points[i].y -= cy; + points[i].y = -points[i].y; + points[i].y += sa->v1->vec.y; + } + } - immBegin(GPU_PRIM_TRI_FAN, 5); + immBegin(GPU_PRIM_TRI_FAN, 5); - for (i = 0; i < 5; i++) { - immVertex2f(pos, points[i].x, points[i].y); - } + for (i = 0; i < 5; i++) { + immVertex2f(pos, points[i].x, points[i].y); + } - immEnd(); + immEnd(); - immBegin(GPU_PRIM_TRI_FAN, 5); + immBegin(GPU_PRIM_TRI_FAN, 5); - for (i = 4; i < 8; i++) { - immVertex2f(pos, points[i].x, points[i].y); - } + for (i = 4; i < 8; i++) { + immVertex2f(pos, points[i].x, points[i].y); + } - immVertex2f(pos, points[0].x, points[0].y); - immEnd(); + immVertex2f(pos, points[0].x, points[0].y); + immEnd(); - immRectf(pos, points[2].x, points[2].y, points[8].x, points[8].y); - immRectf(pos, points[6].x, points[6].y, points[9].x, points[9].y); + immRectf(pos, points[2].x, points[2].y, points[8].x, points[8].y); + immRectf(pos, points[6].x, points[6].y, points[9].x, points[9].y); } /** @@ -206,88 +206,88 @@ static void draw_vertical_join_shape(ScrArea *sa, char dir, unsigned int pos) */ static void draw_join_shape(ScrArea *sa, char dir, unsigned int pos) { - if (dir == 'u' || dir == 'd') { - draw_vertical_join_shape(sa, dir, pos); - } - else { - draw_horizontal_join_shape(sa, dir, pos); - } + if (dir == 'u' || dir == 'd') { + draw_vertical_join_shape(sa, dir, pos); + } + else { + draw_horizontal_join_shape(sa, dir, pos); + } } #define CORNER_RESOLUTION 3 static void do_vert_pair(GPUVertBuf *vbo, uint pos, uint *vidx, int corner, int i) { - float inter[2], exter[2]; - inter[0] = cosf(corner * M_PI_2 + (i * M_PI_2 / (CORNER_RESOLUTION - 1.0f))); - inter[1] = sinf(corner * M_PI_2 + (i * M_PI_2 / (CORNER_RESOLUTION - 1.0f))); - - /* Snap point to edge */ - float div = 1.0f / max_ff(fabsf(inter[0]), fabsf(inter[1])); - mul_v2_v2fl(exter, inter, div); - exter[0] = roundf(exter[0]); - exter[1] = roundf(exter[1]); - - if (i == 0 || i == (CORNER_RESOLUTION - 1)) { - copy_v2_v2(inter, exter); - } - - /* Line width is 20% of the entire corner size. */ - const float line_width = 0.2f; /* Keep in sync with shader */ - mul_v2_fl(inter, 1.0f - line_width); - mul_v2_fl(exter, 1.0f + line_width); - - switch (corner) { - case 0: - add_v2_v2(inter, (float[2]){-1.0f, -1.0f}); - add_v2_v2(exter, (float[2]){-1.0f, -1.0f}); - break; - case 1: - add_v2_v2(inter, (float[2]){1.0f, -1.0f}); - add_v2_v2(exter, (float[2]){1.0f, -1.0f}); - break; - case 2: - add_v2_v2(inter, (float[2]){1.0f, 1.0f}); - add_v2_v2(exter, (float[2]){1.0f, 1.0f}); - break; - case 3: - add_v2_v2(inter, (float[2]){-1.0f, 1.0f}); - add_v2_v2(exter, (float[2]){-1.0f, 1.0f}); - break; - } - - GPU_vertbuf_attr_set(vbo, pos, (*vidx)++, inter); - GPU_vertbuf_attr_set(vbo, pos, (*vidx)++, exter); + float inter[2], exter[2]; + inter[0] = cosf(corner * M_PI_2 + (i * M_PI_2 / (CORNER_RESOLUTION - 1.0f))); + inter[1] = sinf(corner * M_PI_2 + (i * M_PI_2 / (CORNER_RESOLUTION - 1.0f))); + + /* Snap point to edge */ + float div = 1.0f / max_ff(fabsf(inter[0]), fabsf(inter[1])); + mul_v2_v2fl(exter, inter, div); + exter[0] = roundf(exter[0]); + exter[1] = roundf(exter[1]); + + if (i == 0 || i == (CORNER_RESOLUTION - 1)) { + copy_v2_v2(inter, exter); + } + + /* Line width is 20% of the entire corner size. */ + const float line_width = 0.2f; /* Keep in sync with shader */ + mul_v2_fl(inter, 1.0f - line_width); + mul_v2_fl(exter, 1.0f + line_width); + + switch (corner) { + case 0: + add_v2_v2(inter, (float[2]){-1.0f, -1.0f}); + add_v2_v2(exter, (float[2]){-1.0f, -1.0f}); + break; + case 1: + add_v2_v2(inter, (float[2]){1.0f, -1.0f}); + add_v2_v2(exter, (float[2]){1.0f, -1.0f}); + break; + case 2: + add_v2_v2(inter, (float[2]){1.0f, 1.0f}); + add_v2_v2(exter, (float[2]){1.0f, 1.0f}); + break; + case 3: + add_v2_v2(inter, (float[2]){-1.0f, 1.0f}); + add_v2_v2(exter, (float[2]){-1.0f, 1.0f}); + break; + } + + GPU_vertbuf_attr_set(vbo, pos, (*vidx)++, inter); + GPU_vertbuf_attr_set(vbo, pos, (*vidx)++, exter); } static GPUBatch *batch_screen_edges_get(int *corner_len) { - static GPUBatch *screen_edges_batch = NULL; - - if (screen_edges_batch == NULL) { - GPUVertFormat format = {0}; - uint pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - - GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); - GPU_vertbuf_data_alloc(vbo, CORNER_RESOLUTION * 2 * 4 + 2); - - uint vidx = 0; - for (int corner = 0; corner < 4; ++corner) { - for (int c = 0; c < CORNER_RESOLUTION; ++c) { - do_vert_pair(vbo, pos, &vidx, corner, c); - } - } - /* close the loop */ - do_vert_pair(vbo, pos, &vidx, 0, 0); - - screen_edges_batch = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO); - gpu_batch_presets_register(screen_edges_batch); - } - - if (corner_len) { - *corner_len = CORNER_RESOLUTION * 2; - } - return screen_edges_batch; + static GPUBatch *screen_edges_batch = NULL; + + if (screen_edges_batch == NULL) { + GPUVertFormat format = {0}; + uint pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(vbo, CORNER_RESOLUTION * 2 * 4 + 2); + + uint vidx = 0; + for (int corner = 0; corner < 4; ++corner) { + for (int c = 0; c < CORNER_RESOLUTION; ++c) { + do_vert_pair(vbo, pos, &vidx, corner, c); + } + } + /* close the loop */ + do_vert_pair(vbo, pos, &vidx, 0, 0); + + screen_edges_batch = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO); + gpu_batch_presets_register(screen_edges_batch); + } + + if (corner_len) { + *corner_len = CORNER_RESOLUTION * 2; + } + return screen_edges_batch; } #undef CORNER_RESOLUTION @@ -297,10 +297,11 @@ static GPUBatch *batch_screen_edges_get(int *corner_len) */ static void scrarea_draw_shape_dark(ScrArea *sa, char dir, unsigned int pos) { - GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - immUniformColor4ub(0, 0, 0, 50); + GPU_blend_set_func_separate( + GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + immUniformColor4ub(0, 0, 0, 50); - draw_join_shape(sa, dir, pos); + draw_join_shape(sa, dir, pos); } /** @@ -308,42 +309,43 @@ static void scrarea_draw_shape_dark(ScrArea *sa, char dir, unsigned int pos) */ static void scrarea_draw_shape_light(ScrArea *sa, char UNUSED(dir), unsigned int pos) { - GPU_blend_set_func(GPU_DST_COLOR, GPU_SRC_ALPHA); - /* value 181 was hardly computed: 181~105 */ - immUniformColor4ub(255, 255, 255, 50); - /* draw_join_shape(sa, dir); */ + GPU_blend_set_func(GPU_DST_COLOR, GPU_SRC_ALPHA); + /* value 181 was hardly computed: 181~105 */ + immUniformColor4ub(255, 255, 255, 50); + /* draw_join_shape(sa, dir); */ - immRectf(pos, sa->v1->vec.x, sa->v1->vec.y, sa->v3->vec.x, sa->v3->vec.y); + immRectf(pos, sa->v1->vec.x, sa->v1->vec.y, sa->v3->vec.x, sa->v3->vec.y); } -static void drawscredge_area_draw(int sizex, int sizey, short x1, short y1, short x2, short y2, float edge_thickness) +static void drawscredge_area_draw( + int sizex, int sizey, short x1, short y1, short x2, short y2, float edge_thickness) { - rctf rect; - BLI_rctf_init(&rect, (float)x1, (float)x2, (float)y1, (float)y2); - - /* right border area */ - if (x2 >= sizex - 1) { - rect.xmax += edge_thickness * 0.5f; - } - - /* left border area */ - if (x1 <= 0) { /* otherwise it draws the emboss of window over */ - rect.xmin -= edge_thickness * 0.5f; - } - - /* top border area */ - if (y2 >= sizey - 1) { - rect.ymax += edge_thickness * 0.5f; - } - - /* bottom border area */ - if (y1 <= 0) { - rect.ymin -= edge_thickness * 0.5f; - } - - GPUBatch *batch = batch_screen_edges_get(NULL); - GPU_batch_uniform_4fv(batch, "rect", (float *)&rect); - GPU_batch_draw(batch); + rctf rect; + BLI_rctf_init(&rect, (float)x1, (float)x2, (float)y1, (float)y2); + + /* right border area */ + if (x2 >= sizex - 1) { + rect.xmax += edge_thickness * 0.5f; + } + + /* left border area */ + if (x1 <= 0) { /* otherwise it draws the emboss of window over */ + rect.xmin -= edge_thickness * 0.5f; + } + + /* top border area */ + if (y2 >= sizey - 1) { + rect.ymax += edge_thickness * 0.5f; + } + + /* bottom border area */ + if (y1 <= 0) { + rect.ymin -= edge_thickness * 0.5f; + } + + GPUBatch *batch = batch_screen_edges_get(NULL); + GPU_batch_uniform_4fv(batch, "rect", (float *)&rect); + GPU_batch_draw(batch); } /** @@ -351,12 +353,12 @@ static void drawscredge_area_draw(int sizex, int sizey, short x1, short y1, shor */ static void drawscredge_area(ScrArea *sa, int sizex, int sizey, float edge_thickness) { - short x1 = sa->v1->vec.x; - short y1 = sa->v1->vec.y; - short x2 = sa->v3->vec.x; - short y2 = sa->v3->vec.y; + short x1 = sa->v1->vec.x; + short y1 = sa->v1->vec.y; + short x2 = sa->v3->vec.x; + short y2 = sa->v3->vec.y; - drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, edge_thickness); + drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, edge_thickness); } /** @@ -364,71 +366,72 @@ static void drawscredge_area(ScrArea *sa, int sizex, int sizey, float edge_thick */ void ED_screen_draw_edges(wmWindow *win) { - bScreen *screen = WM_window_get_active_screen(win); - screen->do_draw = false; - - if (screen->state == SCREENFULL) { - return; - } - - if (screen->temp && BLI_listbase_is_single(&screen->areabase)) { - return; - } - - const int winsize_x = WM_window_pixels_x(win); - const int winsize_y = WM_window_pixels_y(win); - float col[4], corner_scale, edge_thickness; - int verts_per_corner = 0; - - ScrArea *sa; - - rcti scissor_rect; - BLI_rcti_init_minmax(&scissor_rect); - for (sa = screen->areabase.first; sa; sa = sa->next) { - BLI_rcti_do_minmax_v(&scissor_rect, (int[2]){sa->v1->vec.x, sa->v1->vec.y}); - BLI_rcti_do_minmax_v(&scissor_rect, (int[2]){sa->v3->vec.x, sa->v3->vec.y}); - } - - if (GPU_type_matches(GPU_DEVICE_INTEL_UHD, GPU_OS_UNIX, GPU_DRIVER_ANY)) { - /* For some reason, on linux + Intel UHD Graphics 620 the driver - * hangs if we don't flush before this. (See T57455) */ - GPU_flush(); - } - - GPU_scissor(scissor_rect.xmin, - scissor_rect.ymin, - BLI_rcti_size_x(&scissor_rect) + 1, - BLI_rcti_size_y(&scissor_rect) + 1); - - /* It seems that all areas gets smaller when pixelsize is > 1. - * So in order to avoid missing pixels we just disable de scissors. */ - if (U.pixelsize <= 1.0f) { - glEnable(GL_SCISSOR_TEST); - } - - UI_GetThemeColor4fv(TH_EDITOR_OUTLINE, col); - col[3] = 1.0f; - corner_scale = U.pixelsize * 8.0f; - edge_thickness = corner_scale * 0.21f; - - GPU_blend(true); - GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - - GPUBatch *batch = batch_screen_edges_get(&verts_per_corner); - GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_AREA_EDGES); - GPU_batch_uniform_1i(batch, "cornerLen", verts_per_corner); - GPU_batch_uniform_1f(batch, "scale", corner_scale); - GPU_batch_uniform_4fv(batch, "color", col); - - for (sa = screen->areabase.first; sa; sa = sa->next) { - drawscredge_area(sa, winsize_x, winsize_y, edge_thickness); - } - - GPU_blend(false); - - if (U.pixelsize <= 1.0f) { - glDisable(GL_SCISSOR_TEST); - } + bScreen *screen = WM_window_get_active_screen(win); + screen->do_draw = false; + + if (screen->state == SCREENFULL) { + return; + } + + if (screen->temp && BLI_listbase_is_single(&screen->areabase)) { + return; + } + + const int winsize_x = WM_window_pixels_x(win); + const int winsize_y = WM_window_pixels_y(win); + float col[4], corner_scale, edge_thickness; + int verts_per_corner = 0; + + ScrArea *sa; + + rcti scissor_rect; + BLI_rcti_init_minmax(&scissor_rect); + for (sa = screen->areabase.first; sa; sa = sa->next) { + BLI_rcti_do_minmax_v(&scissor_rect, (int[2]){sa->v1->vec.x, sa->v1->vec.y}); + BLI_rcti_do_minmax_v(&scissor_rect, (int[2]){sa->v3->vec.x, sa->v3->vec.y}); + } + + if (GPU_type_matches(GPU_DEVICE_INTEL_UHD, GPU_OS_UNIX, GPU_DRIVER_ANY)) { + /* For some reason, on linux + Intel UHD Graphics 620 the driver + * hangs if we don't flush before this. (See T57455) */ + GPU_flush(); + } + + GPU_scissor(scissor_rect.xmin, + scissor_rect.ymin, + BLI_rcti_size_x(&scissor_rect) + 1, + BLI_rcti_size_y(&scissor_rect) + 1); + + /* It seems that all areas gets smaller when pixelsize is > 1. + * So in order to avoid missing pixels we just disable de scissors. */ + if (U.pixelsize <= 1.0f) { + glEnable(GL_SCISSOR_TEST); + } + + UI_GetThemeColor4fv(TH_EDITOR_OUTLINE, col); + col[3] = 1.0f; + corner_scale = U.pixelsize * 8.0f; + edge_thickness = corner_scale * 0.21f; + + GPU_blend(true); + GPU_blend_set_func_separate( + GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + + GPUBatch *batch = batch_screen_edges_get(&verts_per_corner); + GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_AREA_EDGES); + GPU_batch_uniform_1i(batch, "cornerLen", verts_per_corner); + GPU_batch_uniform_1f(batch, "scale", corner_scale); + GPU_batch_uniform_4fv(batch, "color", col); + + for (sa = screen->areabase.first; sa; sa = sa->next) { + drawscredge_area(sa, winsize_x, winsize_y, edge_thickness); + } + + GPU_blend(false); + + if (U.pixelsize <= 1.0f) { + glDisable(GL_SCISSOR_TEST); + } } /** @@ -439,100 +442,100 @@ void ED_screen_draw_edges(wmWindow *win) */ void ED_screen_draw_join_shape(ScrArea *sa1, ScrArea *sa2) { - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - - GPU_line_width(1); - - /* blended join arrow */ - int dir = area_getorientation(sa1, sa2); - int dira = -1; - if (dir != -1) { - switch (dir) { - case 0: /* W */ - dir = 'r'; - dira = 'l'; - break; - case 1: /* N */ - dir = 'd'; - dira = 'u'; - break; - case 2: /* E */ - dir = 'l'; - dira = 'r'; - break; - case 3: /* S */ - dir = 'u'; - dira = 'd'; - break; - } - - GPU_blend(true); - - scrarea_draw_shape_dark(sa2, dir, pos); - scrarea_draw_shape_light(sa1, dira, pos); - - GPU_blend(false); - } - - immUnbindProgram(); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + + GPU_line_width(1); + + /* blended join arrow */ + int dir = area_getorientation(sa1, sa2); + int dira = -1; + if (dir != -1) { + switch (dir) { + case 0: /* W */ + dir = 'r'; + dira = 'l'; + break; + case 1: /* N */ + dir = 'd'; + dira = 'u'; + break; + case 2: /* E */ + dir = 'l'; + dira = 'r'; + break; + case 3: /* S */ + dir = 'u'; + dira = 'd'; + break; + } + + GPU_blend(true); + + scrarea_draw_shape_dark(sa2, dir, pos); + scrarea_draw_shape_light(sa1, dira, pos); + + GPU_blend(false); + } + + immUnbindProgram(); } void ED_screen_draw_split_preview(ScrArea *sa, const int dir, const float fac) { - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - /* splitpoint */ - GPU_blend(true); - GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + /* splitpoint */ + GPU_blend(true); + GPU_blend_set_func_separate( + GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - immUniformColor4ub(255, 255, 255, 100); + immUniformColor4ub(255, 255, 255, 100); - immBegin(GPU_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); - if (dir == 'h') { - const float y = (1 - fac) * sa->totrct.ymin + fac * sa->totrct.ymax; + if (dir == 'h') { + const float y = (1 - fac) * sa->totrct.ymin + fac * sa->totrct.ymax; - immVertex2f(pos, sa->totrct.xmin, y); - immVertex2f(pos, sa->totrct.xmax, y); + immVertex2f(pos, sa->totrct.xmin, y); + immVertex2f(pos, sa->totrct.xmax, y); - immEnd(); + immEnd(); - immUniformColor4ub(0, 0, 0, 100); + immUniformColor4ub(0, 0, 0, 100); - immBegin(GPU_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); - immVertex2f(pos, sa->totrct.xmin, y + 1); - immVertex2f(pos, sa->totrct.xmax, y + 1); + immVertex2f(pos, sa->totrct.xmin, y + 1); + immVertex2f(pos, sa->totrct.xmax, y + 1); - immEnd(); - } - else { - BLI_assert(dir == 'v'); - const float x = (1 - fac) * sa->totrct.xmin + fac * sa->totrct.xmax; + immEnd(); + } + else { + BLI_assert(dir == 'v'); + const float x = (1 - fac) * sa->totrct.xmin + fac * sa->totrct.xmax; - immVertex2f(pos, x, sa->totrct.ymin); - immVertex2f(pos, x, sa->totrct.ymax); + immVertex2f(pos, x, sa->totrct.ymin); + immVertex2f(pos, x, sa->totrct.ymax); - immEnd(); + immEnd(); - immUniformColor4ub(0, 0, 0, 100); + immUniformColor4ub(0, 0, 0, 100); - immBegin(GPU_PRIM_LINES, 2); + immBegin(GPU_PRIM_LINES, 2); - immVertex2f(pos, x + 1, sa->totrct.ymin); - immVertex2f(pos, x + 1, sa->totrct.ymax); + immVertex2f(pos, x + 1, sa->totrct.ymin); + immVertex2f(pos, x + 1, sa->totrct.ymax); - immEnd(); - } + immEnd(); + } - GPU_blend(false); + GPU_blend(false); - immUnbindProgram(); + immUnbindProgram(); } - /* -------------------------------------------------------------------- */ /* Screen Thumbnail Preview */ @@ -540,65 +543,65 @@ void ED_screen_draw_split_preview(ScrArea *sa, const int dir, const float fac) * Calculates a scale factor to squash the preview for \a screen into a rectangle of given size and aspect. */ static void screen_preview_scale_get( - const bScreen *screen, float size_x, float size_y, - const float asp[2], - float r_scale[2]) + const bScreen *screen, float size_x, float size_y, const float asp[2], float r_scale[2]) { - float max_x = 0, max_y = 0; - - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - max_x = MAX2(max_x, sa->totrct.xmax); - max_y = MAX2(max_y, sa->totrct.ymax); - } - r_scale[0] = (size_x * asp[0]) / max_x; - r_scale[1] = (size_y * asp[1]) / max_y; + float max_x = 0, max_y = 0; + + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + max_x = MAX2(max_x, sa->totrct.xmax); + max_y = MAX2(max_y, sa->totrct.ymax); + } + r_scale[0] = (size_x * asp[0]) / max_x; + r_scale[1] = (size_y * asp[1]) / max_y; } -static void screen_preview_draw_areas(const bScreen *screen, const float scale[2], const float col[4], +static void screen_preview_draw_areas(const bScreen *screen, + const float scale[2], + const float col[4], const float ofs_between_areas) { - const float ofs_h = ofs_between_areas * 0.5f; - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - immUniformColor4fv(col); - - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - rctf rect = { - .xmin = sa->totrct.xmin * scale[0] + ofs_h, - .xmax = sa->totrct.xmax * scale[0] - ofs_h, - .ymin = sa->totrct.ymin * scale[1] + ofs_h, - .ymax = sa->totrct.ymax * scale[1] - ofs_h, - }; - - immBegin(GPU_PRIM_TRI_FAN, 4); - immVertex2f(pos, rect.xmin, rect.ymin); - immVertex2f(pos, rect.xmax, rect.ymin); - immVertex2f(pos, rect.xmax, rect.ymax); - immVertex2f(pos, rect.xmin, rect.ymax); - immEnd(); - } - - immUnbindProgram(); + const float ofs_h = ofs_between_areas * 0.5f; + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immUniformColor4fv(col); + + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + rctf rect = { + .xmin = sa->totrct.xmin * scale[0] + ofs_h, + .xmax = sa->totrct.xmax * scale[0] - ofs_h, + .ymin = sa->totrct.ymin * scale[1] + ofs_h, + .ymax = sa->totrct.ymax * scale[1] - ofs_h, + }; + + immBegin(GPU_PRIM_TRI_FAN, 4); + immVertex2f(pos, rect.xmin, rect.ymin); + immVertex2f(pos, rect.xmax, rect.ymin); + immVertex2f(pos, rect.xmax, rect.ymax); + immVertex2f(pos, rect.xmin, rect.ymax); + immEnd(); + } + + immUnbindProgram(); } static void screen_preview_draw(const bScreen *screen, int size_x, int size_y) { - const float asp[2] = {1.0f, 0.8f}; /* square previews look a bit ugly */ - /* could use theme color (tui.wcol_menu_item.text), but then we'd need to regenerate all previews when changing */ - const float col[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - float scale[2]; + const float asp[2] = {1.0f, 0.8f}; /* square previews look a bit ugly */ + /* could use theme color (tui.wcol_menu_item.text), but then we'd need to regenerate all previews when changing */ + const float col[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + float scale[2]; - wmOrtho2(0.0f, size_x, 0.0f, size_y); - /* center */ - GPU_matrix_push(); - GPU_matrix_identity_set(); - GPU_matrix_translate_2f(size_x * (1.0f - asp[0]) * 0.5f, size_y * (1.0f - asp[1]) * 0.5f); + wmOrtho2(0.0f, size_x, 0.0f, size_y); + /* center */ + GPU_matrix_push(); + GPU_matrix_identity_set(); + GPU_matrix_translate_2f(size_x * (1.0f - asp[0]) * 0.5f, size_y * (1.0f - asp[1]) * 0.5f); - screen_preview_scale_get(screen, size_x, size_y, asp, scale); - screen_preview_draw_areas(screen, scale, col, 1.5f); + screen_preview_scale_get(screen, size_x, size_y, asp, scale); + screen_preview_draw_areas(screen, scale, col, 1.5f); - GPU_matrix_pop(); + GPU_matrix_pop(); } /** @@ -606,17 +609,17 @@ static void screen_preview_draw(const bScreen *screen, int size_x, int size_y) */ void ED_screen_preview_render(const bScreen *screen, int size_x, int size_y, unsigned int *r_rect) { - char err_out[256] = "unknown"; - GPUOffScreen *offscreen = GPU_offscreen_create(size_x, size_y, 0, true, false, err_out); + char err_out[256] = "unknown"; + GPUOffScreen *offscreen = GPU_offscreen_create(size_x, size_y, 0, true, false, err_out); - GPU_offscreen_bind(offscreen, true); - GPU_clear_color(0.0, 0.0, 0.0, 0.0); - GPU_clear(GPU_COLOR_BIT | GPU_DEPTH_BIT); + GPU_offscreen_bind(offscreen, true); + GPU_clear_color(0.0, 0.0, 0.0, 0.0); + GPU_clear(GPU_COLOR_BIT | GPU_DEPTH_BIT); - screen_preview_draw(screen, size_x, size_y); + screen_preview_draw(screen, size_x, size_y); - GPU_offscreen_read_pixels(offscreen, GL_UNSIGNED_BYTE, r_rect); - GPU_offscreen_unbind(offscreen, true); + GPU_offscreen_read_pixels(offscreen, GL_UNSIGNED_BYTE, r_rect); + GPU_offscreen_unbind(offscreen, true); - GPU_offscreen_free(offscreen); + GPU_offscreen_free(offscreen); } diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 031eee3c9a4..8caa960bb9a 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -21,11 +21,9 @@ * \ingroup edscr */ - #include <string.h> #include <math.h> - #include "MEM_guardedalloc.h" #include "DNA_object_types.h" @@ -64,136 +62,140 @@ #include "DEG_depsgraph_query.h" -#include "screen_intern.h" /* own module include */ - +#include "screen_intern.h" /* own module include */ /* adds no space data */ -static ScrArea *screen_addarea_ex( - ScrAreaMap *area_map, - ScrVert *bottom_left, ScrVert *top_left, ScrVert *top_right, ScrVert *bottom_right, - short spacetype) +static ScrArea *screen_addarea_ex(ScrAreaMap *area_map, + ScrVert *bottom_left, + ScrVert *top_left, + ScrVert *top_right, + ScrVert *bottom_right, + short spacetype) { - ScrArea *sa = MEM_callocN(sizeof(ScrArea), "addscrarea"); + ScrArea *sa = MEM_callocN(sizeof(ScrArea), "addscrarea"); - sa->v1 = bottom_left; - sa->v2 = top_left; - sa->v3 = top_right; - sa->v4 = bottom_right; - sa->spacetype = spacetype; + sa->v1 = bottom_left; + sa->v2 = top_left; + sa->v3 = top_right; + sa->v4 = bottom_right; + sa->spacetype = spacetype; - BLI_addtail(&area_map->areabase, sa); + BLI_addtail(&area_map->areabase, sa); - return sa; + return sa; } -static ScrArea *screen_addarea( - bScreen *sc, - ScrVert *left_bottom, ScrVert *left_top, ScrVert *right_top, ScrVert *right_bottom, - short spacetype) +static ScrArea *screen_addarea(bScreen *sc, + ScrVert *left_bottom, + ScrVert *left_top, + ScrVert *right_top, + ScrVert *right_bottom, + short spacetype) { - return screen_addarea_ex(AREAMAP_FROM_SCREEN(sc), left_bottom, left_top, right_top, right_bottom, - spacetype); + return screen_addarea_ex( + AREAMAP_FROM_SCREEN(sc), left_bottom, left_top, right_top, right_bottom, spacetype); } static void screen_delarea(bContext *C, bScreen *sc, ScrArea *sa) { - ED_area_exit(C, sa); + ED_area_exit(C, sa); - BKE_screen_area_free(sa); + BKE_screen_area_free(sa); - BLI_remlink(&sc->areabase, sa); - MEM_freeN(sa); + BLI_remlink(&sc->areabase, sa); + MEM_freeN(sa); } ScrArea *area_split(const wmWindow *win, bScreen *sc, ScrArea *sa, char dir, float fac, int merge) { - ScrArea *newa = NULL; - ScrVert *sv1, *sv2; - short split; - rcti window_rect; - - if (sa == NULL) return NULL; - - WM_window_rect_calc(win, &window_rect); - - split = screen_geom_find_area_split_point(sa, &window_rect, dir, fac); - if (split == 0) return NULL; - - /* note regarding (fac > 0.5f) checks below. - * normally it shouldn't matter which is used since the copy should match the original - * however with viewport rendering and python console this isn't the case. - campbell */ - - if (dir == 'h') { - /* new vertices */ - sv1 = screen_geom_vertex_add(sc, sa->v1->vec.x, split); - sv2 = screen_geom_vertex_add(sc, sa->v4->vec.x, split); - - /* new edges */ - screen_geom_edge_add(sc, sa->v1, sv1); - screen_geom_edge_add(sc, sv1, sa->v2); - screen_geom_edge_add(sc, sa->v3, sv2); - screen_geom_edge_add(sc, sv2, sa->v4); - screen_geom_edge_add(sc, sv1, sv2); - - if (fac > 0.5f) { - /* new areas: top */ - newa = screen_addarea(sc, sv1, sa->v2, sa->v3, sv2, sa->spacetype); - - /* area below */ - sa->v2 = sv1; - sa->v3 = sv2; - } - else { - /* new areas: bottom */ - newa = screen_addarea(sc, sa->v1, sv1, sv2, sa->v4, sa->spacetype); - - /* area above */ - sa->v1 = sv1; - sa->v4 = sv2; - } - - ED_area_data_copy(newa, sa, true); - - } - else { - /* new vertices */ - sv1 = screen_geom_vertex_add(sc, split, sa->v1->vec.y); - sv2 = screen_geom_vertex_add(sc, split, sa->v2->vec.y); - - /* new edges */ - screen_geom_edge_add(sc, sa->v1, sv1); - screen_geom_edge_add(sc, sv1, sa->v4); - screen_geom_edge_add(sc, sa->v2, sv2); - screen_geom_edge_add(sc, sv2, sa->v3); - screen_geom_edge_add(sc, sv1, sv2); - - if (fac > 0.5f) { - /* new areas: right */ - newa = screen_addarea(sc, sv1, sv2, sa->v3, sa->v4, sa->spacetype); - - /* area left */ - sa->v3 = sv2; - sa->v4 = sv1; - } - else { - /* new areas: left */ - newa = screen_addarea(sc, sa->v1, sa->v2, sv2, sv1, sa->spacetype); - - /* area right */ - sa->v1 = sv1; - sa->v2 = sv2; - } - - ED_area_data_copy(newa, sa, true); - } - - /* remove double vertices en edges */ - if (merge) - BKE_screen_remove_double_scrverts(sc); - BKE_screen_remove_double_scredges(sc); - BKE_screen_remove_unused_scredges(sc); - - return newa; + ScrArea *newa = NULL; + ScrVert *sv1, *sv2; + short split; + rcti window_rect; + + if (sa == NULL) + return NULL; + + WM_window_rect_calc(win, &window_rect); + + split = screen_geom_find_area_split_point(sa, &window_rect, dir, fac); + if (split == 0) + return NULL; + + /* note regarding (fac > 0.5f) checks below. + * normally it shouldn't matter which is used since the copy should match the original + * however with viewport rendering and python console this isn't the case. - campbell */ + + if (dir == 'h') { + /* new vertices */ + sv1 = screen_geom_vertex_add(sc, sa->v1->vec.x, split); + sv2 = screen_geom_vertex_add(sc, sa->v4->vec.x, split); + + /* new edges */ + screen_geom_edge_add(sc, sa->v1, sv1); + screen_geom_edge_add(sc, sv1, sa->v2); + screen_geom_edge_add(sc, sa->v3, sv2); + screen_geom_edge_add(sc, sv2, sa->v4); + screen_geom_edge_add(sc, sv1, sv2); + + if (fac > 0.5f) { + /* new areas: top */ + newa = screen_addarea(sc, sv1, sa->v2, sa->v3, sv2, sa->spacetype); + + /* area below */ + sa->v2 = sv1; + sa->v3 = sv2; + } + else { + /* new areas: bottom */ + newa = screen_addarea(sc, sa->v1, sv1, sv2, sa->v4, sa->spacetype); + + /* area above */ + sa->v1 = sv1; + sa->v4 = sv2; + } + + ED_area_data_copy(newa, sa, true); + } + else { + /* new vertices */ + sv1 = screen_geom_vertex_add(sc, split, sa->v1->vec.y); + sv2 = screen_geom_vertex_add(sc, split, sa->v2->vec.y); + + /* new edges */ + screen_geom_edge_add(sc, sa->v1, sv1); + screen_geom_edge_add(sc, sv1, sa->v4); + screen_geom_edge_add(sc, sa->v2, sv2); + screen_geom_edge_add(sc, sv2, sa->v3); + screen_geom_edge_add(sc, sv1, sv2); + + if (fac > 0.5f) { + /* new areas: right */ + newa = screen_addarea(sc, sv1, sv2, sa->v3, sa->v4, sa->spacetype); + + /* area left */ + sa->v3 = sv2; + sa->v4 = sv1; + } + else { + /* new areas: left */ + newa = screen_addarea(sc, sa->v1, sa->v2, sv2, sv1, sa->spacetype); + + /* area right */ + sa->v1 = sv1; + sa->v2 = sv2; + } + + ED_area_data_copy(newa, sa, true); + } + + /* remove double vertices en edges */ + if (merge) + BKE_screen_remove_double_scrverts(sc); + BKE_screen_remove_double_scredges(sc); + BKE_screen_remove_unused_scredges(sc); + + return newa; } /** @@ -201,74 +203,74 @@ ScrArea *area_split(const wmWindow *win, bScreen *sc, ScrArea *sa, char dir, flo */ bScreen *screen_add(Main *bmain, const char *name, const rcti *rect) { - bScreen *sc; - ScrVert *sv1, *sv2, *sv3, *sv4; + bScreen *sc; + ScrVert *sv1, *sv2, *sv3, *sv4; - sc = BKE_libblock_alloc(bmain, ID_SCR, name, 0); - sc->do_refresh = true; - sc->redraws_flag = TIME_ALL_3D_WIN | TIME_ALL_ANIM_WIN; + sc = BKE_libblock_alloc(bmain, ID_SCR, name, 0); + sc->do_refresh = true; + sc->redraws_flag = TIME_ALL_3D_WIN | TIME_ALL_ANIM_WIN; - sv1 = screen_geom_vertex_add(sc, rect->xmin, rect->ymin); - sv2 = screen_geom_vertex_add(sc, rect->xmin, rect->ymax - 1); - sv3 = screen_geom_vertex_add(sc, rect->xmax - 1, rect->ymax - 1); - sv4 = screen_geom_vertex_add(sc, rect->xmax - 1, rect->ymin); + sv1 = screen_geom_vertex_add(sc, rect->xmin, rect->ymin); + sv2 = screen_geom_vertex_add(sc, rect->xmin, rect->ymax - 1); + sv3 = screen_geom_vertex_add(sc, rect->xmax - 1, rect->ymax - 1); + sv4 = screen_geom_vertex_add(sc, rect->xmax - 1, rect->ymin); - screen_geom_edge_add(sc, sv1, sv2); - screen_geom_edge_add(sc, sv2, sv3); - screen_geom_edge_add(sc, sv3, sv4); - screen_geom_edge_add(sc, sv4, sv1); + screen_geom_edge_add(sc, sv1, sv2); + screen_geom_edge_add(sc, sv2, sv3); + screen_geom_edge_add(sc, sv3, sv4); + screen_geom_edge_add(sc, sv4, sv1); - /* dummy type, no spacedata */ - screen_addarea(sc, sv1, sv2, sv3, sv4, SPACE_EMPTY); + /* dummy type, no spacedata */ + screen_addarea(sc, sv1, sv2, sv3, sv4, SPACE_EMPTY); - return sc; + return sc; } void screen_data_copy(bScreen *to, bScreen *from) { - ScrVert *s1, *s2; - ScrEdge *se; - ScrArea *sa, *saf; - - /* free contents of 'to', is from blenkernel screen.c */ - BKE_screen_free(to); - - to->flag = from->flag; - - BLI_duplicatelist(&to->vertbase, &from->vertbase); - BLI_duplicatelist(&to->edgebase, &from->edgebase); - BLI_duplicatelist(&to->areabase, &from->areabase); - BLI_listbase_clear(&to->regionbase); - - s2 = to->vertbase.first; - for (s1 = from->vertbase.first; s1; s1 = s1->next, s2 = s2->next) { - s1->newv = s2; - } - - for (se = to->edgebase.first; se; se = se->next) { - se->v1 = se->v1->newv; - se->v2 = se->v2->newv; - BKE_screen_sort_scrvert(&(se->v1), &(se->v2)); - } - - saf = from->areabase.first; - for (sa = to->areabase.first; sa; sa = sa->next, saf = saf->next) { - sa->v1 = sa->v1->newv; - sa->v2 = sa->v2->newv; - sa->v3 = sa->v3->newv; - sa->v4 = sa->v4->newv; - - BLI_listbase_clear(&sa->spacedata); - BLI_listbase_clear(&sa->regionbase); - BLI_listbase_clear(&sa->actionzones); - BLI_listbase_clear(&sa->handlers); - - ED_area_data_copy(sa, saf, true); - } - - /* put at zero (needed?) */ - for (s1 = from->vertbase.first; s1; s1 = s1->next) - s1->newv = NULL; + ScrVert *s1, *s2; + ScrEdge *se; + ScrArea *sa, *saf; + + /* free contents of 'to', is from blenkernel screen.c */ + BKE_screen_free(to); + + to->flag = from->flag; + + BLI_duplicatelist(&to->vertbase, &from->vertbase); + BLI_duplicatelist(&to->edgebase, &from->edgebase); + BLI_duplicatelist(&to->areabase, &from->areabase); + BLI_listbase_clear(&to->regionbase); + + s2 = to->vertbase.first; + for (s1 = from->vertbase.first; s1; s1 = s1->next, s2 = s2->next) { + s1->newv = s2; + } + + for (se = to->edgebase.first; se; se = se->next) { + se->v1 = se->v1->newv; + se->v2 = se->v2->newv; + BKE_screen_sort_scrvert(&(se->v1), &(se->v2)); + } + + saf = from->areabase.first; + for (sa = to->areabase.first; sa; sa = sa->next, saf = saf->next) { + sa->v1 = sa->v1->newv; + sa->v2 = sa->v2->newv; + sa->v3 = sa->v3->newv; + sa->v4 = sa->v4->newv; + + BLI_listbase_clear(&sa->spacedata); + BLI_listbase_clear(&sa->regionbase); + BLI_listbase_clear(&sa->actionzones); + BLI_listbase_clear(&sa->handlers); + + ED_area_data_copy(sa, saf, true); + } + + /* put at zero (needed?) */ + for (s1 = from->vertbase.first; s1; s1 = s1->next) + s1->newv = NULL; } /** @@ -276,45 +278,45 @@ void screen_data_copy(bScreen *to, bScreen *from) */ void screen_new_activate_prepare(const wmWindow *win, bScreen *screen_new) { - screen_new->winid = win->winid; - screen_new->do_refresh = true; - screen_new->do_draw = true; + screen_new->winid = win->winid; + screen_new->do_refresh = true; + screen_new->do_draw = true; } - /* with sa as center, sb is located at: 0=W, 1=N, 2=E, 3=S */ /* -1 = not valid check */ /* used with join operator */ int area_getorientation(ScrArea *sa, ScrArea *sb) { - ScrVert *sav1, *sav2, *sav3, *sav4; - ScrVert *sbv1, *sbv2, *sbv3, *sbv4; - - if (sa == NULL || sb == NULL) return -1; - - sav1 = sa->v1; - sav2 = sa->v2; - sav3 = sa->v3; - sav4 = sa->v4; - sbv1 = sb->v1; - sbv2 = sb->v2; - sbv3 = sb->v3; - sbv4 = sb->v4; - - if (sav1 == sbv4 && sav2 == sbv3) { /* sa to right of sb = W */ - return 0; - } - else if (sav2 == sbv1 && sav3 == sbv4) { /* sa to bottom of sb = N */ - return 1; - } - else if (sav3 == sbv2 && sav4 == sbv1) { /* sa to left of sb = E */ - return 2; - } - else if (sav1 == sbv2 && sav4 == sbv3) { /* sa on top of sb = S*/ - return 3; - } - - return -1; + ScrVert *sav1, *sav2, *sav3, *sav4; + ScrVert *sbv1, *sbv2, *sbv3, *sbv4; + + if (sa == NULL || sb == NULL) + return -1; + + sav1 = sa->v1; + sav2 = sa->v2; + sav3 = sa->v3; + sav4 = sa->v4; + sbv1 = sb->v1; + sbv2 = sb->v2; + sbv3 = sb->v3; + sbv4 = sb->v4; + + if (sav1 == sbv4 && sav2 == sbv3) { /* sa to right of sb = W */ + return 0; + } + else if (sav2 == sbv1 && sav3 == sbv4) { /* sa to bottom of sb = N */ + return 1; + } + else if (sav3 == sbv2 && sav4 == sbv1) { /* sa to left of sb = E */ + return 2; + } + else if (sav1 == sbv2 && sav4 == sbv3) { /* sa on top of sb = S*/ + return 3; + } + + return -1; } /* Helper function to join 2 areas, it has a return value, 0=failed 1=success @@ -322,272 +324,273 @@ int area_getorientation(ScrArea *sa, ScrArea *sb) */ int screen_area_join(bContext *C, bScreen *scr, ScrArea *sa1, ScrArea *sa2) { - int dir; - - dir = area_getorientation(sa1, sa2); - /*printf("dir is : %i\n", dir);*/ - - if (dir == -1) { - return 0; - } - - if (dir == 0) { - sa1->v1 = sa2->v1; - sa1->v2 = sa2->v2; - screen_geom_edge_add(scr, sa1->v2, sa1->v3); - screen_geom_edge_add(scr, sa1->v1, sa1->v4); - } - else if (dir == 1) { - sa1->v2 = sa2->v2; - sa1->v3 = sa2->v3; - screen_geom_edge_add(scr, sa1->v1, sa1->v2); - screen_geom_edge_add(scr, sa1->v3, sa1->v4); - } - else if (dir == 2) { - sa1->v3 = sa2->v3; - sa1->v4 = sa2->v4; - screen_geom_edge_add(scr, sa1->v2, sa1->v3); - screen_geom_edge_add(scr, sa1->v1, sa1->v4); - } - else if (dir == 3) { - sa1->v1 = sa2->v1; - sa1->v4 = sa2->v4; - screen_geom_edge_add(scr, sa1->v1, sa1->v2); - screen_geom_edge_add(scr, sa1->v3, sa1->v4); - } - - screen_delarea(C, scr, sa2); - BKE_screen_remove_double_scrverts(scr); - /* Update preview thumbnail */ - BKE_icon_changed(scr->id.icon_id); - - return 1; + int dir; + + dir = area_getorientation(sa1, sa2); + /*printf("dir is : %i\n", dir);*/ + + if (dir == -1) { + return 0; + } + + if (dir == 0) { + sa1->v1 = sa2->v1; + sa1->v2 = sa2->v2; + screen_geom_edge_add(scr, sa1->v2, sa1->v3); + screen_geom_edge_add(scr, sa1->v1, sa1->v4); + } + else if (dir == 1) { + sa1->v2 = sa2->v2; + sa1->v3 = sa2->v3; + screen_geom_edge_add(scr, sa1->v1, sa1->v2); + screen_geom_edge_add(scr, sa1->v3, sa1->v4); + } + else if (dir == 2) { + sa1->v3 = sa2->v3; + sa1->v4 = sa2->v4; + screen_geom_edge_add(scr, sa1->v2, sa1->v3); + screen_geom_edge_add(scr, sa1->v1, sa1->v4); + } + else if (dir == 3) { + sa1->v1 = sa2->v1; + sa1->v4 = sa2->v4; + screen_geom_edge_add(scr, sa1->v1, sa1->v2); + screen_geom_edge_add(scr, sa1->v3, sa1->v4); + } + + screen_delarea(C, scr, sa2); + BKE_screen_remove_double_scrverts(scr); + /* Update preview thumbnail */ + BKE_icon_changed(scr->id.icon_id); + + return 1; } - /* ****************** EXPORTED API TO OTHER MODULES *************************** */ /* screen sets cursor based on active region */ static void region_cursor_set(wmWindow *win, bool swin_changed) { - bScreen *screen = WM_window_get_active_screen(win); - - ED_screen_areas_iter(win, screen, sa) { - for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar == screen->active_region) { - if (swin_changed || (ar->type && ar->type->event_cursor)) { - if (ar->gizmo_map != NULL) { - if (WM_gizmomap_cursor_set(ar->gizmo_map, win)) { - return; - } - } - ED_region_cursor_set(win, sa, ar); - } - return; - } - } - } + bScreen *screen = WM_window_get_active_screen(win); + + ED_screen_areas_iter(win, screen, sa) + { + for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar == screen->active_region) { + if (swin_changed || (ar->type && ar->type->event_cursor)) { + if (ar->gizmo_map != NULL) { + if (WM_gizmomap_cursor_set(ar->gizmo_map, win)) { + return; + } + } + ED_region_cursor_set(win, sa, ar); + } + return; + } + } + } } void ED_screen_do_listen(bContext *C, wmNotifier *note) { - wmWindow *win = CTX_wm_window(C); - bScreen *screen = CTX_wm_screen(C); - - /* generic notes */ - switch (note->category) { - case NC_WM: - if (note->data == ND_FILEREAD) - screen->do_draw = true; - break; - case NC_WINDOW: - screen->do_draw = true; - break; - case NC_SCREEN: - if (note->action == NA_EDITED) - screen->do_draw = screen->do_refresh = true; - break; - case NC_SCENE: - if (note->data == ND_MODE) - region_cursor_set(win, true); - break; - } + wmWindow *win = CTX_wm_window(C); + bScreen *screen = CTX_wm_screen(C); + + /* generic notes */ + switch (note->category) { + case NC_WM: + if (note->data == ND_FILEREAD) + screen->do_draw = true; + break; + case NC_WINDOW: + screen->do_draw = true; + break; + case NC_SCREEN: + if (note->action == NA_EDITED) + screen->do_draw = screen->do_refresh = true; + break; + case NC_SCENE: + if (note->data == ND_MODE) + region_cursor_set(win, true); + break; + } } /* helper call for below, dpi changes headers */ static void screen_refresh_headersizes(void) { - const ListBase *lb = BKE_spacetypes_list(); - SpaceType *st; - - for (st = lb->first; st; st = st->next) { - ARegionType *art; - art = BKE_regiontype_from_id(st, RGN_TYPE_HEADER); - if (art) art->prefsizey = ED_area_headersize(); - - art = BKE_regiontype_from_id(st, RGN_TYPE_FOOTER); - if (art) art->prefsizey = ED_area_headersize(); - } + const ListBase *lb = BKE_spacetypes_list(); + SpaceType *st; + + for (st = lb->first; st; st = st->next) { + ARegionType *art; + art = BKE_regiontype_from_id(st, RGN_TYPE_HEADER); + if (art) + art->prefsizey = ED_area_headersize(); + + art = BKE_regiontype_from_id(st, RGN_TYPE_FOOTER); + if (art) + art->prefsizey = ED_area_headersize(); + } } /* make this screen usable */ /* for file read and first use, for scaling window, area moves */ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win) { - bScreen *screen = WM_window_get_active_screen(win); - - /* exception for bg mode, we only need the screen context */ - if (!G.background) { - /* header size depends on DPI, let's verify */ - WM_window_set_dpi(win); - - ED_screen_global_areas_refresh(win); - screen_refresh_headersizes(); - - screen_geom_vertices_scale(win, screen); - - ED_screen_areas_iter(win, screen, area) { - /* set spacetype and region callbacks, calls init() */ - /* sets subwindows for regions, adds handlers */ - ED_area_initialize(wm, win, area); - } - - /* wake up animtimer */ - if (screen->animtimer) - WM_event_timer_sleep(wm, win, screen->animtimer, false); - } - - if (G.debug & G_DEBUG_EVENTS) { - printf("%s: set screen\n", __func__); - } - screen->do_refresh = false; - /* prevent multiwin errors */ - screen->winid = win->winid; - - screen->context = ed_screen_context; + bScreen *screen = WM_window_get_active_screen(win); + + /* exception for bg mode, we only need the screen context */ + if (!G.background) { + /* header size depends on DPI, let's verify */ + WM_window_set_dpi(win); + + ED_screen_global_areas_refresh(win); + screen_refresh_headersizes(); + + screen_geom_vertices_scale(win, screen); + + ED_screen_areas_iter(win, screen, area) + { + /* set spacetype and region callbacks, calls init() */ + /* sets subwindows for regions, adds handlers */ + ED_area_initialize(wm, win, area); + } + + /* wake up animtimer */ + if (screen->animtimer) + WM_event_timer_sleep(wm, win, screen->animtimer, false); + } + + if (G.debug & G_DEBUG_EVENTS) { + printf("%s: set screen\n", __func__); + } + screen->do_refresh = false; + /* prevent multiwin errors */ + screen->winid = win->winid; + + screen->context = ed_screen_context; } /* file read, set all screens, ... */ void ED_screens_initialize(Main *bmain, wmWindowManager *wm) { - wmWindow *win; - - for (win = wm->windows.first; win; win = win->next) { - if (BKE_workspace_active_get(win->workspace_hook) == NULL) { - BKE_workspace_active_set(win->workspace_hook, bmain->workspaces.first); - } - - ED_screen_refresh(wm, win); - if (win->eventstate) { - ED_screen_set_active_region(NULL, win, &win->eventstate->x); - } - } - - if (U.uiflag & USER_HEADER_FROM_PREF) { - for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { - BKE_screen_header_alignment_reset(screen); - } - } + wmWindow *win; + + for (win = wm->windows.first; win; win = win->next) { + if (BKE_workspace_active_get(win->workspace_hook) == NULL) { + BKE_workspace_active_set(win->workspace_hook, bmain->workspaces.first); + } + + ED_screen_refresh(wm, win); + if (win->eventstate) { + ED_screen_set_active_region(NULL, win, &win->eventstate->x); + } + } + + if (U.uiflag & USER_HEADER_FROM_PREF) { + for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { + BKE_screen_header_alignment_reset(screen); + } + } } void ED_screen_ensure_updated(wmWindowManager *wm, wmWindow *win, bScreen *screen) { - if (screen->do_refresh) { - ED_screen_refresh(wm, win); - } + if (screen->do_refresh) { + ED_screen_refresh(wm, win); + } } - /* *********** exit calls are for closing running stuff ******** */ void ED_region_exit(bContext *C, ARegion *ar) { - wmWindowManager *wm = CTX_wm_manager(C); - wmWindow *win = CTX_wm_window(C); - ARegion *prevar = CTX_wm_region(C); + wmWindowManager *wm = CTX_wm_manager(C); + wmWindow *win = CTX_wm_window(C); + ARegion *prevar = CTX_wm_region(C); - if (ar->type && ar->type->exit) - ar->type->exit(wm, ar); + if (ar->type && ar->type->exit) + ar->type->exit(wm, ar); - CTX_wm_region_set(C, ar); + CTX_wm_region_set(C, ar); - WM_event_remove_handlers(C, &ar->handlers); - WM_event_modal_handler_region_replace(win, ar, NULL); - WM_draw_region_free(ar); + WM_event_remove_handlers(C, &ar->handlers); + WM_event_modal_handler_region_replace(win, ar, NULL); + WM_draw_region_free(ar); - if (ar->headerstr) { - MEM_freeN(ar->headerstr); - ar->headerstr = NULL; - } + if (ar->headerstr) { + MEM_freeN(ar->headerstr); + ar->headerstr = NULL; + } - if (ar->regiontimer) { - WM_event_remove_timer(wm, win, ar->regiontimer); - ar->regiontimer = NULL; - } + if (ar->regiontimer) { + WM_event_remove_timer(wm, win, ar->regiontimer); + ar->regiontimer = NULL; + } - WM_msgbus_clear_by_owner(wm->message_bus, ar); + WM_msgbus_clear_by_owner(wm->message_bus, ar); - CTX_wm_region_set(C, prevar); + CTX_wm_region_set(C, prevar); } void ED_area_exit(bContext *C, ScrArea *sa) { - wmWindowManager *wm = CTX_wm_manager(C); - wmWindow *win = CTX_wm_window(C); - ScrArea *prevsa = CTX_wm_area(C); - ARegion *ar; + wmWindowManager *wm = CTX_wm_manager(C); + wmWindow *win = CTX_wm_window(C); + ScrArea *prevsa = CTX_wm_area(C); + ARegion *ar; - if (sa->type && sa->type->exit) - sa->type->exit(wm, sa); + if (sa->type && sa->type->exit) + sa->type->exit(wm, sa); - CTX_wm_area_set(C, sa); + CTX_wm_area_set(C, sa); - for (ar = sa->regionbase.first; ar; ar = ar->next) - ED_region_exit(C, ar); + for (ar = sa->regionbase.first; ar; ar = ar->next) + ED_region_exit(C, ar); - WM_event_remove_handlers(C, &sa->handlers); - WM_event_modal_handler_area_replace(win, sa, NULL); + WM_event_remove_handlers(C, &sa->handlers); + WM_event_modal_handler_area_replace(win, sa, NULL); - CTX_wm_area_set(C, prevsa); + CTX_wm_area_set(C, prevsa); } void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen) { - wmWindowManager *wm = CTX_wm_manager(C); - wmWindow *prevwin = CTX_wm_window(C); - - CTX_wm_window_set(C, window); - - if (screen->animtimer) - WM_event_remove_timer(wm, window, screen->animtimer); - screen->animtimer = NULL; - screen->scrubbing = false; - - screen->active_region = NULL; - - for (ARegion *ar = screen->regionbase.first; ar; ar = ar->next) { - ED_region_exit(C, ar); - } - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - ED_area_exit(C, sa); - } - /* Don't use ED_screen_areas_iter here, it skips hidden areas. */ - for (ScrArea *sa = window->global_areas.areabase.first; sa; sa = sa->next) { - ED_area_exit(C, sa); - } - - /* mark it available for use for other windows */ - screen->winid = 0; - - if (!WM_window_is_temp_screen(prevwin)) { - /* use previous window if possible */ - CTX_wm_window_set(C, prevwin); - } - else { - /* none otherwise */ - CTX_wm_window_set(C, NULL); - } - + wmWindowManager *wm = CTX_wm_manager(C); + wmWindow *prevwin = CTX_wm_window(C); + + CTX_wm_window_set(C, window); + + if (screen->animtimer) + WM_event_remove_timer(wm, window, screen->animtimer); + screen->animtimer = NULL; + screen->scrubbing = false; + + screen->active_region = NULL; + + for (ARegion *ar = screen->regionbase.first; ar; ar = ar->next) { + ED_region_exit(C, ar); + } + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + ED_area_exit(C, sa); + } + /* Don't use ED_screen_areas_iter here, it skips hidden areas. */ + for (ScrArea *sa = window->global_areas.areabase.first; sa; sa = sa->next) { + ED_area_exit(C, sa); + } + + /* mark it available for use for other windows */ + screen->winid = 0; + + if (!WM_window_is_temp_screen(prevwin)) { + /* use previous window if possible */ + CTX_wm_window_set(C, prevwin); + } + else { + /* none otherwise */ + CTX_wm_window_set(C, NULL); + } } /* *********************************** */ @@ -595,357 +598,364 @@ void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen) /* case when on area-edge or in azones, or outside window */ static void screen_cursor_set(wmWindow *win, const int xy[2]) { - const bScreen *screen = WM_window_get_active_screen(win); - AZone *az = NULL; - ScrArea *sa; - - for (sa = screen->areabase.first; sa; sa = sa->next) - if ((az = ED_area_actionzone_find_xy(sa, xy))) - break; - - if (sa) { - if (az->type == AZONE_AREA) - WM_cursor_set(win, CURSOR_EDIT); - else if (az->type == AZONE_REGION) { - if (az->edge == AE_LEFT_TO_TOPRIGHT || az->edge == AE_RIGHT_TO_TOPLEFT) - WM_cursor_set(win, CURSOR_X_MOVE); - else - WM_cursor_set(win, CURSOR_Y_MOVE); - } - } - else { - ScrEdge *actedge = screen_geom_find_active_scredge(win, screen, xy[0], xy[1]); - - if (actedge) { - if (screen_geom_edge_is_horizontal(actedge)) - WM_cursor_set(win, CURSOR_Y_MOVE); - else - WM_cursor_set(win, CURSOR_X_MOVE); - } - else - WM_cursor_set(win, CURSOR_STD); - } + const bScreen *screen = WM_window_get_active_screen(win); + AZone *az = NULL; + ScrArea *sa; + + for (sa = screen->areabase.first; sa; sa = sa->next) + if ((az = ED_area_actionzone_find_xy(sa, xy))) + break; + + if (sa) { + if (az->type == AZONE_AREA) + WM_cursor_set(win, CURSOR_EDIT); + else if (az->type == AZONE_REGION) { + if (az->edge == AE_LEFT_TO_TOPRIGHT || az->edge == AE_RIGHT_TO_TOPLEFT) + WM_cursor_set(win, CURSOR_X_MOVE); + else + WM_cursor_set(win, CURSOR_Y_MOVE); + } + } + else { + ScrEdge *actedge = screen_geom_find_active_scredge(win, screen, xy[0], xy[1]); + + if (actedge) { + if (screen_geom_edge_is_horizontal(actedge)) + WM_cursor_set(win, CURSOR_Y_MOVE); + else + WM_cursor_set(win, CURSOR_X_MOVE); + } + else + WM_cursor_set(win, CURSOR_STD); + } } - /* called in wm_event_system.c. sets state vars in screen, cursors */ /* event type is mouse move */ void ED_screen_set_active_region(bContext *C, wmWindow *win, const int xy[2]) { - bScreen *scr = WM_window_get_active_screen(win); - - if (scr) { - ScrArea *sa = NULL; - ARegion *ar; - ARegion *old_ar = scr->active_region; - - ED_screen_areas_iter(win, scr, area_iter) { - if (xy[0] > area_iter->totrct.xmin && xy[0] < area_iter->totrct.xmax) { - if (xy[1] > area_iter->totrct.ymin && xy[1] < area_iter->totrct.ymax) { - if (ED_area_azones_update(area_iter, xy) == NULL) { - sa = area_iter; - 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, xy)) { - scr->active_region = ar; - break; - } - } - } - else - scr->active_region = NULL; - - /* check for redraw headers */ - if (old_ar != scr->active_region) { - - ED_screen_areas_iter(win, scr, area_iter) { - bool do_draw = false; - - for (ar = area_iter->regionbase.first; ar; ar = ar->next) { - if (ar == old_ar || ar == scr->active_region) { - do_draw = true; - } - } - - if (do_draw) { - for (ar = area_iter->regionbase.first; ar; ar = ar->next) { - if (ar->regiontype == RGN_TYPE_HEADER) { - ED_region_tag_redraw_no_rebuild(ar); - } - } - } - } - } - - /* cursors, for time being set always on edges, otherwise aregion doesn't switch */ - if (scr->active_region == NULL) { - screen_cursor_set(win, xy); - } - else { - /* notifier invokes freeing the buttons... causing a bit too much redraws */ - if (old_ar != scr->active_region) { - region_cursor_set(win, true); - - /* this used to be a notifier, but needs to be done immediate - * because it can undo setting the right button as active due - * to delayed notifier handling */ - if (C) { - UI_screen_free_active_but(C, scr); - } - } - else - region_cursor_set(win, false); - } - } + bScreen *scr = WM_window_get_active_screen(win); + + if (scr) { + ScrArea *sa = NULL; + ARegion *ar; + ARegion *old_ar = scr->active_region; + + ED_screen_areas_iter(win, scr, area_iter) + { + if (xy[0] > area_iter->totrct.xmin && xy[0] < area_iter->totrct.xmax) { + if (xy[1] > area_iter->totrct.ymin && xy[1] < area_iter->totrct.ymax) { + if (ED_area_azones_update(area_iter, xy) == NULL) { + sa = area_iter; + 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, xy)) { + scr->active_region = ar; + break; + } + } + } + else + scr->active_region = NULL; + + /* check for redraw headers */ + if (old_ar != scr->active_region) { + + ED_screen_areas_iter(win, scr, area_iter) + { + bool do_draw = false; + + for (ar = area_iter->regionbase.first; ar; ar = ar->next) { + if (ar == old_ar || ar == scr->active_region) { + do_draw = true; + } + } + + if (do_draw) { + for (ar = area_iter->regionbase.first; ar; ar = ar->next) { + if (ar->regiontype == RGN_TYPE_HEADER) { + ED_region_tag_redraw_no_rebuild(ar); + } + } + } + } + } + + /* cursors, for time being set always on edges, otherwise aregion doesn't switch */ + if (scr->active_region == NULL) { + screen_cursor_set(win, xy); + } + else { + /* notifier invokes freeing the buttons... causing a bit too much redraws */ + if (old_ar != scr->active_region) { + region_cursor_set(win, true); + + /* this used to be a notifier, but needs to be done immediate + * because it can undo setting the right button as active due + * to delayed notifier handling */ + if (C) { + UI_screen_free_active_but(C, scr); + } + } + else + region_cursor_set(win, false); + } + } } int ED_screen_area_active(const bContext *C) { - wmWindow *win = CTX_wm_window(C); - bScreen *sc = CTX_wm_screen(C); - ScrArea *sa = CTX_wm_area(C); - - if (win && sc && sa) { - AZone *az = ED_area_actionzone_find_xy(sa, &win->eventstate->x); - ARegion *ar; - - if (az && az->type == AZONE_REGION) - return 1; - - for (ar = sa->regionbase.first; ar; ar = ar->next) - if (ar == sc->active_region) - return 1; - } - return 0; + wmWindow *win = CTX_wm_window(C); + bScreen *sc = CTX_wm_screen(C); + ScrArea *sa = CTX_wm_area(C); + + if (win && sc && sa) { + AZone *az = ED_area_actionzone_find_xy(sa, &win->eventstate->x); + ARegion *ar; + + if (az && az->type == AZONE_REGION) + return 1; + + for (ar = sa->regionbase.first; ar; ar = ar->next) + if (ar == sc->active_region) + return 1; + } + return 0; } /** * Add an area and geometry (screen-edges and -vertices) for it to \a area_map, * with coordinates/dimensions matching \a rect. */ -static ScrArea *screen_area_create_with_geometry( - ScrAreaMap *area_map, const rcti *rect, - short spacetype) +static ScrArea *screen_area_create_with_geometry(ScrAreaMap *area_map, + const rcti *rect, + short spacetype) { - ScrVert *bottom_left = screen_geom_vertex_add_ex(area_map, rect->xmin, rect->ymin); - ScrVert *top_left = screen_geom_vertex_add_ex(area_map, rect->xmin, rect->ymax); - ScrVert *top_right = screen_geom_vertex_add_ex(area_map, rect->xmax, rect->ymax); - ScrVert *bottom_right = screen_geom_vertex_add_ex(area_map, rect->xmax, rect->ymin); + ScrVert *bottom_left = screen_geom_vertex_add_ex(area_map, rect->xmin, rect->ymin); + ScrVert *top_left = screen_geom_vertex_add_ex(area_map, rect->xmin, rect->ymax); + ScrVert *top_right = screen_geom_vertex_add_ex(area_map, rect->xmax, rect->ymax); + ScrVert *bottom_right = screen_geom_vertex_add_ex(area_map, rect->xmax, rect->ymin); - screen_geom_edge_add_ex(area_map, bottom_left, top_left); - screen_geom_edge_add_ex(area_map, top_left, top_right); - screen_geom_edge_add_ex(area_map, top_right, bottom_right); - screen_geom_edge_add_ex(area_map, bottom_right, bottom_left); + screen_geom_edge_add_ex(area_map, bottom_left, top_left); + screen_geom_edge_add_ex(area_map, top_left, top_right); + screen_geom_edge_add_ex(area_map, top_right, bottom_right); + screen_geom_edge_add_ex(area_map, bottom_right, bottom_left); - return screen_addarea_ex(area_map, bottom_left, top_left, top_right, bottom_right, spacetype); + return screen_addarea_ex(area_map, bottom_left, top_left, top_right, bottom_right, spacetype); } static void screen_area_set_geometry_rect(ScrArea *sa, const rcti *rect) { - sa->v1->vec.x = rect->xmin; - sa->v1->vec.y = rect->ymin; - sa->v2->vec.x = rect->xmin; - sa->v2->vec.y = rect->ymax; - sa->v3->vec.x = rect->xmax; - sa->v3->vec.y = rect->ymax; - sa->v4->vec.x = rect->xmax; - sa->v4->vec.y = rect->ymin; + sa->v1->vec.x = rect->xmin; + sa->v1->vec.y = rect->ymin; + sa->v2->vec.x = rect->xmin; + sa->v2->vec.y = rect->ymax; + sa->v3->vec.x = rect->xmax; + sa->v3->vec.y = rect->ymax; + sa->v4->vec.x = rect->xmax; + sa->v4->vec.y = rect->ymin; } -static void screen_global_area_refresh( - wmWindow *win, bScreen *screen, - eSpace_Type space_type, GlobalAreaAlign align, const rcti *rect, - const short height_cur, const short height_min, const short height_max) +static void screen_global_area_refresh(wmWindow *win, + bScreen *screen, + eSpace_Type space_type, + GlobalAreaAlign align, + const rcti *rect, + const short height_cur, + const short height_min, + const short height_max) { - ScrArea *area; - - for (area = win->global_areas.areabase.first; area; area = area->next) { - if (area->spacetype == space_type) { - break; - } - } - - if (area) { - screen_area_set_geometry_rect(area, rect); - } - else { - area = screen_area_create_with_geometry(&win->global_areas, rect, space_type); - SpaceType *stype = BKE_spacetype_from_id(space_type); - SpaceLink *slink = stype->new(area, WM_window_get_active_scene(win)); - - area->regionbase = slink->regionbase; - - BLI_addhead(&area->spacedata, slink); - BLI_listbase_clear(&slink->regionbase); - - /* Data specific to global areas. */ - area->global = MEM_callocN(sizeof(*area->global), __func__); - area->global->size_max = height_max; - area->global->size_min = height_min; - area->global->align = align; - } - - if (area->global->cur_fixed_height != height_cur) { - /* Refresh layout if size changes. */ - area->global->cur_fixed_height = height_cur; - screen->do_refresh = true; - } + ScrArea *area; + + for (area = win->global_areas.areabase.first; area; area = area->next) { + if (area->spacetype == space_type) { + break; + } + } + + if (area) { + screen_area_set_geometry_rect(area, rect); + } + else { + area = screen_area_create_with_geometry(&win->global_areas, rect, space_type); + SpaceType *stype = BKE_spacetype_from_id(space_type); + SpaceLink *slink = stype->new (area, WM_window_get_active_scene(win)); + + area->regionbase = slink->regionbase; + + BLI_addhead(&area->spacedata, slink); + BLI_listbase_clear(&slink->regionbase); + + /* Data specific to global areas. */ + area->global = MEM_callocN(sizeof(*area->global), __func__); + area->global->size_max = height_max; + area->global->size_min = height_min; + area->global->align = align; + } + + if (area->global->cur_fixed_height != height_cur) { + /* Refresh layout if size changes. */ + area->global->cur_fixed_height = height_cur; + screen->do_refresh = true; + } } static int screen_global_header_size(void) { - return (int)ceilf(ED_area_headersize() / UI_DPI_FAC); + return (int)ceilf(ED_area_headersize() / UI_DPI_FAC); } static void screen_global_topbar_area_refresh(wmWindow *win, bScreen *screen) { - const short size_min = screen_global_header_size(); - const short size_max = 2.25 * screen_global_header_size(); - const short size = (screen->flag & SCREEN_COLLAPSE_TOPBAR) ? size_min : size_max; - rcti rect; + const short size_min = screen_global_header_size(); + const short size_max = 2.25 * screen_global_header_size(); + const short size = (screen->flag & SCREEN_COLLAPSE_TOPBAR) ? size_min : size_max; + rcti rect; - BLI_rcti_init(&rect, 0, WM_window_pixels_x(win) - 1, 0, WM_window_pixels_y(win) - 1); - rect.ymin = rect.ymax - size_max; + BLI_rcti_init(&rect, 0, WM_window_pixels_x(win) - 1, 0, WM_window_pixels_y(win) - 1); + rect.ymin = rect.ymax - size_max; - screen_global_area_refresh(win, screen, SPACE_TOPBAR, GLOBAL_AREA_ALIGN_TOP, &rect, size, size_min, size_max); + screen_global_area_refresh( + win, screen, SPACE_TOPBAR, GLOBAL_AREA_ALIGN_TOP, &rect, size, size_min, size_max); } static void screen_global_statusbar_area_refresh(wmWindow *win, bScreen *screen) { - const short size_min = 1; - const short size_max = 0.8f * screen_global_header_size(); - const short size = (screen->flag & SCREEN_COLLAPSE_STATUSBAR) ? size_min : size_max; - rcti rect; + const short size_min = 1; + const short size_max = 0.8f * screen_global_header_size(); + const short size = (screen->flag & SCREEN_COLLAPSE_STATUSBAR) ? size_min : size_max; + rcti rect; - BLI_rcti_init(&rect, 0, WM_window_pixels_x(win) - 1, 0, WM_window_pixels_y(win) - 1); - rect.ymax = rect.ymin + size_max; + BLI_rcti_init(&rect, 0, WM_window_pixels_x(win) - 1, 0, WM_window_pixels_y(win) - 1); + rect.ymax = rect.ymin + size_max; - screen_global_area_refresh(win, screen, SPACE_STATUSBAR, GLOBAL_AREA_ALIGN_BOTTOM, &rect, size, size_min, size_max); + screen_global_area_refresh( + win, screen, SPACE_STATUSBAR, GLOBAL_AREA_ALIGN_BOTTOM, &rect, size, size_min, size_max); } void ED_screen_global_areas_sync(wmWindow *win) { - /* Update screen flags from height in window, this is weak and perhaps - * global areas should just become part of the screen instead. */ - bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook); - - screen->flag &= ~(SCREEN_COLLAPSE_STATUSBAR | SCREEN_COLLAPSE_TOPBAR); - - for (ScrArea *area = win->global_areas.areabase.first; area; area = area->next) { - if (area->global->cur_fixed_height == area->global->size_min) { - if (area->spacetype == SPACE_TOPBAR) { - screen->flag |= SCREEN_COLLAPSE_TOPBAR; - } - else if (area->spacetype == SPACE_STATUSBAR) { - screen->flag |= SCREEN_COLLAPSE_STATUSBAR; - } - } - } + /* Update screen flags from height in window, this is weak and perhaps + * global areas should just become part of the screen instead. */ + bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook); + + screen->flag &= ~(SCREEN_COLLAPSE_STATUSBAR | SCREEN_COLLAPSE_TOPBAR); + + for (ScrArea *area = win->global_areas.areabase.first; area; area = area->next) { + if (area->global->cur_fixed_height == area->global->size_min) { + if (area->spacetype == SPACE_TOPBAR) { + screen->flag |= SCREEN_COLLAPSE_TOPBAR; + } + else if (area->spacetype == SPACE_STATUSBAR) { + screen->flag |= SCREEN_COLLAPSE_STATUSBAR; + } + } + } } void ED_screen_global_areas_refresh(wmWindow *win) { - /* Don't create global area for child and temporary windows. */ - bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook); - if ((win->parent != NULL) || screen->temp) { - if (win->global_areas.areabase.first) { - screen->do_refresh = true; - BKE_screen_area_map_free(&win->global_areas); - } - return; - } - - screen_global_topbar_area_refresh(win, screen); - screen_global_statusbar_area_refresh(win, screen); + /* Don't create global area for child and temporary windows. */ + bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook); + if ((win->parent != NULL) || screen->temp) { + if (win->global_areas.areabase.first) { + screen->do_refresh = true; + BKE_screen_area_map_free(&win->global_areas); + } + return; + } + + screen_global_topbar_area_refresh(win, screen); + screen_global_statusbar_area_refresh(win, screen); } - /* -------------------------------------------------------------------- */ /* Screen changing */ static bScreen *screen_fullscreen_find_associated_normal_screen(const Main *bmain, bScreen *screen) { - for (bScreen *screen_iter = bmain->screens.first; screen_iter; screen_iter = screen_iter->id.next) { - ScrArea *sa = screen_iter->areabase.first; - if (sa && sa->full == screen) { - return screen_iter; - } - } - - return screen; + for (bScreen *screen_iter = bmain->screens.first; screen_iter; + screen_iter = screen_iter->id.next) { + ScrArea *sa = screen_iter->areabase.first; + if (sa && sa->full == screen) { + return screen_iter; + } + } + + return screen; } /** * \return the screen to activate. * \warning The returned screen may not always equal \a screen_new! */ -bScreen *screen_change_prepare(bScreen *screen_old, bScreen *screen_new, Main *bmain, bContext *C, wmWindow *win) +bScreen *screen_change_prepare( + bScreen *screen_old, bScreen *screen_new, Main *bmain, bContext *C, wmWindow *win) { - /* validate screen, it's called with notifier reference */ - if (BLI_findindex(&bmain->screens, screen_new) == -1) { - return NULL; - } - - if (ELEM(screen_new->state, SCREENMAXIMIZED, SCREENFULL)) { - screen_new = screen_fullscreen_find_associated_normal_screen(bmain, screen_new); - } - - /* check for valid winid */ - if (!(screen_new->winid == 0 || screen_new->winid == win->winid)) { - return NULL; - } - - if (screen_old != screen_new) { - wmTimer *wt = screen_old->animtimer; - - /* remove handlers referencing areas in old screen */ - for (ScrArea *sa = screen_old->areabase.first; sa; sa = sa->next) { - WM_event_remove_area_handler(&win->modalhandlers, sa); - } - - /* we put timer to sleep, so screen_exit has to think there's no timer */ - screen_old->animtimer = NULL; - if (wt) { - WM_event_timer_sleep(CTX_wm_manager(C), win, wt, true); - } - ED_screen_exit(C, win, screen_old); - - /* Same scene, "transfer" playback to new screen. */ - if (wt) { - screen_new->animtimer = wt; - } - - return screen_new; - } - - return NULL; + /* validate screen, it's called with notifier reference */ + if (BLI_findindex(&bmain->screens, screen_new) == -1) { + return NULL; + } + + if (ELEM(screen_new->state, SCREENMAXIMIZED, SCREENFULL)) { + screen_new = screen_fullscreen_find_associated_normal_screen(bmain, screen_new); + } + + /* check for valid winid */ + if (!(screen_new->winid == 0 || screen_new->winid == win->winid)) { + return NULL; + } + + if (screen_old != screen_new) { + wmTimer *wt = screen_old->animtimer; + + /* remove handlers referencing areas in old screen */ + for (ScrArea *sa = screen_old->areabase.first; sa; sa = sa->next) { + WM_event_remove_area_handler(&win->modalhandlers, sa); + } + + /* we put timer to sleep, so screen_exit has to think there's no timer */ + screen_old->animtimer = NULL; + if (wt) { + WM_event_timer_sleep(CTX_wm_manager(C), win, wt, true); + } + ED_screen_exit(C, win, screen_old); + + /* Same scene, "transfer" playback to new screen. */ + if (wt) { + screen_new->animtimer = wt; + } + + return screen_new; + } + + return NULL; } void screen_change_update(bContext *C, wmWindow *win, bScreen *sc) { - Scene *scene = WM_window_get_active_scene(win); - WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook); - WorkSpaceLayout *layout = BKE_workspace_layout_find(workspace, sc); + Scene *scene = WM_window_get_active_scene(win); + WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook); + WorkSpaceLayout *layout = BKE_workspace_layout_find(workspace, sc); - CTX_wm_window_set(C, win); /* stores C->wm.screen... hrmf */ + CTX_wm_window_set(C, win); /* stores C->wm.screen... hrmf */ - ED_screen_refresh(CTX_wm_manager(C), win); + ED_screen_refresh(CTX_wm_manager(C), win); - BKE_screen_view3d_scene_sync(sc, scene); /* sync new screen with scene data */ - WM_event_add_notifier(C, NC_WINDOW, NULL); - WM_event_add_notifier(C, NC_SCREEN | ND_LAYOUTSET, layout); + BKE_screen_view3d_scene_sync(sc, scene); /* sync new screen with scene data */ + WM_event_add_notifier(C, NC_WINDOW, NULL); + WM_event_add_notifier(C, NC_SCREEN | ND_LAYOUTSET, layout); - /* makes button hilites work */ - WM_event_add_mousemove(C); + /* makes button hilites work */ + WM_event_add_mousemove(C); } - /** * \brief Change the active screen. * @@ -956,117 +966,117 @@ void screen_change_update(bContext *C, wmWindow *win, bScreen *sc) */ bool ED_screen_change(bContext *C, bScreen *sc) { - Main *bmain = CTX_data_main(C); - wmWindow *win = CTX_wm_window(C); - bScreen *screen_old = CTX_wm_screen(C); - bScreen *screen_new = screen_change_prepare(screen_old, sc, bmain, C, win); + Main *bmain = CTX_data_main(C); + wmWindow *win = CTX_wm_window(C); + bScreen *screen_old = CTX_wm_screen(C); + bScreen *screen_new = screen_change_prepare(screen_old, sc, bmain, C, win); - if (screen_new) { - WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook); - WM_window_set_active_screen(win, workspace, sc); - screen_change_update(C, win, screen_new); + if (screen_new) { + WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook); + WM_window_set_active_screen(win, workspace, sc); + screen_change_update(C, win, screen_new); - return true; - } + return true; + } - return false; + return false; } static void screen_set_3dview_camera(Scene *scene, ViewLayer *view_layer, ScrArea *sa, View3D *v3d) { - /* fix any cameras that are used in the 3d view but not in the scene */ - BKE_screen_view3d_sync(v3d, scene); - - if (!v3d->camera || !BKE_view_layer_base_find(view_layer, v3d->camera)) { - v3d->camera = BKE_view_layer_camera_find(view_layer); - // XXX if (sc == curscreen) handle_view3d_lock(); - if (!v3d->camera) { - ARegion *ar; - ListBase *regionbase; - - /* regionbase is in different place depending if space is active */ - if (v3d == sa->spacedata.first) - regionbase = &sa->regionbase; - else - regionbase = &v3d->regionbase; - - for (ar = regionbase->first; ar; ar = ar->next) { - if (ar->regiontype == RGN_TYPE_WINDOW) { - RegionView3D *rv3d = ar->regiondata; - if (rv3d->persp == RV3D_CAMOB) { - rv3d->persp = RV3D_PERSP; - } - } - } - } - } + /* fix any cameras that are used in the 3d view but not in the scene */ + BKE_screen_view3d_sync(v3d, scene); + + if (!v3d->camera || !BKE_view_layer_base_find(view_layer, v3d->camera)) { + v3d->camera = BKE_view_layer_camera_find(view_layer); + // XXX if (sc == curscreen) handle_view3d_lock(); + if (!v3d->camera) { + ARegion *ar; + ListBase *regionbase; + + /* regionbase is in different place depending if space is active */ + if (v3d == sa->spacedata.first) + regionbase = &sa->regionbase; + else + regionbase = &v3d->regionbase; + + for (ar = regionbase->first; ar; ar = ar->next) { + if (ar->regiontype == RGN_TYPE_WINDOW) { + RegionView3D *rv3d = ar->regiondata; + if (rv3d->persp == RV3D_CAMOB) { + rv3d->persp = RV3D_PERSP; + } + } + } + } + } } void ED_screen_scene_change(bContext *C, wmWindow *win, Scene *scene) { #if 0 - ViewLayer *view_layer_old = WM_window_get_active_view_layer(win); + ViewLayer *view_layer_old = WM_window_get_active_view_layer(win); #endif - /* Switch scene. */ - win->scene = scene; - if (CTX_wm_window(C) == win) { - CTX_data_scene_set(C, scene); - } + /* Switch scene. */ + win->scene = scene; + if (CTX_wm_window(C) == win) { + CTX_data_scene_set(C, scene); + } - /* Ensure the view layer name is updated. */ - WM_window_ensure_active_view_layer(win); - ViewLayer *view_layer = WM_window_get_active_view_layer(win); + /* Ensure the view layer name is updated. */ + WM_window_ensure_active_view_layer(win); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); #if 0 - /* Mode Syncing. */ - if (view_layer_old) { - WorkSpace *workspace = CTX_wm_workspace(C); - Object *obact_new = OBACT(view_layer); - UNUSED_VARS(obact_new); - eObjectMode object_mode_old = workspace->object_mode; - Object *obact_old = OBACT(view_layer_old); - UNUSED_VARS(obact_old, object_mode_old); - } + /* Mode Syncing. */ + if (view_layer_old) { + WorkSpace *workspace = CTX_wm_workspace(C); + Object *obact_new = OBACT(view_layer); + UNUSED_VARS(obact_new); + eObjectMode object_mode_old = workspace->object_mode; + Object *obact_old = OBACT(view_layer_old); + UNUSED_VARS(obact_old, object_mode_old); + } #endif - /* Update 3D view cameras. */ - const bScreen *screen = WM_window_get_active_screen(win); - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { - if (sl->spacetype == SPACE_VIEW3D) { - View3D *v3d = (View3D *)sl; - screen_set_3dview_camera(scene, view_layer, sa, v3d); - } - } - } + /* Update 3D view cameras. */ + const bScreen *screen = WM_window_get_active_screen(win); + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + screen_set_3dview_camera(scene, view_layer, sa, v3d); + } + } + } } ScrArea *ED_screen_full_newspace(bContext *C, ScrArea *sa, int type) { - wmWindow *win = CTX_wm_window(C); - ScrArea *newsa = NULL; + wmWindow *win = CTX_wm_window(C); + ScrArea *newsa = NULL; - if (!sa || sa->full == NULL) { - newsa = ED_screen_state_toggle(C, win, sa, SCREENMAXIMIZED); - } + if (!sa || sa->full == NULL) { + newsa = ED_screen_state_toggle(C, win, sa, SCREENMAXIMIZED); + } - if (!newsa) { - newsa = sa; - } + if (!newsa) { + newsa = sa; + } - BLI_assert(newsa); + BLI_assert(newsa); - if (sa && (sa->spacetype != type)) { - newsa->flag |= AREA_FLAG_TEMP_TYPE; - } - else { - newsa->flag &= ~AREA_FLAG_TEMP_TYPE; - } + if (sa && (sa->spacetype != type)) { + newsa->flag |= AREA_FLAG_TEMP_TYPE; + } + else { + newsa->flag &= ~AREA_FLAG_TEMP_TYPE; + } - ED_area_newspace(C, newsa, type, (newsa->flag & AREA_FLAG_TEMP_TYPE)); + ED_area_newspace(C, newsa, type, (newsa->flag & AREA_FLAG_TEMP_TYPE)); - return newsa; + return newsa; } /** @@ -1074,57 +1084,57 @@ ScrArea *ED_screen_full_newspace(bContext *C, ScrArea *sa, int type) */ void ED_screen_full_prevspace(bContext *C, ScrArea *sa) { - BLI_assert(sa->full); - - if (sa->flag & AREA_FLAG_STACKED_FULLSCREEN) { - /* stacked fullscreen -> only go back to previous screen and don't toggle out of fullscreen */ - ED_area_prevspace(C, sa); - } - else { - ED_screen_restore_temp_type(C, sa); - } + BLI_assert(sa->full); + + if (sa->flag & AREA_FLAG_STACKED_FULLSCREEN) { + /* stacked fullscreen -> only go back to previous screen and don't toggle out of fullscreen */ + ED_area_prevspace(C, sa); + } + else { + ED_screen_restore_temp_type(C, sa); + } } void ED_screen_restore_temp_type(bContext *C, ScrArea *sa) { - /* incase nether functions below run */ - ED_area_tag_redraw(sa); - - if (sa->flag & AREA_FLAG_TEMP_TYPE) { - ED_area_prevspace(C, sa); - /* Flag should be cleared now. */ - BLI_assert((sa->flag & AREA_FLAG_TEMP_TYPE) == 0); - } - - if (sa->full) { - ED_screen_state_toggle(C, CTX_wm_window(C), sa, SCREENMAXIMIZED); - } + /* incase nether functions below run */ + ED_area_tag_redraw(sa); + + if (sa->flag & AREA_FLAG_TEMP_TYPE) { + ED_area_prevspace(C, sa); + /* Flag should be cleared now. */ + BLI_assert((sa->flag & AREA_FLAG_TEMP_TYPE) == 0); + } + + if (sa->full) { + ED_screen_state_toggle(C, CTX_wm_window(C), sa, SCREENMAXIMIZED); + } } /* restore a screen / area back to default operation, after temp fullscreen modes */ void ED_screen_full_restore(bContext *C, ScrArea *sa) { - wmWindow *win = CTX_wm_window(C); - SpaceLink *sl = sa->spacedata.first; - bScreen *screen = CTX_wm_screen(C); - short state = (screen ? screen->state : SCREENMAXIMIZED); - - /* if fullscreen area has a temporary space (such as a file browser or fullscreen render - * overlaid on top of an existing setup) then return to the previous space */ - - if (sl->next) { - if (sa->flag & AREA_FLAG_TEMP_TYPE) { - ED_screen_full_prevspace(C, sa); - } - else { - ED_screen_state_toggle(C, win, sa, state); - } - /* warning: 'sa' may be freed */ - } - /* otherwise just tile the area again */ - else { - ED_screen_state_toggle(C, win, sa, state); - } + wmWindow *win = CTX_wm_window(C); + SpaceLink *sl = sa->spacedata.first; + bScreen *screen = CTX_wm_screen(C); + short state = (screen ? screen->state : SCREENMAXIMIZED); + + /* if fullscreen area has a temporary space (such as a file browser or fullscreen render + * overlaid on top of an existing setup) then return to the previous space */ + + if (sl->next) { + if (sa->flag & AREA_FLAG_TEMP_TYPE) { + ED_screen_full_prevspace(C, sa); + } + else { + ED_screen_state_toggle(C, win, sa, state); + } + /* warning: 'sa' may be freed */ + } + /* otherwise just tile the area again */ + else { + ED_screen_state_toggle(C, win, sa, state); + } } /** @@ -1134,180 +1144,186 @@ void ED_screen_full_restore(bContext *C, ScrArea *sa) */ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const short state) { - Main *bmain = CTX_data_main(C); - wmWindowManager *wm = CTX_wm_manager(C); - WorkSpace *workspace = WM_window_get_active_workspace(win); - bScreen *sc, *oldscreen; - ARegion *ar; - - if (sa) { - /* ensure we don't have a button active anymore, can crash when - * switching screens with tooltip open because region and tooltip - * are no longer in the same screen */ - for (ar = sa->regionbase.first; ar; ar = ar->next) { - UI_blocklist_free(C, &ar->uiblocks); - - if (ar->regiontimer) { - WM_event_remove_timer(wm, NULL, ar->regiontimer); - ar->regiontimer = NULL; - } - } - - /* prevent hanging status prints */ - ED_area_status_text(sa, NULL); - ED_workspace_status_text(C, NULL); - } - - if (sa && sa->full) { - WorkSpaceLayout *layout_old = WM_window_get_active_layout(win); - /* restoring back to SCREENNORMAL */ - sc = sa->full; /* the old screen to restore */ - oldscreen = WM_window_get_active_screen(win); /* the one disappearing */ - - BLI_assert(BKE_workspace_layout_screen_get(layout_old) != sc); - BLI_assert(BKE_workspace_layout_screen_get(layout_old)->state != SCREENNORMAL); - - sc->state = SCREENNORMAL; - sc->flag = oldscreen->flag; - - /* find old area to restore from */ - ScrArea *fullsa = NULL; - for (ScrArea *old = sc->areabase.first; old; old = old->next) { - /* area to restore from is always first */ - if (old->full && !fullsa) { - fullsa = old; - } - - /* clear full screen state */ - old->full = NULL; - } - - sa->full = NULL; - - if (fullsa == NULL) { - if (G.debug & G_DEBUG) - printf("%s: something wrong in areafullscreen\n", __func__); - return NULL; - } - - if (state == SCREENFULL) { - /* unhide global areas */ - for (ScrArea *glob_area = win->global_areas.areabase.first; glob_area; glob_area = glob_area->next) { - glob_area->global->flag &= ~GLOBAL_AREA_IS_HIDDEN; - } - /* restore the old side panels/header visibility */ - for (ar = sa->regionbase.first; ar; ar = ar->next) { - ar->flag = ar->flagfullscreen; - } - } - - ED_area_data_swap(fullsa, sa); - - /* animtimer back */ - sc->animtimer = oldscreen->animtimer; - oldscreen->animtimer = NULL; - - ED_screen_change(C, sc); - - BKE_workspace_layout_remove(CTX_data_main(C), workspace, layout_old); - - /* After we've restored back to SCREENNORMAL, we have to wait with - * screen handling as it uses the area coords which aren't updated yet. - * Without doing so, the screen handling gets wrong area coords, - * which in worst case can lead to crashes (see T43139) */ - sc->skip_handling = true; - } - else { - /* change from SCREENNORMAL to new state */ - WorkSpaceLayout *layout_new; - ScrArea *newa; - char newname[MAX_ID_NAME - 2]; - - BLI_assert(ELEM(state, SCREENMAXIMIZED, SCREENFULL)); - - oldscreen = WM_window_get_active_screen(win); - - oldscreen->state = state; - BLI_snprintf(newname, sizeof(newname), "%s-%s", oldscreen->id.name + 2, "nonnormal"); - - layout_new = ED_workspace_layout_add(bmain, workspace, win, newname); - - sc = BKE_workspace_layout_screen_get(layout_new); - sc->state = state; - sc->redraws_flag = oldscreen->redraws_flag; - sc->temp = oldscreen->temp; - sc->flag = oldscreen->flag; - - /* timer */ - sc->animtimer = oldscreen->animtimer; - oldscreen->animtimer = NULL; - - /* use random area when we have no active one, e.g. when the - * mouse is outside of the window and we open a file browser */ - if (!sa || sa->global) { - sa = oldscreen->areabase.first; - } - - newa = (ScrArea *)sc->areabase.first; - - /* copy area */ - ED_area_data_swap(newa, sa); - newa->flag = sa->flag; /* mostly for AREA_FLAG_WASFULLSCREEN */ - - if (state == SCREENFULL) { - /* temporarily hide global areas */ - for (ScrArea *glob_area = win->global_areas.areabase.first; glob_area; glob_area = glob_area->next) { - glob_area->global->flag |= GLOBAL_AREA_IS_HIDDEN; - } - /* temporarily hide the side panels/header */ - for (ar = newa->regionbase.first; ar; ar = ar->next) { - ar->flagfullscreen = ar->flag; - - if (ELEM(ar->regiontype, - RGN_TYPE_UI, RGN_TYPE_HEADER, RGN_TYPE_FOOTER, - RGN_TYPE_TOOLS, RGN_TYPE_NAV_BAR, RGN_TYPE_EXECUTE)) - { - ar->flag |= RGN_FLAG_HIDDEN; - } - } - } - - sa->full = oldscreen; - newa->full = oldscreen; - - ED_screen_change(C, sc); - } - - /* XXX bad code: setscreen() ends with first area active. fullscreen render assumes this too */ - CTX_wm_area_set(C, sc->areabase.first); - - return sc->areabase.first; + Main *bmain = CTX_data_main(C); + wmWindowManager *wm = CTX_wm_manager(C); + WorkSpace *workspace = WM_window_get_active_workspace(win); + bScreen *sc, *oldscreen; + ARegion *ar; + + if (sa) { + /* ensure we don't have a button active anymore, can crash when + * switching screens with tooltip open because region and tooltip + * are no longer in the same screen */ + for (ar = sa->regionbase.first; ar; ar = ar->next) { + UI_blocklist_free(C, &ar->uiblocks); + + if (ar->regiontimer) { + WM_event_remove_timer(wm, NULL, ar->regiontimer); + ar->regiontimer = NULL; + } + } + + /* prevent hanging status prints */ + ED_area_status_text(sa, NULL); + ED_workspace_status_text(C, NULL); + } + + if (sa && sa->full) { + WorkSpaceLayout *layout_old = WM_window_get_active_layout(win); + /* restoring back to SCREENNORMAL */ + sc = sa->full; /* the old screen to restore */ + oldscreen = WM_window_get_active_screen(win); /* the one disappearing */ + + BLI_assert(BKE_workspace_layout_screen_get(layout_old) != sc); + BLI_assert(BKE_workspace_layout_screen_get(layout_old)->state != SCREENNORMAL); + + sc->state = SCREENNORMAL; + sc->flag = oldscreen->flag; + + /* find old area to restore from */ + ScrArea *fullsa = NULL; + for (ScrArea *old = sc->areabase.first; old; old = old->next) { + /* area to restore from is always first */ + if (old->full && !fullsa) { + fullsa = old; + } + + /* clear full screen state */ + old->full = NULL; + } + + sa->full = NULL; + + if (fullsa == NULL) { + if (G.debug & G_DEBUG) + printf("%s: something wrong in areafullscreen\n", __func__); + return NULL; + } + + if (state == SCREENFULL) { + /* unhide global areas */ + for (ScrArea *glob_area = win->global_areas.areabase.first; glob_area; + glob_area = glob_area->next) { + glob_area->global->flag &= ~GLOBAL_AREA_IS_HIDDEN; + } + /* restore the old side panels/header visibility */ + for (ar = sa->regionbase.first; ar; ar = ar->next) { + ar->flag = ar->flagfullscreen; + } + } + + ED_area_data_swap(fullsa, sa); + + /* animtimer back */ + sc->animtimer = oldscreen->animtimer; + oldscreen->animtimer = NULL; + + ED_screen_change(C, sc); + + BKE_workspace_layout_remove(CTX_data_main(C), workspace, layout_old); + + /* After we've restored back to SCREENNORMAL, we have to wait with + * screen handling as it uses the area coords which aren't updated yet. + * Without doing so, the screen handling gets wrong area coords, + * which in worst case can lead to crashes (see T43139) */ + sc->skip_handling = true; + } + else { + /* change from SCREENNORMAL to new state */ + WorkSpaceLayout *layout_new; + ScrArea *newa; + char newname[MAX_ID_NAME - 2]; + + BLI_assert(ELEM(state, SCREENMAXIMIZED, SCREENFULL)); + + oldscreen = WM_window_get_active_screen(win); + + oldscreen->state = state; + BLI_snprintf(newname, sizeof(newname), "%s-%s", oldscreen->id.name + 2, "nonnormal"); + + layout_new = ED_workspace_layout_add(bmain, workspace, win, newname); + + sc = BKE_workspace_layout_screen_get(layout_new); + sc->state = state; + sc->redraws_flag = oldscreen->redraws_flag; + sc->temp = oldscreen->temp; + sc->flag = oldscreen->flag; + + /* timer */ + sc->animtimer = oldscreen->animtimer; + oldscreen->animtimer = NULL; + + /* use random area when we have no active one, e.g. when the + * mouse is outside of the window and we open a file browser */ + if (!sa || sa->global) { + sa = oldscreen->areabase.first; + } + + newa = (ScrArea *)sc->areabase.first; + + /* copy area */ + ED_area_data_swap(newa, sa); + newa->flag = sa->flag; /* mostly for AREA_FLAG_WASFULLSCREEN */ + + if (state == SCREENFULL) { + /* temporarily hide global areas */ + for (ScrArea *glob_area = win->global_areas.areabase.first; glob_area; + glob_area = glob_area->next) { + glob_area->global->flag |= GLOBAL_AREA_IS_HIDDEN; + } + /* temporarily hide the side panels/header */ + for (ar = newa->regionbase.first; ar; ar = ar->next) { + ar->flagfullscreen = ar->flag; + + if (ELEM(ar->regiontype, + RGN_TYPE_UI, + RGN_TYPE_HEADER, + RGN_TYPE_FOOTER, + RGN_TYPE_TOOLS, + RGN_TYPE_NAV_BAR, + RGN_TYPE_EXECUTE)) { + ar->flag |= RGN_FLAG_HIDDEN; + } + } + } + + sa->full = oldscreen; + newa->full = oldscreen; + + ED_screen_change(C, sc); + } + + /* XXX bad code: setscreen() ends with first area active. fullscreen render assumes this too */ + CTX_wm_area_set(C, sc->areabase.first); + + return sc->areabase.first; } /* update frame rate info for viewport drawing */ void ED_refresh_viewport_fps(bContext *C) { - wmTimer *animtimer = CTX_wm_screen(C)->animtimer; - Scene *scene = CTX_data_scene(C); - - /* is anim playback running? */ - if (animtimer && (U.uiflag & USER_SHOW_FPS)) { - ScreenFrameRateInfo *fpsi = scene->fps_info; - - /* if there isn't any info, init it first */ - if (fpsi == NULL) - fpsi = scene->fps_info = MEM_callocN(sizeof(ScreenFrameRateInfo), "refresh_viewport_fps fps_info"); - - /* update the values */ - fpsi->redrawtime = fpsi->lredrawtime; - fpsi->lredrawtime = animtimer->ltime; - } - else { - /* playback stopped or shouldn't be running */ - if (scene->fps_info) - MEM_freeN(scene->fps_info); - scene->fps_info = NULL; - } + wmTimer *animtimer = CTX_wm_screen(C)->animtimer; + Scene *scene = CTX_data_scene(C); + + /* is anim playback running? */ + if (animtimer && (U.uiflag & USER_SHOW_FPS)) { + ScreenFrameRateInfo *fpsi = scene->fps_info; + + /* if there isn't any info, init it first */ + if (fpsi == NULL) + fpsi = scene->fps_info = MEM_callocN(sizeof(ScreenFrameRateInfo), + "refresh_viewport_fps fps_info"); + + /* update the values */ + fpsi->redrawtime = fpsi->lredrawtime; + fpsi->lredrawtime = animtimer->ltime; + } + else { + /* playback stopped or shouldn't be running */ + if (scene->fps_info) + MEM_freeN(scene->fps_info); + scene->fps_info = NULL; + } } /* redraws: uses defines from stime->redraws @@ -1315,138 +1331,136 @@ void ED_refresh_viewport_fps(bContext *C) */ void ED_screen_animation_timer(bContext *C, int redraws, int refresh, int sync, int enable) { - bScreen *screen = CTX_wm_screen(C); - wmWindowManager *wm = CTX_wm_manager(C); - wmWindow *win = CTX_wm_window(C); - Scene *scene = CTX_data_scene(C); - bScreen *stopscreen = ED_screen_animation_playing(wm); - - if (stopscreen) { - WM_event_remove_timer(wm, win, stopscreen->animtimer); - stopscreen->animtimer = NULL; - } - - if (enable) { - ScreenAnimData *sad = MEM_callocN(sizeof(ScreenAnimData), "ScreenAnimData"); - - screen->animtimer = WM_event_add_timer(wm, win, TIMER0, (1.0 / FPS)); - - sad->ar = CTX_wm_region(C); - /* if startframe is larger than current frame, we put currentframe on startframe. - * note: first frame then is not drawn! (ton) */ - if (PRVRANGEON) { - if (scene->r.psfra > scene->r.cfra) { - sad->sfra = scene->r.cfra; - scene->r.cfra = scene->r.psfra; - } - else - sad->sfra = scene->r.cfra; - } - else { - if (scene->r.sfra > scene->r.cfra) { - sad->sfra = scene->r.cfra; - scene->r.cfra = scene->r.sfra; - } - else - sad->sfra = scene->r.cfra; - } - sad->redraws = redraws; - sad->refresh = refresh; - sad->flag |= (enable < 0) ? ANIMPLAY_FLAG_REVERSE : 0; - sad->flag |= (sync == 0) ? ANIMPLAY_FLAG_NO_SYNC : (sync == 1) ? ANIMPLAY_FLAG_SYNC : 0; - - ScrArea *sa = CTX_wm_area(C); - - char spacetype = -1; - - if (sa) - spacetype = sa->spacetype; - - sad->from_anim_edit = (ELEM(spacetype, SPACE_GRAPH, SPACE_ACTION, SPACE_NLA)); - - screen->animtimer->customdata = sad; - - } - - /* notifier catched by top header, for button */ - WM_event_add_notifier(C, NC_SCREEN | ND_ANIMPLAY, NULL); + bScreen *screen = CTX_wm_screen(C); + wmWindowManager *wm = CTX_wm_manager(C); + wmWindow *win = CTX_wm_window(C); + Scene *scene = CTX_data_scene(C); + bScreen *stopscreen = ED_screen_animation_playing(wm); + + if (stopscreen) { + WM_event_remove_timer(wm, win, stopscreen->animtimer); + stopscreen->animtimer = NULL; + } + + if (enable) { + ScreenAnimData *sad = MEM_callocN(sizeof(ScreenAnimData), "ScreenAnimData"); + + screen->animtimer = WM_event_add_timer(wm, win, TIMER0, (1.0 / FPS)); + + sad->ar = CTX_wm_region(C); + /* if startframe is larger than current frame, we put currentframe on startframe. + * note: first frame then is not drawn! (ton) */ + if (PRVRANGEON) { + if (scene->r.psfra > scene->r.cfra) { + sad->sfra = scene->r.cfra; + scene->r.cfra = scene->r.psfra; + } + else + sad->sfra = scene->r.cfra; + } + else { + if (scene->r.sfra > scene->r.cfra) { + sad->sfra = scene->r.cfra; + scene->r.cfra = scene->r.sfra; + } + else + sad->sfra = scene->r.cfra; + } + sad->redraws = redraws; + sad->refresh = refresh; + sad->flag |= (enable < 0) ? ANIMPLAY_FLAG_REVERSE : 0; + sad->flag |= (sync == 0) ? ANIMPLAY_FLAG_NO_SYNC : (sync == 1) ? ANIMPLAY_FLAG_SYNC : 0; + + ScrArea *sa = CTX_wm_area(C); + + char spacetype = -1; + + if (sa) + spacetype = sa->spacetype; + + sad->from_anim_edit = (ELEM(spacetype, SPACE_GRAPH, SPACE_ACTION, SPACE_NLA)); + + screen->animtimer->customdata = sad; + } + + /* notifier catched by top header, for button */ + WM_event_add_notifier(C, NC_SCREEN | ND_ANIMPLAY, NULL); } /* helper for screen_animation_play() - only to be used for TimeLine */ static ARegion *time_top_left_3dwindow(bScreen *screen) { - ARegion *aret = NULL; - ScrArea *sa; - int min = 10000; - - for (sa = screen->areabase.first; sa; sa = sa->next) { - if (sa->spacetype == SPACE_VIEW3D) { - ARegion *ar; - for (ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->regiontype == RGN_TYPE_WINDOW) { - if (ar->winrct.xmin - ar->winrct.ymin < min) { - aret = ar; - min = ar->winrct.xmin - ar->winrct.ymin; - } - } - } - } - } - - return aret; + ARegion *aret = NULL; + ScrArea *sa; + int min = 10000; + + for (sa = screen->areabase.first; sa; sa = sa->next) { + if (sa->spacetype == SPACE_VIEW3D) { + ARegion *ar; + for (ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->regiontype == RGN_TYPE_WINDOW) { + if (ar->winrct.xmin - ar->winrct.ymin < min) { + aret = ar; + min = ar->winrct.xmin - ar->winrct.ymin; + } + } + } + } + } + + return aret; } void ED_screen_animation_timer_update(bScreen *screen, int redraws, int refresh) { - if (screen && screen->animtimer) { - wmTimer *wt = screen->animtimer; - ScreenAnimData *sad = wt->customdata; - - sad->redraws = redraws; - sad->refresh = refresh; - sad->ar = NULL; - if (redraws & TIME_REGION) - sad->ar = time_top_left_3dwindow(screen); - } + if (screen && screen->animtimer) { + wmTimer *wt = screen->animtimer; + ScreenAnimData *sad = wt->customdata; + + sad->redraws = redraws; + sad->refresh = refresh; + sad->ar = NULL; + if (redraws & TIME_REGION) + sad->ar = time_top_left_3dwindow(screen); + } } /* results in fully updated anim system */ void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph) { - Scene *scene = DEG_get_input_scene(depsgraph); + Scene *scene = DEG_get_input_scene(depsgraph); #ifdef DURIAN_CAMERA_SWITCH - void *camera = BKE_scene_camera_switch_find(scene); - if (camera && scene->camera != camera) { - bScreen *sc; - scene->camera = camera; - /* are there cameras in the views that are not in the scene? */ - for (sc = bmain->screens.first; sc; sc = sc->id.next) { - BKE_screen_view3d_scene_sync(sc, scene); - } - DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE); - } + void *camera = BKE_scene_camera_switch_find(scene); + if (camera && scene->camera != camera) { + bScreen *sc; + scene->camera = camera; + /* are there cameras in the views that are not in the scene? */ + for (sc = bmain->screens.first; sc; sc = sc->id.next) { + BKE_screen_view3d_scene_sync(sc, scene); + } + DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE); + } #endif - ED_clip_update_frame(bmain, scene->r.cfra); + ED_clip_update_frame(bmain, scene->r.cfra); - /* this function applies the changes too */ - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + /* this function applies the changes too */ + BKE_scene_graph_update_for_newframe(depsgraph, bmain); - /* composite */ - if (scene->use_nodes && scene->nodetree) - ntreeCompositTagAnimated(scene->nodetree); - - /* update animated texture nodes */ - { - Tex *tex; - for (tex = bmain->textures.first; tex; tex = tex->id.next) { - if (tex->use_nodes && tex->nodetree) { - ntreeTexTagAnimated(tex->nodetree); - } - } - } + /* composite */ + if (scene->use_nodes && scene->nodetree) + ntreeCompositTagAnimated(scene->nodetree); + /* update animated texture nodes */ + { + Tex *tex; + for (tex = bmain->textures.first; tex; tex = tex->id.next) { + if (tex->use_nodes && tex->nodetree) { + ntreeTexTagAnimated(tex->nodetree); + } + } + } } /* @@ -1454,81 +1468,76 @@ void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph) */ bool ED_screen_stereo3d_required(const bScreen *screen, const Scene *scene) { - ScrArea *sa; - const bool is_multiview = (scene->r.scemode & R_MULTIVIEW) != 0; - - for (sa = screen->areabase.first; sa; sa = sa->next) { - switch (sa->spacetype) { - case SPACE_VIEW3D: - { - View3D *v3d; - - if (!is_multiview) - continue; - - v3d = sa->spacedata.first; - if (v3d->camera && v3d->stereo3d_camera == STEREO_3D_ID) { - ARegion *ar; - for (ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->regiondata && ar->regiontype == RGN_TYPE_WINDOW) { - RegionView3D *rv3d = ar->regiondata; - if (rv3d->persp == RV3D_CAMOB) { - return true; - } - } - } - } - break; - } - case SPACE_IMAGE: - { - SpaceImage *sima; - - /* images should always show in stereo, even if - * the file doesn't have views enabled */ - sima = sa->spacedata.first; - if (sima->image && BKE_image_is_stereo(sima->image) && - (sima->iuser.flag & IMA_SHOW_STEREO)) - { - return true; - } - break; - } - case SPACE_NODE: - { - SpaceNode *snode; - - if (!is_multiview) - continue; - - snode = sa->spacedata.first; - if ((snode->flag & SNODE_BACKDRAW) && ED_node_is_compositor(snode)) { - return true; - } - break; - } - case SPACE_SEQ: - { - SpaceSeq *sseq; - - if (!is_multiview) - continue; - - sseq = sa->spacedata.first; - if (ELEM(sseq->view, SEQ_VIEW_PREVIEW, SEQ_VIEW_SEQUENCE_PREVIEW)) { - return true; - } - - if (sseq->draw_flag & SEQ_DRAW_BACKDROP) { - return true; - } - - break; - } - } - } - - return false; + ScrArea *sa; + const bool is_multiview = (scene->r.scemode & R_MULTIVIEW) != 0; + + for (sa = screen->areabase.first; sa; sa = sa->next) { + switch (sa->spacetype) { + case SPACE_VIEW3D: { + View3D *v3d; + + if (!is_multiview) + continue; + + v3d = sa->spacedata.first; + if (v3d->camera && v3d->stereo3d_camera == STEREO_3D_ID) { + ARegion *ar; + for (ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->regiondata && ar->regiontype == RGN_TYPE_WINDOW) { + RegionView3D *rv3d = ar->regiondata; + if (rv3d->persp == RV3D_CAMOB) { + return true; + } + } + } + } + break; + } + case SPACE_IMAGE: { + SpaceImage *sima; + + /* images should always show in stereo, even if + * the file doesn't have views enabled */ + sima = sa->spacedata.first; + if (sima->image && BKE_image_is_stereo(sima->image) && + (sima->iuser.flag & IMA_SHOW_STEREO)) { + return true; + } + break; + } + case SPACE_NODE: { + SpaceNode *snode; + + if (!is_multiview) + continue; + + snode = sa->spacedata.first; + if ((snode->flag & SNODE_BACKDRAW) && ED_node_is_compositor(snode)) { + return true; + } + break; + } + case SPACE_SEQ: { + SpaceSeq *sseq; + + if (!is_multiview) + continue; + + sseq = sa->spacedata.first; + if (ELEM(sseq->view, SEQ_VIEW_PREVIEW, SEQ_VIEW_SEQUENCE_PREVIEW)) { + return true; + } + + if (sseq->draw_flag & SEQ_DRAW_BACKDROP) { + return true; + } + + break; + } + } + } + + return false; } /** @@ -1536,52 +1545,55 @@ bool ED_screen_stereo3d_required(const bScreen *screen, const Scene *scene) * \note Assumes \a screen to be visible/active! */ -Scene *ED_screen_scene_find_with_window(const bScreen *screen, const wmWindowManager *wm, struct wmWindow **r_window) +Scene *ED_screen_scene_find_with_window(const bScreen *screen, + const wmWindowManager *wm, + struct wmWindow **r_window) { - for (wmWindow *win = wm->windows.first; win; win = win->next) { - if (WM_window_get_active_screen(win) == screen) { - if (r_window) { - *r_window = win; - } - return WM_window_get_active_scene(win); - } - } - - BLI_assert(0); - return NULL; + for (wmWindow *win = wm->windows.first; win; win = win->next) { + if (WM_window_get_active_screen(win) == screen) { + if (r_window) { + *r_window = win; + } + return WM_window_get_active_scene(win); + } + } + + BLI_assert(0); + return NULL; } -ScrArea *ED_screen_area_find_with_spacedata(const bScreen *screen, const SpaceLink *sl, const bool only_visible) +ScrArea *ED_screen_area_find_with_spacedata(const bScreen *screen, + const SpaceLink *sl, + const bool only_visible) { - if (only_visible) { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - if (sa->spacedata.first == sl) { - return sa; - } - } - } - else { - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - if (BLI_findindex(&sa->spacedata, sl) != -1) { - return sa; - } - } - } - return NULL; + if (only_visible) { + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + if (sa->spacedata.first == sl) { + return sa; + } + } + } + else { + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + if (BLI_findindex(&sa->spacedata, sl) != -1) { + return sa; + } + } + } + return NULL; } Scene *ED_screen_scene_find(const bScreen *screen, const wmWindowManager *wm) { - return ED_screen_scene_find_with_window(screen, wm, NULL); + return ED_screen_scene_find_with_window(screen, wm, NULL); } - wmWindow *ED_screen_window_find(const bScreen *screen, const wmWindowManager *wm) { - for (wmWindow *win = wm->windows.first; win; win = win->next) { - if (WM_window_get_active_screen(win) == screen) { - return win; - } - } - return NULL; + for (wmWindow *win = wm->windows.first; win; win = win->next) { + if (WM_window_get_active_screen(win) == screen) { + return win; + } + } + return NULL; } diff --git a/source/blender/editors/screen/screen_geometry.c b/source/blender/editors/screen/screen_geometry.c index 68fd28013f8..1ad0e930582 100644 --- a/source/blender/editors/screen/screen_geometry.c +++ b/source/blender/editors/screen/screen_geometry.c @@ -39,108 +39,108 @@ #include "screen_intern.h" - int screen_geom_area_height(const ScrArea *area) { - return area->v2->vec.y - area->v1->vec.y + 1; + return area->v2->vec.y - area->v1->vec.y + 1; } int screen_geom_area_width(const ScrArea *area) { - return area->v4->vec.x - area->v1->vec.x + 1; + return area->v4->vec.x - area->v1->vec.x + 1; } ScrVert *screen_geom_vertex_add_ex(ScrAreaMap *area_map, short x, short y) { - ScrVert *sv = MEM_callocN(sizeof(ScrVert), "addscrvert"); - sv->vec.x = x; - sv->vec.y = y; + ScrVert *sv = MEM_callocN(sizeof(ScrVert), "addscrvert"); + sv->vec.x = x; + sv->vec.y = y; - BLI_addtail(&area_map->vertbase, sv); - return sv; + BLI_addtail(&area_map->vertbase, sv); + return sv; } ScrVert *screen_geom_vertex_add(bScreen *sc, short x, short y) { - return screen_geom_vertex_add_ex(AREAMAP_FROM_SCREEN(sc), x, y); + return screen_geom_vertex_add_ex(AREAMAP_FROM_SCREEN(sc), x, y); } ScrEdge *screen_geom_edge_add_ex(ScrAreaMap *area_map, ScrVert *v1, ScrVert *v2) { - ScrEdge *se = MEM_callocN(sizeof(ScrEdge), "addscredge"); + ScrEdge *se = MEM_callocN(sizeof(ScrEdge), "addscredge"); - BKE_screen_sort_scrvert(&v1, &v2); - se->v1 = v1; - se->v2 = v2; + BKE_screen_sort_scrvert(&v1, &v2); + se->v1 = v1; + se->v2 = v2; - BLI_addtail(&area_map->edgebase, se); - return se; + BLI_addtail(&area_map->edgebase, se); + return se; } ScrEdge *screen_geom_edge_add(bScreen *sc, ScrVert *v1, ScrVert *v2) { - return screen_geom_edge_add_ex(AREAMAP_FROM_SCREEN(sc), v1, v2); + return screen_geom_edge_add_ex(AREAMAP_FROM_SCREEN(sc), v1, v2); } bool screen_geom_edge_is_horizontal(ScrEdge *se) { - return (se->v1->vec.y == se->v2->vec.y); + return (se->v1->vec.y == se->v2->vec.y); } /** * \param bounds_rect: Either window or screen bounds. Used to exclude edges along window/screen edges. */ -ScrEdge *screen_geom_area_map_find_active_scredge( - const ScrAreaMap *area_map, - const rcti *bounds_rect, - const int mx, const int my) +ScrEdge *screen_geom_area_map_find_active_scredge(const ScrAreaMap *area_map, + const rcti *bounds_rect, + const int mx, + const int my) { - int safety = U.widget_unit / 10; - - CLAMP_MIN(safety, 2); - - for (ScrEdge *se = area_map->edgebase.first; se; se = se->next) { - if (screen_geom_edge_is_horizontal(se)) { - if ((se->v1->vec.y > bounds_rect->ymin) && (se->v1->vec.y < (bounds_rect->ymax - 1))) { - short min, max; - 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) <= safety && mx >= min && mx <= max) - return se; - } - } - else { - if ((se->v1->vec.x > bounds_rect->xmin) && (se->v1->vec.x < (bounds_rect->xmax - 1))) { - short min, max; - 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) <= safety && my >= min && my <= max) - return se; - } - } - } - - return NULL; + int safety = U.widget_unit / 10; + + CLAMP_MIN(safety, 2); + + for (ScrEdge *se = area_map->edgebase.first; se; se = se->next) { + if (screen_geom_edge_is_horizontal(se)) { + if ((se->v1->vec.y > bounds_rect->ymin) && (se->v1->vec.y < (bounds_rect->ymax - 1))) { + short min, max; + 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) <= safety && mx >= min && mx <= max) + return se; + } + } + else { + if ((se->v1->vec.x > bounds_rect->xmin) && (se->v1->vec.x < (bounds_rect->xmax - 1))) { + short min, max; + 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) <= safety && my >= min && my <= max) + return se; + } + } + } + + return NULL; } /* need win size to make sure not to include edges along screen edge */ -ScrEdge *screen_geom_find_active_scredge( - const wmWindow *win, const bScreen *screen, - const int mx, const int my) +ScrEdge *screen_geom_find_active_scredge(const wmWindow *win, + const bScreen *screen, + const int mx, + const int my) { - /* Use layout size (screen excluding global areas) for screen-layout area edges */ - rcti screen_rect; - ScrEdge *se; - - WM_window_screen_rect_calc(win, &screen_rect); - se = screen_geom_area_map_find_active_scredge(AREAMAP_FROM_SCREEN(screen), &screen_rect, mx, my); - - if (!se) { - /* Use entire window size (screen including global areas) for global area edges */ - rcti win_rect; - WM_window_rect_calc(win, &win_rect); - se = screen_geom_area_map_find_active_scredge(&win->global_areas, &win_rect, mx, my); - } - return se; + /* Use layout size (screen excluding global areas) for screen-layout area edges */ + rcti screen_rect; + ScrEdge *se; + + WM_window_screen_rect_calc(win, &screen_rect); + se = screen_geom_area_map_find_active_scredge(AREAMAP_FROM_SCREEN(screen), &screen_rect, mx, my); + + if (!se) { + /* Use entire window size (screen including global areas) for global area edges */ + rcti win_rect; + WM_window_rect_calc(win, &win_rect); + se = screen_geom_area_map_find_active_scredge(&win->global_areas, &win_rect, mx, my); + } + return se; } /** @@ -152,262 +152,261 @@ ScrEdge *screen_geom_find_active_scredge( */ void screen_geom_vertices_scale(const wmWindow *win, bScreen *sc) { - /* clamp Y size of header sized areas when expanding windows - * avoids annoying empty space around file menu */ + /* clamp Y size of header sized areas when expanding windows + * avoids annoying empty space around file menu */ #define USE_HEADER_SIZE_CLAMP - rcti window_rect, screen_rect; - - WM_window_rect_calc(win, &window_rect); - WM_window_screen_rect_calc(win, &screen_rect); + rcti window_rect, screen_rect; - const int headery_init = ED_area_headersize(); - const int screen_size_x = BLI_rcti_size_x(&screen_rect); - const int screen_size_y = BLI_rcti_size_y(&screen_rect); - ScrVert *sv = NULL; - ScrArea *sa; - int screen_size_x_prev, screen_size_y_prev; - float min[2], max[2]; + WM_window_rect_calc(win, &window_rect); + WM_window_screen_rect_calc(win, &screen_rect); - /* calculate size */ - min[0] = min[1] = 20000.0f; - max[0] = max[1] = 0.0f; + const int headery_init = ED_area_headersize(); + const int screen_size_x = BLI_rcti_size_x(&screen_rect); + const int screen_size_y = BLI_rcti_size_y(&screen_rect); + ScrVert *sv = NULL; + ScrArea *sa; + int screen_size_x_prev, screen_size_y_prev; + float min[2], max[2]; - for (sv = sc->vertbase.first; sv; sv = sv->next) { - const float fv[2] = {(float)sv->vec.x, (float)sv->vec.y}; - minmax_v2v2_v2(min, max, fv); - } + /* calculate size */ + min[0] = min[1] = 20000.0f; + max[0] = max[1] = 0.0f; - screen_size_x_prev = (max[0] - min[0]) + 1; - screen_size_y_prev = (max[1] - min[1]) + 1; + for (sv = sc->vertbase.first; sv; sv = sv->next) { + const float fv[2] = {(float)sv->vec.x, (float)sv->vec.y}; + minmax_v2v2_v2(min, max, fv); + } + screen_size_x_prev = (max[0] - min[0]) + 1; + screen_size_y_prev = (max[1] - min[1]) + 1; #ifdef USE_HEADER_SIZE_CLAMP -#define TEMP_BOTTOM 1 -#define TEMP_TOP 2 - - /* if the window's Y axis grows, clamp header sized areas */ - if (screen_size_y_prev < screen_size_y) { /* growing? */ - const int headery_margin_max = headery_init + 5; - for (sa = sc->areabase.first; sa; sa = sa->next) { - ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER); - sa->temp = 0; - - if (ar && !(ar->flag & RGN_FLAG_HIDDEN)) { - if (sa->v2->vec.y == max[1]) { - if (screen_geom_area_height(sa) < headery_margin_max) { - sa->temp = TEMP_TOP; - } - } - else if (sa->v1->vec.y == min[1]) { - if (screen_geom_area_height(sa) < headery_margin_max) { - sa->temp = TEMP_BOTTOM; - } - } - } - } - } +# define TEMP_BOTTOM 1 +# define TEMP_TOP 2 + + /* if the window's Y axis grows, clamp header sized areas */ + if (screen_size_y_prev < screen_size_y) { /* growing? */ + const int headery_margin_max = headery_init + 5; + for (sa = sc->areabase.first; sa; sa = sa->next) { + ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER); + sa->temp = 0; + + if (ar && !(ar->flag & RGN_FLAG_HIDDEN)) { + if (sa->v2->vec.y == max[1]) { + if (screen_geom_area_height(sa) < headery_margin_max) { + sa->temp = TEMP_TOP; + } + } + else if (sa->v1->vec.y == min[1]) { + if (screen_geom_area_height(sa) < headery_margin_max) { + sa->temp = TEMP_BOTTOM; + } + } + } + } + } #endif + if (screen_size_x_prev != screen_size_x || screen_size_y_prev != screen_size_y) { + const float facx = ((float)screen_size_x - 1) / ((float)screen_size_x_prev - 1); + const float facy = ((float)screen_size_y - 1) / ((float)screen_size_y_prev - 1); - if (screen_size_x_prev != screen_size_x || screen_size_y_prev != screen_size_y) { - const float facx = ((float)screen_size_x - 1) / ((float)screen_size_x_prev - 1); - const float facy = ((float)screen_size_y - 1) / ((float)screen_size_y_prev - 1); - - /* make sure it fits! */ - for (sv = sc->vertbase.first; sv; sv = sv->next) { - sv->vec.x = screen_rect.xmin + round_fl_to_short((sv->vec.x - min[0]) * facx); - CLAMP(sv->vec.x, screen_rect.xmin, screen_rect.xmax - 1); - - sv->vec.y = screen_rect.ymin + round_fl_to_short((sv->vec.y - min[1]) * facy); - CLAMP(sv->vec.y, screen_rect.ymin, screen_rect.ymax - 1); - } - } + /* make sure it fits! */ + for (sv = sc->vertbase.first; sv; sv = sv->next) { + sv->vec.x = screen_rect.xmin + round_fl_to_short((sv->vec.x - min[0]) * facx); + CLAMP(sv->vec.x, screen_rect.xmin, screen_rect.xmax - 1); + sv->vec.y = screen_rect.ymin + round_fl_to_short((sv->vec.y - min[1]) * facy); + CLAMP(sv->vec.y, screen_rect.ymin, screen_rect.ymax - 1); + } + } #ifdef USE_HEADER_SIZE_CLAMP - if (screen_size_y_prev < screen_size_y) { /* growing? */ - for (sa = sc->areabase.first; sa; sa = sa->next) { - ScrEdge *se = NULL; - - if (sa->temp == 0) - continue; - - if (sa->v1 == sa->v2) - continue; - - /* adjust headery if verts are along the edge of window */ - if (sa->temp == TEMP_TOP) { - /* lower edge */ - const int yval = sa->v2->vec.y - headery_init; - se = BKE_screen_find_edge(sc, sa->v4, sa->v1); - if (se != NULL) { - screen_geom_select_connected_edge(win, se); - } - for (sv = sc->vertbase.first; sv; sv = sv->next) { - if (sv != sa->v2 && sv != sa->v3) { - if (sv->flag) { - sv->vec.y = yval; - } - } - } - } - else { - /* upper edge */ - const int yval = sa->v1->vec.y + headery_init; - se = BKE_screen_find_edge(sc, sa->v2, sa->v3); - if (se != NULL) { - screen_geom_select_connected_edge(win, se); - } - for (sv = sc->vertbase.first; sv; sv = sv->next) { - if (sv != sa->v1 && sv != sa->v4) { - if (sv->flag) { - sv->vec.y = yval; - } - } - } - } - } - } - -#undef USE_HEADER_SIZE_CLAMP -#undef TEMP_BOTTOM -#undef TEMP_TOP + if (screen_size_y_prev < screen_size_y) { /* growing? */ + for (sa = sc->areabase.first; sa; sa = sa->next) { + ScrEdge *se = NULL; + + if (sa->temp == 0) + continue; + + if (sa->v1 == sa->v2) + continue; + + /* adjust headery if verts are along the edge of window */ + if (sa->temp == TEMP_TOP) { + /* lower edge */ + const int yval = sa->v2->vec.y - headery_init; + se = BKE_screen_find_edge(sc, sa->v4, sa->v1); + if (se != NULL) { + screen_geom_select_connected_edge(win, se); + } + for (sv = sc->vertbase.first; sv; sv = sv->next) { + if (sv != sa->v2 && sv != sa->v3) { + if (sv->flag) { + sv->vec.y = yval; + } + } + } + } + else { + /* upper edge */ + const int yval = sa->v1->vec.y + headery_init; + se = BKE_screen_find_edge(sc, sa->v2, sa->v3); + if (se != NULL) { + screen_geom_select_connected_edge(win, se); + } + for (sv = sc->vertbase.first; sv; sv = sv->next) { + if (sv != sa->v1 && sv != sa->v4) { + if (sv->flag) { + sv->vec.y = yval; + } + } + } + } + } + } + +# undef USE_HEADER_SIZE_CLAMP +# undef TEMP_BOTTOM +# undef TEMP_TOP #endif - - /* test for collapsed areas. This could happen in some blender version... */ - /* ton: removed option now, it needs Context... */ - - /* make each window at least ED_area_headersize() high */ - for (sa = sc->areabase.first; sa; sa = sa->next) { - int headery = headery_init; - - /* adjust headery if verts are along the edge of window */ - if (sa->v1->vec.y > window_rect.ymin) - headery += U.pixelsize; - if (sa->v2->vec.y < (window_rect.ymax - 1)) - headery += U.pixelsize; - - if (screen_geom_area_height(sa) < headery) { - /* lower edge */ - ScrEdge *se = BKE_screen_find_edge(sc, sa->v4, sa->v1); - if (se && sa->v1 != sa->v2) { - const int yval = sa->v2->vec.y - headery + 1; - - screen_geom_select_connected_edge(win, se); - - /* all selected vertices get the right offset */ - for (sv = sc->vertbase.first; sv; sv = sv->next) { - /* if is a collapsed area */ - if (sv != sa->v2 && sv != sa->v3) { - if (sv->flag) { - sv->vec.y = yval; - } - } - } - } - } - } - - /* Global areas have a fixed size that only changes with the DPI. Here we ensure that exactly this size is set. */ - for (ScrArea *area = win->global_areas.areabase.first; area; area = area->next) { - if (area->global->flag & GLOBAL_AREA_IS_HIDDEN) { - continue; - } - - int height = ED_area_global_size_y(area) - 1; - - if (area->v1->vec.y > window_rect.ymin) { - height += U.pixelsize; - } - if (area->v2->vec.y < (window_rect.ymax - 1)) { - height += U.pixelsize; - } - - /* width */ - area->v1->vec.x = area->v2->vec.x = window_rect.xmin; - area->v3->vec.x = area->v4->vec.x = window_rect.xmax - 1; - /* height */ - area->v1->vec.y = area->v4->vec.y = window_rect.ymin; - area->v2->vec.y = area->v3->vec.y = window_rect.ymax - 1; - - switch (area->global->align) { - case GLOBAL_AREA_ALIGN_TOP: - area->v1->vec.y = area->v4->vec.y = area->v2->vec.y - height; - break; - case GLOBAL_AREA_ALIGN_BOTTOM: - area->v2->vec.y = area->v3->vec.y = area->v1->vec.y + height; - break; - } - } + /* test for collapsed areas. This could happen in some blender version... */ + /* ton: removed option now, it needs Context... */ + + /* make each window at least ED_area_headersize() high */ + for (sa = sc->areabase.first; sa; sa = sa->next) { + int headery = headery_init; + + /* adjust headery if verts are along the edge of window */ + if (sa->v1->vec.y > window_rect.ymin) + headery += U.pixelsize; + if (sa->v2->vec.y < (window_rect.ymax - 1)) + headery += U.pixelsize; + + if (screen_geom_area_height(sa) < headery) { + /* lower edge */ + ScrEdge *se = BKE_screen_find_edge(sc, sa->v4, sa->v1); + if (se && sa->v1 != sa->v2) { + const int yval = sa->v2->vec.y - headery + 1; + + screen_geom_select_connected_edge(win, se); + + /* all selected vertices get the right offset */ + for (sv = sc->vertbase.first; sv; sv = sv->next) { + /* if is a collapsed area */ + if (sv != sa->v2 && sv != sa->v3) { + if (sv->flag) { + sv->vec.y = yval; + } + } + } + } + } + } + + /* Global areas have a fixed size that only changes with the DPI. Here we ensure that exactly this size is set. */ + for (ScrArea *area = win->global_areas.areabase.first; area; area = area->next) { + if (area->global->flag & GLOBAL_AREA_IS_HIDDEN) { + continue; + } + + int height = ED_area_global_size_y(area) - 1; + + if (area->v1->vec.y > window_rect.ymin) { + height += U.pixelsize; + } + if (area->v2->vec.y < (window_rect.ymax - 1)) { + height += U.pixelsize; + } + + /* width */ + area->v1->vec.x = area->v2->vec.x = window_rect.xmin; + area->v3->vec.x = area->v4->vec.x = window_rect.xmax - 1; + /* height */ + area->v1->vec.y = area->v4->vec.y = window_rect.ymin; + area->v2->vec.y = area->v3->vec.y = window_rect.ymax - 1; + + switch (area->global->align) { + case GLOBAL_AREA_ALIGN_TOP: + area->v1->vec.y = area->v4->vec.y = area->v2->vec.y - height; + break; + case GLOBAL_AREA_ALIGN_BOTTOM: + area->v2->vec.y = area->v3->vec.y = area->v1->vec.y + height; + break; + } + } } /** * \return 0 if no split is possible, otherwise the screen-coordinate at which to split. */ -short screen_geom_find_area_split_point(const ScrArea *sa, const rcti *window_rect, char dir, float fac) +short screen_geom_find_area_split_point(const ScrArea *sa, + const rcti *window_rect, + char dir, + float fac) { - short x, y; - const int cur_area_width = screen_geom_area_width(sa); - const int cur_area_height = screen_geom_area_height(sa); - const short area_min_x = AREAMINX; - const short area_min_y = ED_area_headersize(); - int area_min; - - // area big enough? - if ((dir == 'v') && (cur_area_width <= 2 * area_min_x)) { - return 0; - } - if ((dir == 'h') && (cur_area_height <= 2 * area_min_y)) { - return 0; - } - - // to be sure - CLAMP(fac, 0.0f, 1.0f); - - if (dir == 'h') { - y = sa->v1->vec.y + round_fl_to_short(fac * cur_area_height); - - area_min = area_min_y; - - if (sa->v1->vec.y > window_rect->ymin) { - area_min += U.pixelsize; - } - if (sa->v2->vec.y < (window_rect->ymax - 1)) { - area_min += U.pixelsize; - } - - if (y - sa->v1->vec.y < area_min) { - y = sa->v1->vec.y + area_min; - } - else if (sa->v2->vec.y - y < area_min) { - y = sa->v2->vec.y - area_min; - } - - return y; - } - else { - x = sa->v1->vec.x + round_fl_to_short(fac * cur_area_width); - - area_min = area_min_x; - - if (sa->v1->vec.x > window_rect->xmin) { - area_min += U.pixelsize; - } - if (sa->v4->vec.x < (window_rect->xmax - 1)) { - area_min += U.pixelsize; - } - - if (x - sa->v1->vec.x < area_min) { - x = sa->v1->vec.x + area_min; - } - else if (sa->v4->vec.x - x < area_min) { - x = sa->v4->vec.x - area_min; - } - - return x; - } + short x, y; + const int cur_area_width = screen_geom_area_width(sa); + const int cur_area_height = screen_geom_area_height(sa); + const short area_min_x = AREAMINX; + const short area_min_y = ED_area_headersize(); + int area_min; + + // area big enough? + if ((dir == 'v') && (cur_area_width <= 2 * area_min_x)) { + return 0; + } + if ((dir == 'h') && (cur_area_height <= 2 * area_min_y)) { + return 0; + } + + // to be sure + CLAMP(fac, 0.0f, 1.0f); + + if (dir == 'h') { + y = sa->v1->vec.y + round_fl_to_short(fac * cur_area_height); + + area_min = area_min_y; + + if (sa->v1->vec.y > window_rect->ymin) { + area_min += U.pixelsize; + } + if (sa->v2->vec.y < (window_rect->ymax - 1)) { + area_min += U.pixelsize; + } + + if (y - sa->v1->vec.y < area_min) { + y = sa->v1->vec.y + area_min; + } + else if (sa->v2->vec.y - y < area_min) { + y = sa->v2->vec.y - area_min; + } + + return y; + } + else { + x = sa->v1->vec.x + round_fl_to_short(fac * cur_area_width); + + area_min = area_min_x; + + if (sa->v1->vec.x > window_rect->xmin) { + area_min += U.pixelsize; + } + if (sa->v4->vec.x < (window_rect->xmax - 1)) { + area_min += U.pixelsize; + } + + if (x - sa->v1->vec.x < area_min) { + x = sa->v1->vec.x + area_min; + } + else if (sa->v4->vec.x - x < area_min) { + x = sa->v4->vec.x - area_min; + } + + return x; + } } /** @@ -415,44 +414,45 @@ short screen_geom_find_area_split_point(const ScrArea *sa, const rcti *window_re */ void screen_geom_select_connected_edge(const wmWindow *win, ScrEdge *edge) { - bScreen *sc = WM_window_get_active_screen(win); - bool oneselected = true; - char dir; - - /* select connected, only in the right direction */ - /* 'dir' is the direction of EDGE */ - - if (edge->v1->vec.x == edge->v2->vec.x) { - dir = 'v'; - } - else { - dir = 'h'; - } - - ED_screen_verts_iter(win, sc, sv) { - sv->flag = 0; - } - - edge->v1->flag = 1; - edge->v2->flag = 1; - - while (oneselected) { - oneselected = false; - for (ScrEdge *se = sc->edgebase.first; se; se = se->next) { - if (se->v1->flag + se->v2->flag == 1) { - if (dir == 'h') { - if (se->v1->vec.y == se->v2->vec.y) { - se->v1->flag = se->v2->flag = 1; - oneselected = true; - } - } - if (dir == 'v') { - if (se->v1->vec.x == se->v2->vec.x) { - se->v1->flag = se->v2->flag = 1; - oneselected = true; - } - } - } - } - } + bScreen *sc = WM_window_get_active_screen(win); + bool oneselected = true; + char dir; + + /* select connected, only in the right direction */ + /* 'dir' is the direction of EDGE */ + + if (edge->v1->vec.x == edge->v2->vec.x) { + dir = 'v'; + } + else { + dir = 'h'; + } + + ED_screen_verts_iter(win, sc, sv) + { + sv->flag = 0; + } + + edge->v1->flag = 1; + edge->v2->flag = 1; + + while (oneselected) { + oneselected = false; + for (ScrEdge *se = sc->edgebase.first; se; se = se->next) { + if (se->v1->flag + se->v2->flag == 1) { + if (dir == 'h') { + if (se->v1->vec.y == se->v2->vec.y) { + se->v1->flag = se->v2->flag = 1; + oneselected = true; + } + } + if (dir == 'v') { + if (se->v1->vec.x == se->v2->vec.x) { + se->v1->flag = se->v2->flag = 1; + oneselected = true; + } + } + } + } + } } diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h index cb400bb3734..d2c43d1df28 100644 --- a/source/blender/editors/screen/screen_intern.h +++ b/source/blender/editors/screen/screen_intern.h @@ -30,62 +30,69 @@ struct bContextDataResult; /* internal exports only */ -#define AZONESPOTW UI_HEADER_OFFSET /* width of corner azone - max */ -#define AZONESPOTH (0.6f * U.widget_unit) /* height of corner azone */ -#define AZONEFADEIN (5.0f * U.widget_unit) /* when azone is totally visible */ -#define AZONEFADEOUT (6.5f * U.widget_unit) /* when we start seeing the azone */ +#define AZONESPOTW UI_HEADER_OFFSET /* width of corner azone - max */ +#define AZONESPOTH (0.6f * U.widget_unit) /* height of corner azone */ +#define AZONEFADEIN (5.0f * U.widget_unit) /* when azone is totally visible */ +#define AZONEFADEOUT (6.5f * U.widget_unit) /* when we start seeing the azone */ /* area.c */ -void ED_area_data_copy(ScrArea *sa_dst, ScrArea *sa_src, const bool do_free); -void ED_area_data_swap(ScrArea *sa1, ScrArea *sa2); -void region_toggle_hidden(struct bContext *C, ARegion *ar, const bool do_fade); +void ED_area_data_copy(ScrArea *sa_dst, ScrArea *sa_src, const bool do_free); +void ED_area_data_swap(ScrArea *sa1, ScrArea *sa2); +void region_toggle_hidden(struct bContext *C, ARegion *ar, const bool do_fade); /* screen_edit.c */ -bScreen *screen_add(struct Main *bmain, const char *name, const rcti *rect); -void screen_data_copy(bScreen *to, bScreen *from); -void screen_new_activate_prepare(const wmWindow *win, bScreen *screen_new); -void screen_change_update(struct bContext *C, wmWindow *win, bScreen *sc); -bScreen *screen_change_prepare(bScreen *screen_old, bScreen *screen_new, struct Main *bmain, struct bContext *C, wmWindow *win); -ScrArea *area_split(const wmWindow *win, bScreen *sc, ScrArea *sa, char dir, float fac, int merge); -int screen_area_join(struct bContext *C, bScreen *scr, ScrArea *sa1, ScrArea *sa2); -int area_getorientation(ScrArea *sa, ScrArea *sb); +bScreen *screen_add(struct Main *bmain, const char *name, const rcti *rect); +void screen_data_copy(bScreen *to, bScreen *from); +void screen_new_activate_prepare(const wmWindow *win, bScreen *screen_new); +void screen_change_update(struct bContext *C, wmWindow *win, bScreen *sc); +bScreen *screen_change_prepare(bScreen *screen_old, + bScreen *screen_new, + struct Main *bmain, + struct bContext *C, + wmWindow *win); +ScrArea *area_split(const wmWindow *win, bScreen *sc, ScrArea *sa, char dir, float fac, int merge); +int screen_area_join(struct bContext *C, bScreen *scr, ScrArea *sa1, ScrArea *sa2); +int area_getorientation(ScrArea *sa, ScrArea *sb); struct AZone *ED_area_actionzone_find_xy(ScrArea *sa, const int xy[2]); /* screen_geometry.c */ -int screen_geom_area_height(const ScrArea *area); -int screen_geom_area_width(const ScrArea *area); -ScrVert *screen_geom_vertex_add_ex(ScrAreaMap *area_map, short x, short y); -ScrVert *screen_geom_vertex_add(bScreen *sc, short x, short y); -ScrEdge *screen_geom_edge_add_ex(ScrAreaMap *area_map, ScrVert *v1, ScrVert *v2); -ScrEdge *screen_geom_edge_add(bScreen *sc, ScrVert *v1, ScrVert *v2); -bool screen_geom_edge_is_horizontal(ScrEdge *se); -ScrEdge *screen_geom_area_map_find_active_scredge( - const struct ScrAreaMap *area_map, - const rcti *bounds_rect, - const int mx, const int my); -ScrEdge *screen_geom_find_active_scredge( - const wmWindow *win, const bScreen *screen, - const int mx, const int my); -void screen_geom_vertices_scale(const wmWindow *win, bScreen *sc); -short screen_geom_find_area_split_point(const ScrArea *sa, const rcti *window_rect, char dir, float fac); -void screen_geom_select_connected_edge(const wmWindow *win, ScrEdge *edge); - +int screen_geom_area_height(const ScrArea *area); +int screen_geom_area_width(const ScrArea *area); +ScrVert *screen_geom_vertex_add_ex(ScrAreaMap *area_map, short x, short y); +ScrVert *screen_geom_vertex_add(bScreen *sc, short x, short y); +ScrEdge *screen_geom_edge_add_ex(ScrAreaMap *area_map, ScrVert *v1, ScrVert *v2); +ScrEdge *screen_geom_edge_add(bScreen *sc, ScrVert *v1, ScrVert *v2); +bool screen_geom_edge_is_horizontal(ScrEdge *se); +ScrEdge *screen_geom_area_map_find_active_scredge(const struct ScrAreaMap *area_map, + const rcti *bounds_rect, + const int mx, + const int my); +ScrEdge *screen_geom_find_active_scredge(const wmWindow *win, + const bScreen *screen, + const int mx, + const int my); +void screen_geom_vertices_scale(const wmWindow *win, bScreen *sc); +short screen_geom_find_area_split_point(const ScrArea *sa, + const rcti *window_rect, + char dir, + float fac); +void screen_geom_select_connected_edge(const wmWindow *win, ScrEdge *edge); /* screen_context.c */ -int ed_screen_context( - const struct bContext *C, const char *member, struct bContextDataResult *result); +int ed_screen_context(const struct bContext *C, + const char *member, + struct bContextDataResult *result); extern const char *screen_context_dir[]; /* doc access */ /* screendump.c */ -void SCREEN_OT_screenshot(struct wmOperatorType *ot); +void SCREEN_OT_screenshot(struct wmOperatorType *ot); /* screen_ops.c */ -void region_blend_start(struct bContext *C, struct ScrArea *sa, struct ARegion *ar); +void region_blend_start(struct bContext *C, struct ScrArea *sa, struct ARegion *ar); /* workspace_layout_edit.c */ bool workspace_layout_set_poll(const struct WorkSpaceLayout *layout); - #endif /* __SCREEN_INTERN_H__ */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 3e5bebc4d35..94b5f695de8 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -21,7 +21,6 @@ * \ingroup edscr */ - #include <math.h> #include <string.h> @@ -90,12 +89,12 @@ #include "UI_resources.h" #include "UI_view2d.h" -#include "screen_intern.h" /* own module include */ +#include "screen_intern.h" /* own module include */ -#define KM_MODAL_CANCEL 1 -#define KM_MODAL_APPLY 2 -#define KM_MODAL_SNAP_ON 3 -#define KM_MODAL_SNAP_OFF 4 +#define KM_MODAL_CANCEL 1 +#define KM_MODAL_APPLY 2 +#define KM_MODAL_SNAP_ON 3 +#define KM_MODAL_SNAP_OFF 4 /* -------------------------------------------------------------------- */ /** \name Public Poll API @@ -103,275 +102,286 @@ bool ED_operator_regionactive(bContext *C) { - if (CTX_wm_window(C) == NULL) return 0; - if (CTX_wm_screen(C) == NULL) return 0; - if (CTX_wm_region(C) == NULL) return 0; - return 1; + if (CTX_wm_window(C) == NULL) + return 0; + if (CTX_wm_screen(C) == NULL) + return 0; + if (CTX_wm_region(C) == NULL) + return 0; + return 1; } bool ED_operator_areaactive(bContext *C) { - if (CTX_wm_window(C) == NULL) return 0; - if (CTX_wm_screen(C) == NULL) return 0; - if (CTX_wm_area(C) == NULL) return 0; - return 1; + if (CTX_wm_window(C) == NULL) + return 0; + if (CTX_wm_screen(C) == NULL) + return 0; + if (CTX_wm_area(C) == NULL) + return 0; + return 1; } bool ED_operator_screenactive(bContext *C) { - if (CTX_wm_window(C) == NULL) return 0; - if (CTX_wm_screen(C) == NULL) return 0; - return 1; + if (CTX_wm_window(C) == NULL) + return 0; + if (CTX_wm_screen(C) == NULL) + return 0; + return 1; } /* XXX added this to prevent anim state to change during renders */ static bool ED_operator_screenactive_norender(bContext *C) { - if (G.is_rendering) return 0; - if (CTX_wm_window(C) == NULL) return 0; - if (CTX_wm_screen(C) == NULL) return 0; - return 1; + if (G.is_rendering) + return 0; + if (CTX_wm_window(C) == NULL) + return 0; + if (CTX_wm_screen(C) == NULL) + return 0; + return 1; } /* when mouse is over area-edge */ bool ED_operator_screen_mainwinactive(bContext *C) { - bScreen *screen; - if (CTX_wm_window(C) == NULL) return 0; - screen = CTX_wm_screen(C); - if (screen == NULL) return 0; - if (screen->active_region != NULL) return 0; - return 1; + bScreen *screen; + if (CTX_wm_window(C) == NULL) + return 0; + screen = CTX_wm_screen(C); + if (screen == NULL) + return 0; + if (screen->active_region != NULL) + return 0; + return 1; } bool ED_operator_scene(bContext *C) { - Scene *scene = CTX_data_scene(C); - if (scene) - return 1; - return 0; + Scene *scene = CTX_data_scene(C); + if (scene) + return 1; + return 0; } bool ED_operator_scene_editable(bContext *C) { - Scene *scene = CTX_data_scene(C); - if (scene && !ID_IS_LINKED(scene)) - return 1; - return 0; + Scene *scene = CTX_data_scene(C); + if (scene && !ID_IS_LINKED(scene)) + return 1; + return 0; } bool ED_operator_objectmode(bContext *C) { - Scene *scene = CTX_data_scene(C); - Object *obact = CTX_data_active_object(C); + Scene *scene = CTX_data_scene(C); + Object *obact = CTX_data_active_object(C); - if (scene == NULL || ID_IS_LINKED(scene)) - return 0; - if (CTX_data_edit_object(C)) - return 0; + if (scene == NULL || ID_IS_LINKED(scene)) + return 0; + if (CTX_data_edit_object(C)) + return 0; - /* add a check for ob->mode too? */ - if (obact && (obact->mode != OB_MODE_OBJECT)) - return 0; + /* add a check for ob->mode too? */ + if (obact && (obact->mode != OB_MODE_OBJECT)) + return 0; - return 1; + return 1; } - static bool ed_spacetype_test(bContext *C, int type) { - if (ED_operator_areaactive(C)) { - SpaceLink *sl = (SpaceLink *)CTX_wm_space_data(C); - return sl && (sl->spacetype == type); - } - return 0; + if (ED_operator_areaactive(C)) { + SpaceLink *sl = (SpaceLink *)CTX_wm_space_data(C); + return sl && (sl->spacetype == type); + } + return 0; } bool ED_operator_view3d_active(bContext *C) { - return ed_spacetype_test(C, SPACE_VIEW3D); + return ed_spacetype_test(C, SPACE_VIEW3D); } bool ED_operator_region_view3d_active(bContext *C) { - if (CTX_wm_region_view3d(C)) - return true; + if (CTX_wm_region_view3d(C)) + return true; - CTX_wm_operator_poll_msg_set(C, "expected a view3d region"); - return false; + CTX_wm_operator_poll_msg_set(C, "expected a view3d region"); + return false; } /* generic for any view2d which uses anim_ops */ bool ED_operator_animview_active(bContext *C) { - if (ED_operator_areaactive(C)) { - SpaceLink *sl = (SpaceLink *)CTX_wm_space_data(C); - if (sl && (ELEM(sl->spacetype, SPACE_SEQ, SPACE_ACTION, SPACE_NLA, SPACE_GRAPH))) - return true; - } + if (ED_operator_areaactive(C)) { + SpaceLink *sl = (SpaceLink *)CTX_wm_space_data(C); + if (sl && (ELEM(sl->spacetype, SPACE_SEQ, SPACE_ACTION, SPACE_NLA, SPACE_GRAPH))) + return true; + } - CTX_wm_operator_poll_msg_set(C, "expected a timeline/animation area to be active"); - return 0; + CTX_wm_operator_poll_msg_set(C, "expected a timeline/animation area to be active"); + return 0; } bool ED_operator_outliner_active(bContext *C) { - return ed_spacetype_test(C, SPACE_OUTLINER); + return ed_spacetype_test(C, SPACE_OUTLINER); } bool ED_operator_outliner_active_no_editobject(bContext *C) { - if (ed_spacetype_test(C, SPACE_OUTLINER)) { - Object *ob = ED_object_active_context(C); - Object *obedit = CTX_data_edit_object(C); - if (ob && ob == obedit) - return 0; - else - return 1; - } - return 0; + if (ed_spacetype_test(C, SPACE_OUTLINER)) { + Object *ob = ED_object_active_context(C); + Object *obedit = CTX_data_edit_object(C); + if (ob && ob == obedit) + return 0; + else + return 1; + } + return 0; } bool ED_operator_file_active(bContext *C) { - return ed_spacetype_test(C, SPACE_FILE); + return ed_spacetype_test(C, SPACE_FILE); } bool ED_operator_action_active(bContext *C) { - return ed_spacetype_test(C, SPACE_ACTION); + return ed_spacetype_test(C, SPACE_ACTION); } bool ED_operator_buttons_active(bContext *C) { - return ed_spacetype_test(C, SPACE_PROPERTIES); + return ed_spacetype_test(C, SPACE_PROPERTIES); } bool ED_operator_node_active(bContext *C) { - SpaceNode *snode = CTX_wm_space_node(C); + SpaceNode *snode = CTX_wm_space_node(C); - if (snode && snode->edittree) - return 1; + if (snode && snode->edittree) + return 1; - return 0; + return 0; } bool ED_operator_node_editable(bContext *C) { - SpaceNode *snode = CTX_wm_space_node(C); + SpaceNode *snode = CTX_wm_space_node(C); - if (snode && snode->edittree && !ID_IS_LINKED(snode->edittree)) - return 1; + if (snode && snode->edittree && !ID_IS_LINKED(snode->edittree)) + return 1; - return 0; + return 0; } bool ED_operator_graphedit_active(bContext *C) { - return ed_spacetype_test(C, SPACE_GRAPH); + return ed_spacetype_test(C, SPACE_GRAPH); } bool ED_operator_sequencer_active(bContext *C) { - return ed_spacetype_test(C, SPACE_SEQ); + return ed_spacetype_test(C, SPACE_SEQ); } bool ED_operator_sequencer_active_editable(bContext *C) { - return ed_spacetype_test(C, SPACE_SEQ) && ED_operator_scene_editable(C); + return ed_spacetype_test(C, SPACE_SEQ) && ED_operator_scene_editable(C); } bool ED_operator_image_active(bContext *C) { - return ed_spacetype_test(C, SPACE_IMAGE); + return ed_spacetype_test(C, SPACE_IMAGE); } bool ED_operator_nla_active(bContext *C) { - return ed_spacetype_test(C, SPACE_NLA); + return ed_spacetype_test(C, SPACE_NLA); } bool ED_operator_info_active(bContext *C) { - return ed_spacetype_test(C, SPACE_INFO); + return ed_spacetype_test(C, SPACE_INFO); } - bool ED_operator_console_active(bContext *C) { - return ed_spacetype_test(C, SPACE_CONSOLE); + return ed_spacetype_test(C, SPACE_CONSOLE); } static bool ed_object_hidden(Object *ob) { - /* if hidden but in edit mode, we still display, can happen with animation */ - return ((ob->restrictflag & OB_RESTRICT_VIEW) && !(ob->mode & OB_MODE_EDIT)); + /* if hidden but in edit mode, we still display, can happen with animation */ + return ((ob->restrictflag & OB_RESTRICT_VIEW) && !(ob->mode & OB_MODE_EDIT)); } bool ED_operator_object_active(bContext *C) { - Object *ob = ED_object_active_context(C); - return ((ob != NULL) && !ed_object_hidden(ob)); + Object *ob = ED_object_active_context(C); + return ((ob != NULL) && !ed_object_hidden(ob)); } bool ED_operator_object_active_editable(bContext *C) { - Object *ob = ED_object_active_context(C); - return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob)); + Object *ob = ED_object_active_context(C); + return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob)); } bool ED_operator_object_active_editable_mesh(bContext *C) { - Object *ob = ED_object_active_context(C); - return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob) && - (ob->type == OB_MESH) && !ID_IS_LINKED(ob->data)); + Object *ob = ED_object_active_context(C); + return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob) && (ob->type == OB_MESH) && + !ID_IS_LINKED(ob->data)); } bool ED_operator_object_active_editable_font(bContext *C) { - Object *ob = ED_object_active_context(C); - return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob) && - (ob->type == OB_FONT)); + Object *ob = ED_object_active_context(C); + return ((ob != NULL) && !ID_IS_LINKED(ob) && !ed_object_hidden(ob) && (ob->type == OB_FONT)); } bool ED_operator_editmesh(bContext *C) { - Object *obedit = CTX_data_edit_object(C); - if (obedit && obedit->type == OB_MESH) - return NULL != BKE_editmesh_from_object(obedit); - return 0; + Object *obedit = CTX_data_edit_object(C); + if (obedit && obedit->type == OB_MESH) + return NULL != BKE_editmesh_from_object(obedit); + return 0; } bool ED_operator_editmesh_view3d(bContext *C) { - return ED_operator_editmesh(C) && ED_operator_view3d_active(C); + return ED_operator_editmesh(C) && ED_operator_view3d_active(C); } bool ED_operator_editmesh_region_view3d(bContext *C) { - if (ED_operator_editmesh(C) && CTX_wm_region_view3d(C)) - return 1; + if (ED_operator_editmesh(C) && CTX_wm_region_view3d(C)) + return 1; - CTX_wm_operator_poll_msg_set(C, "expected a view3d region & editmesh"); - return 0; + CTX_wm_operator_poll_msg_set(C, "expected a view3d region & editmesh"); + return 0; } bool ED_operator_editmesh_auto_smooth(bContext *C) { - Object *obedit = CTX_data_edit_object(C); - if (obedit && obedit->type == OB_MESH && (((Mesh *)(obedit->data))->flag & ME_AUTOSMOOTH)) { - return NULL != BKE_editmesh_from_object(obedit); - } - return 0; + Object *obedit = CTX_data_edit_object(C); + if (obedit && obedit->type == OB_MESH && (((Mesh *)(obedit->data))->flag & ME_AUTOSMOOTH)) { + return NULL != BKE_editmesh_from_object(obedit); + } + return 0; } bool ED_operator_editarmature(bContext *C) { - Object *obedit = CTX_data_edit_object(C); - if (obedit && obedit->type == OB_ARMATURE) - return NULL != ((bArmature *)obedit->data)->edbo; - return 0; + Object *obedit = CTX_data_edit_object(C); + if (obedit && obedit->type == OB_ARMATURE) + return NULL != ((bArmature *)obedit->data)->edbo; + return 0; } /** @@ -383,193 +393,189 @@ bool ED_operator_editarmature(bContext *C) */ bool ED_operator_posemode_exclusive(bContext *C) { - Object *obact = CTX_data_active_object(C); + Object *obact = CTX_data_active_object(C); - if (obact && !(obact->mode & OB_MODE_EDIT)) { - Object *obpose; - if ((obpose = BKE_object_pose_armature_get(obact))) { - if (obact == obpose) { - return 1; - } - } - } + if (obact && !(obact->mode & OB_MODE_EDIT)) { + Object *obpose; + if ((obpose = BKE_object_pose_armature_get(obact))) { + if (obact == obpose) { + return 1; + } + } + } - return 0; + return 0; } /* allows for pinned pose objects to be used in the object buttons * and the non-active pose object to be used in the 3D view */ bool ED_operator_posemode_context(bContext *C) { - Object *obpose = ED_pose_object_from_context(C); + Object *obpose = ED_pose_object_from_context(C); - if (obpose && !(obpose->mode & OB_MODE_EDIT)) { - if (BKE_object_pose_context_check(obpose)) { - return 1; - } - } + if (obpose && !(obpose->mode & OB_MODE_EDIT)) { + if (BKE_object_pose_context_check(obpose)) { + return 1; + } + } - return 0; + return 0; } bool ED_operator_posemode(bContext *C) { - Object *obact = CTX_data_active_object(C); + Object *obact = CTX_data_active_object(C); - if (obact && !(obact->mode & OB_MODE_EDIT)) { - Object *obpose; - if ((obpose = BKE_object_pose_armature_get(obact))) { - if ((obact == obpose) || (obact->mode & OB_MODE_WEIGHT_PAINT)) { - return 1; - } - } - } + if (obact && !(obact->mode & OB_MODE_EDIT)) { + Object *obpose; + if ((obpose = BKE_object_pose_armature_get(obact))) { + if ((obact == obpose) || (obact->mode & OB_MODE_WEIGHT_PAINT)) { + return 1; + } + } + } - return 0; + return 0; } bool ED_operator_posemode_local(bContext *C) { - if (ED_operator_posemode(C)) { - Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C)); - bArmature *arm = ob->data; - return !(ID_IS_LINKED(&ob->id) || - ID_IS_LINKED(&arm->id)); - } - return false; + if (ED_operator_posemode(C)) { + Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C)); + bArmature *arm = ob->data; + return !(ID_IS_LINKED(&ob->id) || ID_IS_LINKED(&arm->id)); + } + return false; } /* wrapper for ED_space_image_show_uvedit */ bool ED_operator_uvedit(bContext *C) { - SpaceImage *sima = CTX_wm_space_image(C); - Object *obedit = CTX_data_edit_object(C); - return ED_space_image_show_uvedit(sima, obedit); + SpaceImage *sima = CTX_wm_space_image(C); + Object *obedit = CTX_data_edit_object(C); + return ED_space_image_show_uvedit(sima, obedit); } bool ED_operator_uvedit_space_image(bContext *C) { - SpaceImage *sima = CTX_wm_space_image(C); - Object *obedit = CTX_data_edit_object(C); - return sima && ED_space_image_show_uvedit(sima, obedit); + SpaceImage *sima = CTX_wm_space_image(C); + Object *obedit = CTX_data_edit_object(C); + return sima && ED_space_image_show_uvedit(sima, obedit); } bool ED_operator_uvmap(bContext *C) { - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = NULL; + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = NULL; - if (obedit && obedit->type == OB_MESH) { - em = BKE_editmesh_from_object(obedit); - } + if (obedit && obedit->type == OB_MESH) { + em = BKE_editmesh_from_object(obedit); + } - if (em && (em->bm->totface)) { - return true; - } + if (em && (em->bm->totface)) { + return true; + } - return false; + return false; } bool ED_operator_editsurfcurve(bContext *C) { - Object *obedit = CTX_data_edit_object(C); - if (obedit && ELEM(obedit->type, OB_CURVE, OB_SURF)) - return NULL != ((Curve *)obedit->data)->editnurb; - return 0; + Object *obedit = CTX_data_edit_object(C); + if (obedit && ELEM(obedit->type, OB_CURVE, OB_SURF)) + return NULL != ((Curve *)obedit->data)->editnurb; + return 0; } bool ED_operator_editsurfcurve_region_view3d(bContext *C) { - if (ED_operator_editsurfcurve(C) && CTX_wm_region_view3d(C)) - return 1; + if (ED_operator_editsurfcurve(C) && CTX_wm_region_view3d(C)) + return 1; - CTX_wm_operator_poll_msg_set(C, "expected a view3d region & editcurve"); - return 0; + CTX_wm_operator_poll_msg_set(C, "expected a view3d region & editcurve"); + return 0; } bool ED_operator_editcurve(bContext *C) { - Object *obedit = CTX_data_edit_object(C); - if (obedit && obedit->type == OB_CURVE) - return NULL != ((Curve *)obedit->data)->editnurb; - return 0; + Object *obedit = CTX_data_edit_object(C); + if (obedit && obedit->type == OB_CURVE) + return NULL != ((Curve *)obedit->data)->editnurb; + return 0; } bool ED_operator_editcurve_3d(bContext *C) { - Object *obedit = CTX_data_edit_object(C); - if (obedit && obedit->type == OB_CURVE) { - Curve *cu = (Curve *)obedit->data; + Object *obedit = CTX_data_edit_object(C); + if (obedit && obedit->type == OB_CURVE) { + Curve *cu = (Curve *)obedit->data; - return (cu->flag & CU_3D) && (NULL != cu->editnurb); - } - return 0; + return (cu->flag & CU_3D) && (NULL != cu->editnurb); + } + return 0; } bool ED_operator_editsurf(bContext *C) { - Object *obedit = CTX_data_edit_object(C); - if (obedit && obedit->type == OB_SURF) - return NULL != ((Curve *)obedit->data)->editnurb; - return 0; + Object *obedit = CTX_data_edit_object(C); + if (obedit && obedit->type == OB_SURF) + return NULL != ((Curve *)obedit->data)->editnurb; + return 0; } bool ED_operator_editfont(bContext *C) { - Object *obedit = CTX_data_edit_object(C); - if (obedit && obedit->type == OB_FONT) - return NULL != ((Curve *)obedit->data)->editfont; - return 0; + Object *obedit = CTX_data_edit_object(C); + if (obedit && obedit->type == OB_FONT) + return NULL != ((Curve *)obedit->data)->editfont; + return 0; } bool ED_operator_editlattice(bContext *C) { - Object *obedit = CTX_data_edit_object(C); - if (obedit && obedit->type == OB_LATTICE) - return NULL != ((Lattice *)obedit->data)->editlatt; - return 0; + Object *obedit = CTX_data_edit_object(C); + if (obedit && obedit->type == OB_LATTICE) + return NULL != ((Lattice *)obedit->data)->editlatt; + return 0; } bool ED_operator_editmball(bContext *C) { - Object *obedit = CTX_data_edit_object(C); - if (obedit && obedit->type == OB_MBALL) - return NULL != ((MetaBall *)obedit->data)->editelems; - return 0; + Object *obedit = CTX_data_edit_object(C); + if (obedit && obedit->type == OB_MBALL) + return NULL != ((MetaBall *)obedit->data)->editelems; + return 0; } bool ED_operator_mask(bContext *C) { - ScrArea *sa = CTX_wm_area(C); - if (sa && sa->spacedata.first) { - switch (sa->spacetype) { - case SPACE_CLIP: - { - SpaceClip *sc = sa->spacedata.first; - return ED_space_clip_check_show_maskedit(sc); - } - case SPACE_SEQ: - { - SpaceSeq *sseq = sa->spacedata.first; - Scene *scene = CTX_data_scene(C); - return ED_space_sequencer_check_show_maskedit(sseq, scene); - } - case SPACE_IMAGE: - { - SpaceImage *sima = sa->spacedata.first; - ViewLayer *view_layer = CTX_data_view_layer(C); - return ED_space_image_check_show_maskedit(sima, view_layer); - } - } - } - - return false; + ScrArea *sa = CTX_wm_area(C); + if (sa && sa->spacedata.first) { + switch (sa->spacetype) { + case SPACE_CLIP: { + SpaceClip *sc = sa->spacedata.first; + return ED_space_clip_check_show_maskedit(sc); + } + case SPACE_SEQ: { + SpaceSeq *sseq = sa->spacedata.first; + Scene *scene = CTX_data_scene(C); + return ED_space_sequencer_check_show_maskedit(sseq, scene); + } + case SPACE_IMAGE: { + SpaceImage *sima = sa->spacedata.first; + ViewLayer *view_layer = CTX_data_view_layer(C); + return ED_space_image_check_show_maskedit(sima, view_layer); + } + } + } + + return false; } bool ED_operator_camera(bContext *C) { - struct Camera *cam = CTX_data_pointer_get_type(C, "camera", &RNA_Camera).data; - return (cam != NULL); + struct Camera *cam = CTX_data_pointer_get_type(C, "camera", &RNA_Camera).data; + return (cam != NULL); } /** \} */ @@ -580,31 +586,31 @@ bool ED_operator_camera(bContext *C) static bool screen_active_editable(bContext *C) { - if (ED_operator_screenactive(C)) { - /* no full window splitting allowed */ - if (CTX_wm_screen(C)->state != SCREENNORMAL) - return 0; - return 1; - } - return 0; + if (ED_operator_screenactive(C)) { + /* no full window splitting allowed */ + if (CTX_wm_screen(C)->state != SCREENNORMAL) + return 0; + return 1; + } + return 0; } static ARegion *screen_find_region_type(bContext *C, int type) { - ARegion *ar = CTX_wm_region(C); + ARegion *ar = CTX_wm_region(C); - /* find the header region - * - try context first, but upon failing, search all regions in area... - */ - if ((ar == NULL) || (ar->regiontype != type)) { - ScrArea *sa = CTX_wm_area(C); - ar = BKE_area_find_region_type(sa, type); - } - else { - ar = NULL; - } + /* find the header region + * - try context first, but upon failing, search all regions in area... + */ + if ((ar == NULL) || (ar->regiontype != type)) { + ScrArea *sa = CTX_wm_area(C); + ar = BKE_area_find_region_type(sa, type); + } + else { + ar = NULL; + } - return ar; + return ar; } /** \} */ @@ -620,422 +626,422 @@ static ARegion *screen_find_region_type(bContext *C, int type) * * apply() set action-zone event * - * exit() free customdata + * exit() free customdata * * callbacks: * - * exec() never used + * exec() never used * * invoke() check if in zone * add customdata, put mouseco and area in it * add modal handler * - * modal() accept modal events while doing it + * modal() accept modal events while doing it * call apply() with gesture info, active window, nonactive window * call exit() and remove handler when LMB confirm */ typedef struct sActionzoneData { - ScrArea *sa1, *sa2; - AZone *az; - int x, y, gesture_dir, modifier; + ScrArea *sa1, *sa2; + AZone *az; + int x, y, gesture_dir, modifier; } sActionzoneData; /* quick poll to save operators to be created and handled */ static bool actionzone_area_poll(bContext *C) { - wmWindow *win = CTX_wm_window(C); - bScreen *screen = WM_window_get_active_screen(win); + wmWindow *win = CTX_wm_window(C); + bScreen *screen = WM_window_get_active_screen(win); - if (screen && win && win->eventstate) { - const int *xy = &win->eventstate->x; - AZone *az; + if (screen && win && win->eventstate) { + const int *xy = &win->eventstate->x; + AZone *az; - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (az = sa->actionzones.first; az; az = az->next) - if (BLI_rcti_isect_pt_v(&az->rect, xy)) - return 1; - } - } - return 0; + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + for (az = sa->actionzones.first; az; az = az->next) + if (BLI_rcti_isect_pt_v(&az->rect, xy)) + return 1; + } + } + return 0; } /* the debug drawing of the click_rect is in area_draw_azone_fullscreen, keep both in sync */ -static void fullscreen_click_rcti_init(rcti *rect, const short x1, const short y1, const short x2, const short y2) +static void fullscreen_click_rcti_init( + rcti *rect, const short x1, const short y1, const short x2, const short y2) { - int x = x2 - ((float) x2 - x1) * 0.5f / UI_DPI_FAC; - int y = y2 - ((float) y2 - y1) * 0.5f / UI_DPI_FAC; - float icon_size = UI_DPI_ICON_SIZE + 7 * UI_DPI_FAC; + int x = x2 - ((float)x2 - x1) * 0.5f / UI_DPI_FAC; + int y = y2 - ((float)y2 - y1) * 0.5f / UI_DPI_FAC; + float icon_size = UI_DPI_ICON_SIZE + 7 * UI_DPI_FAC; - /* adjust the icon distance from the corner */ - x += 36.0f / UI_DPI_FAC; - y += 36.0f / UI_DPI_FAC; + /* adjust the icon distance from the corner */ + x += 36.0f / UI_DPI_FAC; + y += 36.0f / UI_DPI_FAC; - /* draws from the left bottom corner of the icon */ - x -= UI_DPI_ICON_SIZE; - y -= UI_DPI_ICON_SIZE; + /* draws from the left bottom corner of the icon */ + x -= UI_DPI_ICON_SIZE; + y -= UI_DPI_ICON_SIZE; - BLI_rcti_init(rect, x, x + icon_size, y, y + icon_size); + BLI_rcti_init(rect, x, x + icon_size, y, y + icon_size); } static AZone *area_actionzone_refresh_xy(ScrArea *sa, const int xy[2], const bool test_only) { - AZone *az = NULL; - - for (az = sa->actionzones.first; az; az = az->next) { - if (BLI_rcti_isect_pt_v(&az->rect, xy)) { - if (az->type == AZONE_AREA) { - break; - } - else if (az->type == AZONE_REGION) { - break; - } - else if (az->type == AZONE_FULLSCREEN) { - rcti click_rect; - fullscreen_click_rcti_init(&click_rect, az->x1, az->y1, az->x2, az->y2); - const bool click_isect = BLI_rcti_isect_pt_v(&click_rect, xy); - - if (test_only) { - if (click_isect) { - break; - } - } - else { - if (click_isect) { - az->alpha = 1.0f; - } - else { - const int mouse_sq = SQUARE(xy[0] - az->x2) + SQUARE(xy[1] - az->y2); - const int spot_sq = SQUARE(AZONESPOTW); - const int fadein_sq = SQUARE(AZONEFADEIN); - const int fadeout_sq = SQUARE(AZONEFADEOUT); - - if (mouse_sq < spot_sq) { - az->alpha = 1.0f; - } - else if (mouse_sq < fadein_sq) { - az->alpha = 1.0f; - } - else if (mouse_sq < fadeout_sq) { - az->alpha = 1.0f - ((float)(mouse_sq - fadein_sq)) / ((float)(fadeout_sq - fadein_sq)); - } - else { - az->alpha = 0.0f; - } - - /* fade in/out but no click */ - az = NULL; - } - - /* XXX force redraw to show/hide the action zone */ - ED_area_tag_redraw(sa); - break; - } - } - else if (az->type == AZONE_REGION_SCROLL) { - ARegion *ar = az->ar; - View2D *v2d = &ar->v2d; - int scroll_flag = 0; - const int isect_value = UI_view2d_mouse_in_scrollers_ex(ar, v2d, xy[0], xy[1], &scroll_flag); - - /* Check if we even have scroll bars. */ - if (((az->direction == AZ_SCROLL_HOR) && !(scroll_flag & V2D_SCROLL_HORIZONTAL)) || - ((az->direction == AZ_SCROLL_VERT) && !(scroll_flag & V2D_SCROLL_VERTICAL))) - { - /* no scrollbars, do nothing. */ - } - else if (test_only) { - if (isect_value != 0) { - break; - } - } - else { - bool redraw = false; - - if (isect_value == 'h') { - if (az->direction == AZ_SCROLL_HOR) { - az->alpha = 1.0f; - v2d->alpha_hor = 255; - redraw = true; - } - } - else if (isect_value == 'v') { - if (az->direction == AZ_SCROLL_VERT) { - az->alpha = 1.0f; - v2d->alpha_vert = 255; - redraw = true; - } - } - else { - const int local_xy[2] = {xy[0] - ar->winrct.xmin, xy[1] - ar->winrct.ymin}; - float dist_fac = 0.0f, alpha = 0.0f; - - if (az->direction == AZ_SCROLL_HOR) { - dist_fac = BLI_rcti_length_y(&v2d->hor, local_xy[1]) / AZONEFADEIN; - CLAMP(dist_fac, 0.0f, 1.0f); - alpha = 1.0f - dist_fac; - - v2d->alpha_hor = alpha * 255; - } - else if (az->direction == AZ_SCROLL_VERT) { - dist_fac = BLI_rcti_length_x(&v2d->vert, local_xy[0]) / AZONEFADEIN; - CLAMP(dist_fac, 0.0f, 1.0f); - alpha = 1.0f - dist_fac; - - v2d->alpha_vert = alpha * 255; - } - az->alpha = alpha; - redraw = true; - } - - if (redraw) { - ED_region_tag_redraw_no_rebuild(ar); - } - /* Don't return! */ - } - } - } - else if (!test_only && !IS_EQF(az->alpha, 0.0f)) { - if (az->type == AZONE_FULLSCREEN) { - az->alpha = 0.0f; - sa->flag &= ~AREA_FLAG_ACTIONZONES_UPDATE; - ED_area_tag_redraw_no_rebuild(sa); - } - else if (az->type == AZONE_REGION_SCROLL) { - if (az->direction == AZ_SCROLL_VERT) { - az->alpha = az->ar->v2d.alpha_vert = 0; - sa->flag &= ~AREA_FLAG_ACTIONZONES_UPDATE; - ED_region_tag_redraw_no_rebuild(az->ar); - } - else if (az->direction == AZ_SCROLL_HOR) { - az->alpha = az->ar->v2d.alpha_hor = 0; - sa->flag &= ~AREA_FLAG_ACTIONZONES_UPDATE; - ED_region_tag_redraw_no_rebuild(az->ar); - } - else { - BLI_assert(0); - } - } - } - } - - return az; + AZone *az = NULL; + + for (az = sa->actionzones.first; az; az = az->next) { + if (BLI_rcti_isect_pt_v(&az->rect, xy)) { + if (az->type == AZONE_AREA) { + break; + } + else if (az->type == AZONE_REGION) { + break; + } + else if (az->type == AZONE_FULLSCREEN) { + rcti click_rect; + fullscreen_click_rcti_init(&click_rect, az->x1, az->y1, az->x2, az->y2); + const bool click_isect = BLI_rcti_isect_pt_v(&click_rect, xy); + + if (test_only) { + if (click_isect) { + break; + } + } + else { + if (click_isect) { + az->alpha = 1.0f; + } + else { + const int mouse_sq = SQUARE(xy[0] - az->x2) + SQUARE(xy[1] - az->y2); + const int spot_sq = SQUARE(AZONESPOTW); + const int fadein_sq = SQUARE(AZONEFADEIN); + const int fadeout_sq = SQUARE(AZONEFADEOUT); + + if (mouse_sq < spot_sq) { + az->alpha = 1.0f; + } + else if (mouse_sq < fadein_sq) { + az->alpha = 1.0f; + } + else if (mouse_sq < fadeout_sq) { + az->alpha = 1.0f - + ((float)(mouse_sq - fadein_sq)) / ((float)(fadeout_sq - fadein_sq)); + } + else { + az->alpha = 0.0f; + } + + /* fade in/out but no click */ + az = NULL; + } + + /* XXX force redraw to show/hide the action zone */ + ED_area_tag_redraw(sa); + break; + } + } + else if (az->type == AZONE_REGION_SCROLL) { + ARegion *ar = az->ar; + View2D *v2d = &ar->v2d; + int scroll_flag = 0; + const int isect_value = UI_view2d_mouse_in_scrollers_ex( + ar, v2d, xy[0], xy[1], &scroll_flag); + + /* Check if we even have scroll bars. */ + if (((az->direction == AZ_SCROLL_HOR) && !(scroll_flag & V2D_SCROLL_HORIZONTAL)) || + ((az->direction == AZ_SCROLL_VERT) && !(scroll_flag & V2D_SCROLL_VERTICAL))) { + /* no scrollbars, do nothing. */ + } + else if (test_only) { + if (isect_value != 0) { + break; + } + } + else { + bool redraw = false; + + if (isect_value == 'h') { + if (az->direction == AZ_SCROLL_HOR) { + az->alpha = 1.0f; + v2d->alpha_hor = 255; + redraw = true; + } + } + else if (isect_value == 'v') { + if (az->direction == AZ_SCROLL_VERT) { + az->alpha = 1.0f; + v2d->alpha_vert = 255; + redraw = true; + } + } + else { + const int local_xy[2] = {xy[0] - ar->winrct.xmin, xy[1] - ar->winrct.ymin}; + float dist_fac = 0.0f, alpha = 0.0f; + + if (az->direction == AZ_SCROLL_HOR) { + dist_fac = BLI_rcti_length_y(&v2d->hor, local_xy[1]) / AZONEFADEIN; + CLAMP(dist_fac, 0.0f, 1.0f); + alpha = 1.0f - dist_fac; + + v2d->alpha_hor = alpha * 255; + } + else if (az->direction == AZ_SCROLL_VERT) { + dist_fac = BLI_rcti_length_x(&v2d->vert, local_xy[0]) / AZONEFADEIN; + CLAMP(dist_fac, 0.0f, 1.0f); + alpha = 1.0f - dist_fac; + + v2d->alpha_vert = alpha * 255; + } + az->alpha = alpha; + redraw = true; + } + + if (redraw) { + ED_region_tag_redraw_no_rebuild(ar); + } + /* Don't return! */ + } + } + } + else if (!test_only && !IS_EQF(az->alpha, 0.0f)) { + if (az->type == AZONE_FULLSCREEN) { + az->alpha = 0.0f; + sa->flag &= ~AREA_FLAG_ACTIONZONES_UPDATE; + ED_area_tag_redraw_no_rebuild(sa); + } + else if (az->type == AZONE_REGION_SCROLL) { + if (az->direction == AZ_SCROLL_VERT) { + az->alpha = az->ar->v2d.alpha_vert = 0; + sa->flag &= ~AREA_FLAG_ACTIONZONES_UPDATE; + ED_region_tag_redraw_no_rebuild(az->ar); + } + else if (az->direction == AZ_SCROLL_HOR) { + az->alpha = az->ar->v2d.alpha_hor = 0; + sa->flag &= ~AREA_FLAG_ACTIONZONES_UPDATE; + ED_region_tag_redraw_no_rebuild(az->ar); + } + else { + BLI_assert(0); + } + } + } + } + + return az; } /* Finds an action-zone by position in entire screen so azones can overlap. */ static AZone *screen_actionzone_find_xy(bScreen *sc, const int xy[2]) { - for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) { - AZone *az = area_actionzone_refresh_xy(sa, xy, true); - if (az != NULL) { - return az; - } - } - return NULL; + for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) { + AZone *az = area_actionzone_refresh_xy(sa, xy, true); + if (az != NULL) { + return az; + } + } + return NULL; } /* Returns the area that the azone belongs to */ static ScrArea *screen_actionzone_area(bScreen *sc, const AZone *az) { - for (ScrArea *area = sc->areabase.first; area; area = area->next) { - for (AZone *zone = area->actionzones.first; zone; zone = zone->next) { - if (zone == az) { - return area; - } - } - } - return NULL; + for (ScrArea *area = sc->areabase.first; area; area = area->next) { + for (AZone *zone = area->actionzones.first; zone; zone = zone->next) { + if (zone == az) { + return area; + } + } + } + return NULL; } AZone *ED_area_actionzone_find_xy(ScrArea *sa, const int xy[2]) { - return area_actionzone_refresh_xy(sa, xy, true); + return area_actionzone_refresh_xy(sa, xy, true); } AZone *ED_area_azones_update(ScrArea *sa, const int xy[2]) { - return area_actionzone_refresh_xy(sa, xy, false); + return area_actionzone_refresh_xy(sa, xy, false); } static void actionzone_exit(wmOperator *op) { - if (op->customdata) - MEM_freeN(op->customdata); - op->customdata = NULL; + if (op->customdata) + MEM_freeN(op->customdata); + op->customdata = NULL; } /* send EVT_ACTIONZONE event */ static void actionzone_apply(bContext *C, wmOperator *op, int type) { - wmEvent event; - wmWindow *win = CTX_wm_window(C); - sActionzoneData *sad = op->customdata; + wmEvent event; + wmWindow *win = CTX_wm_window(C); + sActionzoneData *sad = op->customdata; - sad->modifier = RNA_int_get(op->ptr, "modifier"); + sad->modifier = RNA_int_get(op->ptr, "modifier"); - wm_event_init_from_window(win, &event); + wm_event_init_from_window(win, &event); - if (type == AZONE_AREA) - event.type = EVT_ACTIONZONE_AREA; - else if (type == AZONE_FULLSCREEN) - event.type = EVT_ACTIONZONE_FULLSCREEN; - else - event.type = EVT_ACTIONZONE_REGION; + if (type == AZONE_AREA) + event.type = EVT_ACTIONZONE_AREA; + else if (type == AZONE_FULLSCREEN) + event.type = EVT_ACTIONZONE_FULLSCREEN; + else + event.type = EVT_ACTIONZONE_REGION; - event.val = KM_NOTHING; - event.customdata = op->customdata; - event.customdatafree = true; - op->customdata = NULL; + event.val = KM_NOTHING; + event.customdata = op->customdata; + event.customdatafree = true; + op->customdata = NULL; - wm_event_add(win, &event); + wm_event_add(win, &event); } static int actionzone_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - bScreen *sc = CTX_wm_screen(C); - AZone *az = screen_actionzone_find_xy(sc, &event->x); - sActionzoneData *sad; + bScreen *sc = CTX_wm_screen(C); + AZone *az = screen_actionzone_find_xy(sc, &event->x); + sActionzoneData *sad; - /* quick escape - Scroll azones only hide/unhide the scroll-bars, they have their own handling. */ - if (az == NULL || ELEM(az->type, AZONE_REGION_SCROLL)) - return OPERATOR_PASS_THROUGH; + /* quick escape - Scroll azones only hide/unhide the scroll-bars, they have their own handling. */ + if (az == NULL || ELEM(az->type, AZONE_REGION_SCROLL)) + return OPERATOR_PASS_THROUGH; - /* ok we do the action-zone */ - sad = op->customdata = MEM_callocN(sizeof(sActionzoneData), "sActionzoneData"); - sad->sa1 = screen_actionzone_area(sc, az); - sad->az = az; - sad->x = event->x; sad->y = event->y; + /* ok we do the action-zone */ + sad = op->customdata = MEM_callocN(sizeof(sActionzoneData), "sActionzoneData"); + sad->sa1 = screen_actionzone_area(sc, az); + sad->az = az; + sad->x = event->x; + sad->y = event->y; - /* region azone directly reacts on mouse clicks */ - if (ELEM(sad->az->type, AZONE_REGION, AZONE_FULLSCREEN)) { - actionzone_apply(C, op, sad->az->type); - actionzone_exit(op); - return OPERATOR_FINISHED; - } - else { - /* add modal handler */ - WM_event_add_modal_handler(C, op); + /* region azone directly reacts on mouse clicks */ + if (ELEM(sad->az->type, AZONE_REGION, AZONE_FULLSCREEN)) { + actionzone_apply(C, op, sad->az->type); + actionzone_exit(op); + return OPERATOR_FINISHED; + } + else { + /* add modal handler */ + WM_event_add_modal_handler(C, op); - return OPERATOR_RUNNING_MODAL; - } + return OPERATOR_RUNNING_MODAL; + } } - static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event) { - bScreen *sc = CTX_wm_screen(C); - sActionzoneData *sad = op->customdata; - - switch (event->type) { - case MOUSEMOVE: - { - bool is_gesture; - - const int delta_x = (event->x - sad->x); - const int delta_y = (event->y - sad->y); - - /* Movement in dominant direction. */ - const int delta_max = max_ii(ABS(delta_x), ABS(delta_y)); - - /* Movement in dominant direction before action taken. */ - const int join_threshold = (0.6 * U.widget_unit); - const int split_threshold = (1.2 * U.widget_unit); - const int area_threshold = (0.1 * U.widget_unit); - - /* Calculate gesture cardinal direction. */ - if (delta_y > ABS(delta_x)) - sad->gesture_dir = 'n'; - else if (delta_x >= ABS(delta_y)) - sad->gesture_dir = 'e'; - else if (delta_y < -ABS(delta_x)) - sad->gesture_dir = 's'; - else - sad->gesture_dir = 'w'; - - if (sad->az->type == AZONE_AREA) { - wmWindow *win = CTX_wm_window(C); - rcti screen_rect; - - WM_window_screen_rect_calc(win, &screen_rect); - - /* Have we dragged off the zone and are not on an edge? */ - if ((ED_area_actionzone_find_xy(sad->sa1, &event->x) != sad->az) && - (screen_geom_area_map_find_active_scredge( - AREAMAP_FROM_SCREEN(sc), &screen_rect, event->x, event->y) == NULL)) - { - /* Are we still in same area? */ - if (BKE_screen_find_area_xy(sc, SPACE_TYPE_ANY, event->x, event->y) == sad->sa1) { - /* Same area, so possible split. */ - WM_cursor_set(win, (ELEM(sad->gesture_dir, 'n', 's')) ? BC_V_SPLITCURSOR : BC_H_SPLITCURSOR); - is_gesture = (delta_max > split_threshold); - } - else { - /* Different area, so posible join. */ - if (sad->gesture_dir == 'n') - WM_cursor_set(win, BC_N_ARROWCURSOR); - else if (sad->gesture_dir == 's') - WM_cursor_set(win, BC_S_ARROWCURSOR); - else if (sad->gesture_dir == 'e') - WM_cursor_set(win, BC_E_ARROWCURSOR); - else - WM_cursor_set(win, BC_W_ARROWCURSOR); - is_gesture = (delta_max > join_threshold); - } - } - else { - WM_cursor_set(CTX_wm_window(C), BC_CROSSCURSOR); - is_gesture = false; - } - } - else { - is_gesture = (delta_max > area_threshold); - } - - /* gesture is large enough? */ - if (is_gesture) { - /* second area, for join when (sa1 != sa2) */ - sad->sa2 = BKE_screen_find_area_xy(sc, SPACE_TYPE_ANY, event->x, event->y); - /* apply sends event */ - actionzone_apply(C, op, sad->az->type); - actionzone_exit(op); - - return OPERATOR_FINISHED; - } - break; - } - case ESCKEY: - actionzone_exit(op); - return OPERATOR_CANCELLED; - case LEFTMOUSE: - actionzone_exit(op); - return OPERATOR_CANCELLED; - - } - - return OPERATOR_RUNNING_MODAL; + bScreen *sc = CTX_wm_screen(C); + sActionzoneData *sad = op->customdata; + + switch (event->type) { + case MOUSEMOVE: { + bool is_gesture; + + const int delta_x = (event->x - sad->x); + const int delta_y = (event->y - sad->y); + + /* Movement in dominant direction. */ + const int delta_max = max_ii(ABS(delta_x), ABS(delta_y)); + + /* Movement in dominant direction before action taken. */ + const int join_threshold = (0.6 * U.widget_unit); + const int split_threshold = (1.2 * U.widget_unit); + const int area_threshold = (0.1 * U.widget_unit); + + /* Calculate gesture cardinal direction. */ + if (delta_y > ABS(delta_x)) + sad->gesture_dir = 'n'; + else if (delta_x >= ABS(delta_y)) + sad->gesture_dir = 'e'; + else if (delta_y < -ABS(delta_x)) + sad->gesture_dir = 's'; + else + sad->gesture_dir = 'w'; + + if (sad->az->type == AZONE_AREA) { + wmWindow *win = CTX_wm_window(C); + rcti screen_rect; + + WM_window_screen_rect_calc(win, &screen_rect); + + /* Have we dragged off the zone and are not on an edge? */ + if ((ED_area_actionzone_find_xy(sad->sa1, &event->x) != sad->az) && + (screen_geom_area_map_find_active_scredge( + AREAMAP_FROM_SCREEN(sc), &screen_rect, event->x, event->y) == NULL)) { + /* Are we still in same area? */ + if (BKE_screen_find_area_xy(sc, SPACE_TYPE_ANY, event->x, event->y) == sad->sa1) { + /* Same area, so possible split. */ + WM_cursor_set( + win, (ELEM(sad->gesture_dir, 'n', 's')) ? BC_V_SPLITCURSOR : BC_H_SPLITCURSOR); + is_gesture = (delta_max > split_threshold); + } + else { + /* Different area, so posible join. */ + if (sad->gesture_dir == 'n') + WM_cursor_set(win, BC_N_ARROWCURSOR); + else if (sad->gesture_dir == 's') + WM_cursor_set(win, BC_S_ARROWCURSOR); + else if (sad->gesture_dir == 'e') + WM_cursor_set(win, BC_E_ARROWCURSOR); + else + WM_cursor_set(win, BC_W_ARROWCURSOR); + is_gesture = (delta_max > join_threshold); + } + } + else { + WM_cursor_set(CTX_wm_window(C), BC_CROSSCURSOR); + is_gesture = false; + } + } + else { + is_gesture = (delta_max > area_threshold); + } + + /* gesture is large enough? */ + if (is_gesture) { + /* second area, for join when (sa1 != sa2) */ + sad->sa2 = BKE_screen_find_area_xy(sc, SPACE_TYPE_ANY, event->x, event->y); + /* apply sends event */ + actionzone_apply(C, op, sad->az->type); + actionzone_exit(op); + + return OPERATOR_FINISHED; + } + break; + } + case ESCKEY: + actionzone_exit(op); + return OPERATOR_CANCELLED; + case LEFTMOUSE: + actionzone_exit(op); + return OPERATOR_CANCELLED; + } + + return OPERATOR_RUNNING_MODAL; } static void actionzone_cancel(bContext *UNUSED(C), wmOperator *op) { - actionzone_exit(op); + actionzone_exit(op); } static void SCREEN_OT_actionzone(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Handle Area Action Zones"; - ot->description = "Handle area action zones for mouse actions/gestures"; - ot->idname = "SCREEN_OT_actionzone"; + /* identifiers */ + ot->name = "Handle Area Action Zones"; + ot->description = "Handle area action zones for mouse actions/gestures"; + ot->idname = "SCREEN_OT_actionzone"; - ot->invoke = actionzone_invoke; - ot->modal = actionzone_modal; - ot->poll = actionzone_area_poll; - ot->cancel = actionzone_cancel; + ot->invoke = actionzone_invoke; + ot->modal = actionzone_modal; + ot->poll = actionzone_area_poll; + ot->cancel = actionzone_cancel; - /* flags */ - ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL; + /* flags */ + ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL; - RNA_def_int(ot->srna, "modifier", 0, 0, 2, "Modifier", "Modifier state", 0, 2); + RNA_def_int(ot->srna, "modifier", 0, 0, 2, "Modifier", "Modifier state", 0, 2); } /** \} */ @@ -1065,101 +1071,99 @@ static void SCREEN_OT_actionzone(wmOperatorType *ot) */ typedef struct sAreaSwapData { - ScrArea *sa1, *sa2; + ScrArea *sa1, *sa2; } sAreaSwapData; static int area_swap_init(wmOperator *op, const wmEvent *event) { - sAreaSwapData *sd = NULL; - sActionzoneData *sad = event->customdata; + sAreaSwapData *sd = NULL; + sActionzoneData *sad = event->customdata; - if (sad == NULL || sad->sa1 == NULL) - return 0; + if (sad == NULL || sad->sa1 == NULL) + return 0; - sd = MEM_callocN(sizeof(sAreaSwapData), "sAreaSwapData"); - sd->sa1 = sad->sa1; - sd->sa2 = sad->sa2; - op->customdata = sd; + sd = MEM_callocN(sizeof(sAreaSwapData), "sAreaSwapData"); + sd->sa1 = sad->sa1; + sd->sa2 = sad->sa2; + op->customdata = sd; - return 1; + return 1; } - static void area_swap_exit(bContext *C, wmOperator *op) { - WM_cursor_modal_restore(CTX_wm_window(C)); - if (op->customdata) - MEM_freeN(op->customdata); - op->customdata = NULL; + WM_cursor_modal_restore(CTX_wm_window(C)); + if (op->customdata) + MEM_freeN(op->customdata); + op->customdata = NULL; } static void area_swap_cancel(bContext *C, wmOperator *op) { - area_swap_exit(C, op); + area_swap_exit(C, op); } static int area_swap_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - if (!area_swap_init(op, event)) - return OPERATOR_PASS_THROUGH; + if (!area_swap_init(op, event)) + return OPERATOR_PASS_THROUGH; - /* add modal handler */ - WM_cursor_modal_set(CTX_wm_window(C), BC_SWAPAREA_CURSOR); - WM_event_add_modal_handler(C, op); - - return OPERATOR_RUNNING_MODAL; + /* add modal handler */ + WM_cursor_modal_set(CTX_wm_window(C), BC_SWAPAREA_CURSOR); + WM_event_add_modal_handler(C, op); + return OPERATOR_RUNNING_MODAL; } static int area_swap_modal(bContext *C, wmOperator *op, const wmEvent *event) { - sActionzoneData *sad = op->customdata; + sActionzoneData *sad = op->customdata; - switch (event->type) { - case MOUSEMOVE: - /* second area, for join */ - sad->sa2 = BKE_screen_find_area_xy(CTX_wm_screen(C), SPACE_TYPE_ANY, event->x, event->y); - break; - case LEFTMOUSE: /* release LMB */ - if (event->val == KM_RELEASE) { - if (!sad->sa2 || sad->sa1 == sad->sa2) { - area_swap_cancel(C, op); - return OPERATOR_CANCELLED; - } + switch (event->type) { + case MOUSEMOVE: + /* second area, for join */ + sad->sa2 = BKE_screen_find_area_xy(CTX_wm_screen(C), SPACE_TYPE_ANY, event->x, event->y); + break; + case LEFTMOUSE: /* release LMB */ + if (event->val == KM_RELEASE) { + if (!sad->sa2 || sad->sa1 == sad->sa2) { + area_swap_cancel(C, op); + return OPERATOR_CANCELLED; + } - ED_area_tag_redraw(sad->sa1); - ED_area_tag_redraw(sad->sa2); + ED_area_tag_redraw(sad->sa1); + ED_area_tag_redraw(sad->sa2); - ED_area_swapspace(C, sad->sa1, sad->sa2); + ED_area_swapspace(C, sad->sa1, sad->sa2); - area_swap_exit(C, op); + area_swap_exit(C, op); - WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); + WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); - return OPERATOR_FINISHED; - } - break; + return OPERATOR_FINISHED; + } + break; - case ESCKEY: - area_swap_cancel(C, op); - return OPERATOR_CANCELLED; - } - return OPERATOR_RUNNING_MODAL; + case ESCKEY: + area_swap_cancel(C, op); + return OPERATOR_CANCELLED; + } + return OPERATOR_RUNNING_MODAL; } static void SCREEN_OT_area_swap(wmOperatorType *ot) { - ot->name = "Swap Areas"; - ot->description = "Swap selected areas screen positions"; - ot->idname = "SCREEN_OT_area_swap"; + ot->name = "Swap Areas"; + ot->description = "Swap selected areas screen positions"; + ot->idname = "SCREEN_OT_area_swap"; - ot->invoke = area_swap_invoke; - ot->modal = area_swap_modal; - ot->poll = ED_operator_areaactive; - ot->cancel = area_swap_cancel; + ot->invoke = area_swap_invoke; + ot->modal = area_swap_modal; + ot->poll = ED_operator_areaactive; + ot->cancel = area_swap_cancel; - ot->flag = OPTYPE_BLOCKING; + ot->flag = OPTYPE_BLOCKING; } /** \} */ @@ -1173,81 +1177,81 @@ static void SCREEN_OT_area_swap(wmOperatorType *ot) /* operator callback */ static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - Main *bmain = CTX_data_main(C); - wmWindow *newwin, *win = CTX_wm_window(C); - Scene *scene; - WorkSpace *workspace = WM_window_get_active_workspace(win); - WorkSpaceLayout *layout_old = WM_window_get_active_layout(win); - WorkSpaceLayout *layout_new; - bScreen *newsc; - ScrArea *sa; - rcti rect; - - win = CTX_wm_window(C); - scene = CTX_data_scene(C); - sa = CTX_wm_area(C); + Main *bmain = CTX_data_main(C); + wmWindow *newwin, *win = CTX_wm_window(C); + Scene *scene; + WorkSpace *workspace = WM_window_get_active_workspace(win); + WorkSpaceLayout *layout_old = WM_window_get_active_layout(win); + WorkSpaceLayout *layout_new; + bScreen *newsc; + ScrArea *sa; + rcti rect; - /* XXX hrmf! */ - if (event->type == EVT_ACTIONZONE_AREA) { - sActionzoneData *sad = event->customdata; + win = CTX_wm_window(C); + scene = CTX_data_scene(C); + sa = CTX_wm_area(C); - if (sad == NULL) - return OPERATOR_PASS_THROUGH; + /* XXX hrmf! */ + if (event->type == EVT_ACTIONZONE_AREA) { + sActionzoneData *sad = event->customdata; - sa = sad->sa1; - } + if (sad == NULL) + return OPERATOR_PASS_THROUGH; - /* adds window to WM */ - rect = sa->totrct; - BLI_rcti_translate(&rect, win->posx, win->posy); - rect.xmax = rect.xmin + BLI_rcti_size_x(&rect) / U.pixelsize; - rect.ymax = rect.ymin + BLI_rcti_size_y(&rect) / U.pixelsize; + sa = sad->sa1; + } - newwin = WM_window_open(C, &rect); - if (newwin == NULL) { - BKE_report(op->reports, RPT_ERROR, "Failed to open window!"); - goto finally; - } + /* adds window to WM */ + rect = sa->totrct; + BLI_rcti_translate(&rect, win->posx, win->posy); + rect.xmax = rect.xmin + BLI_rcti_size_x(&rect) / U.pixelsize; + rect.ymax = rect.ymin + BLI_rcti_size_y(&rect) / U.pixelsize; - *newwin->stereo3d_format = *win->stereo3d_format; + newwin = WM_window_open(C, &rect); + if (newwin == NULL) { + BKE_report(op->reports, RPT_ERROR, "Failed to open window!"); + goto finally; + } - newwin->scene = scene; + *newwin->stereo3d_format = *win->stereo3d_format; - BKE_workspace_active_set(newwin->workspace_hook, workspace); - /* allocs new screen and adds to newly created window, using window size */ - layout_new = ED_workspace_layout_add(bmain, workspace, newwin, BKE_workspace_layout_name_get(layout_old)); - newsc = BKE_workspace_layout_screen_get(layout_new); - WM_window_set_active_layout(newwin, workspace, layout_new); + newwin->scene = scene; - /* copy area to new screen */ - ED_area_data_copy((ScrArea *)newsc->areabase.first, sa, true); + BKE_workspace_active_set(newwin->workspace_hook, workspace); + /* allocs new screen and adds to newly created window, using window size */ + layout_new = ED_workspace_layout_add( + bmain, workspace, newwin, BKE_workspace_layout_name_get(layout_old)); + newsc = BKE_workspace_layout_screen_get(layout_new); + WM_window_set_active_layout(newwin, workspace, layout_new); - ED_area_tag_redraw((ScrArea *)newsc->areabase.first); + /* copy area to new screen */ + ED_area_data_copy((ScrArea *)newsc->areabase.first, sa, true); - /* screen, areas init */ - WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); + ED_area_tag_redraw((ScrArea *)newsc->areabase.first); + /* screen, areas init */ + WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); finally: - if (event->type == EVT_ACTIONZONE_AREA) - actionzone_exit(op); + if (event->type == EVT_ACTIONZONE_AREA) + actionzone_exit(op); - if (newwin) { - return OPERATOR_FINISHED; - } - else { - return OPERATOR_CANCELLED; - } + if (newwin) { + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } } static void SCREEN_OT_area_dupli(wmOperatorType *ot) { - ot->name = "Duplicate Area into New Window"; - ot->description = "Duplicate selected area into new window"; - ot->idname = "SCREEN_OT_area_dupli"; + ot->name = "Duplicate Area into New Window"; + ot->description = "Duplicate selected area into new window"; + ot->idname = "SCREEN_OT_area_dupli"; - ot->invoke = area_dupli_invoke; - ot->poll = ED_operator_areaactive; + ot->invoke = area_dupli_invoke; + ot->poll = ED_operator_areaactive; } /** \} */ @@ -1265,9 +1269,9 @@ static void SCREEN_OT_area_dupli(wmOperatorType *ot) * init() set default property values, find edge based on mouse coords, test * if the edge can be moved, select edges, calculate min and max movement * - * apply() apply delta on selection + * apply() apply delta on selection * - * exit() cleanup, send notifier + * exit() cleanup, send notifier * * cancel() cancel moving * @@ -1285,443 +1289,454 @@ static void SCREEN_OT_area_dupli(wmOperatorType *ot) */ typedef struct sAreaMoveData { - int bigger, smaller, origval, step; - char dir; - enum AreaMoveSnapType { - /* Snapping disabled */ - SNAP_NONE = 0, - /* Snap to an invisible grid with a unit defined in AREAGRID */ - SNAP_AREAGRID, - /* Snap to fraction (half, third.. etc) and adjacent edges. */ - SNAP_FRACTION_AND_ADJACENT, - /* Snap to either bigger or smaller, nothing in-between (used for - * global areas). This has priority over other snap types, if it is - * used, toggling SNAP_FRACTION_AND_ADJACENT doesn't work. */ - SNAP_BIGGER_SMALLER_ONLY, - } snap_type; + int bigger, smaller, origval, step; + char dir; + enum AreaMoveSnapType { + /* Snapping disabled */ + SNAP_NONE = 0, + /* Snap to an invisible grid with a unit defined in AREAGRID */ + SNAP_AREAGRID, + /* Snap to fraction (half, third.. etc) and adjacent edges. */ + SNAP_FRACTION_AND_ADJACENT, + /* Snap to either bigger or smaller, nothing in-between (used for + * global areas). This has priority over other snap types, if it is + * used, toggling SNAP_FRACTION_AND_ADJACENT doesn't work. */ + SNAP_BIGGER_SMALLER_ONLY, + } snap_type; } sAreaMoveData; /* helper call to move area-edge, sets limits * need window bounds in order to get correct limits */ static void area_move_set_limits( - wmWindow *win, bScreen *sc, int dir, - int *bigger, int *smaller, - bool *use_bigger_smaller_snap) -{ - rcti window_rect; - int areaminy = ED_area_headersize(); - int areamin; - - /* we check all areas and test for free space with MINSIZE */ - *bigger = *smaller = 100000; - - if (use_bigger_smaller_snap != NULL) { - *use_bigger_smaller_snap = false; - for (ScrArea *area = win->global_areas.areabase.first; area; area = area->next) { - int size_min = ED_area_global_min_size_y(area) - 1; - int size_max = ED_area_global_max_size_y(area) - 1; - - size_min = max_ii(size_min, 0); - BLI_assert(size_min < size_max); - - /* logic here is only tested for lower edge :) */ - /* left edge */ - if ((area->v1->editflag && area->v2->editflag)) { - *smaller = area->v4->vec.x - size_max; - *bigger = area->v4->vec.x - size_min; - *use_bigger_smaller_snap = true; - return; - } - /* top edge */ - else if ((area->v2->editflag && area->v3->editflag)) { - *smaller = area->v1->vec.y + size_min; - *bigger = area->v1->vec.y + size_max; - *use_bigger_smaller_snap = true; - return; - } - /* right edge */ - else if ((area->v3->editflag && area->v4->editflag)) { - *smaller = area->v1->vec.x + size_min; - *bigger = area->v1->vec.x + size_max; - *use_bigger_smaller_snap = true; - return; - } - /* lower edge */ - else if ((area->v4->editflag && area->v1->editflag)) { - *smaller = area->v2->vec.y - size_max; - *bigger = area->v2->vec.y - size_min; - *use_bigger_smaller_snap = true; - return; - } - } - } - - WM_window_rect_calc(win, &window_rect); - - for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) { - if (dir == 'h') { - int y1; - areamin = areaminy; - - if (sa->v1->vec.y > window_rect.ymin) - areamin += U.pixelsize; - if (sa->v2->vec.y < (window_rect.ymax - 1)) - areamin += U.pixelsize; - - y1 = screen_geom_area_height(sa) - areamin; - - /* if top or down edge selected, test height */ - if (sa->v1->editflag && sa->v4->editflag) - *bigger = min_ii(*bigger, y1); - else if (sa->v2->editflag && sa->v3->editflag) - *smaller = min_ii(*smaller, y1); - } - else { - int x1; - areamin = AREAMINX; - - if (sa->v1->vec.x > window_rect.xmin) - areamin += U.pixelsize; - if (sa->v4->vec.x < (window_rect.xmax - 1)) - areamin += U.pixelsize; - - x1 = screen_geom_area_width(sa) - areamin; - - /* if left or right edge selected, test width */ - if (sa->v1->editflag && sa->v2->editflag) - *bigger = min_ii(*bigger, x1); - else if (sa->v3->editflag && sa->v4->editflag) - *smaller = min_ii(*smaller, x1); - } - } + wmWindow *win, bScreen *sc, int dir, int *bigger, int *smaller, bool *use_bigger_smaller_snap) +{ + rcti window_rect; + int areaminy = ED_area_headersize(); + int areamin; + + /* we check all areas and test for free space with MINSIZE */ + *bigger = *smaller = 100000; + + if (use_bigger_smaller_snap != NULL) { + *use_bigger_smaller_snap = false; + for (ScrArea *area = win->global_areas.areabase.first; area; area = area->next) { + int size_min = ED_area_global_min_size_y(area) - 1; + int size_max = ED_area_global_max_size_y(area) - 1; + + size_min = max_ii(size_min, 0); + BLI_assert(size_min < size_max); + + /* logic here is only tested for lower edge :) */ + /* left edge */ + if ((area->v1->editflag && area->v2->editflag)) { + *smaller = area->v4->vec.x - size_max; + *bigger = area->v4->vec.x - size_min; + *use_bigger_smaller_snap = true; + return; + } + /* top edge */ + else if ((area->v2->editflag && area->v3->editflag)) { + *smaller = area->v1->vec.y + size_min; + *bigger = area->v1->vec.y + size_max; + *use_bigger_smaller_snap = true; + return; + } + /* right edge */ + else if ((area->v3->editflag && area->v4->editflag)) { + *smaller = area->v1->vec.x + size_min; + *bigger = area->v1->vec.x + size_max; + *use_bigger_smaller_snap = true; + return; + } + /* lower edge */ + else if ((area->v4->editflag && area->v1->editflag)) { + *smaller = area->v2->vec.y - size_max; + *bigger = area->v2->vec.y - size_min; + *use_bigger_smaller_snap = true; + return; + } + } + } + + WM_window_rect_calc(win, &window_rect); + + for (ScrArea *sa = sc->areabase.first; sa; sa = sa->next) { + if (dir == 'h') { + int y1; + areamin = areaminy; + + if (sa->v1->vec.y > window_rect.ymin) + areamin += U.pixelsize; + if (sa->v2->vec.y < (window_rect.ymax - 1)) + areamin += U.pixelsize; + + y1 = screen_geom_area_height(sa) - areamin; + + /* if top or down edge selected, test height */ + if (sa->v1->editflag && sa->v4->editflag) + *bigger = min_ii(*bigger, y1); + else if (sa->v2->editflag && sa->v3->editflag) + *smaller = min_ii(*smaller, y1); + } + else { + int x1; + areamin = AREAMINX; + + if (sa->v1->vec.x > window_rect.xmin) + areamin += U.pixelsize; + if (sa->v4->vec.x < (window_rect.xmax - 1)) + areamin += U.pixelsize; + + x1 = screen_geom_area_width(sa) - areamin; + + /* if left or right edge selected, test width */ + if (sa->v1->editflag && sa->v2->editflag) + *bigger = min_ii(*bigger, x1); + else if (sa->v3->editflag && sa->v4->editflag) + *smaller = min_ii(*smaller, x1); + } + } } /* validate selection inside screen, set variables OK */ /* return 0: init failed */ static int area_move_init(bContext *C, wmOperator *op) { - bScreen *sc = CTX_wm_screen(C); - wmWindow *win = CTX_wm_window(C); - ScrEdge *actedge; - sAreaMoveData *md; - int x, y; - - /* required properties */ - x = RNA_int_get(op->ptr, "x"); - y = RNA_int_get(op->ptr, "y"); - - /* setup */ - actedge = screen_geom_find_active_scredge(win, sc, x, y); - if (actedge == NULL) return 0; - - md = MEM_callocN(sizeof(sAreaMoveData), "sAreaMoveData"); - op->customdata = md; - - md->dir = screen_geom_edge_is_horizontal(actedge) ? 'h' : 'v'; - if (md->dir == 'h') md->origval = actedge->v1->vec.y; - else md->origval = actedge->v1->vec.x; - - screen_geom_select_connected_edge(win, actedge); - /* now all vertices with 'flag == 1' are the ones that can be moved. Move this to editflag */ - ED_screen_verts_iter(win, sc, v1) { - v1->editflag = v1->flag; - } - - bool use_bigger_smaller_snap = false; - area_move_set_limits(win, sc, md->dir, &md->bigger, &md->smaller, &use_bigger_smaller_snap); - - md->snap_type = use_bigger_smaller_snap ? SNAP_BIGGER_SMALLER_ONLY : SNAP_AREAGRID; - - return 1; -} - -static int area_snap_calc_location( - const bScreen *sc, const enum AreaMoveSnapType snap_type, - const int delta, const int origval, const int dir, - const int bigger, const int smaller) -{ - BLI_assert(snap_type != SNAP_NONE); - int m_cursor_final = -1; - const int m_cursor = origval + delta; - const int m_span = (float)(bigger + smaller); - const int m_min = origval - smaller; - // const int axis_max = axis_min + m_span; - - switch (snap_type) { - case SNAP_AREAGRID: - m_cursor_final = m_cursor; - if (delta != bigger && delta != -smaller) { - m_cursor_final -= (m_cursor % AREAGRID); - CLAMP(m_cursor_final, origval - smaller, origval + bigger); - } - break; - - case SNAP_BIGGER_SMALLER_ONLY: - m_cursor_final = (m_cursor >= bigger) ? bigger : smaller; - break; - - case SNAP_FRACTION_AND_ADJACENT: - { - const int axis = (dir == 'v') ? 0 : 1; - int snap_dist_best = INT_MAX; - { - const float div_array[] = { - /* Middle. */ - 1.0f / 2.0f, - /* Thirds. */ - 1.0f / 3.0f, 2.0f / 3.0f, - /* Quaters. */ - 1.0f / 4.0f, 3.0f / 4.0f, - /* Eighth. */ - 1.0f / 8.0f, 3.0f / 8.0f, - 5.0f / 8.0f, 7.0f / 8.0f, - }; - /* Test the snap to the best division. */ - for (int i = 0; i < ARRAY_SIZE(div_array); i++) { - const int m_cursor_test = m_min + round_fl_to_int(m_span * div_array[i]); - const int snap_dist_test = abs(m_cursor - m_cursor_test); - if (snap_dist_best >= snap_dist_test) { - snap_dist_best = snap_dist_test; - m_cursor_final = m_cursor_test; - } - } - } - - for (const ScrVert *v1 = sc->vertbase.first; v1; v1 = v1->next) { - if (!v1->editflag) { - continue; - } - const int v_loc = (&v1->vec.x)[!axis]; - - for (const ScrVert *v2 = sc->vertbase.first; v2; v2 = v2->next) { - if (v2->editflag) { - continue; - } - if (v_loc == (&v2->vec.x)[!axis]) { - const int v_loc2 = (&v2->vec.x)[axis]; - /* Do not snap to the vertices at the ends. */ - if ((origval - smaller) < v_loc2 && v_loc2 < (origval + bigger)) { - const int snap_dist_test = abs(m_cursor - v_loc2); - if (snap_dist_best >= snap_dist_test) { - snap_dist_best = snap_dist_test; - m_cursor_final = v_loc2; - } - } - } - } - } - break; - } - case SNAP_NONE: - break; - } - - BLI_assert(ELEM(snap_type, SNAP_BIGGER_SMALLER_ONLY) || - IN_RANGE_INCL(m_cursor_final, origval - smaller, origval + bigger)); - - return m_cursor_final; + bScreen *sc = CTX_wm_screen(C); + wmWindow *win = CTX_wm_window(C); + ScrEdge *actedge; + sAreaMoveData *md; + int x, y; + + /* required properties */ + x = RNA_int_get(op->ptr, "x"); + y = RNA_int_get(op->ptr, "y"); + + /* setup */ + actedge = screen_geom_find_active_scredge(win, sc, x, y); + if (actedge == NULL) + return 0; + + md = MEM_callocN(sizeof(sAreaMoveData), "sAreaMoveData"); + op->customdata = md; + + md->dir = screen_geom_edge_is_horizontal(actedge) ? 'h' : 'v'; + if (md->dir == 'h') + md->origval = actedge->v1->vec.y; + else + md->origval = actedge->v1->vec.x; + + screen_geom_select_connected_edge(win, actedge); + /* now all vertices with 'flag == 1' are the ones that can be moved. Move this to editflag */ + ED_screen_verts_iter(win, sc, v1) + { + v1->editflag = v1->flag; + } + + bool use_bigger_smaller_snap = false; + area_move_set_limits(win, sc, md->dir, &md->bigger, &md->smaller, &use_bigger_smaller_snap); + + md->snap_type = use_bigger_smaller_snap ? SNAP_BIGGER_SMALLER_ONLY : SNAP_AREAGRID; + + return 1; +} + +static int area_snap_calc_location(const bScreen *sc, + const enum AreaMoveSnapType snap_type, + const int delta, + const int origval, + const int dir, + const int bigger, + const int smaller) +{ + BLI_assert(snap_type != SNAP_NONE); + int m_cursor_final = -1; + const int m_cursor = origval + delta; + const int m_span = (float)(bigger + smaller); + const int m_min = origval - smaller; + // const int axis_max = axis_min + m_span; + + switch (snap_type) { + case SNAP_AREAGRID: + m_cursor_final = m_cursor; + if (delta != bigger && delta != -smaller) { + m_cursor_final -= (m_cursor % AREAGRID); + CLAMP(m_cursor_final, origval - smaller, origval + bigger); + } + break; + + case SNAP_BIGGER_SMALLER_ONLY: + m_cursor_final = (m_cursor >= bigger) ? bigger : smaller; + break; + + case SNAP_FRACTION_AND_ADJACENT: { + const int axis = (dir == 'v') ? 0 : 1; + int snap_dist_best = INT_MAX; + { + const float div_array[] = { + /* Middle. */ + 1.0f / 2.0f, + /* Thirds. */ + 1.0f / 3.0f, + 2.0f / 3.0f, + /* Quaters. */ + 1.0f / 4.0f, + 3.0f / 4.0f, + /* Eighth. */ + 1.0f / 8.0f, + 3.0f / 8.0f, + 5.0f / 8.0f, + 7.0f / 8.0f, + }; + /* Test the snap to the best division. */ + for (int i = 0; i < ARRAY_SIZE(div_array); i++) { + const int m_cursor_test = m_min + round_fl_to_int(m_span * div_array[i]); + const int snap_dist_test = abs(m_cursor - m_cursor_test); + if (snap_dist_best >= snap_dist_test) { + snap_dist_best = snap_dist_test; + m_cursor_final = m_cursor_test; + } + } + } + + for (const ScrVert *v1 = sc->vertbase.first; v1; v1 = v1->next) { + if (!v1->editflag) { + continue; + } + const int v_loc = (&v1->vec.x)[!axis]; + + for (const ScrVert *v2 = sc->vertbase.first; v2; v2 = v2->next) { + if (v2->editflag) { + continue; + } + if (v_loc == (&v2->vec.x)[!axis]) { + const int v_loc2 = (&v2->vec.x)[axis]; + /* Do not snap to the vertices at the ends. */ + if ((origval - smaller) < v_loc2 && v_loc2 < (origval + bigger)) { + const int snap_dist_test = abs(m_cursor - v_loc2); + if (snap_dist_best >= snap_dist_test) { + snap_dist_best = snap_dist_test; + m_cursor_final = v_loc2; + } + } + } + } + } + break; + } + case SNAP_NONE: + break; + } + + BLI_assert(ELEM(snap_type, SNAP_BIGGER_SMALLER_ONLY) || + IN_RANGE_INCL(m_cursor_final, origval - smaller, origval + bigger)); + + return m_cursor_final; } /* moves selected screen edge amount of delta, used by split & move */ -static void area_move_apply_do( - const bContext *C, int delta, - const int origval, const int dir, - const int bigger, const int smaller, - const enum AreaMoveSnapType snap_type) -{ - wmWindow *win = CTX_wm_window(C); - bScreen *sc = CTX_wm_screen(C); - short final_loc = -1; - bool doredraw = false; - - if (snap_type != SNAP_BIGGER_SMALLER_ONLY) { - CLAMP(delta, -smaller, bigger); - } - - if (snap_type == SNAP_NONE) { - final_loc = origval + delta; - } - else { - final_loc = area_snap_calc_location(sc, snap_type, delta, origval, dir, bigger, smaller); - } - - BLI_assert(final_loc != -1); - short axis = (dir == 'v') ? 0 : 1; - - ED_screen_verts_iter(win, sc, v1) { - if (v1->editflag) { - short oldval = (&v1->vec.x)[axis]; - (&v1->vec.x)[axis] = final_loc; - - if (oldval == final_loc) { - /* nothing will change to the other vertices either. */ - break; - } - doredraw = true; - } - } - - /* only redraw if we actually moved a screen vert, for AREAGRID */ - if (doredraw) { - bool redraw_all = false; - ED_screen_areas_iter(win, sc, sa) { - if (sa->v1->editflag || sa->v2->editflag || sa->v3->editflag || sa->v4->editflag) { - if (ED_area_is_global(sa)) { - /* Snap to minimum or maximum for global areas. */ - int height = round_fl_to_int(screen_geom_area_height(sa) / UI_DPI_FAC); - if (abs(height - sa->global->size_min) < abs(height - sa->global->size_max)) { - sa->global->cur_fixed_height = sa->global->size_min; - } - else { - sa->global->cur_fixed_height = sa->global->size_max; - } - - sc->do_refresh = true; - redraw_all = true; - } - ED_area_tag_redraw(sa); - } - } - if (redraw_all) { - ED_screen_areas_iter(win, sc, sa) { - ED_area_tag_redraw(sa); - } - } - - ED_screen_global_areas_sync(win); - - WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); /* redraw everything */ - /* Update preview thumbnail */ - BKE_icon_changed(sc->id.icon_id); - } +static void area_move_apply_do(const bContext *C, + int delta, + const int origval, + const int dir, + const int bigger, + const int smaller, + const enum AreaMoveSnapType snap_type) +{ + wmWindow *win = CTX_wm_window(C); + bScreen *sc = CTX_wm_screen(C); + short final_loc = -1; + bool doredraw = false; + + if (snap_type != SNAP_BIGGER_SMALLER_ONLY) { + CLAMP(delta, -smaller, bigger); + } + + if (snap_type == SNAP_NONE) { + final_loc = origval + delta; + } + else { + final_loc = area_snap_calc_location(sc, snap_type, delta, origval, dir, bigger, smaller); + } + + BLI_assert(final_loc != -1); + short axis = (dir == 'v') ? 0 : 1; + + ED_screen_verts_iter(win, sc, v1) + { + if (v1->editflag) { + short oldval = (&v1->vec.x)[axis]; + (&v1->vec.x)[axis] = final_loc; + + if (oldval == final_loc) { + /* nothing will change to the other vertices either. */ + break; + } + doredraw = true; + } + } + + /* only redraw if we actually moved a screen vert, for AREAGRID */ + if (doredraw) { + bool redraw_all = false; + ED_screen_areas_iter(win, sc, sa) + { + if (sa->v1->editflag || sa->v2->editflag || sa->v3->editflag || sa->v4->editflag) { + if (ED_area_is_global(sa)) { + /* Snap to minimum or maximum for global areas. */ + int height = round_fl_to_int(screen_geom_area_height(sa) / UI_DPI_FAC); + if (abs(height - sa->global->size_min) < abs(height - sa->global->size_max)) { + sa->global->cur_fixed_height = sa->global->size_min; + } + else { + sa->global->cur_fixed_height = sa->global->size_max; + } + + sc->do_refresh = true; + redraw_all = true; + } + ED_area_tag_redraw(sa); + } + } + if (redraw_all) { + ED_screen_areas_iter(win, sc, sa) + { + ED_area_tag_redraw(sa); + } + } + + ED_screen_global_areas_sync(win); + + WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); /* redraw everything */ + /* Update preview thumbnail */ + BKE_icon_changed(sc->id.icon_id); + } } static void area_move_apply(bContext *C, wmOperator *op) { - sAreaMoveData *md = op->customdata; - int delta = RNA_int_get(op->ptr, "delta"); + sAreaMoveData *md = op->customdata; + int delta = RNA_int_get(op->ptr, "delta"); - area_move_apply_do(C, delta, md->origval, md->dir, md->bigger, md->smaller, md->snap_type); + area_move_apply_do(C, delta, md->origval, md->dir, md->bigger, md->smaller, md->snap_type); } static void area_move_exit(bContext *C, wmOperator *op) { - if (op->customdata) - MEM_freeN(op->customdata); - op->customdata = NULL; + if (op->customdata) + MEM_freeN(op->customdata); + op->customdata = NULL; - /* this makes sure aligned edges will result in aligned grabbing */ - BKE_screen_remove_double_scrverts(CTX_wm_screen(C)); - BKE_screen_remove_double_scredges(CTX_wm_screen(C)); + /* this makes sure aligned edges will result in aligned grabbing */ + BKE_screen_remove_double_scrverts(CTX_wm_screen(C)); + BKE_screen_remove_double_scredges(CTX_wm_screen(C)); - G.moving &= ~G_TRANSFORM_WM; + G.moving &= ~G_TRANSFORM_WM; } static int area_move_exec(bContext *C, wmOperator *op) { - if (!area_move_init(C, op)) - return OPERATOR_CANCELLED; + if (!area_move_init(C, op)) + return OPERATOR_CANCELLED; - area_move_apply(C, op); - area_move_exit(C, op); + area_move_apply(C, op); + area_move_exit(C, op); - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } /* interaction callback */ static int area_move_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - RNA_int_set(op->ptr, "x", event->x); - RNA_int_set(op->ptr, "y", event->y); + RNA_int_set(op->ptr, "x", event->x); + RNA_int_set(op->ptr, "y", event->y); - if (!area_move_init(C, op)) - return OPERATOR_PASS_THROUGH; + if (!area_move_init(C, op)) + return OPERATOR_PASS_THROUGH; - G.moving |= G_TRANSFORM_WM; + G.moving |= G_TRANSFORM_WM; - /* add temp handler */ - WM_event_add_modal_handler(C, op); + /* add temp handler */ + WM_event_add_modal_handler(C, op); - return OPERATOR_RUNNING_MODAL; + return OPERATOR_RUNNING_MODAL; } static void area_move_cancel(bContext *C, wmOperator *op) { - RNA_int_set(op->ptr, "delta", 0); - area_move_apply(C, op); - area_move_exit(C, op); + RNA_int_set(op->ptr, "delta", 0); + area_move_apply(C, op); + area_move_exit(C, op); } /* modal callback for while moving edges */ static int area_move_modal(bContext *C, wmOperator *op, const wmEvent *event) { - sAreaMoveData *md = op->customdata; - int delta, x, y; - - /* execute the events */ - switch (event->type) { - case MOUSEMOVE: - { - x = RNA_int_get(op->ptr, "x"); - y = RNA_int_get(op->ptr, "y"); - - delta = (md->dir == 'v') ? event->x - x : event->y - y; - RNA_int_set(op->ptr, "delta", delta); - - area_move_apply(C, op); - break; - } - case EVT_MODAL_MAP: - { - switch (event->val) { - case KM_MODAL_APPLY: - area_move_exit(C, op); - return OPERATOR_FINISHED; - - case KM_MODAL_CANCEL: - area_move_cancel(C, op); - return OPERATOR_CANCELLED; - - case KM_MODAL_SNAP_ON: - if (md->snap_type != SNAP_BIGGER_SMALLER_ONLY) { - md->snap_type = SNAP_FRACTION_AND_ADJACENT; - } - break; - - case KM_MODAL_SNAP_OFF: - if (md->snap_type != SNAP_BIGGER_SMALLER_ONLY) { - md->snap_type = SNAP_AREAGRID; - } - break; - } - break; - } - } - - return OPERATOR_RUNNING_MODAL; + sAreaMoveData *md = op->customdata; + int delta, x, y; + + /* execute the events */ + switch (event->type) { + case MOUSEMOVE: { + x = RNA_int_get(op->ptr, "x"); + y = RNA_int_get(op->ptr, "y"); + + delta = (md->dir == 'v') ? event->x - x : event->y - y; + RNA_int_set(op->ptr, "delta", delta); + + area_move_apply(C, op); + break; + } + case EVT_MODAL_MAP: { + switch (event->val) { + case KM_MODAL_APPLY: + area_move_exit(C, op); + return OPERATOR_FINISHED; + + case KM_MODAL_CANCEL: + area_move_cancel(C, op); + return OPERATOR_CANCELLED; + + case KM_MODAL_SNAP_ON: + if (md->snap_type != SNAP_BIGGER_SMALLER_ONLY) { + md->snap_type = SNAP_FRACTION_AND_ADJACENT; + } + break; + + case KM_MODAL_SNAP_OFF: + if (md->snap_type != SNAP_BIGGER_SMALLER_ONLY) { + md->snap_type = SNAP_AREAGRID; + } + break; + } + break; + } + } + + return OPERATOR_RUNNING_MODAL; } static void SCREEN_OT_area_move(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Move Area Edges"; - ot->description = "Move selected area edges"; - ot->idname = "SCREEN_OT_area_move"; + /* identifiers */ + ot->name = "Move Area Edges"; + ot->description = "Move selected area edges"; + ot->idname = "SCREEN_OT_area_move"; - ot->exec = area_move_exec; - ot->invoke = area_move_invoke; - ot->cancel = area_move_cancel; - ot->modal = area_move_modal; - ot->poll = ED_operator_screen_mainwinactive; /* when mouse is over area-edge */ + ot->exec = area_move_exec; + ot->invoke = area_move_invoke; + ot->cancel = area_move_cancel; + ot->modal = area_move_modal; + ot->poll = ED_operator_screen_mainwinactive; /* when mouse is over area-edge */ - /* flags */ - ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL; + /* flags */ + ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL; - /* rna */ - RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX); - RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX); - RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX); + /* rna */ + RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX); } /** \} */ @@ -1765,496 +1780,506 @@ static void SCREEN_OT_area_move(wmOperatorType *ot) */ typedef struct sAreaSplitData { - int origval; /* for move areas */ - int bigger, smaller; /* constraints for moving new edge */ - int delta; /* delta move edge */ - int origmin, origsize; /* to calculate fac, for property storage */ - int previewmode; /* draw previewline, then split */ - void *draw_callback; /* call `ED_screen_draw_split_preview` */ - bool do_snap; - - ScrEdge *nedge; /* new edge */ - ScrArea *sarea; /* start area */ - ScrArea *narea; /* new area */ + int origval; /* for move areas */ + int bigger, smaller; /* constraints for moving new edge */ + int delta; /* delta move edge */ + int origmin, origsize; /* to calculate fac, for property storage */ + int previewmode; /* draw previewline, then split */ + void *draw_callback; /* call `ED_screen_draw_split_preview` */ + bool do_snap; + + ScrEdge *nedge; /* new edge */ + ScrArea *sarea; /* start area */ + ScrArea *narea; /* new area */ } sAreaSplitData; static void area_split_draw_cb(const struct wmWindow *UNUSED(win), void *userdata) { - const wmOperator *op = userdata; + const wmOperator *op = userdata; - sAreaSplitData *sd = op->customdata; - if (sd->sarea) { - int dir = RNA_enum_get(op->ptr, "direction"); - float fac = RNA_float_get(op->ptr, "factor"); + sAreaSplitData *sd = op->customdata; + if (sd->sarea) { + int dir = RNA_enum_get(op->ptr, "direction"); + float fac = RNA_float_get(op->ptr, "factor"); - ED_screen_draw_split_preview(sd->sarea, dir, fac); - } + ED_screen_draw_split_preview(sd->sarea, dir, fac); + } } /* generic init, menu case, doesn't need active area */ static int area_split_menu_init(bContext *C, wmOperator *op) { - sAreaSplitData *sd; + sAreaSplitData *sd; - /* custom data */ - sd = (sAreaSplitData *)MEM_callocN(sizeof(sAreaSplitData), "op_area_split"); - op->customdata = sd; + /* custom data */ + sd = (sAreaSplitData *)MEM_callocN(sizeof(sAreaSplitData), "op_area_split"); + op->customdata = sd; - sd->sarea = CTX_wm_area(C); + sd->sarea = CTX_wm_area(C); - return 1; + return 1; } /* generic init, no UI stuff here, assumes active area */ static int area_split_init(bContext *C, wmOperator *op) { - ScrArea *sa = CTX_wm_area(C); - sAreaSplitData *sd; - int areaminy = ED_area_headersize(); - int dir; + ScrArea *sa = CTX_wm_area(C); + sAreaSplitData *sd; + int areaminy = ED_area_headersize(); + int dir; - /* required context */ - if (sa == NULL) return 0; + /* required context */ + if (sa == NULL) + return 0; - /* required properties */ - dir = RNA_enum_get(op->ptr, "direction"); + /* required properties */ + dir = RNA_enum_get(op->ptr, "direction"); - /* minimal size */ - if (dir == 'v' && sa->winx < 2 * AREAMINX) return 0; - if (dir == 'h' && sa->winy < 2 * areaminy) return 0; + /* minimal size */ + if (dir == 'v' && sa->winx < 2 * AREAMINX) + return 0; + if (dir == 'h' && sa->winy < 2 * areaminy) + return 0; - /* custom data */ - sd = (sAreaSplitData *)MEM_callocN(sizeof(sAreaSplitData), "op_area_split"); - op->customdata = sd; + /* custom data */ + sd = (sAreaSplitData *)MEM_callocN(sizeof(sAreaSplitData), "op_area_split"); + op->customdata = sd; - sd->sarea = sa; - if (dir == 'v') { - sd->origmin = sa->v1->vec.x; - sd->origsize = sa->v4->vec.x - sd->origmin; - } - else { - sd->origmin = sa->v1->vec.y; - sd->origsize = sa->v2->vec.y - sd->origmin; - } + sd->sarea = sa; + if (dir == 'v') { + sd->origmin = sa->v1->vec.x; + sd->origsize = sa->v4->vec.x - sd->origmin; + } + else { + sd->origmin = sa->v1->vec.y; + sd->origsize = sa->v2->vec.y - sd->origmin; + } - return 1; + return 1; } /* with sa as center, sb is located at: 0=W, 1=N, 2=E, 3=S */ /* used with split operator */ static ScrEdge *area_findsharededge(bScreen *screen, ScrArea *sa, ScrArea *sb) { - ScrVert *sav1 = sa->v1; - ScrVert *sav2 = sa->v2; - ScrVert *sav3 = sa->v3; - ScrVert *sav4 = sa->v4; - ScrVert *sbv1 = sb->v1; - ScrVert *sbv2 = sb->v2; - ScrVert *sbv3 = sb->v3; - ScrVert *sbv4 = sb->v4; - - if (sav1 == sbv4 && sav2 == sbv3) { /* sa to right of sb = W */ - return BKE_screen_find_edge(screen, sav1, sav2); - } - else if (sav2 == sbv1 && sav3 == sbv4) { /* sa to bottom of sb = N */ - return BKE_screen_find_edge(screen, sav2, sav3); - } - else if (sav3 == sbv2 && sav4 == sbv1) { /* sa to left of sb = E */ - return BKE_screen_find_edge(screen, sav3, sav4); - } - else if (sav1 == sbv2 && sav4 == sbv3) { /* sa on top of sb = S*/ - return BKE_screen_find_edge(screen, sav1, sav4); - } - - return NULL; + ScrVert *sav1 = sa->v1; + ScrVert *sav2 = sa->v2; + ScrVert *sav3 = sa->v3; + ScrVert *sav4 = sa->v4; + ScrVert *sbv1 = sb->v1; + ScrVert *sbv2 = sb->v2; + ScrVert *sbv3 = sb->v3; + ScrVert *sbv4 = sb->v4; + + if (sav1 == sbv4 && sav2 == sbv3) { /* sa to right of sb = W */ + return BKE_screen_find_edge(screen, sav1, sav2); + } + else if (sav2 == sbv1 && sav3 == sbv4) { /* sa to bottom of sb = N */ + return BKE_screen_find_edge(screen, sav2, sav3); + } + else if (sav3 == sbv2 && sav4 == sbv1) { /* sa to left of sb = E */ + return BKE_screen_find_edge(screen, sav3, sav4); + } + else if (sav1 == sbv2 && sav4 == sbv3) { /* sa on top of sb = S*/ + return BKE_screen_find_edge(screen, sav1, sav4); + } + + return NULL; } - /* do the split, return success */ static int area_split_apply(bContext *C, wmOperator *op) { - const wmWindow *win = CTX_wm_window(C); - bScreen *sc = CTX_wm_screen(C); - sAreaSplitData *sd = (sAreaSplitData *)op->customdata; - float fac; - int dir; + const wmWindow *win = CTX_wm_window(C); + bScreen *sc = CTX_wm_screen(C); + sAreaSplitData *sd = (sAreaSplitData *)op->customdata; + float fac; + int dir; - fac = RNA_float_get(op->ptr, "factor"); - dir = RNA_enum_get(op->ptr, "direction"); + fac = RNA_float_get(op->ptr, "factor"); + dir = RNA_enum_get(op->ptr, "direction"); - sd->narea = area_split(win, sc, sd->sarea, dir, fac, 0); /* 0 = no merge */ + sd->narea = area_split(win, sc, sd->sarea, dir, fac, 0); /* 0 = no merge */ - if (sd->narea) { - sd->nedge = area_findsharededge(sc, sd->sarea, sd->narea); + if (sd->narea) { + sd->nedge = area_findsharededge(sc, sd->sarea, sd->narea); - /* select newly created edge, prepare for moving edge */ - ED_screen_verts_iter(win, sc, sv) { - sv->editflag = 0; - } + /* select newly created edge, prepare for moving edge */ + ED_screen_verts_iter(win, sc, sv) + { + sv->editflag = 0; + } - sd->nedge->v1->editflag = 1; - sd->nedge->v2->editflag = 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; + if (dir == 'h') + sd->origval = sd->nedge->v1->vec.y; + else + sd->origval = sd->nedge->v1->vec.x; - ED_area_tag_redraw(sd->sarea); - ED_area_tag_redraw(sd->narea); + ED_area_tag_redraw(sd->sarea); + ED_area_tag_redraw(sd->narea); - WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); - /* Update preview thumbnail */ - BKE_icon_changed(sc->id.icon_id); + WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); + /* Update preview thumbnail */ + BKE_icon_changed(sc->id.icon_id); - return 1; - } + return 1; + } - return 0; + return 0; } static void area_split_exit(bContext *C, wmOperator *op) { - if (op->customdata) { - sAreaSplitData *sd = (sAreaSplitData *)op->customdata; - if (sd->sarea) ED_area_tag_redraw(sd->sarea); - if (sd->narea) ED_area_tag_redraw(sd->narea); + if (op->customdata) { + sAreaSplitData *sd = (sAreaSplitData *)op->customdata; + if (sd->sarea) + ED_area_tag_redraw(sd->sarea); + if (sd->narea) + ED_area_tag_redraw(sd->narea); - if (sd->draw_callback) - WM_draw_cb_exit(CTX_wm_window(C), sd->draw_callback); + if (sd->draw_callback) + WM_draw_cb_exit(CTX_wm_window(C), sd->draw_callback); - MEM_freeN(op->customdata); - op->customdata = NULL; - } + MEM_freeN(op->customdata); + op->customdata = NULL; + } - WM_cursor_modal_restore(CTX_wm_window(C)); - WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); + WM_cursor_modal_restore(CTX_wm_window(C)); + WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); - /* this makes sure aligned edges will result in aligned grabbing */ - BKE_screen_remove_double_scrverts(CTX_wm_screen(C)); - BKE_screen_remove_double_scredges(CTX_wm_screen(C)); + /* this makes sure aligned edges will result in aligned grabbing */ + BKE_screen_remove_double_scrverts(CTX_wm_screen(C)); + BKE_screen_remove_double_scredges(CTX_wm_screen(C)); } static void area_split_preview_update_cursor(bContext *C, wmOperator *op) { - wmWindow *win = CTX_wm_window(C); - int dir = RNA_enum_get(op->ptr, "direction"); - WM_cursor_set(win, (dir == 'n' || dir == 's') ? BC_V_SPLITCURSOR : BC_H_SPLITCURSOR); + wmWindow *win = CTX_wm_window(C); + int dir = RNA_enum_get(op->ptr, "direction"); + WM_cursor_set(win, (dir == 'n' || dir == 's') ? BC_V_SPLITCURSOR : BC_H_SPLITCURSOR); } /* UI callback, adds new handler */ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - wmWindow *win = CTX_wm_window(C); - bScreen *sc = CTX_wm_screen(C); - sAreaSplitData *sd; - int dir; - - /* no full window splitting allowed */ - BLI_assert(sc->state == SCREENNORMAL); - - PropertyRNA *prop_dir = RNA_struct_find_property(op->ptr, "direction"); - PropertyRNA *prop_factor = RNA_struct_find_property(op->ptr, "factor"); - PropertyRNA *prop_cursor = RNA_struct_find_property(op->ptr, "cursor"); - - if (event->type == EVT_ACTIONZONE_AREA) { - sActionzoneData *sad = event->customdata; - - if (sad == NULL || sad->modifier > 0) { - return OPERATOR_PASS_THROUGH; - } - - /* verify *sad itself */ - if (sad->sa1 == NULL || sad->az == NULL) - return OPERATOR_PASS_THROUGH; - - /* is this our *sad? if areas not equal it should be passed on */ - if (CTX_wm_area(C) != sad->sa1 || sad->sa1 != sad->sa2) - return OPERATOR_PASS_THROUGH; - - /* The factor will be close to 1.0f when near the top-left and the bottom-right corners. */ - const float factor_v = ((float)(event->y - sad->sa1->v1->vec.y)) / (float)sad->sa1->winy; - const float factor_h = ((float)(event->x - sad->sa1->v1->vec.x)) / (float)sad->sa1->winx; - const bool is_left = factor_v < 0.5f; - const bool is_bottom = factor_h < 0.5f; - const bool is_right = !is_left; - const bool is_top = !is_bottom; - float factor; - - /* Prepare operator state vars. */ - if (ELEM(sad->gesture_dir, 'n', 's')) { - dir = 'h'; - factor = factor_h; - } - else { - dir = 'v'; - factor = factor_v; - } - - if ((is_top && is_left) || - (is_bottom && is_right)) - { - factor = 1.0f - factor; - } - - RNA_property_float_set(op->ptr, prop_factor, factor); - - RNA_property_enum_set(op->ptr, prop_dir, dir); - - /* general init, also non-UI case, adds customdata, sets area and defaults */ - if (!area_split_init(C, op)) { - return OPERATOR_PASS_THROUGH; - } - } - else if (RNA_property_is_set(op->ptr, prop_dir)) { - ScrArea *sa = CTX_wm_area(C); - if (sa == NULL) { - return OPERATOR_CANCELLED; - } - dir = RNA_property_enum_get(op->ptr, prop_dir); - if (dir == 'h') { - RNA_property_float_set( - op->ptr, prop_factor, - ((float)(event->x - sa->v1->vec.x)) / (float)sa->winx); - } - else { - RNA_property_float_set( - op->ptr, prop_factor, - ((float)(event->y - sa->v1->vec.y)) / (float)sa->winy); - } - - if (!area_split_init(C, op)) { - return OPERATOR_CANCELLED; - } - } - else { - ScrEdge *actedge; - rcti window_rect; - int event_co[2]; - - /* retrieve initial mouse coord, so we can find the active edge */ - if (RNA_property_is_set(op->ptr, prop_cursor)) { - RNA_property_int_get_array(op->ptr, prop_cursor, event_co); - } - else { - copy_v2_v2_int(event_co, &event->x); - } - - WM_window_rect_calc(win, &window_rect); - - actedge = screen_geom_area_map_find_active_scredge( - AREAMAP_FROM_SCREEN(sc), &window_rect, event_co[0], event_co[1]); - if (actedge == NULL) { - return OPERATOR_CANCELLED; - } - - dir = screen_geom_edge_is_horizontal(actedge) ? 'v' : 'h'; - - RNA_property_enum_set(op->ptr, prop_dir, dir); - - /* special case, adds customdata, sets defaults */ - if (!area_split_menu_init(C, op)) { - return OPERATOR_CANCELLED; - } - } - - sd = (sAreaSplitData *)op->customdata; - - if (event->type == EVT_ACTIONZONE_AREA) { - - /* do the split */ - if (area_split_apply(C, op)) { - area_move_set_limits(win, sc, dir, &sd->bigger, &sd->smaller, NULL); - - /* add temp handler for edge move or cancel */ - WM_event_add_modal_handler(C, op); - - return OPERATOR_RUNNING_MODAL; - } - } - else { - sd->previewmode = 1; - sd->draw_callback = WM_draw_cb_activate(win, area_split_draw_cb, op); - /* add temp handler for edge move or cancel */ - WM_event_add_modal_handler(C, op); - area_split_preview_update_cursor(C, op); - - return OPERATOR_RUNNING_MODAL; - - } - - return OPERATOR_PASS_THROUGH; + wmWindow *win = CTX_wm_window(C); + bScreen *sc = CTX_wm_screen(C); + sAreaSplitData *sd; + int dir; + + /* no full window splitting allowed */ + BLI_assert(sc->state == SCREENNORMAL); + + PropertyRNA *prop_dir = RNA_struct_find_property(op->ptr, "direction"); + PropertyRNA *prop_factor = RNA_struct_find_property(op->ptr, "factor"); + PropertyRNA *prop_cursor = RNA_struct_find_property(op->ptr, "cursor"); + + if (event->type == EVT_ACTIONZONE_AREA) { + sActionzoneData *sad = event->customdata; + + if (sad == NULL || sad->modifier > 0) { + return OPERATOR_PASS_THROUGH; + } + + /* verify *sad itself */ + if (sad->sa1 == NULL || sad->az == NULL) + return OPERATOR_PASS_THROUGH; + + /* is this our *sad? if areas not equal it should be passed on */ + if (CTX_wm_area(C) != sad->sa1 || sad->sa1 != sad->sa2) + return OPERATOR_PASS_THROUGH; + + /* The factor will be close to 1.0f when near the top-left and the bottom-right corners. */ + const float factor_v = ((float)(event->y - sad->sa1->v1->vec.y)) / (float)sad->sa1->winy; + const float factor_h = ((float)(event->x - sad->sa1->v1->vec.x)) / (float)sad->sa1->winx; + const bool is_left = factor_v < 0.5f; + const bool is_bottom = factor_h < 0.5f; + const bool is_right = !is_left; + const bool is_top = !is_bottom; + float factor; + + /* Prepare operator state vars. */ + if (ELEM(sad->gesture_dir, 'n', 's')) { + dir = 'h'; + factor = factor_h; + } + else { + dir = 'v'; + factor = factor_v; + } + + if ((is_top && is_left) || (is_bottom && is_right)) { + factor = 1.0f - factor; + } + + RNA_property_float_set(op->ptr, prop_factor, factor); + + RNA_property_enum_set(op->ptr, prop_dir, dir); + + /* general init, also non-UI case, adds customdata, sets area and defaults */ + if (!area_split_init(C, op)) { + return OPERATOR_PASS_THROUGH; + } + } + else if (RNA_property_is_set(op->ptr, prop_dir)) { + ScrArea *sa = CTX_wm_area(C); + if (sa == NULL) { + return OPERATOR_CANCELLED; + } + dir = RNA_property_enum_get(op->ptr, prop_dir); + if (dir == 'h') { + RNA_property_float_set( + op->ptr, prop_factor, ((float)(event->x - sa->v1->vec.x)) / (float)sa->winx); + } + else { + RNA_property_float_set( + op->ptr, prop_factor, ((float)(event->y - sa->v1->vec.y)) / (float)sa->winy); + } + + if (!area_split_init(C, op)) { + return OPERATOR_CANCELLED; + } + } + else { + ScrEdge *actedge; + rcti window_rect; + int event_co[2]; + + /* retrieve initial mouse coord, so we can find the active edge */ + if (RNA_property_is_set(op->ptr, prop_cursor)) { + RNA_property_int_get_array(op->ptr, prop_cursor, event_co); + } + else { + copy_v2_v2_int(event_co, &event->x); + } + + WM_window_rect_calc(win, &window_rect); + + actedge = screen_geom_area_map_find_active_scredge( + AREAMAP_FROM_SCREEN(sc), &window_rect, event_co[0], event_co[1]); + if (actedge == NULL) { + return OPERATOR_CANCELLED; + } + + dir = screen_geom_edge_is_horizontal(actedge) ? 'v' : 'h'; + + RNA_property_enum_set(op->ptr, prop_dir, dir); + + /* special case, adds customdata, sets defaults */ + if (!area_split_menu_init(C, op)) { + return OPERATOR_CANCELLED; + } + } + + sd = (sAreaSplitData *)op->customdata; + + if (event->type == EVT_ACTIONZONE_AREA) { + + /* do the split */ + if (area_split_apply(C, op)) { + area_move_set_limits(win, sc, dir, &sd->bigger, &sd->smaller, NULL); + + /* add temp handler for edge move or cancel */ + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; + } + } + else { + sd->previewmode = 1; + sd->draw_callback = WM_draw_cb_activate(win, area_split_draw_cb, op); + /* add temp handler for edge move or cancel */ + WM_event_add_modal_handler(C, op); + area_split_preview_update_cursor(C, op); + + return OPERATOR_RUNNING_MODAL; + } + + return OPERATOR_PASS_THROUGH; } /* function to be called outside UI context, or for redo */ static int area_split_exec(bContext *C, wmOperator *op) { - if (!area_split_init(C, op)) - return OPERATOR_CANCELLED; + if (!area_split_init(C, op)) + return OPERATOR_CANCELLED; - area_split_apply(C, op); - area_split_exit(C, op); + area_split_apply(C, op); + area_split_exit(C, op); - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } - static void area_split_cancel(bContext *C, wmOperator *op) { - sAreaSplitData *sd = (sAreaSplitData *)op->customdata; + sAreaSplitData *sd = (sAreaSplitData *)op->customdata; - if (sd->previewmode) { - /* pass */ - } - else { - if (screen_area_join(C, CTX_wm_screen(C), sd->sarea, sd->narea)) { - if (CTX_wm_area(C) == sd->narea) { - CTX_wm_area_set(C, NULL); - CTX_wm_region_set(C, NULL); - } - sd->narea = NULL; - } - } - area_split_exit(C, op); + if (sd->previewmode) { + /* pass */ + } + else { + if (screen_area_join(C, CTX_wm_screen(C), sd->sarea, sd->narea)) { + if (CTX_wm_area(C) == sd->narea) { + CTX_wm_area_set(C, NULL); + CTX_wm_region_set(C, NULL); + } + sd->narea = NULL; + } + } + area_split_exit(C, op); } static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event) { - sAreaSplitData *sd = (sAreaSplitData *)op->customdata; - PropertyRNA *prop_dir = RNA_struct_find_property(op->ptr, "direction"); - bool update_factor = false; - - /* execute the events */ - switch (event->type) { - case MOUSEMOVE: - update_factor = true; - break; - - case LEFTMOUSE: - if (sd->previewmode) { - area_split_apply(C, op); - area_split_exit(C, op); - return OPERATOR_FINISHED; - } - else { - if (event->val == KM_RELEASE) { /* mouse up */ - area_split_exit(C, op); - return OPERATOR_FINISHED; - } - } - break; - - case MIDDLEMOUSE: - case TABKEY: - if (sd->previewmode == 0) { - /* pass */ - } - else { - if (event->val == KM_PRESS) { - if (sd->sarea) { - int dir = RNA_property_enum_get(op->ptr, prop_dir); - RNA_property_enum_set(op->ptr, prop_dir, (dir == 'v') ? 'h' : 'v'); - area_split_preview_update_cursor(C, op); - update_factor = true; - } - } - } - - break; - - case RIGHTMOUSE: /* cancel operation */ - case ESCKEY: - area_split_cancel(C, op); - return OPERATOR_CANCELLED; - - case LEFTCTRLKEY: - sd->do_snap = event->val == KM_PRESS; - update_factor = true; - break; - } - - if (update_factor) { - const int dir = RNA_property_enum_get(op->ptr, prop_dir); - - sd->delta = (dir == 'v') ? event->x - sd->origval : event->y - sd->origval; - - if (sd->previewmode == 0) { - if (sd->do_snap) { - const int snap_loc = area_snap_calc_location( - CTX_wm_screen(C), SNAP_FRACTION_AND_ADJACENT, sd->delta, sd->origval, dir, - sd->bigger, sd->smaller); - sd->delta = snap_loc - sd->origval; - } - area_move_apply_do(C, sd->delta, sd->origval, dir, sd->bigger, sd->smaller, SNAP_NONE); - } - else { - if (sd->sarea) { - ED_area_tag_redraw(sd->sarea); - } - /* area context not set */ - sd->sarea = BKE_screen_find_area_xy(CTX_wm_screen(C), SPACE_TYPE_ANY, event->x, event->y); - - if (sd->sarea) { - ScrArea *sa = sd->sarea; - if (dir == 'v') { - sd->origmin = sa->v1->vec.x; - sd->origsize = sa->v4->vec.x - sd->origmin; - } - else { - sd->origmin = sa->v1->vec.y; - sd->origsize = sa->v2->vec.y - sd->origmin; - } - - if (sd->do_snap) { - sa->v1->editflag = sa->v2->editflag = sa->v3->editflag = sa->v4->editflag = 1; - - const int snap_loc = area_snap_calc_location( - CTX_wm_screen(C), SNAP_FRACTION_AND_ADJACENT, sd->delta, sd->origval, dir, - sd->origmin + sd->origsize, -sd->origmin); - - sa->v1->editflag = sa->v2->editflag = sa->v3->editflag = sa->v4->editflag = 0; - sd->delta = snap_loc - sd->origval; - } - - ED_area_tag_redraw(sd->sarea); - } - - CTX_wm_screen(C)->do_draw = true; - } - - float fac = (float)(sd->delta + sd->origval - sd->origmin) / sd->origsize; - RNA_float_set(op->ptr, "factor", fac); - } - - return OPERATOR_RUNNING_MODAL; + sAreaSplitData *sd = (sAreaSplitData *)op->customdata; + PropertyRNA *prop_dir = RNA_struct_find_property(op->ptr, "direction"); + bool update_factor = false; + + /* execute the events */ + switch (event->type) { + case MOUSEMOVE: + update_factor = true; + break; + + case LEFTMOUSE: + if (sd->previewmode) { + area_split_apply(C, op); + area_split_exit(C, op); + return OPERATOR_FINISHED; + } + else { + if (event->val == KM_RELEASE) { /* mouse up */ + area_split_exit(C, op); + return OPERATOR_FINISHED; + } + } + break; + + case MIDDLEMOUSE: + case TABKEY: + if (sd->previewmode == 0) { + /* pass */ + } + else { + if (event->val == KM_PRESS) { + if (sd->sarea) { + int dir = RNA_property_enum_get(op->ptr, prop_dir); + RNA_property_enum_set(op->ptr, prop_dir, (dir == 'v') ? 'h' : 'v'); + area_split_preview_update_cursor(C, op); + update_factor = true; + } + } + } + + break; + + case RIGHTMOUSE: /* cancel operation */ + case ESCKEY: + area_split_cancel(C, op); + return OPERATOR_CANCELLED; + + case LEFTCTRLKEY: + sd->do_snap = event->val == KM_PRESS; + update_factor = true; + break; + } + + if (update_factor) { + const int dir = RNA_property_enum_get(op->ptr, prop_dir); + + sd->delta = (dir == 'v') ? event->x - sd->origval : event->y - sd->origval; + + if (sd->previewmode == 0) { + if (sd->do_snap) { + const int snap_loc = area_snap_calc_location(CTX_wm_screen(C), + SNAP_FRACTION_AND_ADJACENT, + sd->delta, + sd->origval, + dir, + sd->bigger, + sd->smaller); + sd->delta = snap_loc - sd->origval; + } + area_move_apply_do(C, sd->delta, sd->origval, dir, sd->bigger, sd->smaller, SNAP_NONE); + } + else { + if (sd->sarea) { + ED_area_tag_redraw(sd->sarea); + } + /* area context not set */ + sd->sarea = BKE_screen_find_area_xy(CTX_wm_screen(C), SPACE_TYPE_ANY, event->x, event->y); + + if (sd->sarea) { + ScrArea *sa = sd->sarea; + if (dir == 'v') { + sd->origmin = sa->v1->vec.x; + sd->origsize = sa->v4->vec.x - sd->origmin; + } + else { + sd->origmin = sa->v1->vec.y; + sd->origsize = sa->v2->vec.y - sd->origmin; + } + + if (sd->do_snap) { + sa->v1->editflag = sa->v2->editflag = sa->v3->editflag = sa->v4->editflag = 1; + + const int snap_loc = area_snap_calc_location(CTX_wm_screen(C), + SNAP_FRACTION_AND_ADJACENT, + sd->delta, + sd->origval, + dir, + sd->origmin + sd->origsize, + -sd->origmin); + + sa->v1->editflag = sa->v2->editflag = sa->v3->editflag = sa->v4->editflag = 0; + sd->delta = snap_loc - sd->origval; + } + + ED_area_tag_redraw(sd->sarea); + } + + CTX_wm_screen(C)->do_draw = true; + } + + float fac = (float)(sd->delta + sd->origval - sd->origmin) / sd->origsize; + RNA_float_set(op->ptr, "factor", fac); + } + + return OPERATOR_RUNNING_MODAL; } static const EnumPropertyItem prop_direction_items[] = { - {'h', "HORIZONTAL", 0, "Horizontal", ""}, - {'v', "VERTICAL", 0, "Vertical", ""}, - {0, NULL, 0, NULL, NULL}, + {'h', "HORIZONTAL", 0, "Horizontal", ""}, + {'v', "VERTICAL", 0, "Vertical", ""}, + {0, NULL, 0, NULL, NULL}, }; static void SCREEN_OT_area_split(wmOperatorType *ot) { - ot->name = "Split Area"; - ot->description = "Split selected area into new windows"; - ot->idname = "SCREEN_OT_area_split"; + ot->name = "Split Area"; + ot->description = "Split selected area into new windows"; + ot->idname = "SCREEN_OT_area_split"; - ot->exec = area_split_exec; - ot->invoke = area_split_invoke; - ot->modal = area_split_modal; - ot->cancel = area_split_cancel; + ot->exec = area_split_exec; + ot->invoke = area_split_invoke; + ot->modal = area_split_modal; + ot->cancel = area_split_cancel; - ot->poll = screen_active_editable; + ot->poll = screen_active_editable; - /* flags */ - ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL; + /* flags */ + ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL; - /* rna */ - RNA_def_enum(ot->srna, "direction", prop_direction_items, 'h', "Direction", ""); - RNA_def_float(ot->srna, "factor", 0.5f, 0.0, 1.0, "Factor", "", 0.0, 1.0); - RNA_def_int_vector(ot->srna, "cursor", 2, NULL, INT_MIN, INT_MAX, "Cursor", "", INT_MIN, INT_MAX); + /* rna */ + RNA_def_enum(ot->srna, "direction", prop_direction_items, 'h', "Direction", ""); + RNA_def_float(ot->srna, "factor", 0.5f, 0.0, 1.0, "Factor", "", 0.0, 1.0); + RNA_def_int_vector( + ot->srna, "cursor", 2, NULL, INT_MIN, INT_MAX, "Cursor", "", INT_MIN, INT_MAX); } /** \} */ @@ -2264,275 +2289,276 @@ static void SCREEN_OT_area_split(wmOperatorType *ot) * \{ */ typedef struct RegionMoveData { - AZone *az; - ARegion *ar; - ScrArea *sa; - int bigger, smaller, origval; - int origx, origy; - int maxsize; - AZEdge edge; + AZone *az; + ARegion *ar; + ScrArea *sa; + int bigger, smaller, origval; + int origx, origy; + int maxsize; + AZEdge edge; } RegionMoveData; static int area_max_regionsize(ScrArea *sa, ARegion *scalear, AZEdge edge) { - int dist; - - /* regions in regions. */ - if (scalear->alignment & RGN_SPLIT_PREV) { - const int align = scalear->alignment & RGN_ALIGN_ENUM_MASK; - - if (ELEM(align, RGN_ALIGN_TOP, RGN_ALIGN_BOTTOM)) { - ARegion *ar = scalear->prev; - dist = ar->winy + scalear->winy - U.pixelsize; - } - else /* if (ELEM(align, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) */ { - ARegion *ar = scalear->prev; - dist = ar->winx + scalear->winx - U.pixelsize; - } - } - else { - if (edge == AE_RIGHT_TO_TOPLEFT || edge == AE_LEFT_TO_TOPRIGHT) { - dist = BLI_rcti_size_x(&sa->totrct); - } - else { /* AE_BOTTOM_TO_TOPLEFT, AE_TOP_TO_BOTTOMRIGHT */ - dist = BLI_rcti_size_y(&sa->totrct); - } - - /* subtractwidth of regions on opposite side - * prevents dragging regions into other opposite regions */ - for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar == scalear) - continue; - - if (scalear->alignment == RGN_ALIGN_LEFT && ar->alignment == RGN_ALIGN_RIGHT) { - dist -= ar->winx; - } - else if (scalear->alignment == RGN_ALIGN_RIGHT && ar->alignment == RGN_ALIGN_LEFT) { - dist -= ar->winx; - } - else if (scalear->alignment == RGN_ALIGN_TOP && - (ar->alignment == RGN_ALIGN_BOTTOM || ELEM(ar->regiontype, RGN_TYPE_HEADER, RGN_TYPE_FOOTER))) - { - dist -= ar->winy; - } - else if (scalear->alignment == RGN_ALIGN_BOTTOM && - (ar->alignment == RGN_ALIGN_TOP || ELEM(ar->regiontype, RGN_TYPE_HEADER, RGN_TYPE_FOOTER))) - { - dist -= ar->winy; - } - } - } - - dist /= UI_DPI_FAC; - return dist; + int dist; + + /* regions in regions. */ + if (scalear->alignment & RGN_SPLIT_PREV) { + const int align = scalear->alignment & RGN_ALIGN_ENUM_MASK; + + if (ELEM(align, RGN_ALIGN_TOP, RGN_ALIGN_BOTTOM)) { + ARegion *ar = scalear->prev; + dist = ar->winy + scalear->winy - U.pixelsize; + } + else /* if (ELEM(align, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) */ { + ARegion *ar = scalear->prev; + dist = ar->winx + scalear->winx - U.pixelsize; + } + } + else { + if (edge == AE_RIGHT_TO_TOPLEFT || edge == AE_LEFT_TO_TOPRIGHT) { + dist = BLI_rcti_size_x(&sa->totrct); + } + else { /* AE_BOTTOM_TO_TOPLEFT, AE_TOP_TO_BOTTOMRIGHT */ + dist = BLI_rcti_size_y(&sa->totrct); + } + + /* subtractwidth of regions on opposite side + * prevents dragging regions into other opposite regions */ + for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar == scalear) + continue; + + if (scalear->alignment == RGN_ALIGN_LEFT && ar->alignment == RGN_ALIGN_RIGHT) { + dist -= ar->winx; + } + else if (scalear->alignment == RGN_ALIGN_RIGHT && ar->alignment == RGN_ALIGN_LEFT) { + dist -= ar->winx; + } + else if (scalear->alignment == RGN_ALIGN_TOP && + (ar->alignment == RGN_ALIGN_BOTTOM || + ELEM(ar->regiontype, RGN_TYPE_HEADER, RGN_TYPE_FOOTER))) { + dist -= ar->winy; + } + else if (scalear->alignment == RGN_ALIGN_BOTTOM && + (ar->alignment == RGN_ALIGN_TOP || + ELEM(ar->regiontype, RGN_TYPE_HEADER, RGN_TYPE_FOOTER))) { + dist -= ar->winy; + } + } + } + + dist /= UI_DPI_FAC; + return dist; } static int region_scale_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - sActionzoneData *sad = event->customdata; - AZone *az; + sActionzoneData *sad = event->customdata; + AZone *az; - if (event->type != EVT_ACTIONZONE_REGION) { - BKE_report(op->reports, RPT_ERROR, "Can only scale region size from an action zone"); - return OPERATOR_CANCELLED; - } + if (event->type != EVT_ACTIONZONE_REGION) { + BKE_report(op->reports, RPT_ERROR, "Can only scale region size from an action zone"); + return OPERATOR_CANCELLED; + } - az = sad->az; + az = sad->az; - if (az->ar) { - RegionMoveData *rmd = MEM_callocN(sizeof(RegionMoveData), "RegionMoveData"); + if (az->ar) { + RegionMoveData *rmd = MEM_callocN(sizeof(RegionMoveData), "RegionMoveData"); - op->customdata = rmd; + op->customdata = rmd; - rmd->az = az; - rmd->ar = az->ar; - rmd->sa = sad->sa1; - rmd->edge = az->edge; - rmd->origx = event->x; - rmd->origy = event->y; - rmd->maxsize = area_max_regionsize(rmd->sa, rmd->ar, rmd->edge); + rmd->az = az; + rmd->ar = az->ar; + rmd->sa = sad->sa1; + rmd->edge = az->edge; + rmd->origx = event->x; + rmd->origy = event->y; + rmd->maxsize = area_max_regionsize(rmd->sa, rmd->ar, rmd->edge); - /* if not set we do now, otherwise it uses type */ - if (rmd->ar->sizex == 0) - rmd->ar->sizex = rmd->ar->winx; - if (rmd->ar->sizey == 0) - rmd->ar->sizey = rmd->ar->winy; + /* if not set we do now, otherwise it uses type */ + if (rmd->ar->sizex == 0) + rmd->ar->sizex = rmd->ar->winx; + if (rmd->ar->sizey == 0) + rmd->ar->sizey = rmd->ar->winy; - /* now copy to regionmovedata */ - if (rmd->edge == AE_LEFT_TO_TOPRIGHT || rmd->edge == AE_RIGHT_TO_TOPLEFT) { - rmd->origval = rmd->ar->sizex; - } - else { - rmd->origval = rmd->ar->sizey; - } + /* now copy to regionmovedata */ + if (rmd->edge == AE_LEFT_TO_TOPRIGHT || rmd->edge == AE_RIGHT_TO_TOPLEFT) { + rmd->origval = rmd->ar->sizex; + } + else { + rmd->origval = rmd->ar->sizey; + } - CLAMP(rmd->maxsize, 0, 1000); + CLAMP(rmd->maxsize, 0, 1000); - /* add temp handler */ - WM_event_add_modal_handler(C, op); + /* add temp handler */ + WM_event_add_modal_handler(C, op); - return OPERATOR_RUNNING_MODAL; - } + return OPERATOR_RUNNING_MODAL; + } - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } static void region_scale_validate_size(RegionMoveData *rmd) { - if ((rmd->ar->flag & RGN_FLAG_HIDDEN) == 0) { - short *size, maxsize = -1; - + if ((rmd->ar->flag & RGN_FLAG_HIDDEN) == 0) { + short *size, maxsize = -1; - if (rmd->edge == AE_LEFT_TO_TOPRIGHT || rmd->edge == AE_RIGHT_TO_TOPLEFT) - size = &rmd->ar->sizex; - else - size = &rmd->ar->sizey; + if (rmd->edge == AE_LEFT_TO_TOPRIGHT || rmd->edge == AE_RIGHT_TO_TOPLEFT) + size = &rmd->ar->sizex; + else + size = &rmd->ar->sizey; - maxsize = rmd->maxsize - (UI_UNIT_Y / UI_DPI_FAC); + maxsize = rmd->maxsize - (UI_UNIT_Y / UI_DPI_FAC); - if (*size > maxsize && maxsize > 0) - *size = maxsize; - } + if (*size > maxsize && maxsize > 0) + *size = maxsize; + } } static void region_scale_toggle_hidden(bContext *C, RegionMoveData *rmd) { - /* hidden areas may have bad 'View2D.cur' value, - * correct before displaying. see T45156 */ - if (rmd->ar->flag & RGN_FLAG_HIDDEN) { - UI_view2d_curRect_validate(&rmd->ar->v2d); - } + /* hidden areas may have bad 'View2D.cur' value, + * correct before displaying. see T45156 */ + if (rmd->ar->flag & RGN_FLAG_HIDDEN) { + UI_view2d_curRect_validate(&rmd->ar->v2d); + } - region_toggle_hidden(C, rmd->ar, 0); - region_scale_validate_size(rmd); + region_toggle_hidden(C, rmd->ar, 0); + region_scale_validate_size(rmd); } static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event) { - RegionMoveData *rmd = op->customdata; - int delta; - - /* execute the events */ - switch (event->type) { - case MOUSEMOVE: - { - const float aspect = BLI_rctf_size_x(&rmd->ar->v2d.cur) / (BLI_rcti_size_x(&rmd->ar->v2d.mask) + 1); - const int snap_size_threshold = (U.widget_unit * 2) / aspect; - if (rmd->edge == AE_LEFT_TO_TOPRIGHT || rmd->edge == AE_RIGHT_TO_TOPLEFT) { - delta = event->x - rmd->origx; - if (rmd->edge == AE_LEFT_TO_TOPRIGHT) delta = -delta; - - /* region sizes now get multiplied */ - delta /= UI_DPI_FAC; - - rmd->ar->sizex = rmd->origval + delta; - - if (rmd->ar->type->snap_size) { - short sizex_test = rmd->ar->type->snap_size(rmd->ar, rmd->ar->sizex, 0); - if (ABS(rmd->ar->sizex - sizex_test) < snap_size_threshold) { - rmd->ar->sizex = sizex_test; - } - } - CLAMP(rmd->ar->sizex, 0, rmd->maxsize); - - if (rmd->ar->sizex < UI_UNIT_X) { - rmd->ar->sizex = rmd->origval; - if (!(rmd->ar->flag & RGN_FLAG_HIDDEN)) - region_scale_toggle_hidden(C, rmd); - } - else if (rmd->ar->flag & RGN_FLAG_HIDDEN) { - region_scale_toggle_hidden(C, rmd); - } - else if (rmd->ar->flag & RGN_FLAG_DYNAMIC_SIZE) { - rmd->ar->sizex = rmd->origval; - } - } - else { - delta = event->y - rmd->origy; - if (rmd->edge == AE_BOTTOM_TO_TOPLEFT) delta = -delta; - - /* region sizes now get multiplied */ - delta /= UI_DPI_FAC; - - rmd->ar->sizey = rmd->origval + delta; - - if (rmd->ar->type->snap_size) { - short sizey_test = rmd->ar->type->snap_size(rmd->ar, rmd->ar->sizey, 1); - if (ABS(rmd->ar->sizey - sizey_test) < snap_size_threshold) { - rmd->ar->sizey = sizey_test; - } - } - CLAMP(rmd->ar->sizey, 0, rmd->maxsize); - - /* note, 'UI_UNIT_Y/4' means you need to drag the footer and execute region - * almost all the way down for it to become hidden, this is done - * otherwise its too easy to do this by accident */ - if (rmd->ar->sizey < UI_UNIT_Y / 4) { - rmd->ar->sizey = rmd->origval; - if (!(rmd->ar->flag & RGN_FLAG_HIDDEN)) - region_scale_toggle_hidden(C, rmd); - } - else if (rmd->ar->flag & RGN_FLAG_HIDDEN) { - region_scale_toggle_hidden(C, rmd); - } - else if (rmd->ar->flag & RGN_FLAG_DYNAMIC_SIZE) { - rmd->ar->sizey = rmd->origval; - } - } - ED_area_tag_redraw(rmd->sa); - WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); - - break; - } - case LEFTMOUSE: - if (event->val == KM_RELEASE) { - if (len_manhattan_v2v2_int(&event->x, &rmd->origx) <= WM_EVENT_CURSOR_MOTION_THRESHOLD) { - if (rmd->ar->flag & RGN_FLAG_HIDDEN) { - region_scale_toggle_hidden(C, rmd); - } - else if (rmd->ar->flag & RGN_FLAG_TOO_SMALL) { - region_scale_validate_size(rmd); - } - - ED_area_tag_redraw(rmd->sa); - WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); - } - MEM_freeN(op->customdata); - op->customdata = NULL; - - return OPERATOR_FINISHED; - } - break; - - case ESCKEY: - break; - } - - return OPERATOR_RUNNING_MODAL; + RegionMoveData *rmd = op->customdata; + int delta; + + /* execute the events */ + switch (event->type) { + case MOUSEMOVE: { + const float aspect = BLI_rctf_size_x(&rmd->ar->v2d.cur) / + (BLI_rcti_size_x(&rmd->ar->v2d.mask) + 1); + const int snap_size_threshold = (U.widget_unit * 2) / aspect; + if (rmd->edge == AE_LEFT_TO_TOPRIGHT || rmd->edge == AE_RIGHT_TO_TOPLEFT) { + delta = event->x - rmd->origx; + if (rmd->edge == AE_LEFT_TO_TOPRIGHT) + delta = -delta; + + /* region sizes now get multiplied */ + delta /= UI_DPI_FAC; + + rmd->ar->sizex = rmd->origval + delta; + + if (rmd->ar->type->snap_size) { + short sizex_test = rmd->ar->type->snap_size(rmd->ar, rmd->ar->sizex, 0); + if (ABS(rmd->ar->sizex - sizex_test) < snap_size_threshold) { + rmd->ar->sizex = sizex_test; + } + } + CLAMP(rmd->ar->sizex, 0, rmd->maxsize); + + if (rmd->ar->sizex < UI_UNIT_X) { + rmd->ar->sizex = rmd->origval; + if (!(rmd->ar->flag & RGN_FLAG_HIDDEN)) + region_scale_toggle_hidden(C, rmd); + } + else if (rmd->ar->flag & RGN_FLAG_HIDDEN) { + region_scale_toggle_hidden(C, rmd); + } + else if (rmd->ar->flag & RGN_FLAG_DYNAMIC_SIZE) { + rmd->ar->sizex = rmd->origval; + } + } + else { + delta = event->y - rmd->origy; + if (rmd->edge == AE_BOTTOM_TO_TOPLEFT) + delta = -delta; + + /* region sizes now get multiplied */ + delta /= UI_DPI_FAC; + + rmd->ar->sizey = rmd->origval + delta; + + if (rmd->ar->type->snap_size) { + short sizey_test = rmd->ar->type->snap_size(rmd->ar, rmd->ar->sizey, 1); + if (ABS(rmd->ar->sizey - sizey_test) < snap_size_threshold) { + rmd->ar->sizey = sizey_test; + } + } + CLAMP(rmd->ar->sizey, 0, rmd->maxsize); + + /* note, 'UI_UNIT_Y/4' means you need to drag the footer and execute region + * almost all the way down for it to become hidden, this is done + * otherwise its too easy to do this by accident */ + if (rmd->ar->sizey < UI_UNIT_Y / 4) { + rmd->ar->sizey = rmd->origval; + if (!(rmd->ar->flag & RGN_FLAG_HIDDEN)) + region_scale_toggle_hidden(C, rmd); + } + else if (rmd->ar->flag & RGN_FLAG_HIDDEN) { + region_scale_toggle_hidden(C, rmd); + } + else if (rmd->ar->flag & RGN_FLAG_DYNAMIC_SIZE) { + rmd->ar->sizey = rmd->origval; + } + } + ED_area_tag_redraw(rmd->sa); + WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); + + break; + } + case LEFTMOUSE: + if (event->val == KM_RELEASE) { + if (len_manhattan_v2v2_int(&event->x, &rmd->origx) <= WM_EVENT_CURSOR_MOTION_THRESHOLD) { + if (rmd->ar->flag & RGN_FLAG_HIDDEN) { + region_scale_toggle_hidden(C, rmd); + } + else if (rmd->ar->flag & RGN_FLAG_TOO_SMALL) { + region_scale_validate_size(rmd); + } + + ED_area_tag_redraw(rmd->sa); + WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); + } + MEM_freeN(op->customdata); + op->customdata = NULL; + + return OPERATOR_FINISHED; + } + break; + + case ESCKEY: + break; + } + + return OPERATOR_RUNNING_MODAL; } static void region_scale_cancel(bContext *UNUSED(C), wmOperator *op) { - MEM_freeN(op->customdata); - op->customdata = NULL; + MEM_freeN(op->customdata); + op->customdata = NULL; } static void SCREEN_OT_region_scale(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Scale Region Size"; - ot->description = "Scale selected area"; - ot->idname = "SCREEN_OT_region_scale"; + /* identifiers */ + ot->name = "Scale Region Size"; + ot->description = "Scale selected area"; + ot->idname = "SCREEN_OT_region_scale"; - ot->invoke = region_scale_invoke; - ot->modal = region_scale_modal; - ot->cancel = region_scale_cancel; + ot->invoke = region_scale_invoke; + ot->modal = region_scale_modal; + ot->cancel = region_scale_cancel; - ot->poll = ED_operator_areaactive; + ot->poll = ED_operator_areaactive; - /* flags */ - ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL; + /* flags */ + ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL; } /** \} */ @@ -2543,81 +2569,80 @@ static void SCREEN_OT_region_scale(wmOperatorType *ot) static void areas_do_frame_follow(bContext *C, bool middle) { - bScreen *scr = CTX_wm_screen(C); - Scene *scene = CTX_data_scene(C); - wmWindowManager *wm = CTX_wm_manager(C); - for (wmWindow *window = wm->windows.first; window; window = window->next) { - const bScreen *screen = WM_window_get_active_screen(window); - - for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { - for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { - /* do follow here if editor type supports it */ - if ((scr->redraws_flag & TIME_FOLLOW)) { - if ((ar->regiontype == RGN_TYPE_WINDOW && - ELEM(sa->spacetype, SPACE_SEQ, SPACE_GRAPH, SPACE_ACTION, SPACE_NLA)) || - (sa->spacetype == SPACE_CLIP && ar->regiontype == RGN_TYPE_PREVIEW)) - { - float w = BLI_rctf_size_x(&ar->v2d.cur); - - if (middle) { - if ((scene->r.cfra < ar->v2d.cur.xmin) || (scene->r.cfra > ar->v2d.cur.xmax)) { - ar->v2d.cur.xmax = scene->r.cfra + (w / 2); - ar->v2d.cur.xmin = scene->r.cfra - (w / 2); - } - } - else { - if (scene->r.cfra < ar->v2d.cur.xmin) { - ar->v2d.cur.xmax = scene->r.cfra; - ar->v2d.cur.xmin = ar->v2d.cur.xmax - w; - } - else if (scene->r.cfra > ar->v2d.cur.xmax) { - ar->v2d.cur.xmin = scene->r.cfra; - ar->v2d.cur.xmax = ar->v2d.cur.xmin + w; - } - } - } - } - } - } - } + bScreen *scr = CTX_wm_screen(C); + Scene *scene = CTX_data_scene(C); + wmWindowManager *wm = CTX_wm_manager(C); + for (wmWindow *window = wm->windows.first; window; window = window->next) { + const bScreen *screen = WM_window_get_active_screen(window); + + for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) { + for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { + /* do follow here if editor type supports it */ + if ((scr->redraws_flag & TIME_FOLLOW)) { + if ((ar->regiontype == RGN_TYPE_WINDOW && + ELEM(sa->spacetype, SPACE_SEQ, SPACE_GRAPH, SPACE_ACTION, SPACE_NLA)) || + (sa->spacetype == SPACE_CLIP && ar->regiontype == RGN_TYPE_PREVIEW)) { + float w = BLI_rctf_size_x(&ar->v2d.cur); + + if (middle) { + if ((scene->r.cfra < ar->v2d.cur.xmin) || (scene->r.cfra > ar->v2d.cur.xmax)) { + ar->v2d.cur.xmax = scene->r.cfra + (w / 2); + ar->v2d.cur.xmin = scene->r.cfra - (w / 2); + } + } + else { + if (scene->r.cfra < ar->v2d.cur.xmin) { + ar->v2d.cur.xmax = scene->r.cfra; + ar->v2d.cur.xmin = ar->v2d.cur.xmax - w; + } + else if (scene->r.cfra > ar->v2d.cur.xmax) { + ar->v2d.cur.xmin = scene->r.cfra; + ar->v2d.cur.xmax = ar->v2d.cur.xmin + w; + } + } + } + } + } + } + } } /* function to be called outside UI context, or for redo */ static int frame_offset_exec(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - int delta; + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + int delta; - delta = RNA_int_get(op->ptr, "delta"); + delta = RNA_int_get(op->ptr, "delta"); - CFRA += delta; - FRAMENUMBER_MIN_CLAMP(CFRA); - SUBFRA = 0.f; + CFRA += delta; + FRAMENUMBER_MIN_CLAMP(CFRA); + SUBFRA = 0.f; - areas_do_frame_follow(C, false); + areas_do_frame_follow(C, false); - BKE_sound_seek_scene(bmain, scene); + BKE_sound_seek_scene(bmain, scene); - WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); + WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } static void SCREEN_OT_frame_offset(wmOperatorType *ot) { - ot->name = "Frame Offset"; - ot->idname = "SCREEN_OT_frame_offset"; - ot->description = "Move current frame forward/backward by a given number"; + ot->name = "Frame Offset"; + ot->idname = "SCREEN_OT_frame_offset"; + ot->description = "Move current frame forward/backward by a given number"; - ot->exec = frame_offset_exec; + ot->exec = frame_offset_exec; - ot->poll = ED_operator_screenactive_norender; - ot->flag = OPTYPE_UNDO_GROUPED; - ot->undo_group = "Frame Change"; + ot->poll = ED_operator_screenactive_norender; + ot->flag = OPTYPE_UNDO_GROUPED; + ot->undo_group = "Frame Change"; - /* rna */ - RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX); + /* rna */ + RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX); } /** \} */ @@ -2629,54 +2654,54 @@ static void SCREEN_OT_frame_offset(wmOperatorType *ot) /* function to be called outside UI context, or for redo */ static int frame_jump_exec(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - wmTimer *animtimer = CTX_wm_screen(C)->animtimer; + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + wmTimer *animtimer = CTX_wm_screen(C)->animtimer; - /* Don't change CFRA directly if animtimer is running as this can cause - * first/last frame not to be actually shown (bad since for example physics - * simulations aren't reset properly). - */ - if (animtimer) { - ScreenAnimData *sad = animtimer->customdata; + /* Don't change CFRA directly if animtimer is running as this can cause + * first/last frame not to be actually shown (bad since for example physics + * simulations aren't reset properly). + */ + if (animtimer) { + ScreenAnimData *sad = animtimer->customdata; - sad->flag |= ANIMPLAY_FLAG_USE_NEXT_FRAME; + sad->flag |= ANIMPLAY_FLAG_USE_NEXT_FRAME; - if (RNA_boolean_get(op->ptr, "end")) - sad->nextfra = PEFRA; - else - sad->nextfra = PSFRA; - } - else { - if (RNA_boolean_get(op->ptr, "end")) - CFRA = PEFRA; - else - CFRA = PSFRA; + if (RNA_boolean_get(op->ptr, "end")) + sad->nextfra = PEFRA; + else + sad->nextfra = PSFRA; + } + else { + if (RNA_boolean_get(op->ptr, "end")) + CFRA = PEFRA; + else + CFRA = PSFRA; - areas_do_frame_follow(C, true); + areas_do_frame_follow(C, true); - BKE_sound_seek_scene(bmain, scene); + BKE_sound_seek_scene(bmain, scene); - WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); - } + WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); + } - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } static void SCREEN_OT_frame_jump(wmOperatorType *ot) { - ot->name = "Jump to Endpoint"; - ot->description = "Jump to first/last frame in frame range"; - ot->idname = "SCREEN_OT_frame_jump"; + ot->name = "Jump to Endpoint"; + ot->description = "Jump to first/last frame in frame range"; + ot->idname = "SCREEN_OT_frame_jump"; - ot->exec = frame_jump_exec; + ot->exec = frame_jump_exec; - ot->poll = ED_operator_screenactive_norender; - ot->flag = OPTYPE_UNDO_GROUPED; - ot->undo_group = "Frame Change"; + ot->poll = ED_operator_screenactive_norender; + ot->flag = OPTYPE_UNDO_GROUPED; + ot->undo_group = "Frame Change"; - /* rna */ - RNA_def_boolean(ot->srna, "end", 0, "Last Frame", "Jump to the last frame of the frame range"); + /* rna */ + RNA_def_boolean(ot->srna, "end", 0, "Last Frame", "Jump to the last frame of the frame range"); } /** \} */ @@ -2688,108 +2713,108 @@ static void SCREEN_OT_frame_jump(wmOperatorType *ot) /* function to be called outside UI context, or for redo */ static int keyframe_jump_exec(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - Object *ob = CTX_data_active_object(C); - bDopeSheet ads = {NULL}; - DLRBT_Tree keys; - ActKeyColumn *ak; - float cfra; - const bool next = RNA_boolean_get(op->ptr, "next"); - bool done = false; - - /* sanity checks */ - if (scene == NULL) - return OPERATOR_CANCELLED; - - cfra = (float)(CFRA); - - /* init binarytree-list for getting keyframes */ - BLI_dlrbTree_init(&keys); - - /* seed up dummy dopesheet context with flags to perform necessary filtering */ - if ((scene->flag & SCE_KEYS_NO_SELONLY) == 0) { - /* only selected channels are included */ - ads.filterflag |= ADS_FILTER_ONLYSEL; - } - - /* populate tree with keyframe nodes */ - scene_to_keylist(&ads, scene, &keys, 0); - - if (ob) { - ob_to_keylist(&ads, ob, &keys, 0); - - if (ob->type == OB_GPENCIL) { - const bool active = !(scene->flag & SCE_KEYS_NO_SELONLY); - gpencil_to_keylist(&ads, ob->data, &keys, active); - } - } - - { - Mask *mask = CTX_data_edit_mask(C); - if (mask) { - MaskLayer *masklay = BKE_mask_layer_active(mask); - mask_to_keylist(&ads, masklay, &keys); - } - } - - /* find matching keyframe in the right direction */ - if (next) - ak = (ActKeyColumn *)BLI_dlrbTree_search_next(&keys, compare_ak_cfraPtr, &cfra); - else - ak = (ActKeyColumn *)BLI_dlrbTree_search_prev(&keys, compare_ak_cfraPtr, &cfra); - - while ((ak != NULL) && (done == false)) { - if (CFRA != (int)ak->cfra) { - /* this changes the frame, so set the frame and we're done */ - CFRA = (int)ak->cfra; - done = true; - } - else { - /* take another step... */ - if (next) { - ak = ak->next; - } - else { - ak = ak->prev; - } - } - } - - /* free temp stuff */ - BLI_dlrbTree_free(&keys); - - /* any success? */ - if (done == false) { - BKE_report(op->reports, RPT_INFO, "No more keyframes to jump to in this direction"); - - return OPERATOR_CANCELLED; - } - else { - areas_do_frame_follow(C, true); - - BKE_sound_seek_scene(bmain, scene); - - WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); - - return OPERATOR_FINISHED; - } + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + Object *ob = CTX_data_active_object(C); + bDopeSheet ads = {NULL}; + DLRBT_Tree keys; + ActKeyColumn *ak; + float cfra; + const bool next = RNA_boolean_get(op->ptr, "next"); + bool done = false; + + /* sanity checks */ + if (scene == NULL) + return OPERATOR_CANCELLED; + + cfra = (float)(CFRA); + + /* init binarytree-list for getting keyframes */ + BLI_dlrbTree_init(&keys); + + /* seed up dummy dopesheet context with flags to perform necessary filtering */ + if ((scene->flag & SCE_KEYS_NO_SELONLY) == 0) { + /* only selected channels are included */ + ads.filterflag |= ADS_FILTER_ONLYSEL; + } + + /* populate tree with keyframe nodes */ + scene_to_keylist(&ads, scene, &keys, 0); + + if (ob) { + ob_to_keylist(&ads, ob, &keys, 0); + + if (ob->type == OB_GPENCIL) { + const bool active = !(scene->flag & SCE_KEYS_NO_SELONLY); + gpencil_to_keylist(&ads, ob->data, &keys, active); + } + } + + { + Mask *mask = CTX_data_edit_mask(C); + if (mask) { + MaskLayer *masklay = BKE_mask_layer_active(mask); + mask_to_keylist(&ads, masklay, &keys); + } + } + + /* find matching keyframe in the right direction */ + if (next) + ak = (ActKeyColumn *)BLI_dlrbTree_search_next(&keys, compare_ak_cfraPtr, &cfra); + else + ak = (ActKeyColumn *)BLI_dlrbTree_search_prev(&keys, compare_ak_cfraPtr, &cfra); + + while ((ak != NULL) && (done == false)) { + if (CFRA != (int)ak->cfra) { + /* this changes the frame, so set the frame and we're done */ + CFRA = (int)ak->cfra; + done = true; + } + else { + /* take another step... */ + if (next) { + ak = ak->next; + } + else { + ak = ak->prev; + } + } + } + + /* free temp stuff */ + BLI_dlrbTree_free(&keys); + + /* any success? */ + if (done == false) { + BKE_report(op->reports, RPT_INFO, "No more keyframes to jump to in this direction"); + + return OPERATOR_CANCELLED; + } + else { + areas_do_frame_follow(C, true); + + BKE_sound_seek_scene(bmain, scene); + + WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); + + return OPERATOR_FINISHED; + } } static void SCREEN_OT_keyframe_jump(wmOperatorType *ot) { - ot->name = "Jump to Keyframe"; - ot->description = "Jump to previous/next keyframe"; - ot->idname = "SCREEN_OT_keyframe_jump"; + ot->name = "Jump to Keyframe"; + ot->description = "Jump to previous/next keyframe"; + ot->idname = "SCREEN_OT_keyframe_jump"; - ot->exec = keyframe_jump_exec; + ot->exec = keyframe_jump_exec; - ot->poll = ED_operator_screenactive_norender; - ot->flag = OPTYPE_UNDO_GROUPED; - ot->undo_group = "Frame Change"; + ot->poll = ED_operator_screenactive_norender; + ot->flag = OPTYPE_UNDO_GROUPED; + ot->undo_group = "Frame Change"; - /* properties */ - RNA_def_boolean(ot->srna, "next", true, "Next Keyframe", ""); + /* properties */ + RNA_def_boolean(ot->srna, "next", true, "Next Keyframe", ""); } /** \} */ @@ -2801,62 +2826,62 @@ static void SCREEN_OT_keyframe_jump(wmOperatorType *ot) /* function to be called outside UI context, or for redo */ static int marker_jump_exec(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - TimeMarker *marker; - int closest = CFRA; - const bool next = RNA_boolean_get(op->ptr, "next"); - bool found = false; + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + TimeMarker *marker; + int closest = CFRA; + const bool next = RNA_boolean_get(op->ptr, "next"); + bool found = false; - /* find matching marker in the right direction */ - for (marker = scene->markers.first; marker; marker = marker->next) { - if (next) { - if ((marker->frame > CFRA) && (!found || closest > marker->frame)) { - closest = marker->frame; - found = true; - } - } - else { - if ((marker->frame < CFRA) && (!found || closest < marker->frame)) { - closest = marker->frame; - found = true; - } - } - } + /* find matching marker in the right direction */ + for (marker = scene->markers.first; marker; marker = marker->next) { + if (next) { + if ((marker->frame > CFRA) && (!found || closest > marker->frame)) { + closest = marker->frame; + found = true; + } + } + else { + if ((marker->frame < CFRA) && (!found || closest < marker->frame)) { + closest = marker->frame; + found = true; + } + } + } - /* any success? */ - if (!found) { - BKE_report(op->reports, RPT_INFO, "No more markers to jump to in this direction"); + /* any success? */ + if (!found) { + BKE_report(op->reports, RPT_INFO, "No more markers to jump to in this direction"); - return OPERATOR_CANCELLED; - } - else { - CFRA = closest; + return OPERATOR_CANCELLED; + } + else { + CFRA = closest; - areas_do_frame_follow(C, true); + areas_do_frame_follow(C, true); - BKE_sound_seek_scene(bmain, scene); + BKE_sound_seek_scene(bmain, scene); - WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); + WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); - return OPERATOR_FINISHED; - } + return OPERATOR_FINISHED; + } } static void SCREEN_OT_marker_jump(wmOperatorType *ot) { - ot->name = "Jump to Marker"; - ot->description = "Jump to previous/next marker"; - ot->idname = "SCREEN_OT_marker_jump"; + ot->name = "Jump to Marker"; + ot->description = "Jump to previous/next marker"; + ot->idname = "SCREEN_OT_marker_jump"; - ot->exec = marker_jump_exec; + ot->exec = marker_jump_exec; - ot->poll = ED_operator_screenactive_norender; - ot->flag = OPTYPE_UNDO_GROUPED; - ot->undo_group = "Frame Change"; + ot->poll = ED_operator_screenactive_norender; + ot->flag = OPTYPE_UNDO_GROUPED; + ot->undo_group = "Frame Change"; - /* properties */ - RNA_def_boolean(ot->srna, "next", true, "Next Marker", ""); + /* properties */ + RNA_def_boolean(ot->srna, "next", true, "Next Marker", ""); } /** \} */ @@ -2868,27 +2893,27 @@ static void SCREEN_OT_marker_jump(wmOperatorType *ot) /* function to be called outside UI context, or for redo */ static int screen_set_exec(bContext *C, wmOperator *op) { - WorkSpace *workspace = CTX_wm_workspace(C); - int delta = RNA_int_get(op->ptr, "delta"); + WorkSpace *workspace = CTX_wm_workspace(C); + int delta = RNA_int_get(op->ptr, "delta"); - if (ED_workspace_layout_cycle(workspace, delta, C)) { - return OPERATOR_FINISHED; - } + if (ED_workspace_layout_cycle(workspace, delta, C)) { + return OPERATOR_FINISHED; + } - return OPERATOR_CANCELLED; + return OPERATOR_CANCELLED; } static void SCREEN_OT_screen_set(wmOperatorType *ot) { - ot->name = "Set Screen"; - ot->description = "Cycle through available screens"; - ot->idname = "SCREEN_OT_screen_set"; + ot->name = "Set Screen"; + ot->description = "Cycle through available screens"; + ot->idname = "SCREEN_OT_screen_set"; - ot->exec = screen_set_exec; - ot->poll = ED_operator_screenactive; + ot->exec = screen_set_exec; + ot->poll = ED_operator_screenactive; - /* rna */ - RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX); + /* rna */ + RNA_def_int(ot->srna, "delta", 0, INT_MIN, INT_MAX, "Delta", "", INT_MIN, INT_MAX); } /** \} */ @@ -2900,59 +2925,60 @@ static void SCREEN_OT_screen_set(wmOperatorType *ot) /* function to be called outside UI context, or for redo */ static int screen_maximize_area_exec(bContext *C, wmOperator *op) { - bScreen *screen = CTX_wm_screen(C); - ScrArea *sa = NULL; - const bool hide_panels = RNA_boolean_get(op->ptr, "use_hide_panels"); - - /* search current screen for 'fullscreen' areas */ - /* prevents restoring info header, when mouse is over it */ - for (sa = screen->areabase.first; sa; sa = sa->next) { - if (sa->full) break; - } - - if (sa == NULL) { - sa = CTX_wm_area(C); - } - - if (hide_panels) { - if (!ELEM(screen->state, SCREENNORMAL, SCREENFULL)) { - return OPERATOR_CANCELLED; - } - ED_screen_state_toggle(C, CTX_wm_window(C), sa, SCREENFULL); - } - else { - if (!ELEM(screen->state, SCREENNORMAL, SCREENMAXIMIZED)) { - return OPERATOR_CANCELLED; - } - ED_screen_state_toggle(C, CTX_wm_window(C), sa, SCREENMAXIMIZED); - } - - return OPERATOR_FINISHED; + bScreen *screen = CTX_wm_screen(C); + ScrArea *sa = NULL; + const bool hide_panels = RNA_boolean_get(op->ptr, "use_hide_panels"); + + /* search current screen for 'fullscreen' areas */ + /* prevents restoring info header, when mouse is over it */ + for (sa = screen->areabase.first; sa; sa = sa->next) { + if (sa->full) + break; + } + + if (sa == NULL) { + sa = CTX_wm_area(C); + } + + if (hide_panels) { + if (!ELEM(screen->state, SCREENNORMAL, SCREENFULL)) { + return OPERATOR_CANCELLED; + } + ED_screen_state_toggle(C, CTX_wm_window(C), sa, SCREENFULL); + } + else { + if (!ELEM(screen->state, SCREENNORMAL, SCREENMAXIMIZED)) { + return OPERATOR_CANCELLED; + } + ED_screen_state_toggle(C, CTX_wm_window(C), sa, SCREENMAXIMIZED); + } + + return OPERATOR_FINISHED; } static bool screen_maximize_area_poll(bContext *C) { - const bScreen *screen = CTX_wm_screen(C); - const ScrArea *area = CTX_wm_area(C); - return ED_operator_areaactive(C) && - /* Don't allow maximizing global areas but allow minimizing from them. */ - ((screen->state != SCREENNORMAL) || !ED_area_is_global(area)); + const bScreen *screen = CTX_wm_screen(C); + const ScrArea *area = CTX_wm_area(C); + return ED_operator_areaactive(C) && + /* Don't allow maximizing global areas but allow minimizing from them. */ + ((screen->state != SCREENNORMAL) || !ED_area_is_global(area)); } static void SCREEN_OT_screen_full_area(wmOperatorType *ot) { - PropertyRNA *prop; + PropertyRNA *prop; - ot->name = "Toggle Maximize Area"; - ot->description = "Toggle display selected area as fullscreen/maximized"; - ot->idname = "SCREEN_OT_screen_full_area"; + ot->name = "Toggle Maximize Area"; + ot->description = "Toggle display selected area as fullscreen/maximized"; + ot->idname = "SCREEN_OT_screen_full_area"; - ot->exec = screen_maximize_area_exec; - ot->poll = screen_maximize_area_poll; - ot->flag = 0; + ot->exec = screen_maximize_area_exec; + ot->poll = screen_maximize_area_poll; + ot->flag = 0; - prop = RNA_def_boolean(ot->srna, "use_hide_panels", false, "Hide Panels", "Hide all the panels"); - RNA_def_property_flag(prop, PROP_SKIP_SAVE); + prop = RNA_def_boolean(ot->srna, "use_hide_panels", false, "Hide Panels", "Hide all the panels"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } /** \} */ @@ -2973,37 +2999,36 @@ static void SCREEN_OT_screen_full_area(wmOperatorType *ot) * * apply() do the actual join * - * exit() cleanup, send notifier + * exit() cleanup, send notifier * * callbacks: * - * exec() calls init, apply, exit + * exec() calls init, apply, exit * * invoke() sets mouse coords in x,y * call init() * add modal handler * - * modal() accept modal events while doing it + * modal() accept modal events while doing it * call apply() with active window and nonactive window * call exit() and remove handler when LMB confirm */ typedef struct sAreaJoinData { - ScrArea *sa1; /* first area to be considered */ - ScrArea *sa2; /* second area to be considered */ - void *draw_callback; /* call `ED_screen_draw_join_shape` */ + ScrArea *sa1; /* first area to be considered */ + ScrArea *sa2; /* second area to be considered */ + void *draw_callback; /* call `ED_screen_draw_join_shape` */ } sAreaJoinData; - static void area_join_draw_cb(const struct wmWindow *UNUSED(win), void *userdata) { - const wmOperator *op = userdata; + const wmOperator *op = userdata; - sAreaJoinData *sd = op->customdata; - if (sd->sa1 && sd->sa2) { - ED_screen_draw_join_shape(sd->sa1, sd->sa2); - } + sAreaJoinData *sd = op->customdata; + if (sd->sa1 && sd->sa2) { + ED_screen_draw_join_shape(sd->sa1, sd->sa2); + } } /* validate selection inside screen, set variables OK */ @@ -3011,252 +3036,252 @@ static void area_join_draw_cb(const struct wmWindow *UNUSED(win), void *userdata /* XXX todo: find edge based on (x,y) and set other area? */ static int area_join_init(bContext *C, wmOperator *op) { - const wmWindow *win = CTX_wm_window(C); - bScreen *screen = CTX_wm_screen(C); - ScrArea *sa1, *sa2; - sAreaJoinData *jd = NULL; - int x1, y1; - int x2, y2; + const wmWindow *win = CTX_wm_window(C); + bScreen *screen = CTX_wm_screen(C); + ScrArea *sa1, *sa2; + sAreaJoinData *jd = NULL; + int x1, y1; + int x2, y2; - /* required properties, make negative to get return 0 if not set by caller */ - x1 = RNA_int_get(op->ptr, "min_x"); - y1 = RNA_int_get(op->ptr, "min_y"); - x2 = RNA_int_get(op->ptr, "max_x"); - y2 = RNA_int_get(op->ptr, "max_y"); + /* required properties, make negative to get return 0 if not set by caller */ + x1 = RNA_int_get(op->ptr, "min_x"); + y1 = RNA_int_get(op->ptr, "min_y"); + x2 = RNA_int_get(op->ptr, "max_x"); + y2 = RNA_int_get(op->ptr, "max_y"); - sa1 = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, x1, y1); - if (sa1 == NULL) { - sa1 = BKE_screen_area_map_find_area_xy(&win->global_areas, SPACE_TYPE_ANY, x1, y1); - } - sa2 = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, x2, y2); - if (sa2 == NULL) { - sa2 = BKE_screen_area_map_find_area_xy(&win->global_areas, SPACE_TYPE_ANY, x2, y2); - } - if ((sa1 && ED_area_is_global(sa1)) || (sa2 && ED_area_is_global(sa2))) { - BKE_report(op->reports, RPT_ERROR, "Global areas (Top Bar, Status Bar) do not support joining"); - return 0; - } - else if (sa1 == NULL || sa2 == NULL || sa1 == sa2) { - return 0; - } + sa1 = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, x1, y1); + if (sa1 == NULL) { + sa1 = BKE_screen_area_map_find_area_xy(&win->global_areas, SPACE_TYPE_ANY, x1, y1); + } + sa2 = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, x2, y2); + if (sa2 == NULL) { + sa2 = BKE_screen_area_map_find_area_xy(&win->global_areas, SPACE_TYPE_ANY, x2, y2); + } + if ((sa1 && ED_area_is_global(sa1)) || (sa2 && ED_area_is_global(sa2))) { + BKE_report( + op->reports, RPT_ERROR, "Global areas (Top Bar, Status Bar) do not support joining"); + return 0; + } + else if (sa1 == NULL || sa2 == NULL || sa1 == sa2) { + return 0; + } - jd = (sAreaJoinData *)MEM_callocN(sizeof(sAreaJoinData), "op_area_join"); + jd = (sAreaJoinData *)MEM_callocN(sizeof(sAreaJoinData), "op_area_join"); - jd->sa1 = sa1; - jd->sa2 = sa2; + jd->sa1 = sa1; + jd->sa2 = sa2; - op->customdata = jd; + op->customdata = jd; - jd->draw_callback = WM_draw_cb_activate(CTX_wm_window(C), area_join_draw_cb, op); + jd->draw_callback = WM_draw_cb_activate(CTX_wm_window(C), area_join_draw_cb, op); - return 1; + return 1; } /* apply the join of the areas (space types) */ static int area_join_apply(bContext *C, wmOperator *op) { - sAreaJoinData *jd = (sAreaJoinData *)op->customdata; - if (!jd) return 0; + sAreaJoinData *jd = (sAreaJoinData *)op->customdata; + if (!jd) + return 0; - if (!screen_area_join(C, CTX_wm_screen(C), jd->sa1, jd->sa2)) { - return 0; - } - if (CTX_wm_area(C) == jd->sa2) { - CTX_wm_area_set(C, NULL); - CTX_wm_region_set(C, NULL); - } + if (!screen_area_join(C, CTX_wm_screen(C), jd->sa1, jd->sa2)) { + return 0; + } + if (CTX_wm_area(C) == jd->sa2) { + CTX_wm_area_set(C, NULL); + CTX_wm_region_set(C, NULL); + } - return 1; + return 1; } /* finish operation */ static void area_join_exit(bContext *C, wmOperator *op) { - sAreaJoinData *jd = (sAreaJoinData *)op->customdata; + sAreaJoinData *jd = (sAreaJoinData *)op->customdata; - if (jd) { - if (jd->draw_callback) - WM_draw_cb_exit(CTX_wm_window(C), jd->draw_callback); + if (jd) { + if (jd->draw_callback) + WM_draw_cb_exit(CTX_wm_window(C), jd->draw_callback); - MEM_freeN(jd); - op->customdata = NULL; - } + MEM_freeN(jd); + op->customdata = NULL; + } - /* this makes sure aligned edges will result in aligned grabbing */ - BKE_screen_remove_double_scredges(CTX_wm_screen(C)); - BKE_screen_remove_unused_scredges(CTX_wm_screen(C)); - BKE_screen_remove_unused_scrverts(CTX_wm_screen(C)); + /* this makes sure aligned edges will result in aligned grabbing */ + BKE_screen_remove_double_scredges(CTX_wm_screen(C)); + BKE_screen_remove_unused_scredges(CTX_wm_screen(C)); + BKE_screen_remove_unused_scrverts(CTX_wm_screen(C)); } static int area_join_exec(bContext *C, wmOperator *op) { - if (!area_join_init(C, op)) - return OPERATOR_CANCELLED; + if (!area_join_init(C, op)) + return OPERATOR_CANCELLED; - area_join_apply(C, op); - area_join_exit(C, op); + area_join_apply(C, op); + area_join_exit(C, op); - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } /* interaction callback */ static int area_join_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - if (event->type == EVT_ACTIONZONE_AREA) { - sActionzoneData *sad = event->customdata; + if (event->type == EVT_ACTIONZONE_AREA) { + sActionzoneData *sad = event->customdata; - if (sad == NULL || sad->modifier > 0) { - return OPERATOR_PASS_THROUGH; - } + if (sad == NULL || sad->modifier > 0) { + return OPERATOR_PASS_THROUGH; + } - /* verify *sad itself */ - if (sad->sa1 == NULL || sad->sa2 == NULL) - return OPERATOR_PASS_THROUGH; + /* verify *sad itself */ + if (sad->sa1 == NULL || sad->sa2 == NULL) + return OPERATOR_PASS_THROUGH; - /* is this our *sad? if areas equal it should be passed on */ - if (sad->sa1 == sad->sa2) - return OPERATOR_PASS_THROUGH; + /* is this our *sad? if areas equal it should be passed on */ + if (sad->sa1 == sad->sa2) + return OPERATOR_PASS_THROUGH; - /* prepare operator state vars */ - RNA_int_set(op->ptr, "min_x", sad->sa1->totrct.xmin); - RNA_int_set(op->ptr, "min_y", sad->sa1->totrct.ymin); - RNA_int_set(op->ptr, "max_x", sad->sa2->totrct.xmin); - RNA_int_set(op->ptr, "max_y", sad->sa2->totrct.ymin); - } + /* prepare operator state vars */ + RNA_int_set(op->ptr, "min_x", sad->sa1->totrct.xmin); + RNA_int_set(op->ptr, "min_y", sad->sa1->totrct.ymin); + RNA_int_set(op->ptr, "max_x", sad->sa2->totrct.xmin); + RNA_int_set(op->ptr, "max_y", sad->sa2->totrct.ymin); + } + if (!area_join_init(C, op)) + return OPERATOR_CANCELLED; - if (!area_join_init(C, op)) - return OPERATOR_CANCELLED; + /* add temp handler */ + WM_event_add_modal_handler(C, op); - /* add temp handler */ - WM_event_add_modal_handler(C, op); - - return OPERATOR_RUNNING_MODAL; + return OPERATOR_RUNNING_MODAL; } static void area_join_cancel(bContext *C, wmOperator *op) { - WM_event_add_notifier(C, NC_WINDOW, NULL); + WM_event_add_notifier(C, NC_WINDOW, NULL); - area_join_exit(C, op); + area_join_exit(C, op); } /* modal callback while selecting area (space) that will be removed */ static int area_join_modal(bContext *C, wmOperator *op, const wmEvent *event) { - bScreen *sc = CTX_wm_screen(C); - wmWindow *win = CTX_wm_window(C); - sAreaJoinData *jd = (sAreaJoinData *)op->customdata; - - /* execute the events */ - switch (event->type) { - - case MOUSEMOVE: - { - ScrArea *sa = BKE_screen_find_area_xy(sc, SPACE_TYPE_ANY, event->x, event->y); - int dir = -1; - - if (sa) { - if (jd->sa1 != sa) { - dir = area_getorientation(jd->sa1, sa); - if (dir != -1) { - jd->sa2 = sa; - } - else { - /* we are not bordering on the previously selected area - * we check if area has common border with the one marked for removal - * in this case we can swap areas. - */ - dir = area_getorientation(sa, jd->sa2); - if (dir != -1) { - jd->sa1 = jd->sa2; - jd->sa2 = sa; - } - else { - jd->sa2 = NULL; - } - } - WM_event_add_notifier(C, NC_WINDOW, NULL); - } - else { - /* we are back in the area previously selected for keeping - * we swap the areas if possible to allow user to choose */ - if (jd->sa2 != NULL) { - jd->sa1 = jd->sa2; - jd->sa2 = sa; - dir = area_getorientation(jd->sa1, jd->sa2); - if (dir == -1) { - printf("oops, didn't expect that!\n"); - } - } - else { - dir = area_getorientation(jd->sa1, sa); - if (dir != -1) { - jd->sa2 = sa; - } - } - WM_event_add_notifier(C, NC_WINDOW, NULL); - } - } - - if (dir == 1) - WM_cursor_set(win, BC_N_ARROWCURSOR); - else if (dir == 3) - WM_cursor_set(win, BC_S_ARROWCURSOR); - else if (dir == 2) - WM_cursor_set(win, BC_E_ARROWCURSOR); - else if (dir == 0) - WM_cursor_set(win, BC_W_ARROWCURSOR); - else - WM_cursor_set(win, BC_STOPCURSOR); - - break; - } - case LEFTMOUSE: - if (event->val == KM_RELEASE) { - ED_area_tag_redraw(jd->sa1); - ED_area_tag_redraw(jd->sa2); - - area_join_apply(C, op); - WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); - area_join_exit(C, op); - return OPERATOR_FINISHED; - } - break; - - case RIGHTMOUSE: - case ESCKEY: - area_join_cancel(C, op); - return OPERATOR_CANCELLED; - } - - return OPERATOR_RUNNING_MODAL; + bScreen *sc = CTX_wm_screen(C); + wmWindow *win = CTX_wm_window(C); + sAreaJoinData *jd = (sAreaJoinData *)op->customdata; + + /* execute the events */ + switch (event->type) { + + case MOUSEMOVE: { + ScrArea *sa = BKE_screen_find_area_xy(sc, SPACE_TYPE_ANY, event->x, event->y); + int dir = -1; + + if (sa) { + if (jd->sa1 != sa) { + dir = area_getorientation(jd->sa1, sa); + if (dir != -1) { + jd->sa2 = sa; + } + else { + /* we are not bordering on the previously selected area + * we check if area has common border with the one marked for removal + * in this case we can swap areas. + */ + dir = area_getorientation(sa, jd->sa2); + if (dir != -1) { + jd->sa1 = jd->sa2; + jd->sa2 = sa; + } + else { + jd->sa2 = NULL; + } + } + WM_event_add_notifier(C, NC_WINDOW, NULL); + } + else { + /* we are back in the area previously selected for keeping + * we swap the areas if possible to allow user to choose */ + if (jd->sa2 != NULL) { + jd->sa1 = jd->sa2; + jd->sa2 = sa; + dir = area_getorientation(jd->sa1, jd->sa2); + if (dir == -1) { + printf("oops, didn't expect that!\n"); + } + } + else { + dir = area_getorientation(jd->sa1, sa); + if (dir != -1) { + jd->sa2 = sa; + } + } + WM_event_add_notifier(C, NC_WINDOW, NULL); + } + } + + if (dir == 1) + WM_cursor_set(win, BC_N_ARROWCURSOR); + else if (dir == 3) + WM_cursor_set(win, BC_S_ARROWCURSOR); + else if (dir == 2) + WM_cursor_set(win, BC_E_ARROWCURSOR); + else if (dir == 0) + WM_cursor_set(win, BC_W_ARROWCURSOR); + else + WM_cursor_set(win, BC_STOPCURSOR); + + break; + } + case LEFTMOUSE: + if (event->val == KM_RELEASE) { + ED_area_tag_redraw(jd->sa1); + ED_area_tag_redraw(jd->sa2); + + area_join_apply(C, op); + WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); + area_join_exit(C, op); + return OPERATOR_FINISHED; + } + break; + + case RIGHTMOUSE: + case ESCKEY: + area_join_cancel(C, op); + return OPERATOR_CANCELLED; + } + + return OPERATOR_RUNNING_MODAL; } /* Operator for joining two areas (space types) */ static void SCREEN_OT_area_join(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Join Area"; - ot->description = "Join selected areas into new window"; - ot->idname = "SCREEN_OT_area_join"; + /* identifiers */ + ot->name = "Join Area"; + ot->description = "Join selected areas into new window"; + ot->idname = "SCREEN_OT_area_join"; - /* api callbacks */ - ot->exec = area_join_exec; - ot->invoke = area_join_invoke; - ot->modal = area_join_modal; - ot->poll = screen_active_editable; - ot->cancel = area_join_cancel; + /* api callbacks */ + ot->exec = area_join_exec; + ot->invoke = area_join_invoke; + ot->modal = area_join_modal; + ot->poll = screen_active_editable; + ot->cancel = area_join_cancel; - /* flags */ - ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL; + /* flags */ + ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL; - /* rna */ - RNA_def_int(ot->srna, "min_x", -100, INT_MIN, INT_MAX, "X 1", "", INT_MIN, INT_MAX); - RNA_def_int(ot->srna, "min_y", -100, INT_MIN, INT_MAX, "Y 1", "", INT_MIN, INT_MAX); - RNA_def_int(ot->srna, "max_x", -100, INT_MIN, INT_MAX, "X 2", "", INT_MIN, INT_MAX); - RNA_def_int(ot->srna, "max_y", -100, INT_MIN, INT_MAX, "Y 2", "", INT_MIN, INT_MAX); + /* rna */ + RNA_def_int(ot->srna, "min_x", -100, INT_MIN, INT_MAX, "X 1", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "min_y", -100, INT_MIN, INT_MAX, "Y 1", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "max_x", -100, INT_MIN, INT_MAX, "X 2", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "max_y", -100, INT_MIN, INT_MAX, "Y 2", "", INT_MIN, INT_MAX); } /** \} */ @@ -3267,52 +3292,55 @@ static void SCREEN_OT_area_join(wmOperatorType *ot) static int screen_area_options_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - const wmWindow *win = CTX_wm_window(C); - const bScreen *sc = CTX_wm_screen(C); - uiPopupMenu *pup; - uiLayout *layout; - PointerRNA ptr; - ScrEdge *actedge; - rcti window_rect; + const wmWindow *win = CTX_wm_window(C); + const bScreen *sc = CTX_wm_screen(C); + uiPopupMenu *pup; + uiLayout *layout; + PointerRNA ptr; + ScrEdge *actedge; + rcti window_rect; - WM_window_rect_calc(win, &window_rect); - actedge = screen_geom_area_map_find_active_scredge(AREAMAP_FROM_SCREEN(sc), &window_rect, event->x, event->y); + WM_window_rect_calc(win, &window_rect); + actedge = screen_geom_area_map_find_active_scredge( + AREAMAP_FROM_SCREEN(sc), &window_rect, event->x, event->y); - if (actedge == NULL) return OPERATOR_CANCELLED; + if (actedge == NULL) + return OPERATOR_CANCELLED; - pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE); - layout = UI_popup_menu_layout(pup); + pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE); + layout = UI_popup_menu_layout(pup); - uiItemFullO(layout, "SCREEN_OT_area_split", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, &ptr); - /* store initial mouse cursor position */ - RNA_int_set_array(&ptr, "cursor", &event->x); + uiItemFullO( + layout, "SCREEN_OT_area_split", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, &ptr); + /* store initial mouse cursor position */ + RNA_int_set_array(&ptr, "cursor", &event->x); - uiItemFullO(layout, "SCREEN_OT_area_join", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, &ptr); - /* mouse cursor on edge, '4' can fail on wide edges... */ - RNA_int_set(&ptr, "min_x", event->x + 4); - RNA_int_set(&ptr, "min_y", event->y + 4); - RNA_int_set(&ptr, "max_x", event->x - 4); - RNA_int_set(&ptr, "max_y", event->y - 4); + uiItemFullO(layout, "SCREEN_OT_area_join", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, &ptr); + /* mouse cursor on edge, '4' can fail on wide edges... */ + RNA_int_set(&ptr, "min_x", event->x + 4); + RNA_int_set(&ptr, "min_y", event->y + 4); + RNA_int_set(&ptr, "max_x", event->x - 4); + RNA_int_set(&ptr, "max_y", event->y - 4); - UI_popup_menu_end(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_INTERFACE; + return OPERATOR_INTERFACE; } static void SCREEN_OT_area_options(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Area Options"; - ot->description = "Operations for splitting and merging"; - ot->idname = "SCREEN_OT_area_options"; + /* identifiers */ + ot->name = "Area Options"; + ot->description = "Operations for splitting and merging"; + ot->idname = "SCREEN_OT_area_options"; - /* api callbacks */ - ot->invoke = screen_area_options_invoke; + /* api callbacks */ + ot->invoke = screen_area_options_invoke; - ot->poll = ED_operator_screen_mainwinactive; + ot->poll = ED_operator_screen_mainwinactive; - /* flags */ - ot->flag = OPTYPE_INTERNAL; + /* flags */ + ot->flag = OPTYPE_INTERNAL; } /** \} */ @@ -3323,39 +3351,38 @@ static void SCREEN_OT_area_options(wmOperatorType *ot) static int spacedata_cleanup_exec(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); - bScreen *screen; - ScrArea *sa; - int tot = 0; + Main *bmain = CTX_data_main(C); + bScreen *screen; + ScrArea *sa; + int tot = 0; - for (screen = bmain->screens.first; screen; screen = screen->id.next) { - for (sa = screen->areabase.first; sa; sa = sa->next) { - if (sa->spacedata.first != sa->spacedata.last) { - SpaceLink *sl = sa->spacedata.first; + for (screen = bmain->screens.first; screen; screen = screen->id.next) { + for (sa = screen->areabase.first; sa; sa = sa->next) { + if (sa->spacedata.first != sa->spacedata.last) { + SpaceLink *sl = sa->spacedata.first; - BLI_remlink(&sa->spacedata, sl); - tot += BLI_listbase_count(&sa->spacedata); - BKE_spacedata_freelist(&sa->spacedata); - BLI_addtail(&sa->spacedata, sl); - } - } - } - BKE_reportf(op->reports, RPT_INFO, "Removed amount of editors: %d", tot); + BLI_remlink(&sa->spacedata, sl); + tot += BLI_listbase_count(&sa->spacedata); + BKE_spacedata_freelist(&sa->spacedata); + BLI_addtail(&sa->spacedata, sl); + } + } + } + BKE_reportf(op->reports, RPT_INFO, "Removed amount of editors: %d", tot); - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } static void SCREEN_OT_spacedata_cleanup(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Clean-up Space-data"; - ot->description = "Remove unused settings for invisible editors"; - ot->idname = "SCREEN_OT_spacedata_cleanup"; - - /* api callbacks */ - ot->exec = spacedata_cleanup_exec; - ot->poll = WM_operator_winactive; + /* identifiers */ + ot->name = "Clean-up Space-data"; + ot->description = "Remove unused settings for invisible editors"; + ot->idname = "SCREEN_OT_spacedata_cleanup"; + /* api callbacks */ + ot->exec = spacedata_cleanup_exec; + ot->poll = WM_operator_winactive; } /** \} */ @@ -3366,39 +3393,38 @@ static void SCREEN_OT_spacedata_cleanup(wmOperatorType *ot) static int repeat_last_exec(bContext *C, wmOperator *UNUSED(op)) { - wmWindowManager *wm = CTX_wm_manager(C); - wmOperator *lastop = wm->operators.last; + wmWindowManager *wm = CTX_wm_manager(C); + wmOperator *lastop = wm->operators.last; - /* Seek last registered operator */ - while (lastop) { - if (lastop->type->flag & OPTYPE_REGISTER) { - break; - } - else { - lastop = lastop->prev; - } - } + /* Seek last registered operator */ + while (lastop) { + if (lastop->type->flag & OPTYPE_REGISTER) { + break; + } + else { + lastop = lastop->prev; + } + } - if (lastop) { - WM_operator_free_all_after(wm, lastop); - WM_operator_repeat_interactive(C, lastop); - } + if (lastop) { + WM_operator_free_all_after(wm, lastop); + WM_operator_repeat_interactive(C, lastop); + } - return OPERATOR_CANCELLED; + return OPERATOR_CANCELLED; } static void SCREEN_OT_repeat_last(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Repeat Last"; - ot->description = "Repeat last action"; - ot->idname = "SCREEN_OT_repeat_last"; - - /* api callbacks */ - ot->exec = repeat_last_exec; + /* identifiers */ + ot->name = "Repeat Last"; + ot->description = "Repeat last action"; + ot->idname = "SCREEN_OT_repeat_last"; - ot->poll = ED_operator_screenactive; + /* api callbacks */ + ot->exec = repeat_last_exec; + ot->poll = ED_operator_screenactive; } /** \} */ @@ -3409,59 +3435,60 @@ static void SCREEN_OT_repeat_last(wmOperatorType *ot) static int repeat_history_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - wmWindowManager *wm = CTX_wm_manager(C); - wmOperator *lastop; - uiPopupMenu *pup; - uiLayout *layout; - int items, i; + wmWindowManager *wm = CTX_wm_manager(C); + wmOperator *lastop; + uiPopupMenu *pup; + uiLayout *layout; + int items, i; - items = BLI_listbase_count(&wm->operators); - if (items == 0) - return OPERATOR_CANCELLED; + items = BLI_listbase_count(&wm->operators); + if (items == 0) + return OPERATOR_CANCELLED; - pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE); - layout = UI_popup_menu_layout(pup); + pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE); + layout = UI_popup_menu_layout(pup); - for (i = items - 1, lastop = wm->operators.last; lastop; lastop = lastop->prev, i--) - if ((lastop->type->flag & OPTYPE_REGISTER) && WM_operator_repeat_check(C, lastop)) { - uiItemIntO(layout, RNA_struct_ui_name(lastop->type->srna), ICON_NONE, op->type->idname, "index", i); - } + for (i = items - 1, lastop = wm->operators.last; lastop; lastop = lastop->prev, i--) + if ((lastop->type->flag & OPTYPE_REGISTER) && WM_operator_repeat_check(C, lastop)) { + uiItemIntO( + layout, RNA_struct_ui_name(lastop->type->srna), ICON_NONE, op->type->idname, "index", i); + } - UI_popup_menu_end(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_INTERFACE; + return OPERATOR_INTERFACE; } static int repeat_history_exec(bContext *C, wmOperator *op) { - wmWindowManager *wm = CTX_wm_manager(C); + wmWindowManager *wm = CTX_wm_manager(C); - op = BLI_findlink(&wm->operators, RNA_int_get(op->ptr, "index")); - if (op) { - /* let's put it as last operator in list */ - BLI_remlink(&wm->operators, op); - BLI_addtail(&wm->operators, op); + op = BLI_findlink(&wm->operators, RNA_int_get(op->ptr, "index")); + if (op) { + /* let's put it as last operator in list */ + BLI_remlink(&wm->operators, op); + BLI_addtail(&wm->operators, op); - WM_operator_repeat(C, op); - } + WM_operator_repeat(C, op); + } - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } static void SCREEN_OT_repeat_history(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Repeat History"; - ot->description = "Display menu for previous actions performed"; - ot->idname = "SCREEN_OT_repeat_history"; + /* identifiers */ + ot->name = "Repeat History"; + ot->description = "Display menu for previous actions performed"; + ot->idname = "SCREEN_OT_repeat_history"; - /* api callbacks */ - ot->invoke = repeat_history_invoke; - ot->exec = repeat_history_exec; + /* api callbacks */ + ot->invoke = repeat_history_invoke; + ot->exec = repeat_history_exec; - ot->poll = ED_operator_screenactive; + ot->poll = ED_operator_screenactive; - RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, 1000); + RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, 1000); } /** \} */ @@ -3472,25 +3499,25 @@ static void SCREEN_OT_repeat_history(wmOperatorType *ot) static int redo_last_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event)) { - wmOperator *lastop = WM_operator_last_redo(C); + wmOperator *lastop = WM_operator_last_redo(C); - if (lastop) - WM_operator_redo_popup(C, lastop); + if (lastop) + WM_operator_redo_popup(C, lastop); - return OPERATOR_CANCELLED; + return OPERATOR_CANCELLED; } static void SCREEN_OT_redo_last(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Redo Last"; - ot->description = "Display menu for last action performed"; - ot->idname = "SCREEN_OT_redo_last"; + /* identifiers */ + ot->name = "Redo Last"; + ot->description = "Display menu for last action performed"; + ot->idname = "SCREEN_OT_redo_last"; - /* api callbacks */ - ot->invoke = redo_last_invoke; + /* api callbacks */ + ot->invoke = redo_last_invoke; - ot->poll = ED_operator_screenactive; + ot->poll = ED_operator_screenactive; } /** \} */ @@ -3501,153 +3528,162 @@ static void SCREEN_OT_redo_last(wmOperatorType *ot) static void view3d_localview_update_rv3d(struct RegionView3D *rv3d) { - if (rv3d->localvd) { - rv3d->localvd->view = rv3d->view; - rv3d->localvd->persp = rv3d->persp; - copy_qt_qt(rv3d->localvd->viewquat, rv3d->viewquat); - } + if (rv3d->localvd) { + rv3d->localvd->view = rv3d->view; + rv3d->localvd->persp = rv3d->persp; + copy_qt_qt(rv3d->localvd->viewquat, rv3d->viewquat); + } } -static void region_quadview_init_rv3d(ScrArea *sa, ARegion *ar, - const char viewlock, const char view, const char persp) +static void region_quadview_init_rv3d( + ScrArea *sa, ARegion *ar, const char viewlock, const char view, const char persp) { - RegionView3D *rv3d = ar->regiondata; + RegionView3D *rv3d = ar->regiondata; - if (persp == RV3D_CAMOB) { - ED_view3d_lastview_store(rv3d); - } + if (persp == RV3D_CAMOB) { + ED_view3d_lastview_store(rv3d); + } - rv3d->viewlock = viewlock; - rv3d->view = view; - rv3d->persp = persp; + rv3d->viewlock = viewlock; + rv3d->view = view; + rv3d->persp = persp; - ED_view3d_lock(rv3d); - view3d_localview_update_rv3d(rv3d); - if ((viewlock & RV3D_BOXCLIP) && (persp == RV3D_ORTHO)) { - ED_view3d_quadview_update(sa, ar, true); - } + ED_view3d_lock(rv3d); + view3d_localview_update_rv3d(rv3d); + if ((viewlock & RV3D_BOXCLIP) && (persp == RV3D_ORTHO)) { + ED_view3d_quadview_update(sa, ar, true); + } } /* insert a region in the area region list */ static int region_quadview_exec(bContext *C, wmOperator *op) { - ARegion *ar = CTX_wm_region(C); - - /* some rules... */ - if (ar->regiontype != RGN_TYPE_WINDOW) { - BKE_report(op->reports, RPT_ERROR, "Only window region can be 4-splitted"); - } - else if (ar->alignment == RGN_ALIGN_QSPLIT) { - /* Exit quad-view */ - ScrArea *sa = CTX_wm_area(C); - ARegion *arn; - - /* keep current region */ - ar->alignment = 0; - - if (sa->spacetype == SPACE_VIEW3D) { - ARegion *ar_iter; - RegionView3D *rv3d = ar->regiondata; - - /* if this is a locked view, use settings from 'User' view */ - if (rv3d->viewlock) { - View3D *v3d_user; - ARegion *ar_user; - - if (ED_view3d_context_user_region(C, &v3d_user, &ar_user)) { - if (ar != ar_user) { - SWAP(void *, ar->regiondata, ar_user->regiondata); - rv3d = ar->regiondata; - } - } - } - - rv3d->viewlock_quad = RV3D_VIEWLOCK_INIT; - rv3d->viewlock = 0; - rv3d->rflag &= ~RV3D_CLIPPING; - - /* accumulate locks, incase they're mixed */ - for (ar_iter = sa->regionbase.first; ar_iter; ar_iter = ar_iter->next) { - if (ar_iter->regiontype == RGN_TYPE_WINDOW) { - RegionView3D *rv3d_iter = ar_iter->regiondata; - rv3d->viewlock_quad |= rv3d_iter->viewlock; - } - } - } - - for (ar = sa->regionbase.first; ar; ar = arn) { - arn = ar->next; - if (ar->alignment == RGN_ALIGN_QSPLIT) { - ED_region_exit(C, ar); - BKE_area_region_free(sa->type, ar); - BLI_remlink(&sa->regionbase, ar); - MEM_freeN(ar); - } - } - ED_area_tag_redraw(sa); - WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); - } - else if (ar->next) { - BKE_report(op->reports, RPT_ERROR, "Only last region can be 4-splitted"); - } - else { - /* Enter quad-view */ - ScrArea *sa = CTX_wm_area(C); - ARegion *newar; - int count; - - ar->alignment = RGN_ALIGN_QSPLIT; - - for (count = 0; count < 3; count++) { - newar = BKE_area_region_copy(sa->type, ar); - BLI_addtail(&sa->regionbase, newar); - } - - /* lock views and set them */ - if (sa->spacetype == SPACE_VIEW3D) { - View3D *v3d = sa->spacedata.first; - int index_qsplit = 0; - - /* run ED_view3d_lock() so the correct 'rv3d->viewquat' is set, - * otherwise when restoring rv3d->localvd the 'viewquat' won't - * match the 'view', set on entering localview See: [#26315], - * - * We could avoid manipulating rv3d->localvd here if exiting - * localview with a 4-split would assign these view locks */ - RegionView3D *rv3d = ar->regiondata; - const char viewlock = (rv3d->viewlock_quad & RV3D_VIEWLOCK_INIT) ? - (rv3d->viewlock_quad & ~RV3D_VIEWLOCK_INIT) : RV3D_LOCKED; - - region_quadview_init_rv3d(sa, ar, viewlock, ED_view3d_lock_view_from_index(index_qsplit++), RV3D_ORTHO); - region_quadview_init_rv3d(sa, (ar = ar->next), viewlock, ED_view3d_lock_view_from_index(index_qsplit++), RV3D_ORTHO); - region_quadview_init_rv3d(sa, (ar = ar->next), viewlock, ED_view3d_lock_view_from_index(index_qsplit++), RV3D_ORTHO); - /* forcing camera is distracting */ + ARegion *ar = CTX_wm_region(C); + + /* some rules... */ + if (ar->regiontype != RGN_TYPE_WINDOW) { + BKE_report(op->reports, RPT_ERROR, "Only window region can be 4-splitted"); + } + else if (ar->alignment == RGN_ALIGN_QSPLIT) { + /* Exit quad-view */ + ScrArea *sa = CTX_wm_area(C); + ARegion *arn; + + /* keep current region */ + ar->alignment = 0; + + if (sa->spacetype == SPACE_VIEW3D) { + ARegion *ar_iter; + RegionView3D *rv3d = ar->regiondata; + + /* if this is a locked view, use settings from 'User' view */ + if (rv3d->viewlock) { + View3D *v3d_user; + ARegion *ar_user; + + if (ED_view3d_context_user_region(C, &v3d_user, &ar_user)) { + if (ar != ar_user) { + SWAP(void *, ar->regiondata, ar_user->regiondata); + rv3d = ar->regiondata; + } + } + } + + rv3d->viewlock_quad = RV3D_VIEWLOCK_INIT; + rv3d->viewlock = 0; + rv3d->rflag &= ~RV3D_CLIPPING; + + /* accumulate locks, incase they're mixed */ + for (ar_iter = sa->regionbase.first; ar_iter; ar_iter = ar_iter->next) { + if (ar_iter->regiontype == RGN_TYPE_WINDOW) { + RegionView3D *rv3d_iter = ar_iter->regiondata; + rv3d->viewlock_quad |= rv3d_iter->viewlock; + } + } + } + + for (ar = sa->regionbase.first; ar; ar = arn) { + arn = ar->next; + if (ar->alignment == RGN_ALIGN_QSPLIT) { + ED_region_exit(C, ar); + BKE_area_region_free(sa->type, ar); + BLI_remlink(&sa->regionbase, ar); + MEM_freeN(ar); + } + } + ED_area_tag_redraw(sa); + WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); + } + else if (ar->next) { + BKE_report(op->reports, RPT_ERROR, "Only last region can be 4-splitted"); + } + else { + /* Enter quad-view */ + ScrArea *sa = CTX_wm_area(C); + ARegion *newar; + int count; + + ar->alignment = RGN_ALIGN_QSPLIT; + + for (count = 0; count < 3; count++) { + newar = BKE_area_region_copy(sa->type, ar); + BLI_addtail(&sa->regionbase, newar); + } + + /* lock views and set them */ + if (sa->spacetype == SPACE_VIEW3D) { + View3D *v3d = sa->spacedata.first; + int index_qsplit = 0; + + /* run ED_view3d_lock() so the correct 'rv3d->viewquat' is set, + * otherwise when restoring rv3d->localvd the 'viewquat' won't + * match the 'view', set on entering localview See: [#26315], + * + * We could avoid manipulating rv3d->localvd here if exiting + * localview with a 4-split would assign these view locks */ + RegionView3D *rv3d = ar->regiondata; + const char viewlock = (rv3d->viewlock_quad & RV3D_VIEWLOCK_INIT) ? + (rv3d->viewlock_quad & ~RV3D_VIEWLOCK_INIT) : + RV3D_LOCKED; + + region_quadview_init_rv3d( + sa, ar, viewlock, ED_view3d_lock_view_from_index(index_qsplit++), RV3D_ORTHO); + region_quadview_init_rv3d(sa, + (ar = ar->next), + viewlock, + ED_view3d_lock_view_from_index(index_qsplit++), + RV3D_ORTHO); + region_quadview_init_rv3d(sa, + (ar = ar->next), + viewlock, + ED_view3d_lock_view_from_index(index_qsplit++), + RV3D_ORTHO); + /* forcing camera is distracting */ #if 0 - if (v3d->camera) region_quadview_init_rv3d(sa, (ar = ar->next), 0, RV3D_VIEW_CAMERA, RV3D_CAMOB); - else region_quadview_init_rv3d(sa, (ar = ar->next), 0, RV3D_VIEW_USER, RV3D_PERSP); + if (v3d->camera) region_quadview_init_rv3d(sa, (ar = ar->next), 0, RV3D_VIEW_CAMERA, RV3D_CAMOB); + else region_quadview_init_rv3d(sa, (ar = ar->next), 0, RV3D_VIEW_USER, RV3D_PERSP); #else - (void)v3d; + (void)v3d; #endif - } - ED_area_tag_redraw(sa); - WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); - } + } + ED_area_tag_redraw(sa); + WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); + } - - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } static void SCREEN_OT_region_quadview(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Toggle Quad View"; - ot->description = "Split selected area into camera, front, right & top views"; - ot->idname = "SCREEN_OT_region_quadview"; + /* identifiers */ + ot->name = "Toggle Quad View"; + ot->description = "Split selected area into camera, front, right & top views"; + ot->idname = "SCREEN_OT_region_quadview"; - /* api callbacks */ - ot->exec = region_quadview_exec; - ot->poll = ED_operator_region_view3d_active; - ot->flag = 0; + /* api callbacks */ + ot->exec = region_quadview_exec; + ot->poll = ED_operator_region_view3d_active; + ot->flag = 0; } /** \} */ @@ -3659,51 +3695,51 @@ static void SCREEN_OT_region_quadview(wmOperatorType *ot) /* flip a region alignment */ static int region_flip_exec(bContext *C, wmOperator *UNUSED(op)) { - ARegion *ar = CTX_wm_region(C); + ARegion *ar = CTX_wm_region(C); - if (!ar) - return OPERATOR_CANCELLED; + if (!ar) + return OPERATOR_CANCELLED; - if (ar->alignment == RGN_ALIGN_TOP) - ar->alignment = RGN_ALIGN_BOTTOM; - else if (ar->alignment == RGN_ALIGN_BOTTOM) - ar->alignment = RGN_ALIGN_TOP; - else if (ar->alignment == RGN_ALIGN_LEFT) - ar->alignment = RGN_ALIGN_RIGHT; - else if (ar->alignment == RGN_ALIGN_RIGHT) - ar->alignment = RGN_ALIGN_LEFT; + if (ar->alignment == RGN_ALIGN_TOP) + ar->alignment = RGN_ALIGN_BOTTOM; + else if (ar->alignment == RGN_ALIGN_BOTTOM) + ar->alignment = RGN_ALIGN_TOP; + else if (ar->alignment == RGN_ALIGN_LEFT) + ar->alignment = RGN_ALIGN_RIGHT; + else if (ar->alignment == RGN_ALIGN_RIGHT) + ar->alignment = RGN_ALIGN_LEFT; - ED_area_tag_redraw(CTX_wm_area(C)); - WM_event_add_mousemove(C); - WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); + ED_area_tag_redraw(CTX_wm_area(C)); + WM_event_add_mousemove(C); + WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } static bool region_flip_poll(bContext *C) { - ScrArea *area = CTX_wm_area(C); + ScrArea *area = CTX_wm_area(C); - /* don't flip anything around in topbar */ - if (area && area->spacetype == SPACE_TOPBAR) { - CTX_wm_operator_poll_msg_set(C, "Flipping regions in the Top-bar is not allowed"); - return 0; - } + /* don't flip anything around in topbar */ + if (area && area->spacetype == SPACE_TOPBAR) { + CTX_wm_operator_poll_msg_set(C, "Flipping regions in the Top-bar is not allowed"); + return 0; + } - return ED_operator_areaactive(C); + return ED_operator_areaactive(C); } static void SCREEN_OT_region_flip(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Flip Region"; - ot->idname = "SCREEN_OT_region_flip"; - ot->description = "Toggle the region's alignment (left/right or top/bottom)"; + /* identifiers */ + ot->name = "Flip Region"; + ot->idname = "SCREEN_OT_region_flip"; + ot->description = "Toggle the region's alignment (left/right or top/bottom)"; - /* api callbacks */ - ot->exec = region_flip_exec; - ot->poll = region_flip_poll; - ot->flag = 0; + /* api callbacks */ + ot->exec = region_flip_exec; + ot->poll = region_flip_poll; + ot->flag = 0; } /** \} */ @@ -3714,30 +3750,30 @@ static void SCREEN_OT_region_flip(wmOperatorType *ot) static int header_exec(bContext *C, wmOperator *UNUSED(op)) { - ARegion *ar = screen_find_region_type(C, RGN_TYPE_HEADER); + ARegion *ar = screen_find_region_type(C, RGN_TYPE_HEADER); - if (ar == NULL) { - return OPERATOR_CANCELLED; - } + if (ar == NULL) { + return OPERATOR_CANCELLED; + } - ar->flag ^= RGN_FLAG_HIDDEN; + ar->flag ^= RGN_FLAG_HIDDEN; - ED_area_tag_redraw(CTX_wm_area(C)); + ED_area_tag_redraw(CTX_wm_area(C)); - WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); + WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } static void SCREEN_OT_header(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Toggle Header"; - ot->description = "Toggle header display"; - ot->idname = "SCREEN_OT_header"; + /* identifiers */ + ot->name = "Toggle Header"; + ot->description = "Toggle header display"; + ot->idname = "SCREEN_OT_header"; - /* api callbacks */ - ot->exec = header_exec; + /* api callbacks */ + ot->exec = header_exec; } /** \} */ @@ -3749,28 +3785,27 @@ static void SCREEN_OT_header(wmOperatorType *ot) /* show/hide header text menus */ static int header_toggle_menus_exec(bContext *C, wmOperator *UNUSED(op)) { - ScrArea *sa = CTX_wm_area(C); + ScrArea *sa = CTX_wm_area(C); - sa->flag = sa->flag ^ HEADER_NO_PULLDOWN; + sa->flag = sa->flag ^ HEADER_NO_PULLDOWN; - ED_area_tag_redraw(sa); - WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); + ED_area_tag_redraw(sa); + WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } - static void SCREEN_OT_header_toggle_menus(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Expand/Collapse Header Menus"; - ot->idname = "SCREEN_OT_header_toggle_menus"; - ot->description = "Expand or collapse the header pulldown menus"; + /* identifiers */ + ot->name = "Expand/Collapse Header Menus"; + ot->idname = "SCREEN_OT_header_toggle_menus"; + ot->description = "Expand or collapse the header pulldown menus"; - /* api callbacks */ - ot->exec = header_toggle_menus_exec; - ot->poll = ED_operator_areaactive; - ot->flag = 0; + /* api callbacks */ + ot->exec = header_toggle_menus_exec; + ot->poll = ED_operator_areaactive; + ot->flag = 0; } /** \} */ @@ -3781,66 +3816,70 @@ static void SCREEN_OT_header_toggle_menus(wmOperatorType *ot) static bool header_context_menu_poll(bContext *C) { - ScrArea *sa = CTX_wm_area(C); - return (sa && sa->spacetype != SPACE_STATUSBAR); + ScrArea *sa = CTX_wm_area(C); + return (sa && sa->spacetype != SPACE_STATUSBAR); } void ED_screens_header_tools_menu_create(bContext *C, uiLayout *layout, void *UNUSED(arg)) { - ScrArea *sa = CTX_wm_area(C); - ARegion *ar = CTX_wm_region(C); - const char *but_flip_str = (ar->alignment == RGN_ALIGN_TOP) ? IFACE_("Flip to Bottom") : IFACE_("Flip to Top"); + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + const char *but_flip_str = (ar->alignment == RGN_ALIGN_TOP) ? IFACE_("Flip to Bottom") : + IFACE_("Flip to Top"); - if (!ELEM(sa->spacetype, SPACE_TOPBAR)) { - uiItemO(layout, IFACE_("Toggle Header"), ICON_NONE, "SCREEN_OT_header"); - } + if (!ELEM(sa->spacetype, SPACE_TOPBAR)) { + uiItemO(layout, IFACE_("Toggle Header"), ICON_NONE, "SCREEN_OT_header"); + } - /* default is WM_OP_INVOKE_REGION_WIN, which we don't want here. */ - uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT); + /* default is WM_OP_INVOKE_REGION_WIN, which we don't want here. */ + uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT); - if (!ELEM(sa->spacetype, SPACE_TOPBAR)) { - uiItemO(layout, but_flip_str, ICON_NONE, "SCREEN_OT_region_flip"); - } + if (!ELEM(sa->spacetype, SPACE_TOPBAR)) { + uiItemO(layout, but_flip_str, ICON_NONE, "SCREEN_OT_region_flip"); + } - uiItemO(layout, IFACE_("Collapse Menus"), - (sa->flag & HEADER_NO_PULLDOWN) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT, - "SCREEN_OT_header_toggle_menus"); + uiItemO(layout, + IFACE_("Collapse Menus"), + (sa->flag & HEADER_NO_PULLDOWN) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT, + "SCREEN_OT_header_toggle_menus"); - /* File browser should be fullscreen all the time, top-bar should - * never be. But other regions can be maximized/restored. */ - if (!ELEM(sa->spacetype, SPACE_FILE, SPACE_TOPBAR)) { - uiItemS(layout); + /* File browser should be fullscreen all the time, top-bar should + * never be. But other regions can be maximized/restored. */ + if (!ELEM(sa->spacetype, SPACE_FILE, SPACE_TOPBAR)) { + uiItemS(layout); - const char *but_str = sa->full ? IFACE_("Tile Area") : IFACE_("Maximize Area"); - uiItemO(layout, but_str, ICON_NONE, "SCREEN_OT_screen_full_area"); - } + const char *but_str = sa->full ? IFACE_("Tile Area") : IFACE_("Maximize Area"); + uiItemO(layout, but_str, ICON_NONE, "SCREEN_OT_screen_full_area"); + } } -static int header_context_menu_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event)) +static int header_context_menu_invoke(bContext *C, + wmOperator *UNUSED(op), + const wmEvent *UNUSED(event)) { - uiPopupMenu *pup; - uiLayout *layout; + uiPopupMenu *pup; + uiLayout *layout; - pup = UI_popup_menu_begin(C, IFACE_("Header"), ICON_NONE); - layout = UI_popup_menu_layout(pup); + pup = UI_popup_menu_begin(C, IFACE_("Header"), ICON_NONE); + layout = UI_popup_menu_layout(pup); - ED_screens_header_tools_menu_create(C, layout, NULL); + ED_screens_header_tools_menu_create(C, layout, NULL); - UI_popup_menu_end(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_INTERFACE; + return OPERATOR_INTERFACE; } static void SCREEN_OT_header_context_menu(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Header Context Menu"; - ot->description = "Display header region context menu"; - ot->idname = "SCREEN_OT_header_context_menu"; + /* identifiers */ + ot->name = "Header Context Menu"; + ot->description = "Display header region context menu"; + ot->idname = "SCREEN_OT_header_context_menu"; - /* api callbacks */ - ot->poll = header_context_menu_poll; - ot->invoke = header_context_menu_invoke; + /* api callbacks */ + ot->poll = header_context_menu_poll; + ot->invoke = header_context_menu_invoke; } /** \} */ @@ -3851,30 +3890,30 @@ static void SCREEN_OT_header_context_menu(wmOperatorType *ot) static int footer_exec(bContext *C, wmOperator *UNUSED(op)) { - ARegion *ar = screen_find_region_type(C, RGN_TYPE_FOOTER); + ARegion *ar = screen_find_region_type(C, RGN_TYPE_FOOTER); - if (ar == NULL) { - return OPERATOR_CANCELLED; - } + if (ar == NULL) { + return OPERATOR_CANCELLED; + } - ar->flag ^= RGN_FLAG_HIDDEN; + ar->flag ^= RGN_FLAG_HIDDEN; - ED_area_tag_redraw(CTX_wm_area(C)); + ED_area_tag_redraw(CTX_wm_area(C)); - WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); + WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } static void SCREEN_OT_footer(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Toggle Footer"; - ot->description = "Toggle footer display"; - ot->idname = "SCREEN_OT_footer"; + /* identifiers */ + ot->name = "Toggle Footer"; + ot->description = "Toggle footer display"; + ot->idname = "SCREEN_OT_footer"; - /* api callbacks */ - ot->exec = footer_exec; + /* api callbacks */ + ot->exec = footer_exec; } /** \} */ @@ -3885,59 +3924,61 @@ static void SCREEN_OT_footer(wmOperatorType *ot) static bool footer_context_menu_poll(bContext *C) { - ScrArea *sa = CTX_wm_area(C); - return sa; + ScrArea *sa = CTX_wm_area(C); + return sa; } void ED_screens_footer_tools_menu_create(bContext *C, uiLayout *layout, void *UNUSED(arg)) { - ScrArea *sa = CTX_wm_area(C); - ARegion *ar = CTX_wm_region(C); - const char *but_flip_str = (ar->alignment == RGN_ALIGN_TOP) ? IFACE_("Flip to Bottom") : IFACE_("Flip to Top"); - - uiItemO(layout, IFACE_("Toggle Footer"), ICON_NONE, "SCREEN_OT_footer"); + ScrArea *sa = CTX_wm_area(C); + ARegion *ar = CTX_wm_region(C); + const char *but_flip_str = (ar->alignment == RGN_ALIGN_TOP) ? IFACE_("Flip to Bottom") : + IFACE_("Flip to Top"); - /* default is WM_OP_INVOKE_REGION_WIN, which we don't want here. */ - uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT); + uiItemO(layout, IFACE_("Toggle Footer"), ICON_NONE, "SCREEN_OT_footer"); - uiItemO(layout, but_flip_str, ICON_NONE, "SCREEN_OT_region_flip"); + /* default is WM_OP_INVOKE_REGION_WIN, which we don't want here. */ + uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT); + uiItemO(layout, but_flip_str, ICON_NONE, "SCREEN_OT_region_flip"); - /* file browser should be fullscreen all the time, topbar should - * never be. But other regions can be maximized/restored... */ - if (!ELEM(sa->spacetype, SPACE_FILE, SPACE_TOPBAR)) { - uiItemS(layout); + /* file browser should be fullscreen all the time, topbar should + * never be. But other regions can be maximized/restored... */ + if (!ELEM(sa->spacetype, SPACE_FILE, SPACE_TOPBAR)) { + uiItemS(layout); - const char *but_str = sa->full ? IFACE_("Tile Area") : IFACE_("Maximize Area"); - uiItemO(layout, but_str, ICON_NONE, "SCREEN_OT_screen_full_area"); - } + const char *but_str = sa->full ? IFACE_("Tile Area") : IFACE_("Maximize Area"); + uiItemO(layout, but_str, ICON_NONE, "SCREEN_OT_screen_full_area"); + } } -static int footer_context_menu_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event)) +static int footer_context_menu_invoke(bContext *C, + wmOperator *UNUSED(op), + const wmEvent *UNUSED(event)) { - uiPopupMenu *pup; - uiLayout *layout; + uiPopupMenu *pup; + uiLayout *layout; - pup = UI_popup_menu_begin(C, IFACE_("Footer"), ICON_NONE); - layout = UI_popup_menu_layout(pup); + pup = UI_popup_menu_begin(C, IFACE_("Footer"), ICON_NONE); + layout = UI_popup_menu_layout(pup); - ED_screens_footer_tools_menu_create(C, layout, NULL); + ED_screens_footer_tools_menu_create(C, layout, NULL); - UI_popup_menu_end(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_INTERFACE; + return OPERATOR_INTERFACE; } static void SCREEN_OT_footer_context_menu(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Footer Context Menu"; - ot->description = "Display footer region context menu"; - ot->idname = "SCREEN_OT_footer_context_menu"; + /* identifiers */ + ot->name = "Footer Context Menu"; + ot->description = "Display footer region context menu"; + ot->idname = "SCREEN_OT_footer_context_menu"; - /* api callbacks */ - ot->poll = footer_context_menu_poll; - ot->invoke = footer_context_menu_invoke; + /* api callbacks */ + ot->poll = footer_context_menu_poll; + ot->invoke = footer_context_menu_invoke; } /** \} */ @@ -3948,13 +3989,14 @@ static void SCREEN_OT_footer_context_menu(wmOperatorType *ot) void ED_screens_navigation_bar_tools_menu_create(bContext *C, uiLayout *layout, void *UNUSED(arg)) { - const ARegion *ar = CTX_wm_region(C); - const char *but_flip_str = (ar->alignment == RGN_ALIGN_LEFT) ? IFACE_("Flip to Right") : IFACE_("Flip to Left"); + const ARegion *ar = CTX_wm_region(C); + const char *but_flip_str = (ar->alignment == RGN_ALIGN_LEFT) ? IFACE_("Flip to Right") : + IFACE_("Flip to Left"); - /* default is WM_OP_INVOKE_REGION_WIN, which we don't want here. */ - uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT); + /* default is WM_OP_INVOKE_REGION_WIN, which we don't want here. */ + uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT); - uiItemO(layout, but_flip_str, ICON_NONE, "SCREEN_OT_region_flip"); + uiItemO(layout, but_flip_str, ICON_NONE, "SCREEN_OT_region_flip"); } /** \} */ @@ -3967,297 +4009,299 @@ void ED_screens_navigation_bar_tools_menu_create(bContext *C, uiLayout *layout, static int match_area_with_refresh(int spacetype, int refresh) { - switch (spacetype) { - case SPACE_TIME: - if (refresh & SPACE_TIME) - return 1; - break; - } - - return 0; -} - -static int match_region_with_redraws(int spacetype, int regiontype, int redraws, bool from_anim_edit) -{ - if (regiontype == RGN_TYPE_WINDOW) { - - switch (spacetype) { - case SPACE_VIEW3D: - if ((redraws & TIME_ALL_3D_WIN) || from_anim_edit) - return 1; - break; - case SPACE_GRAPH: - case SPACE_NLA: - if ((redraws & TIME_ALL_ANIM_WIN) || from_anim_edit) - return 1; - break; - case SPACE_ACTION: - /* if only 1 window or 3d windows, we do timeline too - * NOTE: Now we do do action editor in all these cases, since timeline is here - */ - if ((redraws & (TIME_ALL_ANIM_WIN | TIME_REGION | TIME_ALL_3D_WIN)) || from_anim_edit) - return 1; - break; - case SPACE_PROPERTIES: - if (redraws & TIME_ALL_BUTS_WIN) - return 1; - break; - case SPACE_SEQ: - if ((redraws & (TIME_SEQ | TIME_ALL_ANIM_WIN)) || from_anim_edit) - return 1; - break; - case SPACE_NODE: - if (redraws & (TIME_NODES)) - return 1; - break; - case SPACE_IMAGE: - if ((redraws & TIME_ALL_IMAGE_WIN) || from_anim_edit) - return 1; - break; - case SPACE_CLIP: - if ((redraws & TIME_CLIPS) || from_anim_edit) - return 1; - break; - - } - } - else if (regiontype == RGN_TYPE_CHANNELS) { - switch (spacetype) { - case SPACE_GRAPH: - case SPACE_ACTION: - case SPACE_NLA: - if (redraws & TIME_ALL_ANIM_WIN) - return 1; - break; - } - } - else if (regiontype == RGN_TYPE_UI) { - if (spacetype == SPACE_CLIP) { - /* Track Preview button is on Properties Editor in SpaceClip, - * and it's very common case when users want it be refreshing - * during playback, so asking people to enable special option - * for this is a bit tricky, so add exception here for refreshing - * Properties Editor for SpaceClip always */ - return 1; - } - - if (redraws & TIME_ALL_BUTS_WIN) - return 1; - } - else if (regiontype == RGN_TYPE_HEADER) { - if (spacetype == SPACE_ACTION) - return 1; - } - else if (regiontype == RGN_TYPE_PREVIEW) { - switch (spacetype) { - case SPACE_SEQ: - if (redraws & (TIME_SEQ | TIME_ALL_ANIM_WIN)) - return 1; - break; - case SPACE_CLIP: - return 1; - } - } - return 0; + switch (spacetype) { + case SPACE_TIME: + if (refresh & SPACE_TIME) + return 1; + break; + } + + return 0; +} + +static int match_region_with_redraws(int spacetype, + int regiontype, + int redraws, + bool from_anim_edit) +{ + if (regiontype == RGN_TYPE_WINDOW) { + + switch (spacetype) { + case SPACE_VIEW3D: + if ((redraws & TIME_ALL_3D_WIN) || from_anim_edit) + return 1; + break; + case SPACE_GRAPH: + case SPACE_NLA: + if ((redraws & TIME_ALL_ANIM_WIN) || from_anim_edit) + return 1; + break; + case SPACE_ACTION: + /* if only 1 window or 3d windows, we do timeline too + * NOTE: Now we do do action editor in all these cases, since timeline is here + */ + if ((redraws & (TIME_ALL_ANIM_WIN | TIME_REGION | TIME_ALL_3D_WIN)) || from_anim_edit) + return 1; + break; + case SPACE_PROPERTIES: + if (redraws & TIME_ALL_BUTS_WIN) + return 1; + break; + case SPACE_SEQ: + if ((redraws & (TIME_SEQ | TIME_ALL_ANIM_WIN)) || from_anim_edit) + return 1; + break; + case SPACE_NODE: + if (redraws & (TIME_NODES)) + return 1; + break; + case SPACE_IMAGE: + if ((redraws & TIME_ALL_IMAGE_WIN) || from_anim_edit) + return 1; + break; + case SPACE_CLIP: + if ((redraws & TIME_CLIPS) || from_anim_edit) + return 1; + break; + } + } + else if (regiontype == RGN_TYPE_CHANNELS) { + switch (spacetype) { + case SPACE_GRAPH: + case SPACE_ACTION: + case SPACE_NLA: + if (redraws & TIME_ALL_ANIM_WIN) + return 1; + break; + } + } + else if (regiontype == RGN_TYPE_UI) { + if (spacetype == SPACE_CLIP) { + /* Track Preview button is on Properties Editor in SpaceClip, + * and it's very common case when users want it be refreshing + * during playback, so asking people to enable special option + * for this is a bit tricky, so add exception here for refreshing + * Properties Editor for SpaceClip always */ + return 1; + } + + if (redraws & TIME_ALL_BUTS_WIN) + return 1; + } + else if (regiontype == RGN_TYPE_HEADER) { + if (spacetype == SPACE_ACTION) + return 1; + } + else if (regiontype == RGN_TYPE_PREVIEW) { + switch (spacetype) { + case SPACE_SEQ: + if (redraws & (TIME_SEQ | TIME_ALL_ANIM_WIN)) + return 1; + break; + case SPACE_CLIP: + return 1; + } + } + return 0; } //#define PROFILE_AUDIO_SYNCH static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { - bScreen *screen = CTX_wm_screen(C); + bScreen *screen = CTX_wm_screen(C); #ifdef PROFILE_AUDIO_SYNCH - static int old_frame = 0; - int newfra_int; + static int old_frame = 0; + int newfra_int; #endif - if (screen->animtimer && screen->animtimer == event->customdata) { - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - struct Depsgraph *depsgraph = CTX_data_depsgraph(C); - wmTimer *wt = screen->animtimer; - ScreenAnimData *sad = wt->customdata; - wmWindowManager *wm = CTX_wm_manager(C); - wmWindow *window; - ScrArea *sa; - int sync; - float time; - - /* sync, don't sync, or follow scene setting */ - if (sad->flag & ANIMPLAY_FLAG_SYNC) sync = 1; - else if (sad->flag & ANIMPLAY_FLAG_NO_SYNC) sync = 0; - else sync = (scene->flag & SCE_FRAME_DROP); - - if ((scene->audio.flag & AUDIO_SYNC) && - (sad->flag & ANIMPLAY_FLAG_REVERSE) == false && - isfinite(time = BKE_sound_sync_scene(scene))) - { - double newfra = (double)time * FPS; - - /* give some space here to avoid jumps */ - if (newfra + 0.5 > scene->r.cfra && newfra - 0.5 < scene->r.cfra) - scene->r.cfra++; - else - scene->r.cfra = newfra + 0.5; + if (screen->animtimer && screen->animtimer == event->customdata) { + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + struct Depsgraph *depsgraph = CTX_data_depsgraph(C); + wmTimer *wt = screen->animtimer; + ScreenAnimData *sad = wt->customdata; + wmWindowManager *wm = CTX_wm_manager(C); + wmWindow *window; + ScrArea *sa; + int sync; + float time; + + /* sync, don't sync, or follow scene setting */ + if (sad->flag & ANIMPLAY_FLAG_SYNC) + sync = 1; + else if (sad->flag & ANIMPLAY_FLAG_NO_SYNC) + sync = 0; + else + sync = (scene->flag & SCE_FRAME_DROP); + + if ((scene->audio.flag & AUDIO_SYNC) && (sad->flag & ANIMPLAY_FLAG_REVERSE) == false && + isfinite(time = BKE_sound_sync_scene(scene))) { + double newfra = (double)time * FPS; + + /* give some space here to avoid jumps */ + if (newfra + 0.5 > scene->r.cfra && newfra - 0.5 < scene->r.cfra) + scene->r.cfra++; + else + scene->r.cfra = newfra + 0.5; #ifdef PROFILE_AUDIO_SYNCH - newfra_int = scene->r.cfra; - if (newfra_int < old_frame) { - printf("back jump detected, frame %d!\n", newfra_int); - } - else if (newfra_int > old_frame + 1) { - printf("forward jump detected, frame %d!\n", newfra_int); - } - fflush(stdout); - old_frame = newfra_int; + newfra_int = scene->r.cfra; + if (newfra_int < old_frame) { + printf("back jump detected, frame %d!\n", newfra_int); + } + else if (newfra_int > old_frame + 1) { + printf("forward jump detected, frame %d!\n", newfra_int); + } + fflush(stdout); + old_frame = newfra_int; #endif - } - else { - if (sync) { - /* note: this is very simplistic, - * its has problem that it may skip too many frames. - * however at least this gives a less jittery playback */ - const int step = max_ii(1, floor((wt->duration - sad->last_duration) * FPS)); - - /* skip frames */ - if (sad->flag & ANIMPLAY_FLAG_REVERSE) - scene->r.cfra -= step; - else - scene->r.cfra += step; - } - else { - /* one frame +/- */ - if (sad->flag & ANIMPLAY_FLAG_REVERSE) - scene->r.cfra--; - else - scene->r.cfra++; - } - } - - sad->last_duration = wt->duration; - - /* reset 'jumped' flag before checking if we need to jump... */ - sad->flag &= ~ANIMPLAY_FLAG_JUMPED; - - if (sad->flag & ANIMPLAY_FLAG_REVERSE) { - /* jump back to end? */ - if (PRVRANGEON) { - if (scene->r.cfra < scene->r.psfra) { - scene->r.cfra = scene->r.pefra; - sad->flag |= ANIMPLAY_FLAG_JUMPED; - } - } - else { - if (scene->r.cfra < scene->r.sfra) { - scene->r.cfra = scene->r.efra; - sad->flag |= ANIMPLAY_FLAG_JUMPED; - } - } - } - else { - /* jump back to start? */ - if (PRVRANGEON) { - if (scene->r.cfra > scene->r.pefra) { - scene->r.cfra = scene->r.psfra; - sad->flag |= ANIMPLAY_FLAG_JUMPED; - } - } - else { - if (scene->r.cfra > scene->r.efra) { - scene->r.cfra = scene->r.sfra; - sad->flag |= ANIMPLAY_FLAG_JUMPED; - } - } - } - - /* next frame overridden by user action (pressed jump to first/last frame) */ - if (sad->flag & ANIMPLAY_FLAG_USE_NEXT_FRAME) { - scene->r.cfra = sad->nextfra; - sad->flag &= ~ANIMPLAY_FLAG_USE_NEXT_FRAME; - sad->flag |= ANIMPLAY_FLAG_JUMPED; - } - - if (sad->flag & ANIMPLAY_FLAG_JUMPED) { - BKE_sound_seek_scene(bmain, scene); + } + else { + if (sync) { + /* note: this is very simplistic, + * its has problem that it may skip too many frames. + * however at least this gives a less jittery playback */ + const int step = max_ii(1, floor((wt->duration - sad->last_duration) * FPS)); + + /* skip frames */ + if (sad->flag & ANIMPLAY_FLAG_REVERSE) + scene->r.cfra -= step; + else + scene->r.cfra += step; + } + else { + /* one frame +/- */ + if (sad->flag & ANIMPLAY_FLAG_REVERSE) + scene->r.cfra--; + else + scene->r.cfra++; + } + } + + sad->last_duration = wt->duration; + + /* reset 'jumped' flag before checking if we need to jump... */ + sad->flag &= ~ANIMPLAY_FLAG_JUMPED; + + if (sad->flag & ANIMPLAY_FLAG_REVERSE) { + /* jump back to end? */ + if (PRVRANGEON) { + if (scene->r.cfra < scene->r.psfra) { + scene->r.cfra = scene->r.pefra; + sad->flag |= ANIMPLAY_FLAG_JUMPED; + } + } + else { + if (scene->r.cfra < scene->r.sfra) { + scene->r.cfra = scene->r.efra; + sad->flag |= ANIMPLAY_FLAG_JUMPED; + } + } + } + else { + /* jump back to start? */ + if (PRVRANGEON) { + if (scene->r.cfra > scene->r.pefra) { + scene->r.cfra = scene->r.psfra; + sad->flag |= ANIMPLAY_FLAG_JUMPED; + } + } + else { + if (scene->r.cfra > scene->r.efra) { + scene->r.cfra = scene->r.sfra; + sad->flag |= ANIMPLAY_FLAG_JUMPED; + } + } + } + + /* next frame overridden by user action (pressed jump to first/last frame) */ + if (sad->flag & ANIMPLAY_FLAG_USE_NEXT_FRAME) { + scene->r.cfra = sad->nextfra; + sad->flag &= ~ANIMPLAY_FLAG_USE_NEXT_FRAME; + sad->flag |= ANIMPLAY_FLAG_JUMPED; + } + + if (sad->flag & ANIMPLAY_FLAG_JUMPED) { + BKE_sound_seek_scene(bmain, scene); #ifdef PROFILE_AUDIO_SYNCH - old_frame = CFRA; + old_frame = CFRA; #endif - } - - /* since we follow drawflags, we can't send notifier but tag regions ourselves */ - ED_update_for_newframe(bmain, depsgraph); - - for (window = wm->windows.first; window; window = window->next) { - const bScreen *win_screen = WM_window_get_active_screen(window); - - for (sa = win_screen->areabase.first; sa; sa = sa->next) { - ARegion *ar; - for (ar = sa->regionbase.first; ar; ar = ar->next) { - bool redraw = false; - if (ar == sad->ar) { - redraw = true; - } - else if (match_region_with_redraws(sa->spacetype, ar->regiontype, sad->redraws, sad->from_anim_edit)) { - redraw = true; - } - - if (redraw) { - ED_region_tag_redraw(ar); - /* do follow here if editor type supports it */ - if ((sad->redraws & TIME_FOLLOW)) { - if ((ar->regiontype == RGN_TYPE_WINDOW && - ELEM(sa->spacetype, SPACE_SEQ, SPACE_GRAPH, SPACE_ACTION, SPACE_NLA)) || - (sa->spacetype == SPACE_CLIP && ar->regiontype == RGN_TYPE_PREVIEW)) - { - float w = BLI_rctf_size_x(&ar->v2d.cur); - if (scene->r.cfra < ar->v2d.cur.xmin) { - ar->v2d.cur.xmax = scene->r.cfra; - ar->v2d.cur.xmin = ar->v2d.cur.xmax - w; - } - else if (scene->r.cfra > ar->v2d.cur.xmax) { - ar->v2d.cur.xmin = scene->r.cfra; - ar->v2d.cur.xmax = ar->v2d.cur.xmin + w; - } - } - } - } - } - - if (match_area_with_refresh(sa->spacetype, sad->refresh)) - ED_area_tag_refresh(sa); - } - } - - /* update frame rate info too - * NOTE: this may not be accurate enough, since we might need this after modifiers/etc. - * have been calculated instead of just before updates have been done? - */ - ED_refresh_viewport_fps(C); - - /* Recalculate the time-step for the timer now that we've finished calculating this, - * since the frames-per-second value may have been changed. - */ - /* TODO: this may make evaluation a bit slower if the value doesn't change... any way to avoid this? */ - wt->timestep = (1.0 / FPS); - - return OPERATOR_FINISHED; - } - return OPERATOR_PASS_THROUGH; + } + + /* since we follow drawflags, we can't send notifier but tag regions ourselves */ + ED_update_for_newframe(bmain, depsgraph); + + for (window = wm->windows.first; window; window = window->next) { + const bScreen *win_screen = WM_window_get_active_screen(window); + + for (sa = win_screen->areabase.first; sa; sa = sa->next) { + ARegion *ar; + for (ar = sa->regionbase.first; ar; ar = ar->next) { + bool redraw = false; + if (ar == sad->ar) { + redraw = true; + } + else if (match_region_with_redraws( + sa->spacetype, ar->regiontype, sad->redraws, sad->from_anim_edit)) { + redraw = true; + } + + if (redraw) { + ED_region_tag_redraw(ar); + /* do follow here if editor type supports it */ + if ((sad->redraws & TIME_FOLLOW)) { + if ((ar->regiontype == RGN_TYPE_WINDOW && + ELEM(sa->spacetype, SPACE_SEQ, SPACE_GRAPH, SPACE_ACTION, SPACE_NLA)) || + (sa->spacetype == SPACE_CLIP && ar->regiontype == RGN_TYPE_PREVIEW)) { + float w = BLI_rctf_size_x(&ar->v2d.cur); + if (scene->r.cfra < ar->v2d.cur.xmin) { + ar->v2d.cur.xmax = scene->r.cfra; + ar->v2d.cur.xmin = ar->v2d.cur.xmax - w; + } + else if (scene->r.cfra > ar->v2d.cur.xmax) { + ar->v2d.cur.xmin = scene->r.cfra; + ar->v2d.cur.xmax = ar->v2d.cur.xmin + w; + } + } + } + } + } + + if (match_area_with_refresh(sa->spacetype, sad->refresh)) + ED_area_tag_refresh(sa); + } + } + + /* update frame rate info too + * NOTE: this may not be accurate enough, since we might need this after modifiers/etc. + * have been calculated instead of just before updates have been done? + */ + ED_refresh_viewport_fps(C); + + /* Recalculate the time-step for the timer now that we've finished calculating this, + * since the frames-per-second value may have been changed. + */ + /* TODO: this may make evaluation a bit slower if the value doesn't change... any way to avoid this? */ + wt->timestep = (1.0 / FPS); + + return OPERATOR_FINISHED; + } + return OPERATOR_PASS_THROUGH; } static void SCREEN_OT_animation_step(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Animation Step"; - ot->description = "Step through animation by position"; - ot->idname = "SCREEN_OT_animation_step"; + /* identifiers */ + ot->name = "Animation Step"; + ot->description = "Step through animation by position"; + ot->idname = "SCREEN_OT_animation_step"; - /* api callbacks */ - ot->invoke = screen_animation_step; - - ot->poll = ED_operator_screenactive_norender; + /* api callbacks */ + ot->invoke = screen_animation_step; + ot->poll = ED_operator_screenactive_norender; } /** \} */ @@ -4271,93 +4315,93 @@ static void SCREEN_OT_animation_step(wmOperatorType *ot) /* find window that owns the animation timer */ bScreen *ED_screen_animation_playing(const wmWindowManager *wm) { - for (wmWindow *win = wm->windows.first; win; win = win->next) { - bScreen *screen = WM_window_get_active_screen(win); + for (wmWindow *win = wm->windows.first; win; win = win->next) { + bScreen *screen = WM_window_get_active_screen(win); - if (screen->animtimer || screen->scrubbing) { - return screen; - } - } + if (screen->animtimer || screen->scrubbing) { + return screen; + } + } - return NULL; + return NULL; } bScreen *ED_screen_animation_no_scrub(const wmWindowManager *wm) { - for (wmWindow *win = wm->windows.first; win; win = win->next) { - bScreen *screen = WM_window_get_active_screen(win); + for (wmWindow *win = wm->windows.first; win; win = win->next) { + bScreen *screen = WM_window_get_active_screen(win); - if (screen->animtimer) { - return screen; - } - } + if (screen->animtimer) { + return screen; + } + } - return NULL; + return NULL; } - /* toggle operator */ int ED_screen_animation_play(bContext *C, int sync, int mode) { - bScreen *screen = CTX_wm_screen(C); - Scene *scene = CTX_data_scene(C); + bScreen *screen = CTX_wm_screen(C); + Scene *scene = CTX_data_scene(C); - if (ED_screen_animation_playing(CTX_wm_manager(C))) { - /* stop playback now */ - ED_screen_animation_timer(C, 0, 0, 0, 0); - BKE_sound_stop_scene(scene); + if (ED_screen_animation_playing(CTX_wm_manager(C))) { + /* stop playback now */ + ED_screen_animation_timer(C, 0, 0, 0, 0); + BKE_sound_stop_scene(scene); - WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); - } - else { - /* these settings are currently only available from a menu in the TimeLine */ - int refresh = SPACE_ACTION; + WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); + } + else { + /* these settings are currently only available from a menu in the TimeLine */ + int refresh = SPACE_ACTION; - if (mode == 1) /* XXX only play audio forwards!? */ - BKE_sound_play_scene(scene); + if (mode == 1) /* XXX only play audio forwards!? */ + BKE_sound_play_scene(scene); - ED_screen_animation_timer(C, screen->redraws_flag, refresh, sync, mode); + ED_screen_animation_timer(C, screen->redraws_flag, refresh, sync, mode); - if (screen->animtimer) { - wmTimer *wt = screen->animtimer; - ScreenAnimData *sad = wt->customdata; + if (screen->animtimer) { + wmTimer *wt = screen->animtimer; + ScreenAnimData *sad = wt->customdata; - sad->ar = CTX_wm_region(C); - } - } + sad->ar = CTX_wm_region(C); + } + } - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } static int screen_animation_play_exec(bContext *C, wmOperator *op) { - int mode = (RNA_boolean_get(op->ptr, "reverse")) ? -1 : 1; - int sync = -1; + int mode = (RNA_boolean_get(op->ptr, "reverse")) ? -1 : 1; + int sync = -1; - if (RNA_struct_property_is_set(op->ptr, "sync")) - sync = (RNA_boolean_get(op->ptr, "sync")); + if (RNA_struct_property_is_set(op->ptr, "sync")) + sync = (RNA_boolean_get(op->ptr, "sync")); - return ED_screen_animation_play(C, sync, mode); + return ED_screen_animation_play(C, sync, mode); } static void SCREEN_OT_animation_play(wmOperatorType *ot) { - PropertyRNA *prop; + PropertyRNA *prop; - /* identifiers */ - ot->name = "Play Animation"; - ot->description = "Play animation"; - ot->idname = "SCREEN_OT_animation_play"; + /* identifiers */ + ot->name = "Play Animation"; + ot->description = "Play animation"; + ot->idname = "SCREEN_OT_animation_play"; - /* api callbacks */ - ot->exec = screen_animation_play_exec; + /* api callbacks */ + ot->exec = screen_animation_play_exec; - ot->poll = ED_operator_screenactive_norender; + ot->poll = ED_operator_screenactive_norender; - prop = RNA_def_boolean(ot->srna, "reverse", 0, "Play in Reverse", "Animation is played backwards"); - RNA_def_property_flag(prop, PROP_SKIP_SAVE); - prop = RNA_def_boolean(ot->srna, "sync", 0, "Sync", "Drop frames to maintain framerate"); - RNA_def_property_flag(prop, PROP_SKIP_SAVE); + prop = RNA_def_boolean( + ot->srna, "reverse", 0, "Play in Reverse", "Animation is played backwards"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + prop = RNA_def_boolean(ot->srna, "sync", 0, "Sync", "Drop frames to maintain framerate"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } /** \} */ @@ -4368,41 +4412,45 @@ static void SCREEN_OT_animation_play(wmOperatorType *ot) static int screen_animation_cancel_exec(bContext *C, wmOperator *op) { - bScreen *screen = ED_screen_animation_playing(CTX_wm_manager(C)); + bScreen *screen = ED_screen_animation_playing(CTX_wm_manager(C)); - if (screen) { - if (RNA_boolean_get(op->ptr, "restore_frame") && screen->animtimer) { - ScreenAnimData *sad = screen->animtimer->customdata; - Scene *scene = CTX_data_scene(C); + if (screen) { + if (RNA_boolean_get(op->ptr, "restore_frame") && screen->animtimer) { + ScreenAnimData *sad = screen->animtimer->customdata; + Scene *scene = CTX_data_scene(C); - /* reset current frame before stopping, and just send a notifier to deal with the rest - * (since playback still needs to be stopped) - */ - scene->r.cfra = sad->sfra; + /* reset current frame before stopping, and just send a notifier to deal with the rest + * (since playback still needs to be stopped) + */ + scene->r.cfra = sad->sfra; - WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); - } + WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); + } - /* call the other "toggling" operator to clean up now */ - ED_screen_animation_play(C, 0, 0); - } + /* call the other "toggling" operator to clean up now */ + ED_screen_animation_play(C, 0, 0); + } - return OPERATOR_PASS_THROUGH; + return OPERATOR_PASS_THROUGH; } static void SCREEN_OT_animation_cancel(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Cancel Animation"; - ot->description = "Cancel animation, returning to the original frame"; - ot->idname = "SCREEN_OT_animation_cancel"; + /* identifiers */ + ot->name = "Cancel Animation"; + ot->description = "Cancel animation, returning to the original frame"; + ot->idname = "SCREEN_OT_animation_cancel"; - /* api callbacks */ - ot->exec = screen_animation_cancel_exec; + /* api callbacks */ + ot->exec = screen_animation_cancel_exec; - ot->poll = ED_operator_screenactive; + ot->poll = ED_operator_screenactive; - RNA_def_boolean(ot->srna, "restore_frame", true, "Restore Frame", "Restore the frame when animation was initialized"); + RNA_def_boolean(ot->srna, + "restore_frame", + true, + "Restore Frame", + "Restore the frame when animation was initialized"); } /** \} */ @@ -4419,48 +4467,48 @@ static void SCREEN_OT_animation_cancel(wmOperatorType *ot) * * callbacks: * - * exec() has to be filled in by user + * exec() has to be filled in by user * * invoke() default WM function * adds modal handler * - * modal() default WM function + * modal() default WM function * accept modal events while doing it, calls exec(), handles ESC and border drawing * - * poll() has to be filled in by user for context + * poll() has to be filled in by user for context */ #if 0 static int box_select_exec(bContext *C, wmOperator *op) { - int event_type = RNA_int_get(op->ptr, "event_type"); + int event_type = RNA_int_get(op->ptr, "event_type"); - if (event_type == LEFTMOUSE) - printf("box select do select\n"); - else if (event_type == RIGHTMOUSE) - printf("box select deselect\n"); - else - printf("box select do something\n"); + if (event_type == LEFTMOUSE) + printf("box select do select\n"); + else if (event_type == RIGHTMOUSE) + printf("box select deselect\n"); + else + printf("box select do something\n"); - return 1; + return 1; } static void SCREEN_OT_box_select(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Box Select"; - ot->idname = "SCREEN_OT_box_select"; + /* identifiers */ + ot->name = "Box Select"; + ot->idname = "SCREEN_OT_box_select"; - /* api callbacks */ - ot->exec = box_select_exec; - ot->invoke = WM_gesture_box_invoke; - ot->modal = WM_gesture_box_modal; - ot->cancel = WM_gesture_box_cancel; + /* api callbacks */ + ot->exec = box_select_exec; + ot->invoke = WM_gesture_box_invoke; + ot->modal = WM_gesture_box_modal; + ot->cancel = WM_gesture_box_cancel; - ot->poll = ED_operator_areaactive; + ot->poll = ED_operator_areaactive; - /* rna */ - RNA_def_int(ot->srna, "event_type", 0, INT_MIN, INT_MAX, "Event Type", "", INT_MIN, INT_MAX); - WM_operator_properties_border(ot); + /* rna */ + RNA_def_int(ot->srna, "event_type", 0, INT_MIN, INT_MAX, "Event Type", "", INT_MIN, INT_MAX); + WM_operator_properties_border(ot); } #endif @@ -4472,36 +4520,36 @@ static void SCREEN_OT_box_select(wmOperatorType *ot) /* *********************** generic fullscreen 'back' button *************** */ - static int fullscreen_back_exec(bContext *C, wmOperator *op) { - bScreen *screen = CTX_wm_screen(C); - ScrArea *sa = NULL; + bScreen *screen = CTX_wm_screen(C); + ScrArea *sa = NULL; - /* search current screen for 'fullscreen' areas */ - for (sa = screen->areabase.first; sa; sa = sa->next) { - if (sa->full) break; - } - if (!sa) { - BKE_report(op->reports, RPT_ERROR, "No fullscreen areas were found"); - return OPERATOR_CANCELLED; - } + /* search current screen for 'fullscreen' areas */ + for (sa = screen->areabase.first; sa; sa = sa->next) { + if (sa->full) + break; + } + if (!sa) { + BKE_report(op->reports, RPT_ERROR, "No fullscreen areas were found"); + return OPERATOR_CANCELLED; + } - ED_screen_full_prevspace(C, sa); + ED_screen_full_prevspace(C, sa); - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } static void SCREEN_OT_back_to_previous(struct wmOperatorType *ot) { - /* identifiers */ - ot->name = "Back to Previous Screen"; - ot->description = "Revert back to the original screen layout, before fullscreen area overlay"; - ot->idname = "SCREEN_OT_back_to_previous"; + /* identifiers */ + ot->name = "Back to Previous Screen"; + ot->description = "Revert back to the original screen layout, before fullscreen area overlay"; + ot->idname = "SCREEN_OT_back_to_previous"; - /* api callbacks */ - ot->exec = fullscreen_back_exec; - ot->poll = ED_operator_screenactive; + /* api callbacks */ + ot->exec = fullscreen_back_exec; + ot->poll = ED_operator_screenactive; } /** \} */ @@ -4512,35 +4560,34 @@ static void SCREEN_OT_back_to_previous(struct wmOperatorType *ot) static int userpref_show_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - int sizex = (500 + UI_NAVIGATION_REGION_WIDTH) * UI_DPI_FAC; - int sizey = 520 * UI_DPI_FAC; + int sizex = (500 + UI_NAVIGATION_REGION_WIDTH) * UI_DPI_FAC; + int sizey = 520 * UI_DPI_FAC; - /* changes context! */ - if (WM_window_open_temp(C, event->x, event->y, sizex, sizey, WM_WINDOW_USERPREFS) != NULL) { - /* The header only contains the editor switcher and looks empty. - * So hiding in the temp window makes sense. */ - ScrArea *area = CTX_wm_area(C); - ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_HEADER); - region->flag |= RGN_FLAG_HIDDEN; - return OPERATOR_FINISHED; - } - else { - BKE_report(op->reports, RPT_ERROR, "Failed to open window!"); - return OPERATOR_CANCELLED; - } + /* changes context! */ + if (WM_window_open_temp(C, event->x, event->y, sizex, sizey, WM_WINDOW_USERPREFS) != NULL) { + /* The header only contains the editor switcher and looks empty. + * So hiding in the temp window makes sense. */ + ScrArea *area = CTX_wm_area(C); + ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_HEADER); + region->flag |= RGN_FLAG_HIDDEN; + return OPERATOR_FINISHED; + } + else { + BKE_report(op->reports, RPT_ERROR, "Failed to open window!"); + return OPERATOR_CANCELLED; + } } - static void SCREEN_OT_userpref_show(struct wmOperatorType *ot) { - /* identifiers */ - ot->name = "Show Preferences"; - ot->description = "Edit user preferences and system settings"; - ot->idname = "SCREEN_OT_userpref_show"; + /* identifiers */ + ot->name = "Show Preferences"; + ot->description = "Edit user preferences and system settings"; + ot->idname = "SCREEN_OT_userpref_show"; - /* api callbacks */ - ot->invoke = userpref_show_invoke; - ot->poll = ED_operator_screenactive; + /* api callbacks */ + ot->invoke = userpref_show_invoke; + ot->poll = ED_operator_screenactive; } /** \} */ @@ -4551,64 +4598,61 @@ static void SCREEN_OT_userpref_show(struct wmOperatorType *ot) static int drivers_editor_show_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - PointerRNA ptr = {{NULL}}; - PropertyRNA *prop = NULL; - int index = -1; - uiBut *but = NULL; - - int sizex = 900 * UI_DPI_FAC; - int sizey = 580 * UI_DPI_FAC; - - /* Get active property to show driver for - * - Need to grab it first, or else this info disappears - * after we've created the window - */ - but = UI_context_active_but_prop_get(C, &ptr, &prop, &index); - - /* changes context! */ - if (WM_window_open_temp(C, event->x, event->y, sizex, sizey, WM_WINDOW_DRIVERS) != NULL) { - /* activate driver F-Curve for the property under the cursor */ - if (but) { - FCurve *fcu; - bool driven, special; - - fcu = rna_get_fcurve_context_ui(C, - &ptr, prop, index, - NULL, NULL, &driven, &special); - if (fcu) { - /* Isolate this F-Curve... */ - bAnimContext ac; - if (ANIM_animdata_get_context(C, &ac)) { - int filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_NODUPLIS; - ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, 0, ACHANNEL_SETFLAG_CLEAR); - ANIM_set_active_channel(&ac, ac.data, ac.datatype, filter, fcu, ANIMTYPE_FCURVE); - } - else { - /* Just blindly isolate... This isn't the best, and shouldn't happen, but may be enough... */ - fcu->flag |= (FCURVE_ACTIVE | FCURVE_SELECTED); - } - } - } - - return OPERATOR_FINISHED; - } - else { - BKE_report(op->reports, RPT_ERROR, "Failed to open window!"); - return OPERATOR_CANCELLED; - } + PointerRNA ptr = {{NULL}}; + PropertyRNA *prop = NULL; + int index = -1; + uiBut *but = NULL; + + int sizex = 900 * UI_DPI_FAC; + int sizey = 580 * UI_DPI_FAC; + + /* Get active property to show driver for + * - Need to grab it first, or else this info disappears + * after we've created the window + */ + but = UI_context_active_but_prop_get(C, &ptr, &prop, &index); + + /* changes context! */ + if (WM_window_open_temp(C, event->x, event->y, sizex, sizey, WM_WINDOW_DRIVERS) != NULL) { + /* activate driver F-Curve for the property under the cursor */ + if (but) { + FCurve *fcu; + bool driven, special; + + fcu = rna_get_fcurve_context_ui(C, &ptr, prop, index, NULL, NULL, &driven, &special); + if (fcu) { + /* Isolate this F-Curve... */ + bAnimContext ac; + if (ANIM_animdata_get_context(C, &ac)) { + int filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_NODUPLIS; + ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, 0, ACHANNEL_SETFLAG_CLEAR); + ANIM_set_active_channel(&ac, ac.data, ac.datatype, filter, fcu, ANIMTYPE_FCURVE); + } + else { + /* Just blindly isolate... This isn't the best, and shouldn't happen, but may be enough... */ + fcu->flag |= (FCURVE_ACTIVE | FCURVE_SELECTED); + } + } + } + + return OPERATOR_FINISHED; + } + else { + BKE_report(op->reports, RPT_ERROR, "Failed to open window!"); + return OPERATOR_CANCELLED; + } } - static void SCREEN_OT_drivers_editor_show(struct wmOperatorType *ot) { - /* identifiers */ - ot->name = "Show Drivers Editor"; - ot->description = "Show drivers editor in a separate window"; - ot->idname = "SCREEN_OT_drivers_editor_show"; + /* identifiers */ + ot->name = "Show Drivers Editor"; + ot->description = "Show drivers editor in a separate window"; + ot->idname = "SCREEN_OT_drivers_editor_show"; - /* api callbacks */ - ot->invoke = drivers_editor_show_invoke; - ot->poll = ED_operator_screenactive; + /* api callbacks */ + ot->invoke = drivers_editor_show_invoke; + ot->poll = ED_operator_screenactive; } /** \} */ @@ -4619,28 +4663,28 @@ static void SCREEN_OT_drivers_editor_show(struct wmOperatorType *ot) static int screen_new_exec(bContext *C, wmOperator *UNUSED(op)) { - Main *bmain = CTX_data_main(C); - wmWindow *win = CTX_wm_window(C); - WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook); - WorkSpaceLayout *layout_old = BKE_workspace_active_layout_get(win->workspace_hook); - WorkSpaceLayout *layout_new; + Main *bmain = CTX_data_main(C); + wmWindow *win = CTX_wm_window(C); + WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook); + WorkSpaceLayout *layout_old = BKE_workspace_active_layout_get(win->workspace_hook); + WorkSpaceLayout *layout_new; - layout_new = ED_workspace_layout_duplicate(bmain, workspace, layout_old, win); - WM_event_add_notifier(C, NC_SCREEN | ND_LAYOUTBROWSE, layout_new); + layout_new = ED_workspace_layout_duplicate(bmain, workspace, layout_old, win); + WM_event_add_notifier(C, NC_SCREEN | ND_LAYOUTBROWSE, layout_new); - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } static void SCREEN_OT_new(wmOperatorType *ot) { - /* identifiers */ - ot->name = "New Screen"; - ot->description = "Add a new screen"; - ot->idname = "SCREEN_OT_new"; + /* identifiers */ + ot->name = "New Screen"; + ot->description = "Add a new screen"; + ot->idname = "SCREEN_OT_new"; - /* api callbacks */ - ot->exec = screen_new_exec; - ot->poll = WM_operator_winactive; + /* api callbacks */ + ot->exec = screen_new_exec; + ot->poll = WM_operator_winactive; } /** \} */ @@ -4651,24 +4695,24 @@ static void SCREEN_OT_new(wmOperatorType *ot) static int screen_delete_exec(bContext *C, wmOperator *UNUSED(op)) { - bScreen *sc = CTX_wm_screen(C); - WorkSpace *workspace = CTX_wm_workspace(C); - WorkSpaceLayout *layout = BKE_workspace_layout_find(workspace, sc); + bScreen *sc = CTX_wm_screen(C); + WorkSpace *workspace = CTX_wm_workspace(C); + WorkSpaceLayout *layout = BKE_workspace_layout_find(workspace, sc); - WM_event_add_notifier(C, NC_SCREEN | ND_LAYOUTDELETE, layout); + WM_event_add_notifier(C, NC_SCREEN | ND_LAYOUTDELETE, layout); - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } static void SCREEN_OT_delete(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Delete Screen"; - ot->description = "Delete active screen"; - ot->idname = "SCREEN_OT_delete"; + /* identifiers */ + ot->name = "Delete Screen"; + ot->description = "Delete active screen"; + ot->idname = "SCREEN_OT_delete"; - /* api callbacks */ - ot->exec = screen_delete_exec; + /* api callbacks */ + ot->exec = screen_delete_exec; } /** \} */ @@ -4682,288 +4726,289 @@ static void SCREEN_OT_delete(wmOperatorType *ot) * This because flag RGN_HIDDEN is set in end - region doesn't draw at all then */ typedef struct RegionAlphaInfo { - ScrArea *sa; - ARegion *ar, *child_ar; /* other region */ - int hidden; + ScrArea *sa; + ARegion *ar, *child_ar; /* other region */ + int hidden; } RegionAlphaInfo; -#define TIMEOUT 0.1f -#define TIMESTEP (1.0f / 60.0f) +#define TIMEOUT 0.1f +#define TIMESTEP (1.0f / 60.0f) float ED_region_blend_alpha(ARegion *ar) { - /* check parent too */ - if (ar->regiontimer == NULL && (ar->alignment & RGN_SPLIT_PREV) && ar->prev) { - ar = ar->prev; - } + /* 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; + 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; + 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; + 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, const bool 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; - + 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) { + wmWindowManager *wm = CTX_wm_manager(C); + wmWindow *win = CTX_wm_window(C); + RegionAlphaInfo *rgi; - region_blend_end(C, ar, true); - } - rgi = MEM_callocN(sizeof(RegionAlphaInfo), "RegionAlphaInfo"); + /* end running timer */ + if (ar->regiontimer) { - rgi->hidden = ar->flag & RGN_FLAG_HIDDEN; - rgi->sa = sa; - rgi->ar = ar; - ar->flag &= ~RGN_FLAG_HIDDEN; + region_blend_end(C, ar, true); + } + rgi = MEM_callocN(sizeof(RegionAlphaInfo), "RegionAlphaInfo"); - /* 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); + rgi->hidden = ar->flag & RGN_FLAG_HIDDEN; + rgi->sa = sa; + rgi->ar = ar; + ar->flag &= ~RGN_FLAG_HIDDEN; - if (ar->next) { - if (ar->next->alignment & RGN_SPLIT_PREV) { - rgi->child_ar = ar->next; - } - } + /* 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); - /* new timer */ - ar->regiontimer = WM_event_add_timer(wm, win, TIMERREGION, TIMESTEP); - ar->regiontimer->customdata = rgi; + 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), const wmEvent *event) { - RegionAlphaInfo *rgi; - wmTimer *timer = event->customdata; + RegionAlphaInfo *rgi; + wmTimer *timer = event->customdata; - /* event type is TIMERREGION, but we better check */ - if (event->type != TIMERREGION || timer == NULL) - return OPERATOR_PASS_THROUGH; + /* event type is TIMERREGION, but we better check */ + if (event->type != TIMERREGION || timer == NULL) + return OPERATOR_PASS_THROUGH; - rgi = timer->customdata; + rgi = timer->customdata; - /* always send redraws */ - ED_region_tag_redraw(rgi->ar); - if (rgi->child_ar) - ED_region_tag_redraw(rgi->child_ar); + /* 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, false); - return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH); - } + /* end timer? */ + if (rgi->ar->regiontimer->duration > (double)TIMEOUT) { + region_blend_end(C, rgi->ar, false); + return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH); + } - 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"; + /* 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; + /* api callbacks */ + ot->invoke = region_blend_invoke; - /* flags */ - ot->flag = OPTYPE_INTERNAL; + /* flags */ + ot->flag = OPTYPE_INTERNAL; - /* properties */ + /* properties */ } /** \} */ - /* -------------------------------------------------------------------- */ /** \name Space Type Set or Cycle Operator * \{ */ static bool space_type_set_or_cycle_poll(bContext *C) { - ScrArea *sa = CTX_wm_area(C); - return (sa && !ELEM(sa->spacetype, SPACE_TOPBAR, SPACE_STATUSBAR)); + ScrArea *sa = CTX_wm_area(C); + return (sa && !ELEM(sa->spacetype, SPACE_TOPBAR, SPACE_STATUSBAR)); } static int space_type_set_or_cycle_exec(bContext *C, wmOperator *op) { - const int space_type = RNA_enum_get(op->ptr, "space_type"); - - PointerRNA ptr; - ScrArea *sa = CTX_wm_area(C); - RNA_pointer_create((ID *)CTX_wm_screen(C), &RNA_Area, sa, &ptr); - PropertyRNA *prop_type = RNA_struct_find_property(&ptr, "type"); - PropertyRNA *prop_ui_type = RNA_struct_find_property(&ptr, "ui_type"); - - if (sa->spacetype != space_type) { - /* Set the type. */ - RNA_property_enum_set(&ptr, prop_type, space_type); - RNA_property_update(C, &ptr, prop_type); - } - else { - /* Types match, cycle the subtype. */ - const int space_type_ui = RNA_property_enum_get(&ptr, prop_ui_type); - const EnumPropertyItem *item; - int item_len; - bool free; - RNA_property_enum_items(C, &ptr, prop_ui_type, &item, &item_len, &free); - int index = RNA_enum_from_value(item, space_type_ui); - for (int i = 1; i < item_len; i++) { - const EnumPropertyItem *item_test = &item[(index + i) % item_len]; - if ((item_test->value >> 16) == space_type) { - RNA_property_enum_set(&ptr, prop_ui_type, item_test->value); - RNA_property_update(C, &ptr, prop_ui_type); - break; - } - } - if (free) { - MEM_freeN((void *)item); - } - } - - return OPERATOR_FINISHED; + const int space_type = RNA_enum_get(op->ptr, "space_type"); + + PointerRNA ptr; + ScrArea *sa = CTX_wm_area(C); + RNA_pointer_create((ID *)CTX_wm_screen(C), &RNA_Area, sa, &ptr); + PropertyRNA *prop_type = RNA_struct_find_property(&ptr, "type"); + PropertyRNA *prop_ui_type = RNA_struct_find_property(&ptr, "ui_type"); + + if (sa->spacetype != space_type) { + /* Set the type. */ + RNA_property_enum_set(&ptr, prop_type, space_type); + RNA_property_update(C, &ptr, prop_type); + } + else { + /* Types match, cycle the subtype. */ + const int space_type_ui = RNA_property_enum_get(&ptr, prop_ui_type); + const EnumPropertyItem *item; + int item_len; + bool free; + RNA_property_enum_items(C, &ptr, prop_ui_type, &item, &item_len, &free); + int index = RNA_enum_from_value(item, space_type_ui); + for (int i = 1; i < item_len; i++) { + const EnumPropertyItem *item_test = &item[(index + i) % item_len]; + if ((item_test->value >> 16) == space_type) { + RNA_property_enum_set(&ptr, prop_ui_type, item_test->value); + RNA_property_update(C, &ptr, prop_ui_type); + break; + } + } + if (free) { + MEM_freeN((void *)item); + } + } + + return OPERATOR_FINISHED; } static void SCREEN_OT_space_type_set_or_cycle(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Cycle Space Type Set"; - ot->description = "Set the space type or cycle sub-type"; - ot->idname = "SCREEN_OT_space_type_set_or_cycle"; + /* identifiers */ + ot->name = "Cycle Space Type Set"; + ot->description = "Set the space type or cycle sub-type"; + ot->idname = "SCREEN_OT_space_type_set_or_cycle"; - /* api callbacks */ - ot->exec = space_type_set_or_cycle_exec; - ot->poll = space_type_set_or_cycle_poll; + /* api callbacks */ + ot->exec = space_type_set_or_cycle_exec; + ot->poll = space_type_set_or_cycle_poll; - ot->flag = 0; + ot->flag = 0; - RNA_def_enum(ot->srna, "space_type", rna_enum_space_type_items, SPACE_EMPTY, "Type", ""); + RNA_def_enum(ot->srna, "space_type", rna_enum_space_type_items, SPACE_EMPTY, "Type", ""); } /** \} */ - /* -------------------------------------------------------------------- */ /** \name Space Context Cycle Operator * \{ */ static const EnumPropertyItem space_context_cycle_direction[] = { - {SPACE_CONTEXT_CYCLE_PREV, "PREV", 0, "Previous", ""}, - {SPACE_CONTEXT_CYCLE_NEXT, "NEXT", 0, "Next", ""}, - {0, NULL, 0, NULL, NULL}, + {SPACE_CONTEXT_CYCLE_PREV, "PREV", 0, "Previous", ""}, + {SPACE_CONTEXT_CYCLE_NEXT, "NEXT", 0, "Next", ""}, + {0, NULL, 0, NULL, NULL}, }; static bool space_context_cycle_poll(bContext *C) { - ScrArea *sa = CTX_wm_area(C); - /* sa might be NULL if called out of window bounds */ - return (sa && ELEM(sa->spacetype, SPACE_PROPERTIES, SPACE_USERPREF)); + ScrArea *sa = CTX_wm_area(C); + /* sa might be NULL if called out of window bounds */ + return (sa && ELEM(sa->spacetype, SPACE_PROPERTIES, SPACE_USERPREF)); } /** * Helper to get the correct RNA pointer/property pair for changing * the display context of active space type in \a sa. */ -static void context_cycle_prop_get( - bScreen *screen, const ScrArea *sa, - PointerRNA *r_ptr, PropertyRNA **r_prop) -{ - const char *propname; - - switch (sa->spacetype) { - case SPACE_PROPERTIES: - RNA_pointer_create(&screen->id, &RNA_SpaceProperties, sa->spacedata.first, r_ptr); - propname = "context"; - break; - case SPACE_USERPREF: - RNA_pointer_create(NULL, &RNA_Preferences, &U, r_ptr); - propname = "active_section"; - break; - default: - BLI_assert(0); - propname = ""; - } - - *r_prop = RNA_struct_find_property(r_ptr, propname); +static void context_cycle_prop_get(bScreen *screen, + const ScrArea *sa, + PointerRNA *r_ptr, + PropertyRNA **r_prop) +{ + const char *propname; + + switch (sa->spacetype) { + case SPACE_PROPERTIES: + RNA_pointer_create(&screen->id, &RNA_SpaceProperties, sa->spacedata.first, r_ptr); + propname = "context"; + break; + case SPACE_USERPREF: + RNA_pointer_create(NULL, &RNA_Preferences, &U, r_ptr); + propname = "active_section"; + break; + default: + BLI_assert(0); + propname = ""; + } + + *r_prop = RNA_struct_find_property(r_ptr, propname); } static int space_context_cycle_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - const int direction = RNA_enum_get(op->ptr, "direction"); + const int direction = RNA_enum_get(op->ptr, "direction"); - PointerRNA ptr; - PropertyRNA *prop; - context_cycle_prop_get(CTX_wm_screen(C), CTX_wm_area(C), &ptr, &prop); - const int old_context = RNA_property_enum_get(&ptr, prop); - const int new_context = RNA_property_enum_step( - C, &ptr, prop, old_context, - direction == SPACE_CONTEXT_CYCLE_PREV ? -1 : 1); - RNA_property_enum_set(&ptr, prop, new_context); - RNA_property_update(C, &ptr, prop); + PointerRNA ptr; + PropertyRNA *prop; + context_cycle_prop_get(CTX_wm_screen(C), CTX_wm_area(C), &ptr, &prop); + const int old_context = RNA_property_enum_get(&ptr, prop); + const int new_context = RNA_property_enum_step( + C, &ptr, prop, old_context, direction == SPACE_CONTEXT_CYCLE_PREV ? -1 : 1); + RNA_property_enum_set(&ptr, prop, new_context); + RNA_property_update(C, &ptr, prop); - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } static void SCREEN_OT_space_context_cycle(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Cycle Space Context"; - ot->description = "Cycle through the editor context by activating the next/previous one"; - ot->idname = "SCREEN_OT_space_context_cycle"; + /* identifiers */ + ot->name = "Cycle Space Context"; + ot->description = "Cycle through the editor context by activating the next/previous one"; + ot->idname = "SCREEN_OT_space_context_cycle"; - /* api callbacks */ - ot->invoke = space_context_cycle_invoke; - ot->poll = space_context_cycle_poll; + /* api callbacks */ + ot->invoke = space_context_cycle_invoke; + ot->poll = space_context_cycle_poll; - ot->flag = 0; + ot->flag = 0; - RNA_def_enum(ot->srna, "direction", space_context_cycle_direction, SPACE_CONTEXT_CYCLE_NEXT, "Direction", - "Direction to cycle through"); + RNA_def_enum(ot->srna, + "direction", + space_context_cycle_direction, + SPACE_CONTEXT_CYCLE_NEXT, + "Direction", + "Direction to cycle through"); } /** \} */ @@ -4974,63 +5019,67 @@ static void SCREEN_OT_space_context_cycle(wmOperatorType *ot) static int space_workspace_cycle_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - wmWindow *win = CTX_wm_window(C); - if (WM_window_is_temp_screen(win)) { - return OPERATOR_CANCELLED; - } + wmWindow *win = CTX_wm_window(C); + if (WM_window_is_temp_screen(win)) { + return OPERATOR_CANCELLED; + } - Main *bmain = CTX_data_main(C); - const int direction = RNA_enum_get(op->ptr, "direction"); - WorkSpace *workspace_src = WM_window_get_active_workspace(win); - WorkSpace *workspace_dst = NULL; + Main *bmain = CTX_data_main(C); + const int direction = RNA_enum_get(op->ptr, "direction"); + WorkSpace *workspace_src = WM_window_get_active_workspace(win); + WorkSpace *workspace_dst = NULL; - ListBase ordered; - BKE_id_ordered_list(&ordered, &bmain->workspaces); + ListBase ordered; + BKE_id_ordered_list(&ordered, &bmain->workspaces); - for (LinkData *link = ordered.first; link; link = link->next) { - if (link->data == workspace_src) { - if (direction == SPACE_CONTEXT_CYCLE_PREV) { - workspace_dst = (link->prev) ? link->prev->data : NULL; - } - else { - workspace_dst = (link->next) ? link->next->data : NULL; - } - } - } + for (LinkData *link = ordered.first; link; link = link->next) { + if (link->data == workspace_src) { + if (direction == SPACE_CONTEXT_CYCLE_PREV) { + workspace_dst = (link->prev) ? link->prev->data : NULL; + } + else { + workspace_dst = (link->next) ? link->next->data : NULL; + } + } + } - if (workspace_dst == NULL) { - LinkData *link = (direction == SPACE_CONTEXT_CYCLE_PREV) ? ordered.last : ordered.first; - workspace_dst = link->data; - } + if (workspace_dst == NULL) { + LinkData *link = (direction == SPACE_CONTEXT_CYCLE_PREV) ? ordered.last : ordered.first; + workspace_dst = link->data; + } - BLI_freelistN(&ordered); + BLI_freelistN(&ordered); - if (workspace_src == workspace_dst) { - return OPERATOR_CANCELLED; - } + if (workspace_src == workspace_dst) { + return OPERATOR_CANCELLED; + } - win->workspace_hook->temp_workspace_store = workspace_dst; - WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_SET, workspace_dst); - win->workspace_hook->temp_workspace_store = NULL; + win->workspace_hook->temp_workspace_store = workspace_dst; + WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_SET, workspace_dst); + win->workspace_hook->temp_workspace_store = NULL; - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } static void SCREEN_OT_workspace_cycle(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Cycle Workspace"; - ot->description = "Cycle through workspaces"; - ot->idname = "SCREEN_OT_workspace_cycle"; + /* identifiers */ + ot->name = "Cycle Workspace"; + ot->description = "Cycle through workspaces"; + ot->idname = "SCREEN_OT_workspace_cycle"; - /* api callbacks */ - ot->invoke = space_workspace_cycle_invoke; - ot->poll = ED_operator_screenactive; + /* api callbacks */ + ot->invoke = space_workspace_cycle_invoke; + ot->poll = ED_operator_screenactive; - ot->flag = 0; + ot->flag = 0; - RNA_def_enum(ot->srna, "direction", space_context_cycle_direction, SPACE_CONTEXT_CYCLE_NEXT, "Direction", - "Direction to cycle through"); + RNA_def_enum(ot->srna, + "direction", + space_context_cycle_direction, + SPACE_CONTEXT_CYCLE_NEXT, + "Direction", + "Direction to cycle through"); } /** \} */ @@ -5042,62 +5091,61 @@ static void SCREEN_OT_workspace_cycle(wmOperatorType *ot) /* called in spacetypes.c */ void ED_operatortypes_screen(void) { - /* generic UI stuff */ - WM_operatortype_append(SCREEN_OT_actionzone); - WM_operatortype_append(SCREEN_OT_repeat_last); - WM_operatortype_append(SCREEN_OT_repeat_history); - WM_operatortype_append(SCREEN_OT_redo_last); - - /* screen tools */ - WM_operatortype_append(SCREEN_OT_area_move); - WM_operatortype_append(SCREEN_OT_area_split); - WM_operatortype_append(SCREEN_OT_area_join); - WM_operatortype_append(SCREEN_OT_area_options); - WM_operatortype_append(SCREEN_OT_area_dupli); - WM_operatortype_append(SCREEN_OT_area_swap); - WM_operatortype_append(SCREEN_OT_region_quadview); - WM_operatortype_append(SCREEN_OT_region_scale); - WM_operatortype_append(SCREEN_OT_region_flip); - WM_operatortype_append(SCREEN_OT_header); - WM_operatortype_append(SCREEN_OT_header_toggle_menus); - WM_operatortype_append(SCREEN_OT_header_context_menu); - WM_operatortype_append(SCREEN_OT_footer); - WM_operatortype_append(SCREEN_OT_footer_context_menu); - WM_operatortype_append(SCREEN_OT_screen_set); - WM_operatortype_append(SCREEN_OT_screen_full_area); - WM_operatortype_append(SCREEN_OT_back_to_previous); - WM_operatortype_append(SCREEN_OT_spacedata_cleanup); - WM_operatortype_append(SCREEN_OT_screenshot); - WM_operatortype_append(SCREEN_OT_userpref_show); - WM_operatortype_append(SCREEN_OT_drivers_editor_show); - WM_operatortype_append(SCREEN_OT_region_blend); - WM_operatortype_append(SCREEN_OT_space_type_set_or_cycle); - WM_operatortype_append(SCREEN_OT_space_context_cycle); - WM_operatortype_append(SCREEN_OT_workspace_cycle); - - /*frame changes*/ - WM_operatortype_append(SCREEN_OT_frame_offset); - WM_operatortype_append(SCREEN_OT_frame_jump); - WM_operatortype_append(SCREEN_OT_keyframe_jump); - WM_operatortype_append(SCREEN_OT_marker_jump); - - WM_operatortype_append(SCREEN_OT_animation_step); - WM_operatortype_append(SCREEN_OT_animation_play); - WM_operatortype_append(SCREEN_OT_animation_cancel); - - /* new/delete */ - WM_operatortype_append(SCREEN_OT_new); - WM_operatortype_append(SCREEN_OT_delete); - - /* tools shared by more space types */ - WM_operatortype_append(ED_OT_undo); - WM_operatortype_append(ED_OT_undo_push); - WM_operatortype_append(ED_OT_redo); - WM_operatortype_append(ED_OT_undo_redo); - WM_operatortype_append(ED_OT_undo_history); - - WM_operatortype_append(ED_OT_flush_edits); - + /* generic UI stuff */ + WM_operatortype_append(SCREEN_OT_actionzone); + WM_operatortype_append(SCREEN_OT_repeat_last); + WM_operatortype_append(SCREEN_OT_repeat_history); + WM_operatortype_append(SCREEN_OT_redo_last); + + /* screen tools */ + WM_operatortype_append(SCREEN_OT_area_move); + WM_operatortype_append(SCREEN_OT_area_split); + WM_operatortype_append(SCREEN_OT_area_join); + WM_operatortype_append(SCREEN_OT_area_options); + WM_operatortype_append(SCREEN_OT_area_dupli); + WM_operatortype_append(SCREEN_OT_area_swap); + WM_operatortype_append(SCREEN_OT_region_quadview); + WM_operatortype_append(SCREEN_OT_region_scale); + WM_operatortype_append(SCREEN_OT_region_flip); + WM_operatortype_append(SCREEN_OT_header); + WM_operatortype_append(SCREEN_OT_header_toggle_menus); + WM_operatortype_append(SCREEN_OT_header_context_menu); + WM_operatortype_append(SCREEN_OT_footer); + WM_operatortype_append(SCREEN_OT_footer_context_menu); + WM_operatortype_append(SCREEN_OT_screen_set); + WM_operatortype_append(SCREEN_OT_screen_full_area); + WM_operatortype_append(SCREEN_OT_back_to_previous); + WM_operatortype_append(SCREEN_OT_spacedata_cleanup); + WM_operatortype_append(SCREEN_OT_screenshot); + WM_operatortype_append(SCREEN_OT_userpref_show); + WM_operatortype_append(SCREEN_OT_drivers_editor_show); + WM_operatortype_append(SCREEN_OT_region_blend); + WM_operatortype_append(SCREEN_OT_space_type_set_or_cycle); + WM_operatortype_append(SCREEN_OT_space_context_cycle); + WM_operatortype_append(SCREEN_OT_workspace_cycle); + + /*frame changes*/ + WM_operatortype_append(SCREEN_OT_frame_offset); + WM_operatortype_append(SCREEN_OT_frame_jump); + WM_operatortype_append(SCREEN_OT_keyframe_jump); + WM_operatortype_append(SCREEN_OT_marker_jump); + + WM_operatortype_append(SCREEN_OT_animation_step); + WM_operatortype_append(SCREEN_OT_animation_play); + WM_operatortype_append(SCREEN_OT_animation_cancel); + + /* new/delete */ + WM_operatortype_append(SCREEN_OT_new); + WM_operatortype_append(SCREEN_OT_delete); + + /* tools shared by more space types */ + WM_operatortype_append(ED_OT_undo); + WM_operatortype_append(ED_OT_undo_push); + WM_operatortype_append(ED_OT_redo); + WM_operatortype_append(ED_OT_undo_redo); + WM_operatortype_append(ED_OT_undo_history); + + WM_operatortype_append(ED_OT_flush_edits); } /** \} */ @@ -5108,62 +5156,63 @@ void ED_operatortypes_screen(void) static void keymap_modal_set(wmKeyConfig *keyconf) { - static const EnumPropertyItem modal_items[] = { - {KM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, - {KM_MODAL_APPLY, "APPLY", 0, "Apply", ""}, - {KM_MODAL_SNAP_ON, "SNAP", 0, "Snap on", ""}, - {KM_MODAL_SNAP_OFF, "SNAP_OFF", 0, "Snap off", ""}, - {0, NULL, 0, NULL, NULL}, - }; - wmKeyMap *keymap; + static const EnumPropertyItem modal_items[] = { + {KM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, + {KM_MODAL_APPLY, "APPLY", 0, "Apply", ""}, + {KM_MODAL_SNAP_ON, "SNAP", 0, "Snap on", ""}, + {KM_MODAL_SNAP_OFF, "SNAP_OFF", 0, "Snap off", ""}, + {0, NULL, 0, NULL, NULL}, + }; + wmKeyMap *keymap; - /* Standard Modal keymap ------------------------------------------------ */ - keymap = WM_modalkeymap_add(keyconf, "Standard Modal Map", modal_items); - - WM_modalkeymap_assign(keymap, "SCREEN_OT_area_move"); + /* Standard Modal keymap ------------------------------------------------ */ + keymap = WM_modalkeymap_add(keyconf, "Standard Modal Map", modal_items); + WM_modalkeymap_assign(keymap, "SCREEN_OT_area_move"); } -static bool blend_file_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip)) +static bool blend_file_drop_poll(bContext *UNUSED(C), + wmDrag *drag, + const wmEvent *UNUSED(event), + const char **UNUSED(tooltip)) { - if (drag->type == WM_DRAG_PATH) { - if (drag->icon == ICON_FILE_BLEND) - return 1; - } - return 0; + if (drag->type == WM_DRAG_PATH) { + if (drag->icon == ICON_FILE_BLEND) + return 1; + } + return 0; } static void blend_file_drop_copy(wmDrag *drag, wmDropBox *drop) { - /* copy drag path to properties */ - RNA_string_set(drop->ptr, "filepath", drag->path); + /* copy drag path to properties */ + RNA_string_set(drop->ptr, "filepath", drag->path); } - /* called in spacetypes.c */ void ED_keymap_screen(wmKeyConfig *keyconf) { - ListBase *lb; + ListBase *lb; - /* Screen Editing ------------------------------------------------ */ - WM_keymap_ensure(keyconf, "Screen Editing", 0, 0); + /* Screen Editing ------------------------------------------------ */ + WM_keymap_ensure(keyconf, "Screen Editing", 0, 0); - /* Header Editing ------------------------------------------------ */ - /* note: this is only used when the cursor is inside the header */ - WM_keymap_ensure(keyconf, "Header", 0, 0); + /* Header Editing ------------------------------------------------ */ + /* note: this is only used when the cursor is inside the header */ + WM_keymap_ensure(keyconf, "Header", 0, 0); - /* Screen General ------------------------------------------------ */ - WM_keymap_ensure(keyconf, "Screen", 0, 0); + /* Screen General ------------------------------------------------ */ + WM_keymap_ensure(keyconf, "Screen", 0, 0); - /* Anim Playback ------------------------------------------------ */ - WM_keymap_ensure(keyconf, "Frames", 0, 0); + /* Anim Playback ------------------------------------------------ */ + WM_keymap_ensure(keyconf, "Frames", 0, 0); - /* dropbox for entire window */ - lb = WM_dropboxmap_find("Window", 0, 0); - WM_dropbox_add(lb, "WM_OT_drop_blend_file", blend_file_drop_poll, blend_file_drop_copy); - WM_dropbox_add(lb, "UI_OT_drop_color", UI_drop_color_poll, UI_drop_color_copy); + /* dropbox for entire window */ + lb = WM_dropboxmap_find("Window", 0, 0); + WM_dropbox_add(lb, "WM_OT_drop_blend_file", blend_file_drop_poll, blend_file_drop_copy); + WM_dropbox_add(lb, "UI_OT_drop_color", UI_drop_color_poll, UI_drop_color_copy); - keymap_modal_set(keyconf); + keymap_modal_set(keyconf); } /** \} */ diff --git a/source/blender/editors/screen/screen_user_menu.c b/source/blender/editors/screen/screen_user_menu.c index 4b8f210f1d9..0ec989db12b 100644 --- a/source/blender/editors/screen/screen_user_menu.c +++ b/source/blender/editors/screen/screen_user_menu.c @@ -57,29 +57,33 @@ bUserMenu **ED_screen_user_menus_find(const bContext *C, uint *r_len) { - SpaceLink *sl = CTX_wm_space_data(C); - const char *context = CTX_data_mode_string(C); - - if (sl == NULL) { - *r_len = 0; - return NULL; - } - - uint array_len = 3; - bUserMenu **um_array = MEM_calloc_arrayN(array_len, sizeof(*um_array), __func__); - um_array[0] = BKE_blender_user_menu_find(&U.user_menus, sl->spacetype, context); - um_array[1] = (sl->spacetype != SPACE_TOPBAR) ? BKE_blender_user_menu_find(&U.user_menus, SPACE_TOPBAR, context) : NULL; - um_array[2] = (sl->spacetype == SPACE_VIEW3D) ? BKE_blender_user_menu_find(&U.user_menus, SPACE_PROPERTIES, context) : NULL; - - *r_len = array_len; - return um_array; + SpaceLink *sl = CTX_wm_space_data(C); + const char *context = CTX_data_mode_string(C); + + if (sl == NULL) { + *r_len = 0; + return NULL; + } + + uint array_len = 3; + bUserMenu **um_array = MEM_calloc_arrayN(array_len, sizeof(*um_array), __func__); + um_array[0] = BKE_blender_user_menu_find(&U.user_menus, sl->spacetype, context); + um_array[1] = (sl->spacetype != SPACE_TOPBAR) ? + BKE_blender_user_menu_find(&U.user_menus, SPACE_TOPBAR, context) : + NULL; + um_array[2] = (sl->spacetype == SPACE_VIEW3D) ? + BKE_blender_user_menu_find(&U.user_menus, SPACE_PROPERTIES, context) : + NULL; + + *r_len = array_len; + return um_array; } bUserMenu *ED_screen_user_menu_ensure(bContext *C) { - SpaceLink *sl = CTX_wm_space_data(C); - const char *context = CTX_data_mode_string(C); - return BKE_blender_user_menu_ensure(&U.user_menus, sl->spacetype, context); + SpaceLink *sl = CTX_wm_space_data(C); + const char *context = CTX_data_mode_string(C); + return BKE_blender_user_menu_ensure(&U.user_menus, sl->spacetype, context); } /** \} */ @@ -88,96 +92,98 @@ bUserMenu *ED_screen_user_menu_ensure(bContext *C) /** \name Menu Item * \{ */ -bUserMenuItem_Op *ED_screen_user_menu_item_find_operator( - ListBase *lb, - const wmOperatorType *ot, IDProperty *prop, short opcontext) +bUserMenuItem_Op *ED_screen_user_menu_item_find_operator(ListBase *lb, + const wmOperatorType *ot, + IDProperty *prop, + short opcontext) { - for (bUserMenuItem *umi = lb->first; umi; umi = umi->next) { - if (umi->type == USER_MENU_TYPE_OPERATOR) { - bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi; - if (STREQ(ot->idname, umi_op->op_idname) && - (opcontext == umi_op->opcontext) && - (IDP_EqualsProperties(prop, umi_op->prop))) - { - return umi_op; - } - } - } - return NULL; + for (bUserMenuItem *umi = lb->first; umi; umi = umi->next) { + if (umi->type == USER_MENU_TYPE_OPERATOR) { + bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi; + if (STREQ(ot->idname, umi_op->op_idname) && (opcontext == umi_op->opcontext) && + (IDP_EqualsProperties(prop, umi_op->prop))) { + return umi_op; + } + } + } + return NULL; } -struct bUserMenuItem_Menu *ED_screen_user_menu_item_find_menu( - struct ListBase *lb, - const struct MenuType *mt) +struct bUserMenuItem_Menu *ED_screen_user_menu_item_find_menu(struct ListBase *lb, + const struct MenuType *mt) { - for (bUserMenuItem *umi = lb->first; umi; umi = umi->next) { - if (umi->type == USER_MENU_TYPE_MENU) { - bUserMenuItem_Menu *umi_mt = (bUserMenuItem_Menu *)umi; - if (STREQ(mt->idname, umi_mt->mt_idname)) { - return umi_mt; - } - } - } - return NULL; + for (bUserMenuItem *umi = lb->first; umi; umi = umi->next) { + if (umi->type == USER_MENU_TYPE_MENU) { + bUserMenuItem_Menu *umi_mt = (bUserMenuItem_Menu *)umi; + if (STREQ(mt->idname, umi_mt->mt_idname)) { + return umi_mt; + } + } + } + return NULL; } -struct bUserMenuItem_Prop *ED_screen_user_menu_item_find_prop( - struct ListBase *lb, - const char *context_data_path, const char *prop_id, int prop_index) +struct bUserMenuItem_Prop *ED_screen_user_menu_item_find_prop(struct ListBase *lb, + const char *context_data_path, + const char *prop_id, + int prop_index) { - for (bUserMenuItem *umi = lb->first; umi; umi = umi->next) { - if (umi->type == USER_MENU_TYPE_PROP) { - bUserMenuItem_Prop *umi_pr = (bUserMenuItem_Prop *)umi; - if (STREQ(context_data_path, umi_pr->context_data_path) && - STREQ(prop_id, umi_pr->prop_id) && - (prop_index == umi_pr->prop_index)) - { - return umi_pr; - } - } - } - return NULL; + for (bUserMenuItem *umi = lb->first; umi; umi = umi->next) { + if (umi->type == USER_MENU_TYPE_PROP) { + bUserMenuItem_Prop *umi_pr = (bUserMenuItem_Prop *)umi; + if (STREQ(context_data_path, umi_pr->context_data_path) && STREQ(prop_id, umi_pr->prop_id) && + (prop_index == umi_pr->prop_index)) { + return umi_pr; + } + } + } + return NULL; } -void ED_screen_user_menu_item_add_operator( - ListBase *lb, const char *ui_name, - const wmOperatorType *ot, const IDProperty *prop, short opcontext) +void ED_screen_user_menu_item_add_operator(ListBase *lb, + const char *ui_name, + const wmOperatorType *ot, + const IDProperty *prop, + short opcontext) { - bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)BKE_blender_user_menu_item_add(lb, USER_MENU_TYPE_OPERATOR); - umi_op->opcontext = opcontext; - if (!STREQ(ui_name, ot->name)) { - STRNCPY(umi_op->item.ui_name, ui_name); - } - STRNCPY(umi_op->op_idname, ot->idname); - umi_op->prop = prop ? IDP_CopyProperty(prop) : NULL; + bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)BKE_blender_user_menu_item_add( + lb, USER_MENU_TYPE_OPERATOR); + umi_op->opcontext = opcontext; + if (!STREQ(ui_name, ot->name)) { + STRNCPY(umi_op->item.ui_name, ui_name); + } + STRNCPY(umi_op->op_idname, ot->idname); + umi_op->prop = prop ? IDP_CopyProperty(prop) : NULL; } -void ED_screen_user_menu_item_add_menu( - ListBase *lb, const char *ui_name, - const MenuType *mt) +void ED_screen_user_menu_item_add_menu(ListBase *lb, const char *ui_name, const MenuType *mt) { - bUserMenuItem_Menu *umi_mt = (bUserMenuItem_Menu *)BKE_blender_user_menu_item_add(lb, USER_MENU_TYPE_MENU); - if (!STREQ(ui_name, mt->label)) { - STRNCPY(umi_mt->item.ui_name, ui_name); - } - STRNCPY(umi_mt->mt_idname, mt->idname); + bUserMenuItem_Menu *umi_mt = (bUserMenuItem_Menu *)BKE_blender_user_menu_item_add( + lb, USER_MENU_TYPE_MENU); + if (!STREQ(ui_name, mt->label)) { + STRNCPY(umi_mt->item.ui_name, ui_name); + } + STRNCPY(umi_mt->mt_idname, mt->idname); } -void ED_screen_user_menu_item_add_prop( - ListBase *lb, const char *ui_name, - const char *context_data_path, const char *prop_id, int prop_index) +void ED_screen_user_menu_item_add_prop(ListBase *lb, + const char *ui_name, + const char *context_data_path, + const char *prop_id, + int prop_index) { - bUserMenuItem_Prop *umi_pr = (bUserMenuItem_Prop *)BKE_blender_user_menu_item_add(lb, USER_MENU_TYPE_PROP); - STRNCPY(umi_pr->item.ui_name, ui_name); - STRNCPY(umi_pr->context_data_path, context_data_path); - STRNCPY(umi_pr->prop_id, prop_id); - umi_pr->prop_index = prop_index; + bUserMenuItem_Prop *umi_pr = (bUserMenuItem_Prop *)BKE_blender_user_menu_item_add( + lb, USER_MENU_TYPE_PROP); + STRNCPY(umi_pr->item.ui_name, ui_name); + STRNCPY(umi_pr->context_data_path, context_data_path); + STRNCPY(umi_pr->prop_id, prop_id); + umi_pr->prop_index = prop_index; } void ED_screen_user_menu_item_remove(ListBase *lb, bUserMenuItem *umi) { - BLI_remlink(lb, umi); - BKE_blender_user_menu_item_free(umi); + BLI_remlink(lb, umi); + BKE_blender_user_menu_item_free(umi); } /** \} */ @@ -188,95 +194,92 @@ void ED_screen_user_menu_item_remove(ListBase *lb, bUserMenuItem *umi) static void screen_user_menu_draw(const bContext *C, Menu *menu) { - uint um_array_len; - bUserMenu **um_array = ED_screen_user_menus_find(C, &um_array_len); - bool is_empty = true; - for (int um_index = 0; um_index < um_array_len; um_index++) { - bUserMenu *um = um_array[um_index]; - if (um == NULL) { - continue; - } - for (bUserMenuItem *umi = um->items.first; umi; umi = umi->next) { - const char *ui_name = umi->ui_name[0] ? umi->ui_name : NULL; - if (umi->type == USER_MENU_TYPE_OPERATOR) { - bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi; - IDProperty *prop = umi_op->prop ? IDP_CopyProperty(umi_op->prop) : NULL; - uiItemFullO( - menu->layout, umi_op->op_idname, ui_name, - ICON_NONE, prop, umi_op->opcontext, 0, NULL); - is_empty = false; - } - else if (umi->type == USER_MENU_TYPE_MENU) { - bUserMenuItem_Menu *umi_mt = (bUserMenuItem_Menu *)umi; - uiItemM(menu->layout, umi_mt->mt_idname, ui_name, - ICON_NONE); - is_empty = false; - } - else if (umi->type == USER_MENU_TYPE_PROP) { - bUserMenuItem_Prop *umi_pr = (bUserMenuItem_Prop *)umi; - - char *data_path = strchr(umi_pr->context_data_path, '.'); - if (data_path) { - *data_path = '\0'; - } - PointerRNA ptr = CTX_data_pointer_get(C, umi_pr->context_data_path); - if (ptr.type == NULL) { - PointerRNA ctx_ptr; - RNA_pointer_create(NULL, &RNA_Context, (void *)C, &ctx_ptr); - if (!RNA_path_resolve_full(&ctx_ptr, umi_pr->context_data_path, &ptr, NULL, NULL)) { - ptr.type = NULL; - } - } - if (data_path) { - *data_path = '.'; - data_path += 1; - } - - bool ok = false; - if (ptr.type != NULL) { - PropertyRNA *prop = NULL; - PointerRNA prop_ptr = ptr; - if ((data_path == NULL) || RNA_path_resolve_full(&ptr, data_path, &prop_ptr, NULL, NULL)) { - prop = RNA_struct_find_property(&prop_ptr, umi_pr->prop_id); - if (prop) { - ok = true; - uiItemFullR( - menu->layout, - &prop_ptr, prop, umi_pr->prop_index, - 0, 0, ui_name, ICON_NONE); - is_empty = false; - } - } - } - if (!ok) { - char label[512]; - SNPRINTF(label, "Missing: %s.%s", umi_pr->context_data_path, umi_pr->prop_id); - uiItemL(menu->layout, label, ICON_NONE); - } - } - else if (umi->type == USER_MENU_TYPE_SEP) { - uiItemS(menu->layout); - } - } - } - if (um_array) { - MEM_freeN(um_array); - } - - if (is_empty) { - uiItemL(menu->layout, IFACE_("No menu items found"), ICON_NONE); - uiItemL(menu->layout, IFACE_("Right click on buttons to add them to this menu"), ICON_NONE); - } + uint um_array_len; + bUserMenu **um_array = ED_screen_user_menus_find(C, &um_array_len); + bool is_empty = true; + for (int um_index = 0; um_index < um_array_len; um_index++) { + bUserMenu *um = um_array[um_index]; + if (um == NULL) { + continue; + } + for (bUserMenuItem *umi = um->items.first; umi; umi = umi->next) { + const char *ui_name = umi->ui_name[0] ? umi->ui_name : NULL; + if (umi->type == USER_MENU_TYPE_OPERATOR) { + bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi; + IDProperty *prop = umi_op->prop ? IDP_CopyProperty(umi_op->prop) : NULL; + uiItemFullO( + menu->layout, umi_op->op_idname, ui_name, ICON_NONE, prop, umi_op->opcontext, 0, NULL); + is_empty = false; + } + else if (umi->type == USER_MENU_TYPE_MENU) { + bUserMenuItem_Menu *umi_mt = (bUserMenuItem_Menu *)umi; + uiItemM(menu->layout, umi_mt->mt_idname, ui_name, ICON_NONE); + is_empty = false; + } + else if (umi->type == USER_MENU_TYPE_PROP) { + bUserMenuItem_Prop *umi_pr = (bUserMenuItem_Prop *)umi; + + char *data_path = strchr(umi_pr->context_data_path, '.'); + if (data_path) { + *data_path = '\0'; + } + PointerRNA ptr = CTX_data_pointer_get(C, umi_pr->context_data_path); + if (ptr.type == NULL) { + PointerRNA ctx_ptr; + RNA_pointer_create(NULL, &RNA_Context, (void *)C, &ctx_ptr); + if (!RNA_path_resolve_full(&ctx_ptr, umi_pr->context_data_path, &ptr, NULL, NULL)) { + ptr.type = NULL; + } + } + if (data_path) { + *data_path = '.'; + data_path += 1; + } + + bool ok = false; + if (ptr.type != NULL) { + PropertyRNA *prop = NULL; + PointerRNA prop_ptr = ptr; + if ((data_path == NULL) || + RNA_path_resolve_full(&ptr, data_path, &prop_ptr, NULL, NULL)) { + prop = RNA_struct_find_property(&prop_ptr, umi_pr->prop_id); + if (prop) { + ok = true; + uiItemFullR( + menu->layout, &prop_ptr, prop, umi_pr->prop_index, 0, 0, ui_name, ICON_NONE); + is_empty = false; + } + } + } + if (!ok) { + char label[512]; + SNPRINTF(label, "Missing: %s.%s", umi_pr->context_data_path, umi_pr->prop_id); + uiItemL(menu->layout, label, ICON_NONE); + } + } + else if (umi->type == USER_MENU_TYPE_SEP) { + uiItemS(menu->layout); + } + } + } + if (um_array) { + MEM_freeN(um_array); + } + + if (is_empty) { + uiItemL(menu->layout, IFACE_("No menu items found"), ICON_NONE); + uiItemL(menu->layout, IFACE_("Right click on buttons to add them to this menu"), ICON_NONE); + } } void ED_screen_user_menu_register(void) { - MenuType *mt = MEM_callocN(sizeof(MenuType), __func__); - strcpy(mt->idname, "SCREEN_MT_user_menu"); - strcpy(mt->label, "Quick Favorites"); - strcpy(mt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA); - mt->draw = screen_user_menu_draw; - WM_menutype_add(mt); + MenuType *mt = MEM_callocN(sizeof(MenuType), __func__); + strcpy(mt->idname, "SCREEN_MT_user_menu"); + strcpy(mt->label, "Quick Favorites"); + strcpy(mt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA); + mt->draw = screen_user_menu_draw; + WM_menutype_add(mt); } /** \} */ diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c index 2e634cccedb..37ffdef0b9b 100644 --- a/source/blender/editors/screen/screendump.c +++ b/source/blender/editors/screen/screendump.c @@ -22,7 +22,6 @@ * \ingroup edscr */ - #include <string.h> #include <errno.h> @@ -57,239 +56,249 @@ #include "screen_intern.h" typedef struct ScreenshotData { - unsigned int *dumprect; - int dumpsx, dumpsy; - rcti crop; + unsigned int *dumprect; + int dumpsx, dumpsy; + rcti crop; - ImageFormatData im_format; + ImageFormatData im_format; } ScreenshotData; static void screenshot_read_pixels(int x, int y, int w, int h, unsigned char *rect) { - int i; + int i; - glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rect); - glFinish(); + glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rect); + glFinish(); - /* clear alpha, it is not set to a meaningful value in opengl */ - for (i = 0, rect += 3; i < w * h; i++, rect += 4) - *rect = 255; + /* clear alpha, it is not set to a meaningful value in opengl */ + for (i = 0, rect += 3; i < w * h; i++, rect += 4) + *rect = 255; } /* get shot from frontbuffer */ static unsigned int *screenshot(bContext *C, int *dumpsx, int *dumpsy) { - wmWindow *win = CTX_wm_window(C); - int x = 0, y = 0; - unsigned int *dumprect = NULL; + wmWindow *win = CTX_wm_window(C); + int x = 0, y = 0; + unsigned int *dumprect = NULL; - x = 0; - y = 0; - *dumpsx = WM_window_pixels_x(win); - *dumpsy = WM_window_pixels_y(win); + x = 0; + y = 0; + *dumpsx = WM_window_pixels_x(win); + *dumpsy = WM_window_pixels_y(win); - if (*dumpsx && *dumpsy) { + if (*dumpsx && *dumpsy) { - dumprect = MEM_mallocN(sizeof(int) * (*dumpsx) * (*dumpsy), "dumprect"); - glReadBuffer(GL_FRONT); - screenshot_read_pixels(x, y, *dumpsx, *dumpsy, (unsigned char *)dumprect); - glReadBuffer(GL_BACK); - } + dumprect = MEM_mallocN(sizeof(int) * (*dumpsx) * (*dumpsy), "dumprect"); + glReadBuffer(GL_FRONT); + screenshot_read_pixels(x, y, *dumpsx, *dumpsy, (unsigned char *)dumprect); + glReadBuffer(GL_BACK); + } - return dumprect; + return dumprect; } /* call from both exec and invoke */ static int screenshot_data_create(bContext *C, wmOperator *op) { - unsigned int *dumprect; - int dumpsx, dumpsy; + unsigned int *dumprect; + int dumpsx, dumpsy; - /* do redraw so we don't show popups/menus */ - WM_redraw_windows(C); + /* do redraw so we don't show popups/menus */ + WM_redraw_windows(C); - dumprect = screenshot(C, &dumpsx, &dumpsy); + dumprect = screenshot(C, &dumpsx, &dumpsy); - if (dumprect) { - ScreenshotData *scd = MEM_callocN(sizeof(ScreenshotData), "screenshot"); - ScrArea *sa = CTX_wm_area(C); + if (dumprect) { + ScreenshotData *scd = MEM_callocN(sizeof(ScreenshotData), "screenshot"); + ScrArea *sa = CTX_wm_area(C); - scd->dumpsx = dumpsx; - scd->dumpsy = dumpsy; - scd->dumprect = dumprect; - if (sa) { - scd->crop = sa->totrct; - } + scd->dumpsx = dumpsx; + scd->dumpsy = dumpsy; + scd->dumprect = dumprect; + if (sa) { + scd->crop = sa->totrct; + } - BKE_imformat_defaults(&scd->im_format); + BKE_imformat_defaults(&scd->im_format); - op->customdata = scd; + op->customdata = scd; - return true; - } - else { - op->customdata = NULL; - return false; - } + return true; + } + else { + op->customdata = NULL; + return false; + } } static void screenshot_data_free(wmOperator *op) { - ScreenshotData *scd = op->customdata; - - if (scd) { - if (scd->dumprect) - MEM_freeN(scd->dumprect); - MEM_freeN(scd); - op->customdata = NULL; - } + ScreenshotData *scd = op->customdata; + + if (scd) { + if (scd->dumprect) + MEM_freeN(scd->dumprect); + MEM_freeN(scd); + op->customdata = NULL; + } } static void screenshot_crop(ImBuf *ibuf, rcti crop) { - unsigned int *to = ibuf->rect; - unsigned int *from = ibuf->rect + crop.ymin * ibuf->x + crop.xmin; - int crop_x = BLI_rcti_size_x(&crop); - int crop_y = BLI_rcti_size_y(&crop); - int y; - - if (crop_x > 0 && crop_y > 0) { - for (y = 0; y < crop_y; y++, to += crop_x, from += ibuf->x) - memmove(to, from, sizeof(unsigned int) * crop_x); - - ibuf->x = crop_x; - ibuf->y = crop_y; - } + unsigned int *to = ibuf->rect; + unsigned int *from = ibuf->rect + crop.ymin * ibuf->x + crop.xmin; + int crop_x = BLI_rcti_size_x(&crop); + int crop_y = BLI_rcti_size_y(&crop); + int y; + + if (crop_x > 0 && crop_y > 0) { + for (y = 0; y < crop_y; y++, to += crop_x, from += ibuf->x) + memmove(to, from, sizeof(unsigned int) * crop_x); + + ibuf->x = crop_x; + ibuf->y = crop_y; + } } static int screenshot_exec(bContext *C, wmOperator *op) { - ScreenshotData *scd = op->customdata; - bool ok = false; - - if (scd == NULL) { - /* when running exec directly */ - screenshot_data_create(C, op); - scd = op->customdata; - } - - if (scd) { - if (scd->dumprect) { - ImBuf *ibuf; - char path[FILE_MAX]; - - RNA_string_get(op->ptr, "filepath", path); - BLI_path_abs(path, BKE_main_blendfile_path_from_global()); - - /* operator ensures the extension */ - ibuf = IMB_allocImBuf(scd->dumpsx, scd->dumpsy, 24, 0); - ibuf->rect = scd->dumprect; - - /* crop to show only single editor */ - if (!RNA_boolean_get(op->ptr, "full")) - screenshot_crop(ibuf, scd->crop); - - if (scd->im_format.planes == R_IMF_PLANES_BW) { - /* bw screenshot? - users will notice if it fails! */ - IMB_color_to_bw(ibuf); - } - if (BKE_imbuf_write(ibuf, path, &scd->im_format)) { - ok = true; - } - else { - BKE_reportf(op->reports, RPT_ERROR, "Could not write image: %s", strerror(errno)); - } - - IMB_freeImBuf(ibuf); - } - } - - screenshot_data_free(op); - - return ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED; + ScreenshotData *scd = op->customdata; + bool ok = false; + + if (scd == NULL) { + /* when running exec directly */ + screenshot_data_create(C, op); + scd = op->customdata; + } + + if (scd) { + if (scd->dumprect) { + ImBuf *ibuf; + char path[FILE_MAX]; + + RNA_string_get(op->ptr, "filepath", path); + BLI_path_abs(path, BKE_main_blendfile_path_from_global()); + + /* operator ensures the extension */ + ibuf = IMB_allocImBuf(scd->dumpsx, scd->dumpsy, 24, 0); + ibuf->rect = scd->dumprect; + + /* crop to show only single editor */ + if (!RNA_boolean_get(op->ptr, "full")) + screenshot_crop(ibuf, scd->crop); + + if (scd->im_format.planes == R_IMF_PLANES_BW) { + /* bw screenshot? - users will notice if it fails! */ + IMB_color_to_bw(ibuf); + } + if (BKE_imbuf_write(ibuf, path, &scd->im_format)) { + ok = true; + } + else { + BKE_reportf(op->reports, RPT_ERROR, "Could not write image: %s", strerror(errno)); + } + + IMB_freeImBuf(ibuf); + } + } + + screenshot_data_free(op); + + return ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } static int screenshot_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - if (screenshot_data_create(C, op)) { - if (RNA_struct_property_is_set(op->ptr, "filepath")) - return screenshot_exec(C, op); - - /* extension is added by 'screenshot_check' after */ - char filepath[FILE_MAX] = "//screen"; - if (G.relbase_valid) { - BLI_strncpy(filepath, BKE_main_blendfile_path_from_global(), sizeof(filepath)); - BLI_path_extension_replace(filepath, sizeof(filepath), ""); /* strip '.blend' */ - } - RNA_string_set(op->ptr, "filepath", filepath); - - WM_event_add_fileselect(C, op); - - return OPERATOR_RUNNING_MODAL; - } - return OPERATOR_CANCELLED; + if (screenshot_data_create(C, op)) { + if (RNA_struct_property_is_set(op->ptr, "filepath")) + return screenshot_exec(C, op); + + /* extension is added by 'screenshot_check' after */ + char filepath[FILE_MAX] = "//screen"; + if (G.relbase_valid) { + BLI_strncpy(filepath, BKE_main_blendfile_path_from_global(), sizeof(filepath)); + BLI_path_extension_replace(filepath, sizeof(filepath), ""); /* strip '.blend' */ + } + RNA_string_set(op->ptr, "filepath", filepath); + + WM_event_add_fileselect(C, op); + + return OPERATOR_RUNNING_MODAL; + } + return OPERATOR_CANCELLED; } static bool screenshot_check(bContext *UNUSED(C), wmOperator *op) { - ScreenshotData *scd = op->customdata; - return WM_operator_filesel_ensure_ext_imtype(op, &scd->im_format); + ScreenshotData *scd = op->customdata; + return WM_operator_filesel_ensure_ext_imtype(op, &scd->im_format); } static void screenshot_cancel(bContext *UNUSED(C), wmOperator *op) { - screenshot_data_free(op); + screenshot_data_free(op); } -static bool screenshot_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data)) +static bool screenshot_draw_check_prop(PointerRNA *UNUSED(ptr), + PropertyRNA *prop, + void *UNUSED(user_data)) { - const char *prop_id = RNA_property_identifier(prop); + const char *prop_id = RNA_property_identifier(prop); - return !(STREQ(prop_id, "filepath")); + return !(STREQ(prop_id, "filepath")); } static void screenshot_draw(bContext *UNUSED(C), wmOperator *op) { - uiLayout *layout = op->layout; - ScreenshotData *scd = op->customdata; - PointerRNA ptr; - - /* image template */ - RNA_pointer_create(NULL, &RNA_ImageFormatSettings, &scd->im_format, &ptr); - uiTemplateImageSettings(layout, &ptr, false); - - /* main draw call */ - RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr); - uiDefAutoButsRNA(layout, &ptr, screenshot_draw_check_prop, NULL, NULL, UI_BUT_LABEL_ALIGN_NONE, false); + uiLayout *layout = op->layout; + ScreenshotData *scd = op->customdata; + PointerRNA ptr; + + /* image template */ + RNA_pointer_create(NULL, &RNA_ImageFormatSettings, &scd->im_format, &ptr); + uiTemplateImageSettings(layout, &ptr, false); + + /* main draw call */ + RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr); + uiDefAutoButsRNA( + layout, &ptr, screenshot_draw_check_prop, NULL, NULL, UI_BUT_LABEL_ALIGN_NONE, false); } static bool screenshot_poll(bContext *C) { - if (G.background) - return false; + if (G.background) + return false; - return WM_operator_winactive(C); + return WM_operator_winactive(C); } void SCREEN_OT_screenshot(wmOperatorType *ot) { - /* weak: opname starting with 'save' makes filewindow give save-over */ - ot->name = "Save Screenshot"; - ot->idname = "SCREEN_OT_screenshot"; - ot->description = "Capture a picture of the active area or whole Blender window"; - - ot->invoke = screenshot_invoke; - ot->check = screenshot_check; - ot->exec = screenshot_exec; - ot->cancel = screenshot_cancel; - ot->ui = screenshot_draw; - ot->poll = screenshot_poll; - - ot->flag = 0; - - WM_operator_properties_filesel( - ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE, FILE_SPECIAL, FILE_SAVE, - WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA); - RNA_def_boolean(ot->srna, "full", 1, "Full Screen", - "Capture the whole window (otherwise only capture the active area)"); + /* weak: opname starting with 'save' makes filewindow give save-over */ + ot->name = "Save Screenshot"; + ot->idname = "SCREEN_OT_screenshot"; + ot->description = "Capture a picture of the active area or whole Blender window"; + + ot->invoke = screenshot_invoke; + ot->check = screenshot_check; + ot->exec = screenshot_exec; + ot->cancel = screenshot_cancel; + ot->ui = screenshot_draw; + ot->poll = screenshot_poll; + + ot->flag = 0; + + WM_operator_properties_filesel(ot, + FILE_TYPE_FOLDER | FILE_TYPE_IMAGE, + FILE_SPECIAL, + FILE_SAVE, + WM_FILESEL_FILEPATH, + FILE_DEFAULTDISPLAY, + FILE_SORT_ALPHA); + RNA_def_boolean(ot->srna, + "full", + 1, + "Full Screen", + "Capture the whole window (otherwise only capture the active area)"); } diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c index 63d25cb96c4..5750a1f36a7 100644 --- a/source/blender/editors/screen/workspace_edit.c +++ b/source/blender/editors/screen/workspace_edit.c @@ -67,7 +67,6 @@ #include "screen_intern.h" - /** \name Workspace API * * \brief API for managing workspaces and their data. @@ -75,69 +74,70 @@ WorkSpace *ED_workspace_add(Main *bmain, const char *name) { - return BKE_workspace_add(bmain, name); + return BKE_workspace_add(bmain, name); } /** * Changes the object mode (if needed) to the one set in \a workspace_new. * Object mode is still stored on object level. In future it should all be workspace level instead. */ -static void workspace_change_update( - WorkSpace *workspace_new, const WorkSpace *workspace_old, - bContext *C, wmWindowManager *wm) +static void workspace_change_update(WorkSpace *workspace_new, + const WorkSpace *workspace_old, + bContext *C, + wmWindowManager *wm) { - /* needs to be done before changing mode! (to ensure right context) */ - UNUSED_VARS(workspace_old, workspace_new, C, wm); + /* needs to be done before changing mode! (to ensure right context) */ + UNUSED_VARS(workspace_old, workspace_new, C, wm); #if 0 - Object *ob_act = CTX_data_active_object(C) - eObjectMode mode_old = workspace_old->object_mode; - eObjectMode mode_new = workspace_new->object_mode; - - if (mode_old != mode_new) { - ED_object_mode_compat_set(C, ob_act, mode_new, &wm->reports); - ED_object_mode_toggle(C, mode_new); - } + Object *ob_act = CTX_data_active_object(C) + eObjectMode mode_old = workspace_old->object_mode; + eObjectMode mode_new = workspace_new->object_mode; + + if (mode_old != mode_new) { + ED_object_mode_compat_set(C, ob_act, mode_new, &wm->reports); + ED_object_mode_toggle(C, mode_new); + } #endif } static bool workspace_change_find_new_layout_cb(const WorkSpaceLayout *layout, void *UNUSED(arg)) { - /* return false to stop the iterator if we've found a layout that can be activated */ - return workspace_layout_set_poll(layout) ? false : true; + /* return false to stop the iterator if we've found a layout that can be activated */ + return workspace_layout_set_poll(layout) ? false : true; } -static WorkSpaceLayout *workspace_change_get_new_layout( - Main *bmain, WorkSpace *workspace_new, wmWindow *win) +static WorkSpaceLayout *workspace_change_get_new_layout(Main *bmain, + WorkSpace *workspace_new, + wmWindow *win) { - /* ED_workspace_duplicate may have stored a layout to activate once the workspace gets activated. */ - WorkSpaceLayout *layout_old = WM_window_get_active_layout(win); - WorkSpaceLayout *layout_new; - bScreen *screen_new; - - if (win->workspace_hook->temp_workspace_store) { - layout_new = win->workspace_hook->temp_layout_store; - } - else { - layout_new = BKE_workspace_hook_layout_for_workspace_get(win->workspace_hook, workspace_new); - if (!layout_new) { - layout_new = BKE_workspace_layouts_get(workspace_new)->first; - } - } - screen_new = BKE_workspace_layout_screen_get(layout_new); - - if (screen_new->winid) { - /* screen is already used, try to find a free one */ - WorkSpaceLayout *layout_temp = BKE_workspace_layout_iter_circular( - workspace_new, layout_new, workspace_change_find_new_layout_cb, - NULL, false); - if (!layout_temp) { - /* fallback solution: duplicate layout from old workspace */ - layout_temp = ED_workspace_layout_duplicate(bmain, workspace_new, layout_old, win); - } - layout_new = layout_temp; - } - - return layout_new; + /* ED_workspace_duplicate may have stored a layout to activate once the workspace gets activated. */ + WorkSpaceLayout *layout_old = WM_window_get_active_layout(win); + WorkSpaceLayout *layout_new; + bScreen *screen_new; + + if (win->workspace_hook->temp_workspace_store) { + layout_new = win->workspace_hook->temp_layout_store; + } + else { + layout_new = BKE_workspace_hook_layout_for_workspace_get(win->workspace_hook, workspace_new); + if (!layout_new) { + layout_new = BKE_workspace_layouts_get(workspace_new)->first; + } + } + screen_new = BKE_workspace_layout_screen_get(layout_new); + + if (screen_new->winid) { + /* screen is already used, try to find a free one */ + WorkSpaceLayout *layout_temp = BKE_workspace_layout_iter_circular( + workspace_new, layout_new, workspace_change_find_new_layout_cb, NULL, false); + if (!layout_temp) { + /* fallback solution: duplicate layout from old workspace */ + layout_temp = ED_workspace_layout_duplicate(bmain, workspace_new, layout_old, win); + } + layout_new = layout_temp; + } + + return layout_new; } /** @@ -149,464 +149,472 @@ static WorkSpaceLayout *workspace_change_get_new_layout( * \warning Do NOT call in area/region queues! * \returns if workspace changing was successful. */ -bool ED_workspace_change( - WorkSpace *workspace_new, bContext *C, wmWindowManager *wm, wmWindow *win) +bool ED_workspace_change(WorkSpace *workspace_new, bContext *C, wmWindowManager *wm, wmWindow *win) { - Main *bmain = CTX_data_main(C); - WorkSpace *workspace_old = WM_window_get_active_workspace(win); - WorkSpaceLayout *layout_new = workspace_change_get_new_layout(bmain, workspace_new, win); - bScreen *screen_new = BKE_workspace_layout_screen_get(layout_new); - bScreen *screen_old = BKE_workspace_active_screen_get(win->workspace_hook); + Main *bmain = CTX_data_main(C); + WorkSpace *workspace_old = WM_window_get_active_workspace(win); + WorkSpaceLayout *layout_new = workspace_change_get_new_layout(bmain, workspace_new, win); + bScreen *screen_new = BKE_workspace_layout_screen_get(layout_new); + bScreen *screen_old = BKE_workspace_active_screen_get(win->workspace_hook); - win->workspace_hook->temp_layout_store = NULL; - if (workspace_old == workspace_new) { - /* Could also return true, everything that needs to be done was done (nothing :P), but nothing changed */ - return false; - } + win->workspace_hook->temp_layout_store = NULL; + if (workspace_old == workspace_new) { + /* Could also return true, everything that needs to be done was done (nothing :P), but nothing changed */ + return false; + } - screen_new = screen_change_prepare(screen_old, screen_new, bmain, C, win); - BLI_assert(BKE_workspace_layout_screen_get(layout_new) == screen_new); + screen_new = screen_change_prepare(screen_old, screen_new, bmain, C, win); + BLI_assert(BKE_workspace_layout_screen_get(layout_new) == screen_new); - if (screen_new == NULL) { - return false; - } + if (screen_new == NULL) { + return false; + } - BKE_workspace_hook_layout_for_workspace_set(win->workspace_hook, workspace_new, layout_new); - BKE_workspace_active_set(win->workspace_hook, workspace_new); + BKE_workspace_hook_layout_for_workspace_set(win->workspace_hook, workspace_new, layout_new); + BKE_workspace_active_set(win->workspace_hook, workspace_new); - /* update screen *after* changing workspace - which also causes the - * actual screen change and updates context (including CTX_wm_workspace) */ - screen_change_update(C, win, screen_new); - workspace_change_update(workspace_new, workspace_old, C, wm); + /* update screen *after* changing workspace - which also causes the + * actual screen change and updates context (including CTX_wm_workspace) */ + screen_change_update(C, win, screen_new); + workspace_change_update(workspace_new, workspace_old, C, wm); - BLI_assert(CTX_wm_workspace(C) == workspace_new); + BLI_assert(CTX_wm_workspace(C) == workspace_new); - WM_toolsystem_unlink_all(C, workspace_old); - /* Area initialization will initialize based on the new workspace. */ + WM_toolsystem_unlink_all(C, workspace_old); + /* Area initialization will initialize based on the new workspace. */ - /* Automatic mode switching. */ - if (workspace_new->object_mode != workspace_old->object_mode) { - ED_object_mode_generic_enter(C, workspace_new->object_mode); - } + /* Automatic mode switching. */ + if (workspace_new->object_mode != workspace_old->object_mode) { + ED_object_mode_generic_enter(C, workspace_new->object_mode); + } - return true; + return true; } /** * Duplicate a workspace including its layouts. Does not activate the workspace, but * it stores the screen-layout to be activated (BKE_workspace_temp_layout_store) */ -WorkSpace *ED_workspace_duplicate( - WorkSpace *workspace_old, Main *bmain, wmWindow *win) +WorkSpace *ED_workspace_duplicate(WorkSpace *workspace_old, Main *bmain, wmWindow *win) { - WorkSpaceLayout *layout_active_old = BKE_workspace_active_layout_get(win->workspace_hook); - ListBase *layouts_old = BKE_workspace_layouts_get(workspace_old); - WorkSpace *workspace_new = ED_workspace_add(bmain, workspace_old->id.name + 2); + WorkSpaceLayout *layout_active_old = BKE_workspace_active_layout_get(win->workspace_hook); + ListBase *layouts_old = BKE_workspace_layouts_get(workspace_old); + WorkSpace *workspace_new = ED_workspace_add(bmain, workspace_old->id.name + 2); - workspace_new->flags = workspace_old->flags; - BLI_duplicatelist(&workspace_new->owner_ids, &workspace_old->owner_ids); + workspace_new->flags = workspace_old->flags; + BLI_duplicatelist(&workspace_new->owner_ids, &workspace_old->owner_ids); - /* TODO(campbell): tools */ + /* TODO(campbell): tools */ - for (WorkSpaceLayout *layout_old = layouts_old->first; layout_old; layout_old = layout_old->next) { - WorkSpaceLayout *layout_new = ED_workspace_layout_duplicate(bmain, workspace_new, layout_old, win); + for (WorkSpaceLayout *layout_old = layouts_old->first; layout_old; + layout_old = layout_old->next) { + WorkSpaceLayout *layout_new = ED_workspace_layout_duplicate( + bmain, workspace_new, layout_old, win); - if (layout_active_old == layout_old) { - win->workspace_hook->temp_layout_store = layout_new; - } - } - return workspace_new; + if (layout_active_old == layout_old) { + win->workspace_hook->temp_layout_store = layout_new; + } + } + return workspace_new; } /** * \return if succeeded. */ -bool ED_workspace_delete( - WorkSpace *workspace, Main *bmain, bContext *C, wmWindowManager *wm) +bool ED_workspace_delete(WorkSpace *workspace, Main *bmain, bContext *C, wmWindowManager *wm) { - if (BLI_listbase_is_single(&bmain->workspaces)) { - return false; - } - - ListBase ordered; - BKE_id_ordered_list(&ordered, &bmain->workspaces); - WorkSpace *prev = NULL, *next = NULL; - for (LinkData *link = ordered.first; link; link = link->next) { - if (link->data == workspace) { - prev = link->prev ? link->prev->data : NULL; - next = link->next ? link->next->data : NULL; - break; - } - } - BLI_freelistN(&ordered); - BLI_assert((prev != NULL) || (next != NULL)); - - for (wmWindow *win = wm->windows.first; win; win = win->next) { - WorkSpace *workspace_active = WM_window_get_active_workspace(win); - if (workspace_active == workspace) { - ED_workspace_change((prev != NULL) ? prev : next, C, wm, win); - } - } - - BKE_id_free(bmain, &workspace->id); - return true; + if (BLI_listbase_is_single(&bmain->workspaces)) { + return false; + } + + ListBase ordered; + BKE_id_ordered_list(&ordered, &bmain->workspaces); + WorkSpace *prev = NULL, *next = NULL; + for (LinkData *link = ordered.first; link; link = link->next) { + if (link->data == workspace) { + prev = link->prev ? link->prev->data : NULL; + next = link->next ? link->next->data : NULL; + break; + } + } + BLI_freelistN(&ordered); + BLI_assert((prev != NULL) || (next != NULL)); + + for (wmWindow *win = wm->windows.first; win; win = win->next) { + WorkSpace *workspace_active = WM_window_get_active_workspace(win); + if (workspace_active == workspace) { + ED_workspace_change((prev != NULL) ? prev : next, C, wm, win); + } + } + + BKE_id_free(bmain, &workspace->id); + return true; } /** * Some editor data may need to be synced with scene data (3D View camera and layers). * This function ensures data is synced for editors in active layout of \a workspace. */ -void ED_workspace_scene_data_sync( - WorkSpaceInstanceHook *hook, Scene *scene) +void ED_workspace_scene_data_sync(WorkSpaceInstanceHook *hook, Scene *scene) { - bScreen *screen = BKE_workspace_active_screen_get(hook); - BKE_screen_view3d_scene_sync(screen, scene); + bScreen *screen = BKE_workspace_active_screen_get(hook); + BKE_screen_view3d_scene_sync(screen, scene); } /** \} Workspace API */ - /** \name Workspace Operators * * \{ */ static WorkSpace *workspace_context_get(bContext *C) { - ID *id = UI_context_active_but_get_tab_ID(C); - if (id && GS(id->name) == ID_WS) { - return (WorkSpace *)id; - } + ID *id = UI_context_active_but_get_tab_ID(C); + if (id && GS(id->name) == ID_WS) { + return (WorkSpace *)id; + } - wmWindow *win = CTX_wm_window(C); - return WM_window_get_active_workspace(win); + wmWindow *win = CTX_wm_window(C); + return WM_window_get_active_workspace(win); } static bool workspace_context_poll(bContext *C) { - return workspace_context_get(C) != NULL; + return workspace_context_get(C) != NULL; } static int workspace_new_exec(bContext *C, wmOperator *UNUSED(op)) { - Main *bmain = CTX_data_main(C); - wmWindow *win = CTX_wm_window(C); - WorkSpace *workspace = workspace_context_get(C); + Main *bmain = CTX_data_main(C); + wmWindow *win = CTX_wm_window(C); + WorkSpace *workspace = workspace_context_get(C); - workspace = ED_workspace_duplicate(workspace, bmain, win); + workspace = ED_workspace_duplicate(workspace, bmain, win); - WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_SET, workspace); + WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_SET, workspace); - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } static void WORKSPACE_OT_duplicate(wmOperatorType *ot) { - /* identifiers */ - ot->name = "New Workspace"; - ot->description = "Add a new workspace"; - ot->idname = "WORKSPACE_OT_duplicate"; - - /* api callbacks */ - ot->poll = workspace_context_poll; - ot->exec = workspace_new_exec; + /* identifiers */ + ot->name = "New Workspace"; + ot->description = "Add a new workspace"; + ot->idname = "WORKSPACE_OT_duplicate"; + + /* api callbacks */ + ot->poll = workspace_context_poll; + ot->exec = workspace_new_exec; } static int workspace_delete_exec(bContext *C, wmOperator *UNUSED(op)) { - WorkSpace *workspace = workspace_context_get(C); - WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_DELETE, workspace); - WM_event_add_notifier(C, NC_WINDOW, NULL); + WorkSpace *workspace = workspace_context_get(C); + WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_DELETE, workspace); + WM_event_add_notifier(C, NC_WINDOW, NULL); - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } static void WORKSPACE_OT_delete(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Delete Workspace"; - ot->description = "Delete the active workspace"; - ot->idname = "WORKSPACE_OT_delete"; - - /* api callbacks */ - ot->poll = workspace_context_poll; - ot->exec = workspace_delete_exec; + /* identifiers */ + ot->name = "Delete Workspace"; + ot->description = "Delete the active workspace"; + ot->idname = "WORKSPACE_OT_delete"; + + /* api callbacks */ + ot->poll = workspace_context_poll; + ot->exec = workspace_delete_exec; } static bool workspace_append_activate_poll(bContext *C) { - wmOperatorType *ot = WM_operatortype_find("WM_OT_append", false); - return WM_operator_poll(C, ot); + wmOperatorType *ot = WM_operatortype_find("WM_OT_append", false); + return WM_operator_poll(C, ot); } static int workspace_append(bContext *C, const char *directory, const char *idname) { - wmOperatorType *ot = WM_operatortype_find("WM_OT_append", false); - PointerRNA opptr; - int retval; + wmOperatorType *ot = WM_operatortype_find("WM_OT_append", false); + PointerRNA opptr; + int retval; - WM_operator_properties_create_ptr(&opptr, ot); - RNA_string_set(&opptr, "directory", directory); - RNA_string_set(&opptr, "filename", idname); - RNA_boolean_set(&opptr, "autoselect", false); + WM_operator_properties_create_ptr(&opptr, ot); + RNA_string_set(&opptr, "directory", directory); + RNA_string_set(&opptr, "filename", idname); + RNA_boolean_set(&opptr, "autoselect", false); - retval = WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &opptr); + retval = WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &opptr); - WM_operator_properties_free(&opptr); + WM_operator_properties_free(&opptr); - return retval; + return retval; } static int workspace_append_activate_exec(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); - char idname[MAX_ID_NAME - 2], filepath[FILE_MAX]; + Main *bmain = CTX_data_main(C); + char idname[MAX_ID_NAME - 2], filepath[FILE_MAX]; - if (!RNA_struct_property_is_set(op->ptr, "idname") || - !RNA_struct_property_is_set(op->ptr, "filepath")) - { - return OPERATOR_CANCELLED; - } - RNA_string_get(op->ptr, "idname", idname); - RNA_string_get(op->ptr, "filepath", filepath); + if (!RNA_struct_property_is_set(op->ptr, "idname") || + !RNA_struct_property_is_set(op->ptr, "filepath")) { + return OPERATOR_CANCELLED; + } + RNA_string_get(op->ptr, "idname", idname); + RNA_string_get(op->ptr, "filepath", filepath); - if (workspace_append(C, filepath, idname) != OPERATOR_CANCELLED) { - WorkSpace *appended_workspace = BLI_findstring(&bmain->workspaces, idname, offsetof(ID, name) + 2); - BLI_assert(appended_workspace != NULL); + if (workspace_append(C, filepath, idname) != OPERATOR_CANCELLED) { + WorkSpace *appended_workspace = BLI_findstring( + &bmain->workspaces, idname, offsetof(ID, name) + 2); + BLI_assert(appended_workspace != NULL); - /* Reorder to last position. */ - BKE_id_reorder(&bmain->workspaces, &appended_workspace->id, NULL, true); + /* Reorder to last position. */ + BKE_id_reorder(&bmain->workspaces, &appended_workspace->id, NULL, true); - /* Changing workspace changes context. Do delayed! */ - WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_SET, appended_workspace); + /* Changing workspace changes context. Do delayed! */ + WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_SET, appended_workspace); - return OPERATOR_FINISHED; - } + return OPERATOR_FINISHED; + } - return OPERATOR_CANCELLED; + return OPERATOR_CANCELLED; } static void WORKSPACE_OT_append_activate(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Append and Activate Workspace"; - ot->description = "Append a workspace and make it the active one in the current window"; - ot->idname = "WORKSPACE_OT_append_activate"; - - /* api callbacks */ - ot->exec = workspace_append_activate_exec; - ot->poll = workspace_append_activate_poll; - - RNA_def_string(ot->srna, "idname", NULL, MAX_ID_NAME - 2, "Identifier", - "Name of the workspace to append and activate"); - RNA_def_string(ot->srna, "filepath", NULL, FILE_MAX, "Filepath", - "Path to the library"); + /* identifiers */ + ot->name = "Append and Activate Workspace"; + ot->description = "Append a workspace and make it the active one in the current window"; + ot->idname = "WORKSPACE_OT_append_activate"; + + /* api callbacks */ + ot->exec = workspace_append_activate_exec; + ot->poll = workspace_append_activate_poll; + + RNA_def_string(ot->srna, + "idname", + NULL, + MAX_ID_NAME - 2, + "Identifier", + "Name of the workspace to append and activate"); + RNA_def_string(ot->srna, "filepath", NULL, FILE_MAX, "Filepath", "Path to the library"); } static WorkspaceConfigFileData *workspace_config_file_read(const char *app_template) { - const char *cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, app_template); - char startup_file_path[FILE_MAX] = {0}; + const char *cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, app_template); + char startup_file_path[FILE_MAX] = {0}; - if (cfgdir) { - BLI_join_dirfile(startup_file_path, sizeof(startup_file_path), cfgdir, BLENDER_STARTUP_FILE); - } + if (cfgdir) { + BLI_join_dirfile(startup_file_path, sizeof(startup_file_path), cfgdir, BLENDER_STARTUP_FILE); + } - bool has_path = BLI_exists(startup_file_path); - return (has_path) ? BKE_blendfile_workspace_config_read(startup_file_path, NULL, 0, NULL) : NULL; + bool has_path = BLI_exists(startup_file_path); + return (has_path) ? BKE_blendfile_workspace_config_read(startup_file_path, NULL, 0, NULL) : NULL; } static WorkspaceConfigFileData *workspace_system_file_read(const char *app_template) { - if (app_template == NULL) { - return BKE_blendfile_workspace_config_read(NULL, datatoc_startup_blend, datatoc_startup_blend_size, NULL); - } - - char template_dir[FILE_MAX]; - if (!BKE_appdir_app_template_id_search(app_template, template_dir, sizeof(template_dir))) { - return NULL; - } - - char startup_file_path[FILE_MAX]; - BLI_join_dirfile(startup_file_path, sizeof(startup_file_path), template_dir, BLENDER_STARTUP_FILE); - - bool has_path = BLI_exists(startup_file_path); - return (has_path) ? BKE_blendfile_workspace_config_read(startup_file_path, NULL, 0, NULL) : NULL; + if (app_template == NULL) { + return BKE_blendfile_workspace_config_read( + NULL, datatoc_startup_blend, datatoc_startup_blend_size, NULL); + } + + char template_dir[FILE_MAX]; + if (!BKE_appdir_app_template_id_search(app_template, template_dir, sizeof(template_dir))) { + return NULL; + } + + char startup_file_path[FILE_MAX]; + BLI_join_dirfile( + startup_file_path, sizeof(startup_file_path), template_dir, BLENDER_STARTUP_FILE); + + bool has_path = BLI_exists(startup_file_path); + return (has_path) ? BKE_blendfile_workspace_config_read(startup_file_path, NULL, 0, NULL) : NULL; } -static void workspace_append_button( - uiLayout *layout, wmOperatorType *ot_append, const WorkSpace *workspace, const Main *from_main) +static void workspace_append_button(uiLayout *layout, + wmOperatorType *ot_append, + const WorkSpace *workspace, + const Main *from_main) { - const ID *id = (ID *)workspace; - PointerRNA opptr; - char lib_path[FILE_MAX_LIBEXTRA]; - const char *filepath = from_main->name; - - if (strlen(filepath) == 0) { - filepath = BLO_EMBEDDED_STARTUP_BLEND; - } - - BLI_path_join( - lib_path, sizeof(lib_path), filepath, BKE_idcode_to_name(GS(id->name)), NULL); - - BLI_assert(STREQ(ot_append->idname, "WORKSPACE_OT_append_activate")); - uiItemFullO_ptr( - layout, ot_append, workspace->id.name + 2, ICON_NONE, NULL, - WM_OP_EXEC_DEFAULT, 0, &opptr); - RNA_string_set(&opptr, "idname", id->name + 2); - RNA_string_set(&opptr, "filepath", lib_path); + const ID *id = (ID *)workspace; + PointerRNA opptr; + char lib_path[FILE_MAX_LIBEXTRA]; + const char *filepath = from_main->name; + + if (strlen(filepath) == 0) { + filepath = BLO_EMBEDDED_STARTUP_BLEND; + } + + BLI_path_join(lib_path, sizeof(lib_path), filepath, BKE_idcode_to_name(GS(id->name)), NULL); + + BLI_assert(STREQ(ot_append->idname, "WORKSPACE_OT_append_activate")); + uiItemFullO_ptr( + layout, ot_append, workspace->id.name + 2, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr); + RNA_string_set(&opptr, "idname", id->name + 2); + RNA_string_set(&opptr, "filepath", lib_path); } static void workspace_add_menu(bContext *C, uiLayout *layout, void *template_v) { - Main *bmain = CTX_data_main(C); - const char *app_template = template_v; - bool has_startup_items = false; - - wmOperatorType *ot_append = WM_operatortype_find("WORKSPACE_OT_append_activate", true); - WorkspaceConfigFileData *startup_config = workspace_config_file_read(app_template); - WorkspaceConfigFileData *builtin_config = workspace_system_file_read(app_template); - - if (startup_config) { - for (WorkSpace *workspace = startup_config->workspaces.first; workspace; workspace = workspace->id.next) { - uiLayout *row = uiLayoutRow(layout, false); - if (BLI_findstring(&bmain->workspaces, workspace->id.name, offsetof(ID, name))) { - uiLayoutSetActive(row, false); - } - - workspace_append_button(row, ot_append, workspace, startup_config->main); - has_startup_items = true; - } - } - - if (builtin_config) { - bool has_title = false; - - for (WorkSpace *workspace = builtin_config->workspaces.first; workspace; workspace = workspace->id.next) { - if (startup_config && BLI_findstring(&startup_config->workspaces, workspace->id.name, offsetof(ID, name))) { - continue; - } - - if (!has_title) { - if (has_startup_items) { - uiItemS(layout); - } - has_title = true; - } - - uiLayout *row = uiLayoutRow(layout, false); - if (BLI_findstring(&bmain->workspaces, workspace->id.name, offsetof(ID, name))) { - uiLayoutSetActive(row, false); - } - - workspace_append_button(row, ot_append, workspace, builtin_config->main); - } - } - - if (startup_config) { - BKE_blendfile_workspace_config_data_free(startup_config); - } - if (builtin_config) { - BKE_blendfile_workspace_config_data_free(builtin_config); - } + Main *bmain = CTX_data_main(C); + const char *app_template = template_v; + bool has_startup_items = false; + + wmOperatorType *ot_append = WM_operatortype_find("WORKSPACE_OT_append_activate", true); + WorkspaceConfigFileData *startup_config = workspace_config_file_read(app_template); + WorkspaceConfigFileData *builtin_config = workspace_system_file_read(app_template); + + if (startup_config) { + for (WorkSpace *workspace = startup_config->workspaces.first; workspace; + workspace = workspace->id.next) { + uiLayout *row = uiLayoutRow(layout, false); + if (BLI_findstring(&bmain->workspaces, workspace->id.name, offsetof(ID, name))) { + uiLayoutSetActive(row, false); + } + + workspace_append_button(row, ot_append, workspace, startup_config->main); + has_startup_items = true; + } + } + + if (builtin_config) { + bool has_title = false; + + for (WorkSpace *workspace = builtin_config->workspaces.first; workspace; + workspace = workspace->id.next) { + if (startup_config && + BLI_findstring(&startup_config->workspaces, workspace->id.name, offsetof(ID, name))) { + continue; + } + + if (!has_title) { + if (has_startup_items) { + uiItemS(layout); + } + has_title = true; + } + + uiLayout *row = uiLayoutRow(layout, false); + if (BLI_findstring(&bmain->workspaces, workspace->id.name, offsetof(ID, name))) { + uiLayoutSetActive(row, false); + } + + workspace_append_button(row, ot_append, workspace, builtin_config->main); + } + } + + if (startup_config) { + BKE_blendfile_workspace_config_data_free(startup_config); + } + if (builtin_config) { + BKE_blendfile_workspace_config_data_free(builtin_config); + } } static int workspace_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - uiPopupMenu *pup = UI_popup_menu_begin(C, op->type->name, ICON_ADD); - uiLayout *layout = UI_popup_menu_layout(pup); + uiPopupMenu *pup = UI_popup_menu_begin(C, op->type->name, ICON_ADD); + uiLayout *layout = UI_popup_menu_layout(pup); - uiItemMenuF(layout, IFACE_("General"), ICON_NONE, workspace_add_menu, NULL); + uiItemMenuF(layout, IFACE_("General"), ICON_NONE, workspace_add_menu, NULL); - ListBase templates; - BKE_appdir_app_templates(&templates); + ListBase templates; + BKE_appdir_app_templates(&templates); - for (LinkData *link = templates.first; link; link = link->next) { - char *template = link->data; - char display_name[FILE_MAX]; + for (LinkData *link = templates.first; link; link = link->next) { + char *template = link->data; + char display_name[FILE_MAX]; - BLI_path_to_display_name(display_name, sizeof(display_name), template); + BLI_path_to_display_name(display_name, sizeof(display_name), template); - /* Steals ownership of link data string. */ - uiItemMenuFN(layout, display_name, ICON_NONE, workspace_add_menu, template); - } + /* Steals ownership of link data string. */ + uiItemMenuFN(layout, display_name, ICON_NONE, workspace_add_menu, template); + } - BLI_freelistN(&templates); + BLI_freelistN(&templates); - uiItemS(layout); - uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Duplicate Current"), ICON_DUPLICATE, - "WORKSPACE_OT_duplicate"); + uiItemS(layout); + uiItemO(layout, + CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Duplicate Current"), + ICON_DUPLICATE, + "WORKSPACE_OT_duplicate"); - UI_popup_menu_end(C, pup); + UI_popup_menu_end(C, pup); - return OPERATOR_INTERFACE; + return OPERATOR_INTERFACE; } static void WORKSPACE_OT_add(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Add Workspace"; - ot->description = "Add a new workspace by duplicating the current one or appending one " - "from the user configuration"; - ot->idname = "WORKSPACE_OT_add"; - - /* api callbacks */ - ot->invoke = workspace_add_invoke; + /* identifiers */ + ot->name = "Add Workspace"; + ot->description = + "Add a new workspace by duplicating the current one or appending one " + "from the user configuration"; + ot->idname = "WORKSPACE_OT_add"; + + /* api callbacks */ + ot->invoke = workspace_add_invoke; } static int workspace_reorder_to_back_exec(bContext *C, wmOperator *UNUSED(op)) { - Main *bmain = CTX_data_main(C); - WorkSpace *workspace = workspace_context_get(C); + Main *bmain = CTX_data_main(C); + WorkSpace *workspace = workspace_context_get(C); - BKE_id_reorder(&bmain->workspaces, &workspace->id, NULL, true); - WM_event_add_notifier(C, NC_WINDOW, NULL); + BKE_id_reorder(&bmain->workspaces, &workspace->id, NULL, true); + WM_event_add_notifier(C, NC_WINDOW, NULL); - return OPERATOR_INTERFACE; + return OPERATOR_INTERFACE; } static void WORKSPACE_OT_reorder_to_back(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Workspace Reorder to Back"; - ot->description = "Reorder workspace to be first in the list"; - ot->idname = "WORKSPACE_OT_reorder_to_back"; - - /* api callbacks */ - ot->poll = workspace_context_poll; - ot->exec = workspace_reorder_to_back_exec; + /* identifiers */ + ot->name = "Workspace Reorder to Back"; + ot->description = "Reorder workspace to be first in the list"; + ot->idname = "WORKSPACE_OT_reorder_to_back"; + + /* api callbacks */ + ot->poll = workspace_context_poll; + ot->exec = workspace_reorder_to_back_exec; } static int workspace_reorder_to_front_exec(bContext *C, wmOperator *UNUSED(op)) { - Main *bmain = CTX_data_main(C); - WorkSpace *workspace = workspace_context_get(C); + Main *bmain = CTX_data_main(C); + WorkSpace *workspace = workspace_context_get(C); - BKE_id_reorder(&bmain->workspaces, &workspace->id, NULL, false); - WM_event_add_notifier(C, NC_WINDOW, NULL); + BKE_id_reorder(&bmain->workspaces, &workspace->id, NULL, false); + WM_event_add_notifier(C, NC_WINDOW, NULL); - return OPERATOR_INTERFACE; + return OPERATOR_INTERFACE; } static void WORKSPACE_OT_reorder_to_front(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Workspace Reorder to Front"; - ot->description = "Reorder workspace to be first in the list"; - ot->idname = "WORKSPACE_OT_reorder_to_front"; - - /* api callbacks */ - ot->poll = workspace_context_poll; - ot->exec = workspace_reorder_to_front_exec; + /* identifiers */ + ot->name = "Workspace Reorder to Front"; + ot->description = "Reorder workspace to be first in the list"; + ot->idname = "WORKSPACE_OT_reorder_to_front"; + + /* api callbacks */ + ot->poll = workspace_context_poll; + ot->exec = workspace_reorder_to_front_exec; } void ED_operatortypes_workspace(void) { - WM_operatortype_append(WORKSPACE_OT_duplicate); - WM_operatortype_append(WORKSPACE_OT_delete); - WM_operatortype_append(WORKSPACE_OT_add); - WM_operatortype_append(WORKSPACE_OT_append_activate); - WM_operatortype_append(WORKSPACE_OT_reorder_to_back); - WM_operatortype_append(WORKSPACE_OT_reorder_to_front); + WM_operatortype_append(WORKSPACE_OT_duplicate); + WM_operatortype_append(WORKSPACE_OT_delete); + WM_operatortype_append(WORKSPACE_OT_add); + WM_operatortype_append(WORKSPACE_OT_append_activate); + WM_operatortype_append(WORKSPACE_OT_reorder_to_back); + WM_operatortype_append(WORKSPACE_OT_reorder_to_front); } /** \} Workspace Operators */ diff --git a/source/blender/editors/screen/workspace_layout_edit.c b/source/blender/editors/screen/workspace_layout_edit.c index 401f0323af6..67ac5067134 100644 --- a/source/blender/editors/screen/workspace_layout_edit.c +++ b/source/blender/editors/screen/workspace_layout_edit.c @@ -40,164 +40,163 @@ /** * Empty screen, with 1 dummy area without spacedata. Uses window size. */ -WorkSpaceLayout *ED_workspace_layout_add( - Main *bmain, - WorkSpace *workspace, - wmWindow *win, - const char *name) +WorkSpaceLayout *ED_workspace_layout_add(Main *bmain, + WorkSpace *workspace, + wmWindow *win, + const char *name) { - bScreen *screen; - rcti screen_rect; + bScreen *screen; + rcti screen_rect; - WM_window_screen_rect_calc(win, &screen_rect); - screen = screen_add(bmain, name, &screen_rect); + WM_window_screen_rect_calc(win, &screen_rect); + screen = screen_add(bmain, name, &screen_rect); - return BKE_workspace_layout_add(bmain, workspace, screen, name); + return BKE_workspace_layout_add(bmain, workspace, screen, name); } -WorkSpaceLayout *ED_workspace_layout_duplicate( - Main *bmain, - WorkSpace *workspace, const WorkSpaceLayout *layout_old, - wmWindow *win) +WorkSpaceLayout *ED_workspace_layout_duplicate(Main *bmain, + WorkSpace *workspace, + const WorkSpaceLayout *layout_old, + wmWindow *win) { - bScreen *screen_old = BKE_workspace_layout_screen_get(layout_old); - const char *name = BKE_workspace_layout_name_get(layout_old); - bScreen *screen_new; - WorkSpaceLayout *layout_new; - - layout_new = ED_workspace_layout_add(bmain, workspace, win, name); - screen_new = BKE_workspace_layout_screen_get(layout_new); - - if (BKE_screen_is_fullscreen_area(screen_old)) { - for (ScrArea *area_old = screen_old->areabase.first; area_old; area_old = area_old->next) { - if (area_old->full) { - ScrArea *area_new = (ScrArea *)screen_new->areabase.first; - ED_area_data_copy(area_new, area_old, true); - ED_area_tag_redraw(area_new); - break; - } - } - } - else { - screen_data_copy(screen_new, screen_old); - } - - return layout_new; + bScreen *screen_old = BKE_workspace_layout_screen_get(layout_old); + const char *name = BKE_workspace_layout_name_get(layout_old); + bScreen *screen_new; + WorkSpaceLayout *layout_new; + + layout_new = ED_workspace_layout_add(bmain, workspace, win, name); + screen_new = BKE_workspace_layout_screen_get(layout_new); + + if (BKE_screen_is_fullscreen_area(screen_old)) { + for (ScrArea *area_old = screen_old->areabase.first; area_old; area_old = area_old->next) { + if (area_old->full) { + ScrArea *area_new = (ScrArea *)screen_new->areabase.first; + ED_area_data_copy(area_new, area_old, true); + ED_area_tag_redraw(area_new); + break; + } + } + } + else { + screen_data_copy(screen_new, screen_old); + } + + return layout_new; } -static bool workspace_layout_delete_doit( - WorkSpace *workspace, WorkSpaceLayout *layout_old, WorkSpaceLayout *layout_new, - bContext *C) +static bool workspace_layout_delete_doit(WorkSpace *workspace, + WorkSpaceLayout *layout_old, + WorkSpaceLayout *layout_new, + bContext *C) { - Main *bmain = CTX_data_main(C); - wmWindow *win = CTX_wm_window(C); - bScreen *screen_new = BKE_workspace_layout_screen_get(layout_new); + Main *bmain = CTX_data_main(C); + wmWindow *win = CTX_wm_window(C); + bScreen *screen_new = BKE_workspace_layout_screen_get(layout_new); - ED_screen_change(C, screen_new); + ED_screen_change(C, screen_new); - if (BKE_workspace_active_layout_get(win->workspace_hook) != layout_old) { - BKE_workspace_layout_remove(bmain, workspace, layout_old); - return true; - } + if (BKE_workspace_active_layout_get(win->workspace_hook) != layout_old) { + BKE_workspace_layout_remove(bmain, workspace, layout_old); + return true; + } - return false; + return false; } bool workspace_layout_set_poll(const WorkSpaceLayout *layout) { - const bScreen *screen = BKE_workspace_layout_screen_get(layout); - - return ((BKE_screen_is_used(screen) == false) && - /* in typical usage temp screens should have a nonzero winid - * (all temp screens should be used, or closed & freed). */ - (screen->temp == false) && - (BKE_screen_is_fullscreen_area(screen) == false) && - (screen->id.name[2] != '.' || !(U.uiflag & USER_HIDE_DOT))); + const bScreen *screen = BKE_workspace_layout_screen_get(layout); + + return ((BKE_screen_is_used(screen) == false) && + /* in typical usage temp screens should have a nonzero winid + * (all temp screens should be used, or closed & freed). */ + (screen->temp == false) && (BKE_screen_is_fullscreen_area(screen) == false) && + (screen->id.name[2] != '.' || !(U.uiflag & USER_HIDE_DOT))); } static WorkSpaceLayout *workspace_layout_delete_find_new(const WorkSpaceLayout *layout_old) { - for (WorkSpaceLayout *layout_new = layout_old->prev; layout_new; layout_new = layout_new->next) { - if (workspace_layout_set_poll(layout_new)) { - return layout_new; - } - } - - for (WorkSpaceLayout *layout_new = layout_old->next; layout_new; layout_new = layout_new->next) { - if (workspace_layout_set_poll(layout_new)) { - return layout_new; - } - } - - return NULL; + for (WorkSpaceLayout *layout_new = layout_old->prev; layout_new; layout_new = layout_new->next) { + if (workspace_layout_set_poll(layout_new)) { + return layout_new; + } + } + + for (WorkSpaceLayout *layout_new = layout_old->next; layout_new; layout_new = layout_new->next) { + if (workspace_layout_set_poll(layout_new)) { + return layout_new; + } + } + + return NULL; } /** * \warning Only call outside of area/region loops! * \return true if succeeded. */ -bool ED_workspace_layout_delete( - WorkSpace *workspace, WorkSpaceLayout *layout_old, - bContext *C) +bool ED_workspace_layout_delete(WorkSpace *workspace, WorkSpaceLayout *layout_old, bContext *C) { - const bScreen *screen_old = BKE_workspace_layout_screen_get(layout_old); - WorkSpaceLayout *layout_new; + const bScreen *screen_old = BKE_workspace_layout_screen_get(layout_old); + WorkSpaceLayout *layout_new; - BLI_assert(BLI_findindex(BKE_workspace_layouts_get(workspace), layout_old) != -1); + BLI_assert(BLI_findindex(BKE_workspace_layouts_get(workspace), layout_old) != -1); - /* don't allow deleting temp fullscreens for now */ - if (BKE_screen_is_fullscreen_area(screen_old)) { - return false; - } + /* don't allow deleting temp fullscreens for now */ + if (BKE_screen_is_fullscreen_area(screen_old)) { + return false; + } - /* A layout/screen can only be in use by one window at a time, so as - * long as we are able to find a layout/screen that is unused, we - * can safely assume ours is not in use anywhere an delete it. */ + /* A layout/screen can only be in use by one window at a time, so as + * long as we are able to find a layout/screen that is unused, we + * can safely assume ours is not in use anywhere an delete it. */ - layout_new = workspace_layout_delete_find_new(layout_old); + layout_new = workspace_layout_delete_find_new(layout_old); - if (layout_new) { - return workspace_layout_delete_doit(workspace, layout_old, layout_new, C); - } + if (layout_new) { + return workspace_layout_delete_doit(workspace, layout_old, layout_new, C); + } - return false; + return false; } static bool workspace_layout_cycle_iter_cb(const WorkSpaceLayout *layout, void *UNUSED(arg)) { - /* return false to stop iterator when we have found a layout to activate */ - return !workspace_layout_set_poll(layout); + /* return false to stop iterator when we have found a layout to activate */ + return !workspace_layout_set_poll(layout); } -bool ED_workspace_layout_cycle( - WorkSpace *workspace, const short direction, bContext *C) +bool ED_workspace_layout_cycle(WorkSpace *workspace, const short direction, bContext *C) { - wmWindow *win = CTX_wm_window(C); - WorkSpaceLayout *old_layout = BKE_workspace_active_layout_get(win->workspace_hook); - WorkSpaceLayout *new_layout; - const bScreen *old_screen = BKE_workspace_layout_screen_get(old_layout); - ScrArea *sa = CTX_wm_area(C); + wmWindow *win = CTX_wm_window(C); + WorkSpaceLayout *old_layout = BKE_workspace_active_layout_get(win->workspace_hook); + WorkSpaceLayout *new_layout; + const bScreen *old_screen = BKE_workspace_layout_screen_get(old_layout); + ScrArea *sa = CTX_wm_area(C); - if (old_screen->temp || (sa && sa->full && sa->full->temp)) { - return false; - } + if (old_screen->temp || (sa && sa->full && sa->full->temp)) { + return false; + } - BLI_assert(ELEM(direction, 1, -1)); - new_layout = BKE_workspace_layout_iter_circular(workspace, old_layout, workspace_layout_cycle_iter_cb, - NULL, (direction == -1) ? true : false); + BLI_assert(ELEM(direction, 1, -1)); + new_layout = BKE_workspace_layout_iter_circular(workspace, + old_layout, + workspace_layout_cycle_iter_cb, + NULL, + (direction == -1) ? true : false); - if (new_layout && (old_layout != new_layout)) { - bScreen *new_screen = BKE_workspace_layout_screen_get(new_layout); + if (new_layout && (old_layout != new_layout)) { + bScreen *new_screen = BKE_workspace_layout_screen_get(new_layout); - if (sa && sa->full) { - /* return to previous state before switching screens */ - ED_screen_full_restore(C, sa); /* may free screen of old_layout */ - } + if (sa && sa->full) { + /* return to previous state before switching screens */ + ED_screen_full_restore(C, sa); /* may free screen of old_layout */ + } - ED_screen_change(C, new_screen); + ED_screen_change(C, new_screen); - return true; - } + return true; + } - return false; + return false; } |