diff options
Diffstat (limited to 'source/blender/editors/screen')
-rw-r--r-- | source/blender/editors/screen/area.c | 263 | ||||
-rw-r--r-- | source/blender/editors/screen/glutil.c | 41 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_context.c | 24 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_edit.c | 106 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_intern.h | 2 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 58 | ||||
-rw-r--r-- | source/blender/editors/screen/screendump.c | 36 |
7 files changed, 468 insertions, 62 deletions
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index c423d81bfe2..7fe6518134e 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -61,6 +61,9 @@ #include "BIF_glutil.h" #include "BLF_api.h" +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + #include "UI_interface.h" #include "UI_interface_icons.h" #include "UI_resources.h" @@ -149,6 +152,34 @@ void ED_area_do_refresh(bContext *C, ScrArea *sa) } /** + * Action zones are only updated if the mouse is inside of them, but in some cases (currently only fullscreen icon) + * it might be needed to update their properties and redraw if the mouse isn't inside. + */ +void ED_area_azones_update(ScrArea *sa, const int mouse_xy[2]) +{ + AZone *az; + bool changed = false; + + for (az = sa->actionzones.first; az; az = az->next) { + if (az->type == AZONE_FULLSCREEN) { + /* only if mouse is not hovering the azone */ + if (BLI_rcti_isect_pt_v(&az->rect, mouse_xy) == false) { + az->alpha = 0.0f; + changed = true; + + /* can break since currently only this is handled here */ + break; + } + } + } + + if (changed) { + sa->flag &= ~AREA_FLAG_ACTIONZONES_UPDATE; + ED_area_tag_redraw(sa); + } +} + +/** * \brief Corner widget use for quitting fullscreen. */ static void area_draw_azone_fullscreen(short x1, short y1, short x2, short y2, float alpha) @@ -366,6 +397,11 @@ static void region_draw_azone_tria(AZone *az) glDisable(GL_BLEND); } +static void area_azone_tag_update(ScrArea *sa) +{ + sa->flag |= AREA_FLAG_ACTIONZONES_UPDATE; +} + static void region_draw_azones(ScrArea *sa, ARegion *ar) { AZone *az; @@ -406,6 +442,10 @@ static void region_draw_azones(ScrArea *sa, ARegion *ar) } else if (az->type == AZONE_FULLSCREEN) { area_draw_azone_fullscreen(az->x1, az->y1, az->x2, az->y2, az->alpha); + + if (az->alpha != 0.0f) { + area_azone_tag_update(sa); + } } } } @@ -493,7 +533,6 @@ void ED_region_do_draw(bContext *C, ARegion *ar) glDisable(GL_BLEND); #endif - ar->do_draw = 0; memset(&ar->drawrct, 0, sizeof(ar->drawrct)); UI_blocklist_free_inactive(C, &ar->uiblocks); @@ -773,7 +812,7 @@ static void region_azone_tab_plus(ScrArea *sa, AZone *az, ARegion *ar) switch (az->edge) { case AE_TOP_TO_BOTTOMRIGHT: - if (ar->winrct.ymax == sa->totrct.ymin) add = 1; else add = 0; + add = (ar->winrct.ymax == sa->totrct.ymin) ? 1 : 0; az->x1 = ar->winrct.xmax - 2.5f * AZONEPAD_TAB_PLUSW; az->y1 = ar->winrct.ymax - add; az->x2 = ar->winrct.xmax - 1.5f * AZONEPAD_TAB_PLUSW; @@ -818,7 +857,7 @@ static void region_azone_tab(ScrArea *sa, AZone *az, ARegion *ar) switch (az->edge) { case AE_TOP_TO_BOTTOMRIGHT: - if (ar->winrct.ymax == sa->totrct.ymin) add = 1; else add = 0; + add = (ar->winrct.ymax == sa->totrct.ymin) ? 1 : 0; az->x1 = ar->winrct.xmax - 2 * AZONEPAD_TABW; az->y1 = ar->winrct.ymax - add; az->x2 = ar->winrct.xmax - AZONEPAD_TABW; @@ -863,7 +902,7 @@ static void region_azone_tria(ScrArea *sa, AZone *az, ARegion *ar) switch (az->edge) { case AE_TOP_TO_BOTTOMRIGHT: - if (ar->winrct.ymax == sa->totrct.ymin) add = 1; else add = 0; + add = (ar->winrct.ymax == sa->totrct.ymin) ? 1 : 0; az->x1 = ar->winrct.xmax - 2 * AZONEPAD_TRIAW; az->y1 = ar->winrct.ymax - add; az->x2 = ar->winrct.xmax - AZONEPAD_TRIAW; @@ -1224,16 +1263,22 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti if (ar->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)) { ar->winrct = *remainder; - if (alignment == RGN_ALIGN_TOP) - ar->winrct.ymin = ar->winrct.ymax; - else if (alignment == RGN_ALIGN_BOTTOM) - ar->winrct.ymax = ar->winrct.ymin; - else if (alignment == RGN_ALIGN_RIGHT) - ar->winrct.xmin = ar->winrct.xmax; - else if (alignment == RGN_ALIGN_LEFT) - ar->winrct.xmax = ar->winrct.xmin; - else /* prevent winrct to be valid */ - ar->winrct.xmax = ar->winrct.xmin; + 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 */ @@ -2028,6 +2073,196 @@ void ED_region_info_draw(ARegion *ar, const char *text, int block, float fill_co glScissor(scissor[0], scissor[1], scissor[2], scissor[3]); } +#define MAX_METADATA_STR 1024 + +static const char *meta_data_list[] = +{ + "File", + "Strip", + "Note", + "Date", + "RenderTime", + "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, meta_data_list[index], r_str + offset, MAX_METADATA_STR - offset) && r_str[0]); +} + +static void metadata_draw_imbuf(ImBuf *ibuf, 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 vertical_offset = height + (0.1f * U.widget_unit); + + 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, rect.xmin + (0.2f * U.widget_unit), + rect.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, rect.xmax - line_width - (0.2f * U.widget_unit), + rect.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; + } + else if (i == 1) { + 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, rect.xmin + (0.2f * U.widget_unit), + rect.ymax - vertical_offset - ofs_y, 0.0f); + BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); + ofs_y += vertical_offset; + } + } + 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, rect.xmax - line_width - (0.2f * U.widget_unit), + rect.ymax - vertical_offset - ofs_y, 0.0f); + BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX); + ofs_y += vertical_offset; + } + } + } + } + else { + int ofs_x = 0; + 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, rect.xmin + (0.2f * U.widget_unit) + ofs_x, + rect.ymin + (0.3f * U.widget_unit), 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; + } + } + } +} + +static float metadata_box_height_get(ImBuf *ibuf, int fontid, const bool is_top) +{ + char str[MAX_METADATA_STR] = ""; + short i, count = 0; + const float height = BLF_height_max(fontid) + 0.1f * U.widget_unit; + + 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)) { + count++; + } + } + } + else { + for (i = 5; i < 10; i++) { + if (metadata_is_valid(ibuf, str, i, 0)) { + count = 1; + } + } + } + + if (count) { + return (height * count + (0.1f * U.widget_unit)); + } + + return 0; +} + +#undef MAX_METADATA_STR + +void ED_region_image_metadata_draw(int x, int y, ImBuf *ibuf, rctf frame, float zoomx, float zoomy) +{ + float box_y; + rctf rect; + uiStyle *style = UI_style_get_dpi(); + + if (!ibuf->metadata) + return; + + /* find window pixel coordinates of origin */ + glPushMatrix(); + + /* offset and zoom using ogl */ + glTranslatef(x, y, 0.0f); + glScalef(zoomx, zoomy, 1.0f); + + BLF_size(blf_mono_font, style->widgetlabel.points * 1.5f, U.dpi); + + /* *** upper box*** */ + + /* get needed box height */ + box_y = metadata_box_height_get(ibuf, blf_mono_font, true); + + if (box_y) { + UI_ThemeColor(TH_METADATA_BG); + + /* set up rect */ + BLI_rctf_init(&rect, frame.xmin, frame.xmax, frame.ymax, frame.ymax + box_y); + /* draw top box */ + glRectf(rect.xmin, rect.ymin, rect.xmax, rect.ymax); + + BLF_clipping(blf_mono_font, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + BLF_enable(blf_mono_font, BLF_CLIPPING); + + UI_ThemeColor(TH_METADATA_TEXT); + metadata_draw_imbuf(ibuf, rect, blf_mono_font, true); + + BLF_disable(blf_mono_font, BLF_CLIPPING); + } + + + /* *** lower box*** */ + + box_y = metadata_box_height_get(ibuf, blf_mono_font, false); + + if (box_y) { + UI_ThemeColor(TH_METADATA_BG); + + /* set up box rect */ + BLI_rctf_init(&rect, frame.xmin, frame.xmax, frame.ymin - box_y, frame.ymin); + /* draw top box */ + glRectf(rect.xmin, rect.ymin, rect.xmax, rect.ymax); + + BLF_clipping(blf_mono_font, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + BLF_enable(blf_mono_font, BLF_CLIPPING); + + UI_ThemeColor(TH_METADATA_TEXT); + metadata_draw_imbuf(ibuf, rect, blf_mono_font, false); + + BLF_disable(blf_mono_font, BLF_CLIPPING); + } + + glPopMatrix(); +} + void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy) { float gridsize, gridstep = 1.0f / 32.0f; diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index 6001534e88d..fd65d81baad 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -579,25 +579,25 @@ void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, continue; if (type == GL_FLOAT) { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, format, GL_FLOAT, &f_rect[subpart_y * offset_y * img_w * components + subpart_x * offset_x * components]); + 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[subpart_y * offset_y * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]); + 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[(subpart_y * offset_y + subpart_h - 1) * img_w * components + subpart_x * offset_x * components]); + 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[(subpart_y * offset_y + subpart_h - 1) * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]); + 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[subpart_y * offset_y * img_w * components + subpart_x * offset_x * components]); + 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[subpart_y * offset_y * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]); + 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[(subpart_y * offset_y + subpart_h - 1) * img_w * components + subpart_x * offset_x * components]); + 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[(subpart_y * offset_y + subpart_h - 1) * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]); + 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]); } glEnable(GL_TEXTURE_2D); @@ -841,7 +841,7 @@ void gla2DDrawTranslatePt(gla2DDrawInfo *di, float wo_x, float wo_y, int *r_sc_x /** * Translate the \a world point from world coordinates into screen space. */ -void gla2DDrawTranslatePtv(gla2DDrawInfo *di, float world[2], int screen_r[2]) +void gla2DDrawTranslatePtv(gla2DDrawInfo *di, float world[2], int r_screen[2]) { screen_r[0] = (world[0] - di->world_rect.xmin) * di->wo_to_sc[0]; screen_r[1] = (world[1] - di->world_rect.ymin) * di->wo_to_sc[1]; @@ -991,7 +991,7 @@ void bgl_get_mats(bglMats *mats) /** * \note \a viewdist is only for ortho at the moment. */ -void bglPolygonOffset(float viewdist, float dist) +void bglPolygonOffset(float viewdist, float dist) { static float winmat[16], offset = 0.0; @@ -1007,8 +1007,25 @@ void bglPolygonOffset(float viewdist, float dist) /* dist is from camera to center point */ - if (winmat[15] > 0.5f) offs = 0.00001f * dist * viewdist; // ortho tweaking - else offs = 0.0005f * dist; // should be clipping value or so... + if (winmat[15] > 0.5f) { +#if 1 + offs = 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); +#endif + } + else { + /* should be clipping value or so... */ + offs = 0.0005f * dist; + } winmat[14] -= offs; offset += offs; diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index 3431ce9f50a..87c0ce398e5 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -47,6 +47,7 @@ #include "BKE_action.h" #include "BKE_armature.h" #include "BKE_gpencil.h" +#include "BKE_screen.h" #include "BKE_sequencer.h" #include "RNA_access.h" @@ -59,6 +60,18 @@ #include "screen_intern.h" +static unsigned int context_layers(bScreen *sc, Scene *scene, ScrArea *sa_ctx) +{ + /* needed for 'USE_ALLSELECT' define, otherwise we end up editing off-screen layers. */ + if (sc && sa_ctx && (sa_ctx->spacetype == SPACE_BUTS)) { + const unsigned int lay = BKE_screen_view3d_layer_all(sc); + if (lay) { + return lay; + } + } + return scene->lay; +} + const char *screen_context_dir[] = { "scene", "visible_objects", "visible_bases", "selectable_objects", "selectable_bases", "selected_objects", "selected_bases", @@ -81,7 +94,6 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult ScrArea *sa = CTX_wm_area(C); Scene *scene = sc->scene; Base *base; - unsigned int lay = scene->lay; #if 0 /* Using the context breaks adding objects in the UI. Need to find out why - campbell */ Object *obact = CTX_data_active_object(C); @@ -102,10 +114,11 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult return 1; } else if (CTX_data_equals(member, "visible_objects") || CTX_data_equals(member, "visible_bases")) { + const unsigned int lay = context_layers(sc, scene, sa); int visible_objects = CTX_data_equals(member, "visible_objects"); for (base = scene->base.first; base; base = base->next) { - if (((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) && (base->lay & scene->lay)) { + if (((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) && (base->lay & lay)) { if (visible_objects) CTX_data_id_list_add(result, &base->object->id); else @@ -116,6 +129,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult return 1; } else if (CTX_data_equals(member, "selectable_objects") || CTX_data_equals(member, "selectable_bases")) { + const unsigned int lay = context_layers(sc, scene, sa); int selectable_objects = CTX_data_equals(member, "selectable_objects"); for (base = scene->base.first; base; base = base->next) { @@ -132,10 +146,11 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult return 1; } else if (CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) { + const unsigned int lay = context_layers(sc, scene, sa); int selected_objects = CTX_data_equals(member, "selected_objects"); for (base = scene->base.first; base; base = base->next) { - if ((base->flag & SELECT) && (base->lay & scene->lay)) { + if ((base->flag & SELECT) && (base->lay & lay)) { if (selected_objects) CTX_data_id_list_add(result, &base->object->id); else @@ -146,10 +161,11 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult return 1; } else if (CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) { + const unsigned int lay = context_layers(sc, scene, sa); int selected_editable_objects = CTX_data_equals(member, "selected_editable_objects"); for (base = scene->base.first; base; base = base->next) { - if ((base->flag & SELECT) && (base->lay & scene->lay)) { + if ((base->flag & SELECT) && (base->lay & lay)) { if ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0) { if (0 == BKE_object_is_libdata(base->object)) { if (selected_editable_objects) diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index aadfa9e6608..0c40c833c0d 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -59,6 +59,7 @@ #include "ED_screen.h" #include "ED_screen_types.h" #include "ED_clip.h" +#include "ED_node.h" #include "ED_render.h" #include "UI_interface.h" @@ -1747,7 +1748,9 @@ ScrArea *ED_screen_full_newspace(bContext *C, ScrArea *sa, int type) newsa = sa; } } - + + BLI_assert(newsa); + if (sa && (sa->spacetype != type)) { newsa->flag |= AREA_FLAG_TEMP_TYPE; } @@ -1760,11 +1763,18 @@ ScrArea *ED_screen_full_newspace(bContext *C, ScrArea *sa, int type) return newsa; } -void ED_screen_full_prevspace(bContext *C, ScrArea *sa) +/** + * \a was_prev_temp for the case previous space was a temporary fullscreen as well + */ +void ED_screen_full_prevspace(bContext *C, ScrArea *sa, const bool was_prev_temp) { 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); + /* only clear if previous space wasn't a temp fullscreen as well */ + if (!was_prev_temp) { + sa->flag &= ~AREA_FLAG_TEMP_TYPE; + } } else { ED_screen_restore_temp_type(C, sa); @@ -1799,13 +1809,12 @@ void ED_screen_full_restore(bContext *C, ScrArea *sa) if (sl->next) { if (sa->flag & AREA_FLAG_TEMP_TYPE) { - ED_screen_full_prevspace(C, sa); + ED_screen_full_prevspace(C, sa, false); } else { ED_screen_state_toggle(C, win, sa, state); } - - sa->flag &= ~AREA_FLAG_TEMP_TYPE; + /* warning: 'sa' may be freed */ } /* otherwise just tile the area again */ else { @@ -1813,7 +1822,11 @@ void ED_screen_full_restore(bContext *C, ScrArea *sa) } } -/* this function toggles: if area is maximized/full then the parent will be restored */ +/** + * this function toggles: if area is maximized/full then the parent will be restored + * + * \warning \a sa may be freed. + */ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const short state) { bScreen *sc, *oldscreen; @@ -2118,4 +2131,85 @@ void ED_update_for_newframe(Main *bmain, Scene *scene, int UNUSED(mute)) } +/* + * return true if any active area requires to see in 3D + */ +bool ED_screen_stereo3d_required(bScreen *screen) +{ + ScrArea *sa; + Scene *sce = screen->scene; + const bool is_multiview = (sce->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 && (sima->image->flag & IMA_IS_STEREO) && + (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; +} diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h index 79036d3356f..ccb6d5a6dca 100644 --- a/source/blender/editors/screen/screen_intern.h +++ b/source/blender/editors/screen/screen_intern.h @@ -32,8 +32,6 @@ #define __SCREEN_INTERN_H__ /* internal exports only */ -struct wmWindow; -struct Scene; #define AZONESPOT (0.6f * U.widget_unit) #define AZONEFADEIN (5.0f * U.widget_unit) /* when azone is totally visible */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 48d39020236..e5c3cb4e5e2 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -81,6 +81,7 @@ #include "UI_interface.h" #include "UI_resources.h" +#include "UI_view2d.h" #include "screen_intern.h" /* own module include */ @@ -717,7 +718,7 @@ static void actionzone_apply(bContext *C, wmOperator *op, int type) else event.type = EVT_ACTIONZONE_REGION; - event.val = 0; + event.val = KM_NOTHING; event.customdata = op->customdata; event.customdatafree = true; op->customdata = NULL; @@ -990,6 +991,7 @@ static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event) rect.ymax = rect.ymin + BLI_rcti_size_y(&rect) / U.pixelsize; newwin = WM_window_open(C, &rect); + *newwin->stereo3d_format = *win->stereo3d_format; /* allocs new screen and adds to newly created window, using window size */ newsc = ED_screen_add(newwin, CTX_data_scene(C), sc->id.name + 2); @@ -1928,6 +1930,12 @@ static void region_scale_validate_size(RegionMoveData *rmd) 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); + } + region_toggle_hidden(C, rmd->ar, 0); region_scale_validate_size(rmd); } @@ -2099,7 +2107,7 @@ static int frame_offset_exec(bContext *C, wmOperator *op) areas_do_frame_follow(C, false); - sound_seek_scene(bmain, scene); + BKE_sound_seek_scene(bmain, scene); WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); @@ -2151,7 +2159,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op) areas_do_frame_follow(C, true); - sound_seek_scene(bmain, scene); + BKE_sound_seek_scene(bmain, scene); WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); } @@ -2257,7 +2265,7 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op) else { areas_do_frame_follow(C, true); - sound_seek_scene(bmain, scene); + BKE_sound_seek_scene(bmain, scene); WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); @@ -2319,7 +2327,7 @@ static int marker_jump_exec(bContext *C, wmOperator *op) areas_do_frame_follow(C, true); - sound_seek_scene(bmain, scene); + BKE_sound_seek_scene(bmain, scene); WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); @@ -3413,10 +3421,17 @@ static int match_region_with_redraws(int spacetype, int regiontype, int redraws) 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); +#ifdef PROFILE_AUDIO_SYNCH + 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); @@ -3435,14 +3450,27 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv if ((scene->audio.flag & AUDIO_SYNC) && (sad->flag & ANIMPLAY_FLAG_REVERSE) == false && - finite(time = sound_sync_scene(scene))) + finite(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; +#endif } else { if (sync) { @@ -3509,8 +3537,12 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv sad->flag |= ANIMPLAY_FLAG_JUMPED; } - if (sad->flag & ANIMPLAY_FLAG_JUMPED) - sound_seek_scene(bmain, scene); + if (sad->flag & ANIMPLAY_FLAG_JUMPED) { + BKE_sound_seek_scene(bmain, scene); +#ifdef PROFILE_AUDIO_SYNCH + old_frame = CFRA; +#endif + } /* since we follow drawflags, we can't send notifier but tag regions ourselves */ ED_update_for_newframe(bmain, scene, 1); @@ -3610,7 +3642,7 @@ int ED_screen_animation_play(bContext *C, int sync, int mode) if (ED_screen_animation_playing(CTX_wm_manager(C))) { /* stop playback now */ ED_screen_animation_timer(C, 0, 0, 0, 0); - sound_stop_scene(scene); + BKE_sound_stop_scene(scene); WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); } @@ -3618,7 +3650,7 @@ int ED_screen_animation_play(bContext *C, int sync, int mode) int refresh = SPACE_TIME; /* these settings are currently only available from a menu in the TimeLine */ if (mode == 1) /* XXX only play audio forwards!? */ - sound_play_scene(scene); + BKE_sound_play_scene(scene); ED_screen_animation_timer(C, screen->redraws_flag, refresh, sync, mode); @@ -3775,7 +3807,7 @@ static int fullscreen_back_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - ED_screen_full_prevspace(C, sa); + ED_screen_full_prevspace(C, sa, false); return OPERATOR_FINISHED; } @@ -4227,6 +4259,8 @@ void ED_keymap_screen(wmKeyConfig *keyconf) WM_keymap_verify_item(keymap, "SCREEN_OT_area_dupli", EVT_ACTIONZONE_AREA, 0, KM_SHIFT, 0); WM_keymap_verify_item(keymap, "SCREEN_OT_area_swap", EVT_ACTIONZONE_AREA, 0, KM_CTRL, 0); WM_keymap_verify_item(keymap, "SCREEN_OT_region_scale", EVT_ACTIONZONE_REGION, 0, 0, 0); + kmi = WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", EVT_ACTIONZONE_FULLSCREEN, 0, 0, 0); + RNA_boolean_set(kmi->ptr, "use_hide_panels", true); /* area move after action zones */ WM_keymap_verify_item(keymap, "SCREEN_OT_area_move", LEFTMOUSE, KM_PRESS, 0, 0); @@ -4254,8 +4288,6 @@ void ED_keymap_screen(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", SPACEKEY, KM_PRESS, KM_SHIFT, 0); kmi = WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", F10KEY, KM_PRESS, KM_ALT, 0); RNA_boolean_set(kmi->ptr, "use_hide_panels", true); - kmi = WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", EVT_ACTIONZONE_FULLSCREEN, 0, 0, 0); - RNA_boolean_set(kmi->ptr, "use_hide_panels", true); WM_keymap_add_item(keymap, "SCREEN_OT_screenshot", F3KEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "SCREEN_OT_screencast", F3KEY, KM_PRESS, KM_ALT, 0); diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c index 9c05f1d4780..3f66d84c185 100644 --- a/source/blender/editors/screen/screendump.c +++ b/source/blender/editors/screen/screendump.c @@ -303,6 +303,9 @@ typedef struct ScreenshotJob { const short *stop; const short *do_update; ReportList reports; + + bMovieHandle *movie_handle; + void *movie_ctx; } ScreenshotJob; @@ -312,7 +315,13 @@ static void screenshot_freejob(void *sjv) if (sj->dumprect) MEM_freeN(sj->dumprect); - + + if (sj->movie_handle) { + bMovieHandle *mh = sj->movie_handle; + mh->end_movie(sj->movie_ctx); + mh->context_free(sj->movie_ctx); + } + MEM_freeN(sj); } @@ -337,20 +346,22 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float { ScreenshotJob *sj = sjv; RenderData rd = sj->scene->r; - bMovieHandle *mh = BKE_movie_handle_get(sj->scene->r.im_format.imtype); - + bMovieHandle *mh = NULL; + /* we need this as local variables for renderdata */ rd.frs_sec = U.scrcastfps; rd.frs_sec_base = 1.0f; if (BKE_imtype_is_movie(rd.im_format.imtype)) { - if (!mh->start_movie(sj->scene, &rd, sj->dumpsx, sj->dumpsy, &sj->reports)) { + mh = BKE_movie_handle_get(sj->scene->r.im_format.imtype); + sj->movie_ctx = mh->context_create(); + sj->movie_handle = mh; + + if (!mh->start_movie(sj->movie_ctx, sj->scene, &rd, sj->dumpsx, sj->dumpsy, &sj->reports, false, "")) { printf("screencast job stopped\n"); return; } } - else - mh = NULL; sj->stop = stop; sj->do_update = do_update; @@ -362,8 +373,8 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float if (sj->dumprect) { if (mh) { - if (mh->append_movie(&rd, rd.sfra, rd.cfra, (int *)sj->dumprect, - sj->dumpsx, sj->dumpsy, &sj->reports)) + if (mh->append_movie(sj->movie_ctx, &rd, rd.sfra, rd.cfra, (int *)sj->dumprect, + sj->dumpsx, sj->dumpsy, "", &sj->reports)) { BKE_reportf(&sj->reports, RPT_INFO, "Appended frame: %d", rd.cfra); printf("Appended frame %d\n", rd.cfra); @@ -379,7 +390,7 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float BKE_image_path_from_imformat( name, rd.pic, sj->bmain->name, rd.cfra, - &rd.im_format, (rd.scemode & R_EXTENSION) != 0, true); + &rd.im_format, (rd.scemode & R_EXTENSION) != 0, true, NULL); ibuf->rect = sj->dumprect; ok = BKE_imbuf_write(ibuf, name, &rd.im_format); @@ -410,8 +421,11 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float PIL_sleep_ms(U.scrcastwait); } - if (mh) - mh->end_movie(); + if (mh) { + mh->end_movie(sj->movie_ctx); + mh->context_free(sj->movie_ctx); + sj->movie_handle = NULL; + } BKE_report(&sj->reports, RPT_INFO, "Screencast job stopped"); } |